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 if ((e_config->wm_win_rotation) &&
6020 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
6022 (rot.vkbd_hide_prepare_timer))
6024 con = bd->zone->container;
6025 bd = e_border_new(con, e->win, 0, 0);
6030 if (!bd->lock_client_iconify)
6031 e_border_uniconify(bd);
6035 /* FIXME: make border "urgent" for a bit - it wants attention */
6036 /* e_border_show(bd); */
6037 if (!bd->lock_client_stacking)
6040 return ECORE_CALLBACK_PASS_ON;
6044 _e_border_cb_window_destroy(void *data __UNUSED__,
6045 int ev_type __UNUSED__,
6049 Ecore_X_Event_Window_Destroy *e;
6052 bd = e_border_find_by_client_window(e->win);
6053 if (!bd) return ECORE_CALLBACK_PASS_ON;
6054 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
6055 #ifdef _F_ZONE_WINDOW_ROTATION_
6056 if (e_config->wm_win_rotation)
6058 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6060 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
6061 if (!rot.vkbd_hide_prepare_timer)
6063 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6064 e_border_hide(bd, 0);
6065 if (!rot.vkbd_hide_prepare_timer)
6067 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6068 e_object_del(E_OBJECT(bd));
6071 return ECORE_CALLBACK_PASS_ON;
6076 #ifdef _F_DEICONIFY_APPROVE_
6077 if (e_config->wm_win_rotation)
6079 if (bd->client.e.state.pending_event.pending)
6081 bd->client.e.state.pending_event.destroy.pending = 1;
6082 bd->client.e.state.pending_event.destroy.win = e->win;
6083 bd->client.e.state.pending_event.destroy.event_win = e->event_win;
6084 ELB(ELBT_BD, "PENDING destroy event", bd->client.win);
6085 return ECORE_CALLBACK_CANCEL;
6089 ELB(ELBT_BD, "Real Destroy", bd->client.win);
6092 e_border_hide(bd, 0);
6093 e_object_del(E_OBJECT(bd));
6094 return ECORE_CALLBACK_PASS_ON;
6097 #ifdef _F_DEICONIFY_APPROVE_
6099 _e_border_find_below_win(E_Border* bd)
6107 passed = EINA_FALSE;
6111 bl = e_container_border_list_last(bd->zone->container);
6112 while ((temp_bd = e_container_border_list_prev(bl)))
6114 /* skip if it's the same border */
6121 if (e_object_is_del(E_OBJECT(temp_bd))) continue;
6123 /* skip if it's not on this zone */
6124 if (temp_bd->zone != bd->zone) continue;
6126 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))
6128 if (!temp_bd->client.argb && temp_bd->visible)
6135 if (!passed) continue;
6137 if ((!temp_bd->client.argb) &&
6138 (temp_bd->x == temp_bd->zone->x) &&
6139 (temp_bd->y == temp_bd->zone->y) &&
6140 (temp_bd->w == temp_bd->zone->w) &&
6141 (temp_bd->h == temp_bd->zone->h))
6143 if (temp_bd->visible)
6149 if (ecore_x_window_visible_get(temp_bd->client.win))
6156 e_container_border_list_free(bl);
6163 _e_border_cb_window_hide(void *data __UNUSED__,
6164 int ev_type __UNUSED__,
6167 E_Border *bd = NULL;
6168 Ecore_X_Event_Window_Hide *e;
6171 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
6172 // not interested in hide events from windows other than the window in question
6173 if (e->win != e->event_win)
6175 bd = e_border_find_by_client_window(e->win);
6176 if (!bd) return ECORE_CALLBACK_PASS_ON;
6177 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
6181 (bd->zone->container->manager->root == e->event_win)))
6182 return ECORE_CALLBACK_PASS_ON;
6185 if (!bd) bd = e_border_find_by_client_window(e->win);
6186 // printf(" bd = %p\n", bd);
6189 if (ecore_x_window_visible_get(e->win))
6191 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
6192 ecore_x_window_hide(e->win);
6194 return ECORE_CALLBACK_PASS_ON;
6197 #ifdef _F_DEICONIFY_APPROVE_
6198 if (e_config->wm_win_rotation)
6200 if (bd->client.e.state.pending_event.done)
6203 if (bd->client.e.state.pending_event.pending)
6205 return ECORE_CALLBACK_CANCEL;
6208 if (!E_CONTAINS(bd->x, bd->y, bd->w, bd->h, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
6212 // 1. find below non-alpha full size win
6213 below_bd = _e_border_find_below_win(bd);
6217 // 2. check those rotation
6218 bd->client.e.state.pending_event.pending = 1;
6219 bd->client.e.state.pending_event.hold_bd = below_bd;
6221 bd->client.e.state.pending_event.hide.pending = 1;
6222 bd->client.e.state.pending_event.hide.win = e->win;
6223 bd->client.e.state.pending_event.hide.event_win = e->event_win;
6224 bd->client.e.state.pending_event.hide.send_event = e->send_event;
6226 below_bd->client.e.state.deiconify_approve.pending_bd = bd;
6227 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);
6229 // 3. if not same then uniconify
6230 e_border_uniconify(below_bd);
6232 ELB(ELBT_BD, "PENDING hide event", bd->client.win);
6233 return ECORE_CALLBACK_CANCEL;
6238 bd->client.e.state.pending_event.done = 0;
6239 bd->client.e.state.pending_event.pending = 0;
6240 ELB(ELBT_BD, "Real hide", bd->client.win);
6243 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
6244 if (bd->ignore_first_unmap > 0)
6246 bd->ignore_first_unmap--;
6247 return ECORE_CALLBACK_PASS_ON;
6249 /* Don't delete hidden or iconified windows */
6250 #ifdef _F_USE_EXTENDED_ICONIFY_
6251 if (bd->await_hide_event > 0)
6253 if ((bd->iconic) || (bd->await_hide_event > 0))
6256 // printf(" Don't delete hidden or iconified windows\n");
6257 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6258 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6259 if (bd->await_hide_event > 0)
6261 bd->await_hide_event--;
6265 // printf(" hide really\n");
6266 /* Only hide the border if it is visible */
6267 if (bd->visible) e_border_hide(bd, 1);
6272 // printf(" hide2\n");
6273 #ifdef _F_USE_EXTENDED_ICONIFY_
6281 #ifdef _F_ZONE_WINDOW_ROTATION_
6282 if (e_config->wm_win_rotation)
6284 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6286 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6287 if (!rot.vkbd_hide_prepare_timer)
6289 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6290 e_border_hide(bd, 0);
6291 if (!rot.vkbd_hide_prepare_timer)
6293 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6294 e_object_del(E_OBJECT(bd));
6297 return ECORE_CALLBACK_PASS_ON;
6301 e_border_hide(bd, 0);
6302 e_object_del(E_OBJECT(bd));
6304 return ECORE_CALLBACK_PASS_ON;
6308 _e_border_cb_window_reparent(void *data __UNUSED__,
6309 int ev_type __UNUSED__,
6310 void *ev __UNUSED__)
6314 Ecore_X_Event_Window_Reparent *e;
6317 bd = e_border_find_by_client_window(e->win);
6319 if (e->parent == bd->client.shell_win) return 1;
6320 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6324 e_border_hide(bd, 0);
6325 e_object_del(E_OBJECT(bd));
6327 return ECORE_CALLBACK_PASS_ON;
6331 _e_border_cb_window_configure_request(void *data __UNUSED__,
6332 int ev_type __UNUSED__,
6336 Ecore_X_Event_Window_Configure_Request *e;
6339 bd = e_border_find_by_client_window(e->win);
6342 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6343 if (!e_util_container_window_find(e->win))
6344 ecore_x_window_configure(e->win, e->value_mask,
6345 e->x, e->y, e->w, e->h, e->border,
6346 e->abovewin, e->detail);
6347 return ECORE_CALLBACK_PASS_ON;
6350 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6351 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6357 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6359 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6361 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6362 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6368 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6369 w = e->w + bd->client_inset.l + bd->client_inset.r;
6370 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6371 h = e->h + bd->client_inset.t + bd->client_inset.b;
6372 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6374 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6376 bd->saved.x = x - bd->zone->x;
6377 bd->saved.y = y - bd->zone->y;
6382 e_border_move_resize(bd, x, y, w, h);
6384 else if (!bd->lock_client_location)
6386 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6388 bd->saved.x = x - bd->zone->x;
6389 bd->saved.y = y - bd->zone->y;
6392 e_border_move(bd, x, y);
6394 else if (!bd->lock_client_size)
6396 if ((bd->shaded) || (bd->shading))
6402 if ((bd->shade.dir == E_DIRECTION_UP) ||
6403 (bd->shade.dir == E_DIRECTION_DOWN))
6405 e_border_resize(bd, w, bd->h);
6410 e_border_resize(bd, bd->w, h);
6416 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6422 e_border_resize(bd, w, h);
6428 if (!bd->lock_client_location)
6430 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6432 bd->saved.x = x - bd->zone->x;
6433 bd->saved.y = y - bd->zone->y;
6436 e_border_move(bd, x, y);
6440 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6441 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6447 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6448 w = e->w + bd->client_inset.l + bd->client_inset.r;
6449 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6450 h = e->h + bd->client_inset.t + bd->client_inset.b;
6451 #ifdef _F_ZONE_WINDOW_ROTATION_
6452 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6454 if (!bd->lock_client_size)
6456 if ((bd->shaded) || (bd->shading))
6462 if ((bd->shade.dir == E_DIRECTION_UP) ||
6463 (bd->shade.dir == E_DIRECTION_DOWN))
6465 e_border_resize(bd, w, bd->h);
6470 e_border_resize(bd, bd->w, h);
6476 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6481 zx = zy = zw = zh = 0;
6484 * This code does resize and move a window on a
6485 * X configure request into an useful geometry.
6486 * This is really useful for size jumping file dialogs.
6491 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6493 if (e_config->geometry_auto_resize_limit == 1)
6502 e_border_resize(bd, w, h);
6504 if (e_config->geometry_auto_move == 1)
6506 /* z{x,y,w,h} are only set here; FIXME! */
6509 // move window horizontal if resize to not useful geometry
6510 if (bd->x + bd->w > zx + zw)
6511 rx = zx + zw - bd->w;
6512 else if (bd->x < zx)
6515 // move window vertical if resize to not useful geometry
6516 if (bd->y + bd->h > zy + zh)
6517 ry = zy + zh - bd->h;
6518 else if (bd->y < zy)
6521 e_border_move(bd, rx, ry);
6527 if (!bd->lock_client_stacking)
6529 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6530 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6534 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6536 obd = e_border_find_by_client_window(e->abovewin);
6539 e_border_stack_above(bd, obd);
6543 ecore_x_window_configure(bd->win,
6544 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6545 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6547 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6548 /* FIXME: need to rebuiuld border list from current stacking */
6551 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6553 obd = e_border_find_by_client_window(e->abovewin);
6556 e_border_stack_below(bd, obd);
6560 ecore_x_window_configure(bd->win,
6561 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6562 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6564 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6565 /* FIXME: need to rebuiuld border list from current stacking */
6568 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6572 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6576 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6581 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6583 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6587 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6591 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6595 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6599 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6606 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6607 _e_border_client_move_resize_send(bd);
6608 return ECORE_CALLBACK_PASS_ON;
6612 _e_border_cb_window_resize_request(void *data __UNUSED__,
6613 int ev_type __UNUSED__,
6617 Ecore_X_Event_Window_Resize_Request *e;
6620 bd = e_border_find_by_client_window(e->win);
6623 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6624 ecore_x_window_resize(e->win, e->w, e->h);
6625 return ECORE_CALLBACK_PASS_ON;
6630 w = e->w + bd->client_inset.l + bd->client_inset.r;
6631 h = e->h + bd->client_inset.t + bd->client_inset.b;
6632 if ((bd->shaded) || (bd->shading))
6638 if ((bd->shade.dir == E_DIRECTION_UP) ||
6639 (bd->shade.dir == E_DIRECTION_DOWN))
6641 e_border_resize(bd, w, bd->h);
6646 e_border_resize(bd, bd->w, h);
6651 e_border_resize(bd, w, h);
6654 _e_border_client_move_resize_send(bd);
6655 return ECORE_CALLBACK_PASS_ON;
6659 _e_border_cb_window_gravity(void *data __UNUSED__,
6660 int ev_type __UNUSED__,
6661 void *ev __UNUSED__)
6664 // Ecore_X_Event_Window_Gravity *e;
6667 // bd = e_border_find_by_client_window(e->win);
6668 // if (!bd) return 1;
6673 _e_border_cb_window_stack_request(void *data __UNUSED__,
6674 int ev_type __UNUSED__,
6678 Ecore_X_Event_Window_Stack_Request *e;
6681 bd = e_border_find_by_client_window(e->win);
6684 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6685 if (!e_util_container_window_find(e->win))
6687 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6688 ecore_x_window_raise(e->win);
6689 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6690 ecore_x_window_lower(e->win);
6692 return ECORE_CALLBACK_PASS_ON;
6694 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6696 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6698 return ECORE_CALLBACK_PASS_ON;
6702 _e_border_cb_window_property(void *data __UNUSED__,
6703 int ev_type __UNUSED__,
6707 Ecore_X_Event_Window_Property *e;
6710 bd = e_border_find_by_client_window(e->win);
6711 if (!bd) return ECORE_CALLBACK_PASS_ON;
6712 if (e->atom == ECORE_X_ATOM_WM_NAME)
6714 if ((!bd->client.netwm.name) &&
6715 (!bd->client.netwm.fetch.name))
6717 bd->client.icccm.fetch.title = 1;
6721 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6723 bd->client.netwm.fetch.name = 1;
6726 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6728 bd->client.icccm.fetch.name_class = 1;
6731 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6733 if ((!bd->client.netwm.icon_name) &&
6734 (!bd->client.netwm.fetch.icon_name))
6736 bd->client.icccm.fetch.icon_name = 1;
6740 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6742 bd->client.netwm.fetch.icon_name = 1;
6745 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6747 bd->client.icccm.fetch.machine = 1;
6750 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6752 bd->client.icccm.fetch.protocol = 1;
6755 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6757 bd->client.icccm.fetch.hints = 1;
6760 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6762 bd->client.icccm.fetch.size_pos_hints = 1;
6765 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6768 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6769 (!bd->client.netwm.fetch.type))
6772 bd->client.mwm.fetch.hints = 1;
6778 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6780 bd->client.icccm.fetch.transient_for = 1;
6783 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6785 bd->client.icccm.fetch.client_leader = 1;
6788 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6790 bd->client.icccm.fetch.window_role = 1;
6793 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6795 bd->client.netwm.fetch.icon = 1;
6798 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6800 bd->client.qtopia.fetch.soft_menu = 1;
6803 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6805 bd->client.qtopia.fetch.soft_menus = 1;
6808 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6810 bd->client.vkbd.fetch.state = 1;
6813 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6815 bd->client.vkbd.fetch.vkbd = 1;
6818 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6820 bd->client.illume.conformant.fetch.conformant = 1;
6823 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6825 bd->client.illume.quickpanel.fetch.state = 1;
6828 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6830 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6833 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6835 bd->client.illume.quickpanel.fetch.priority.major = 1;
6838 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6840 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6843 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6845 bd->client.illume.quickpanel.fetch.zone = 1;
6848 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6850 bd->client.illume.drag.fetch.locked = 1;
6853 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6855 bd->client.illume.drag.fetch.drag = 1;
6858 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6860 bd->client.illume.win_state.fetch.state = 1;
6864 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6866 bd->client.netwm.fetch.user_time = 1;
6869 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6871 bd->client.netwm.fetch.strut = 1;
6874 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6876 bd->client.netwm.fetch.strut = 1;
6880 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6882 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6884 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6886 bd->client.e.fetch.video_position = 1;
6889 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6891 bd->client.e.fetch.video_parent = 1;
6894 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6896 bd->client.netwm.fetch.state = 1;
6899 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6900 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6902 bd->client.e.fetch.profile_list = 1;
6906 #ifdef _F_ZONE_WINDOW_ROTATION_
6907 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6909 if (e_config->wm_win_rotation)
6911 bd->client.e.fetch.rot.support = 1;
6915 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6916 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6917 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6918 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6920 if (e_config->wm_win_rotation)
6922 bd->client.e.fetch.rot.geom_hint = 1;
6926 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6928 if (e_config->wm_win_rotation)
6930 bd->client.e.fetch.rot.app_set = 1;
6934 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6936 if (e_config->wm_win_rotation)
6938 bd->client.e.fetch.rot.preferred_rot = 1;
6942 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6944 if (e_config->wm_win_rotation)
6946 bd->client.e.fetch.rot.available_rots = 1;
6952 return ECORE_CALLBACK_PASS_ON;
6956 _e_border_cb_window_colormap(void *data __UNUSED__,
6957 int ev_type __UNUSED__,
6961 Ecore_X_Event_Window_Colormap *e;
6964 bd = e_border_find_by_client_window(e->win);
6965 if (!bd) return ECORE_CALLBACK_PASS_ON;
6966 return ECORE_CALLBACK_PASS_ON;
6970 _e_border_cb_window_shape(void *data __UNUSED__,
6971 int ev_type __UNUSED__,
6975 Ecore_X_Event_Window_Shape *e;
6978 bd = e_border_find_by_client_window(e->win);
6980 if (e->type == ECORE_X_SHAPE_INPUT)
6984 bd->need_shape_merge = 1;
6985 // YYY bd->shaped_input = 1;
6986 bd->changes.shape_input = 1;
6990 return ECORE_CALLBACK_PASS_ON;
6995 bd->changes.shape = 1;
6997 return ECORE_CALLBACK_PASS_ON;
6999 bd = e_border_find_by_window(e->win);
7002 bd->need_shape_export = 1;
7004 return ECORE_CALLBACK_PASS_ON;
7006 bd = e_border_find_by_frame_window(e->win);
7009 bd->need_shape_merge = 1;
7011 return ECORE_CALLBACK_PASS_ON;
7013 return ECORE_CALLBACK_PASS_ON;
7017 _e_border_cb_window_focus_in(void *data __UNUSED__,
7018 int ev_type __UNUSED__,
7022 Ecore_X_Event_Window_Focus_In *e;
7025 bd = e_border_find_by_client_window(e->win);
7026 if (!bd) return ECORE_CALLBACK_PASS_ON;
7027 #ifdef INOUTDEBUG_FOCUS
7032 const char *modes[] = {
7034 "MODE_WHILE_GRABBED",
7038 const char *details[] = {
7042 "DETAIL_NON_LINEAR",
7043 "DETAIL_NON_LINEAR_VIRTUAL",
7045 "DETAIL_POINTER_ROOT",
7046 "DETAIL_DETAIL_NONE"
7050 ct[strlen(ct) - 1] = 0;
7051 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
7056 details[e->detail]);
7058 DBG("%s cb focus in %d %d\n",
7059 e_border_name_get(bd),
7060 bd->client.icccm.accepts_focus,
7061 bd->client.icccm.take_focus);
7064 _e_border_pri_raise(bd);
7065 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
7067 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
7069 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
7071 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
7074 /* ignore focus in from !take_focus windows, we just gave it em */
7075 /* if (!bd->client.icccm.take_focus)
7076 * return ECORE_CALLBACK_PASS_ON; */
7078 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
7079 if (e->time >= focus_time)
7080 e_border_focus_set(bd, 1, 0);
7081 return ECORE_CALLBACK_PASS_ON;
7085 _e_border_cb_window_focus_out(void *data __UNUSED__,
7086 int ev_type __UNUSED__,
7090 Ecore_X_Event_Window_Focus_Out *e;
7093 bd = e_border_find_by_client_window(e->win);
7094 if (!bd) return ECORE_CALLBACK_PASS_ON;
7095 #ifdef INOUTDEBUG_FOCUS
7100 const char *modes[] = {
7102 "MODE_WHILE_GRABBED",
7106 const char *details[] = {
7110 "DETAIL_NON_LINEAR",
7111 "DETAIL_NON_LINEAR_VIRTUAL",
7113 "DETAIL_POINTER_ROOT",
7114 "DETAIL_DETAIL_NONE"
7118 ct[strlen(ct) - 1] = 0;
7119 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
7124 details[e->detail]);
7126 DBG("%s cb focus out %d %d",
7127 e_border_name_get(bd),
7128 bd->client.icccm.accepts_focus,
7129 bd->client.icccm.take_focus);
7132 _e_border_pri_norm(bd);
7133 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
7135 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
7136 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
7137 return ECORE_CALLBACK_PASS_ON;
7138 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
7139 return ECORE_CALLBACK_PASS_ON;
7141 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
7143 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
7144 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
7145 return ECORE_CALLBACK_PASS_ON;
7146 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
7147 return ECORE_CALLBACK_PASS_ON;
7148 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
7149 return ECORE_CALLBACK_PASS_ON;
7150 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
7151 return ECORE_CALLBACK_PASS_ON;
7153 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
7155 /* for firefox/thunderbird (xul) menu walking */
7156 /* NB: why did i disable this before? */
7157 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
7158 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
7159 return ECORE_CALLBACK_PASS_ON;
7161 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
7163 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
7164 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
7165 return ECORE_CALLBACK_PASS_ON;
7167 e_border_focus_set(bd, 0, 0);
7168 return ECORE_CALLBACK_PASS_ON;
7171 #if _F_BORDER_CLIP_TO_ZONE_
7173 _e_border_shape_input_clip_to_zone(E_Border *bd)
7175 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
7179 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
7180 bd->zone->w, bd->zone->h,
7181 bd->x, bd->y, bd->w, bd->h)))
7184 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
7185 E_RECTS_CLIP_TO_RECT(x, y, w, h,
7186 bd->zone->x, bd->zone->y,
7187 bd->zone->w, bd->zone->h);
7190 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
7191 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
7195 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
7196 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
7199 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
7202 _e_border_cb_client_message(void *data __UNUSED__,
7203 int ev_type __UNUSED__,
7206 Ecore_X_Event_Client_Message *e;
7210 #ifdef _F_DEICONIFY_APPROVE_
7211 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
7213 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
7215 bd = e_border_find_by_client_window(e->win);
7218 if (bd->client.e.state.deiconify_approve.support)
7220 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
7221 bd->client.e.state.deiconify_approve.render_done = 1;
7223 E_Border *ancestor_bd;
7224 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
7227 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
7228 bd->client.e.state.deiconify_approve.ancestor = NULL;
7235 ELBF(ELBT_BD, 0, bd->client.win,
7236 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
7238 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
7239 (ancestor_bd->client.e.state.deiconify_approve.render_done))
7241 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
7243 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
7244 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
7246 if (bd->client.e.state.deiconify_approve.wait_timer)
7248 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7249 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7252 e_border_uniconify(ancestor_bd);
7256 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
7257 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7261 if (bd != ancestor_bd)
7263 if (bd->client.e.state.deiconify_approve.wait_timer)
7265 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
7266 bd->client.e.state.deiconify_approve.wait_timer = NULL;
7271 return ECORE_CALLBACK_PASS_ON;
7275 #ifdef _F_ZONE_WINDOW_ROTATION_
7276 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7278 bd = e_border_find_by_client_window(e->win);
7281 if (e_config->wm_win_rotation)
7283 Ecore_X_Event_Client_Message *msg = NULL;
7284 Ecore_X_Atom t = e->message_type;
7285 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7286 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7287 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7288 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7290 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7291 if (!msg) return ECORE_CALLBACK_PASS_ON;
7294 msg->message_type = e->message_type;
7295 msg->data.l[0] = e->data.l[0];
7296 msg->data.l[1] = e->data.l[1];
7297 msg->data.l[2] = e->data.l[2];
7298 msg->data.l[3] = e->data.l[3];
7299 msg->data.l[4] = e->data.l[4];
7300 rot.msgs = eina_list_append(rot.msgs, msg);
7302 rot.fetch = EINA_TRUE;
7305 return ECORE_CALLBACK_PASS_ON;
7308 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7310 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7311 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7313 if (e_config->wm_win_rotation)
7315 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7317 _e_border_rotation_list_remove(bd);
7318 if (bd->client.e.state.rot.pending_show)
7320 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7322 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
7323 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
7324 _e_border_check_stack(bd);
7326 bd->client.e.state.rot.pending_show = 0;
7332 return ECORE_CALLBACK_PASS_ON;
7336 _e_border_cb_window_state_request(void *data __UNUSED__,
7337 int ev_type __UNUSED__,
7341 Ecore_X_Event_Window_State_Request *e;
7345 bd = e_border_find_by_client_window(e->win);
7346 if (!bd) return ECORE_CALLBACK_PASS_ON;
7348 for (i = 0; i < 2; i++)
7349 e_hints_window_state_update(bd, e->state[i], e->action);
7351 return ECORE_CALLBACK_PASS_ON;
7355 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7356 int ev_type __UNUSED__,
7360 Ecore_X_Event_Window_Move_Resize_Request *e;
7363 bd = e_border_find_by_client_window(e->win);
7364 if (!bd) return ECORE_CALLBACK_PASS_ON;
7366 if ((bd->shaded) || (bd->shading) ||
7367 (bd->fullscreen) || (bd->moving) ||
7368 (bd->resize_mode != RESIZE_NONE))
7369 return ECORE_CALLBACK_PASS_ON;
7371 if ((e->button >= 1) && (e->button <= 3))
7373 bd->mouse.last_down[e->button - 1].mx = e->x;
7374 bd->mouse.last_down[e->button - 1].my = e->y;
7375 bd->mouse.last_down[e->button - 1].x = bd->x;
7376 bd->mouse.last_down[e->button - 1].y = bd->y;
7377 bd->mouse.last_down[e->button - 1].w = bd->w;
7378 bd->mouse.last_down[e->button - 1].h = bd->h;
7382 bd->moveinfo.down.x = bd->x;
7383 bd->moveinfo.down.y = bd->y;
7384 bd->moveinfo.down.w = bd->w;
7385 bd->moveinfo.down.h = bd->h;
7387 bd->mouse.current.mx = e->x;
7388 bd->mouse.current.my = e->y;
7389 bd->moveinfo.down.button = e->button;
7390 bd->moveinfo.down.mx = e->x;
7391 bd->moveinfo.down.my = e->y;
7394 if (!bd->lock_user_stacking)
7397 if (e->direction == MOVE)
7399 bd->cur_mouse_action = e_action_find("window_move");
7400 if (bd->cur_mouse_action)
7402 if ((!bd->cur_mouse_action->func.end_mouse) &&
7403 (!bd->cur_mouse_action->func.end))
7404 bd->cur_mouse_action = NULL;
7405 if (bd->cur_mouse_action)
7407 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7408 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7411 return ECORE_CALLBACK_PASS_ON;
7414 if (!_e_border_resize_begin(bd))
7415 return ECORE_CALLBACK_PASS_ON;
7417 switch (e->direction)
7420 bd->resize_mode = RESIZE_TL;
7421 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7425 bd->resize_mode = RESIZE_T;
7426 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7430 bd->resize_mode = RESIZE_TR;
7431 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7435 bd->resize_mode = RESIZE_R;
7436 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7440 bd->resize_mode = RESIZE_BR;
7441 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7445 bd->resize_mode = RESIZE_B;
7446 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7450 bd->resize_mode = RESIZE_BL;
7451 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7455 bd->resize_mode = RESIZE_L;
7456 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7460 return ECORE_CALLBACK_PASS_ON;
7463 bd->cur_mouse_action = e_action_find("window_resize");
7464 if (bd->cur_mouse_action)
7466 if ((!bd->cur_mouse_action->func.end_mouse) &&
7467 (!bd->cur_mouse_action->func.end))
7468 bd->cur_mouse_action = NULL;
7470 if (bd->cur_mouse_action)
7471 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7473 return ECORE_CALLBACK_PASS_ON;
7477 _e_border_cb_desktop_change(void *data __UNUSED__,
7478 int ev_type __UNUSED__,
7482 Ecore_X_Event_Desktop_Change *e;
7485 bd = e_border_find_by_client_window(e->win);
7488 if (e->desk == 0xffffffff)
7490 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7494 desk = e_desk_at_pos_get(bd->zone, e->desk);
7496 e_border_desk_set(bd, desk);
7501 ecore_x_netwm_desktop_set(e->win, e->desk);
7503 return ECORE_CALLBACK_PASS_ON;
7507 _e_border_cb_sync_alarm(void *data __UNUSED__,
7508 int ev_type __UNUSED__,
7512 Ecore_X_Event_Sync_Alarm *e;
7513 unsigned int serial;
7516 bd = e_border_find_by_alarm(e->alarm);
7517 if (!bd) return ECORE_CALLBACK_PASS_ON;
7519 if (bd->client.netwm.sync.wait)
7520 bd->client.netwm.sync.wait--;
7522 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7524 E_Border_Pending_Move_Resize *pnd = NULL;
7526 /* skip pending for which we didn't get a reply */
7527 while (bd->pending_move_resize)
7529 pnd = bd->pending_move_resize->data;
7530 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7532 if (serial == pnd->serial)
7544 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7545 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7550 bd->changes.size = 1;
7551 bd->changes.pos = 1;
7554 evas_render(bd->bg_evas);
7556 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7557 &bd->mouse.current.mx,
7558 &bd->mouse.current.my);
7560 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7561 _e_border_resize_handle(bd);
7563 return ECORE_CALLBACK_PASS_ON;
7567 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7568 int ev_type __UNUSED__,
7569 void *ev __UNUSED__)
7574 /* mark all borders for desktop/icon updates */
7575 EINA_LIST_FOREACH(borders, l, bd)
7579 efreet_desktop_free(bd->desktop);
7582 bd->changes.icon = 1;
7586 e_init_status_set(_("Desktop files scan done"));
7589 return ECORE_CALLBACK_PASS_ON;
7593 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7594 int ev_type __UNUSED__,
7595 void *ev __UNUSED__)
7600 /* mark all borders for desktop/icon updates */
7601 EINA_LIST_FOREACH(borders, l, bd)
7603 bd->changes.icon = 1;
7606 return ECORE_CALLBACK_PASS_ON;
7610 _e_border_cb_pointer_warp(void *data __UNUSED__,
7611 int ev_type __UNUSED__,
7614 E_Event_Pointer_Warp *e;
7617 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7618 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7619 return ECORE_CALLBACK_PASS_ON;
7623 _e_border_cb_signal_bind(void *data,
7624 Evas_Object *obj __UNUSED__,
7625 const char *emission,
7631 if (e_dnd_active()) return;
7632 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7637 _e_border_cb_mouse_in(void *data,
7638 int type __UNUSED__,
7641 Ecore_X_Event_Mouse_In *ev;
7646 #ifdef INOUTDEBUG_MOUSE
7651 const char *modes[] = {
7653 "MODE_WHILE_GRABBED",
7657 const char *details[] = {
7661 "DETAIL_NON_LINEAR",
7662 "DETAIL_NON_LINEAR_VIRTUAL",
7664 "DETAIL_POINTER_ROOT",
7665 "DETAIL_DETAIL_NONE"
7669 ct[strlen(ct) - 1] = 0;
7670 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7671 ev->win, ev->event_win,
7674 details[ev->detail]);
7677 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7678 if (ev->event_win == bd->win)
7680 e_focus_event_mouse_in(bd);
7683 if ((ev->win != bd->win) &&
7684 (ev->win != bd->event_win) &&
7685 (ev->event_win != bd->win) &&
7686 (ev->event_win != bd->event_win))
7687 return ECORE_CALLBACK_PASS_ON;
7689 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7691 bd->mouse.current.mx = ev->root.x;
7692 bd->mouse.current.my = ev->root.y;
7693 if (!bd->bg_evas_in)
7695 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7696 bd->bg_evas_in = EINA_TRUE;
7698 return ECORE_CALLBACK_PASS_ON;
7702 _e_border_cb_mouse_out(void *data,
7703 int type __UNUSED__,
7706 Ecore_X_Event_Mouse_Out *ev;
7711 #ifdef INOUTDEBUG_MOUSE
7716 const char *modes[] = {
7718 "MODE_WHILE_GRABBED",
7722 const char *details[] = {
7726 "DETAIL_NON_LINEAR",
7727 "DETAIL_NON_LINEAR_VIRTUAL",
7729 "DETAIL_POINTER_ROOT",
7730 "DETAIL_DETAIL_NONE"
7734 ct[strlen(ct) - 1] = 0;
7735 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7736 ev->win, ev->event_win,
7739 details[ev->detail]);
7742 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7743 if (ev->event_win == bd->win)
7746 return ECORE_CALLBACK_PASS_ON;
7747 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7748 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7749 return ECORE_CALLBACK_PASS_ON;
7750 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7751 return ECORE_CALLBACK_PASS_ON;
7752 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7753 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7754 return ECORE_CALLBACK_PASS_ON;
7755 e_focus_event_mouse_out(bd);
7758 if ((ev->win != bd->win) &&
7759 (ev->win != bd->event_win) &&
7760 (ev->event_win != bd->win) &&
7761 (ev->event_win != bd->event_win))
7762 return ECORE_CALLBACK_PASS_ON;
7764 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7766 bd->mouse.current.mx = ev->root.x;
7767 bd->mouse.current.my = ev->root.y;
7770 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7771 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7772 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7774 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7775 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7776 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7777 bd->bg_evas_in = EINA_FALSE;
7780 return ECORE_CALLBACK_PASS_ON;
7784 _e_border_cb_mouse_wheel(void *data,
7785 int type __UNUSED__,
7788 Ecore_Event_Mouse_Wheel *ev;
7793 if ((ev->event_window == bd->win) ||
7794 (ev->event_window == bd->event_win))
7796 bd->mouse.current.mx = ev->root.x;
7797 bd->mouse.current.my = ev->root.y;
7798 if (!bd->cur_mouse_action)
7799 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7802 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7803 return ECORE_CALLBACK_PASS_ON;
7807 _e_border_cb_mouse_down(void *data,
7808 int type __UNUSED__,
7811 Ecore_Event_Mouse_Button *ev;
7816 if ((ev->event_window == bd->win) ||
7817 (ev->event_window == bd->event_win))
7819 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7821 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7822 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7823 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7824 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7825 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7826 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7830 bd->moveinfo.down.x = bd->x + bd->fx.x;
7831 bd->moveinfo.down.y = bd->y + bd->fx.y;
7832 bd->moveinfo.down.w = bd->w;
7833 bd->moveinfo.down.h = bd->h;
7835 bd->mouse.current.mx = ev->root.x;
7836 bd->mouse.current.my = ev->root.y;
7837 if (!bd->cur_mouse_action)
7839 bd->cur_mouse_action =
7840 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7842 if (bd->cur_mouse_action)
7844 if ((!bd->cur_mouse_action->func.end_mouse) &&
7845 (!bd->cur_mouse_action->func.end))
7846 bd->cur_mouse_action = NULL;
7847 if (bd->cur_mouse_action)
7848 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7851 e_focus_event_mouse_down(bd);
7853 if (ev->window != ev->event_window)
7857 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7861 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7863 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7864 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7865 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7866 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7867 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7868 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7872 bd->moveinfo.down.x = bd->x + bd->fx.x;
7873 bd->moveinfo.down.y = bd->y + bd->fx.y;
7874 bd->moveinfo.down.w = bd->w;
7875 bd->moveinfo.down.h = bd->h;
7877 bd->mouse.current.mx = ev->root.x;
7878 bd->mouse.current.my = ev->root.y;
7883 else if (bd->resize_mode != RESIZE_NONE)
7889 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7891 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7892 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7893 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7895 return ECORE_CALLBACK_PASS_ON;
7899 _e_border_cb_mouse_up(void *data,
7900 int type __UNUSED__,
7903 Ecore_Event_Mouse_Button *ev;
7908 if ((ev->event_window == bd->win) ||
7909 (ev->event_window == bd->event_win))
7911 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7913 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7914 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7915 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7916 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7918 bd->mouse.current.mx = ev->root.x;
7919 bd->mouse.current.my = ev->root.y;
7920 /* also we dont pass the same params that went in - then again that */
7921 /* should be ok as we are just ending the action if it has an end */
7922 if (bd->cur_mouse_action)
7924 if (bd->cur_mouse_action->func.end_mouse)
7925 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7926 else if (bd->cur_mouse_action->func.end)
7927 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7928 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7929 bd->cur_mouse_action = NULL;
7933 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7934 e_focus_event_mouse_up(bd);
7937 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7938 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7940 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7941 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7942 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7943 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7945 bd->mouse.current.mx = ev->root.x;
7946 bd->mouse.current.my = ev->root.y;
7950 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7951 return ECORE_CALLBACK_PASS_ON;
7955 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7957 #ifdef _F_BORDER_CLIP_TO_ZONE_
7958 int new_x_max, new_y_max;
7959 int new_x_min, new_y_min;
7960 int margin_x, margin_y;
7962 margin_x = bd->w - 100;
7963 margin_y = bd->h - 100;
7965 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7966 new_x_min = bd->zone->x - margin_x;
7967 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7968 new_y_min = bd->zone->y - margin_y;
7970 if (x >= new_x_max) *new_x = new_x_max;
7971 else if (x <= new_x_min) *new_x = new_x_min;
7973 if (y >= new_y_max) *new_y = new_y_max;
7974 else if (y <= new_y_min) *new_y = new_y_min;
7979 _e_border_cb_mouse_move(void *data,
7980 int type __UNUSED__,
7983 Ecore_Event_Mouse_Move *ev;
7988 if ((ev->window != bd->event_win) &&
7989 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7990 bd->mouse.current.mx = ev->root.x;
7991 bd->mouse.current.my = ev->root.y;
7994 int x, y, new_x, new_y;
7996 Eina_List *skiplist = NULL;
7998 // FIXME: remove? sync what for when only moving?
7999 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
8000 bd->client.netwm.sync.wait = 0;
8001 if ((bd->client.netwm.sync.request) &&
8002 (bd->client.netwm.sync.alarm) &&
8003 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
8005 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
8007 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
8008 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8009 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
8010 (bd->mouse.current.my - bd->moveinfo.down.my);
8014 x = bd->moveinfo.down.x +
8015 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8016 y = bd->moveinfo.down.y +
8017 (bd->mouse.current.my - bd->moveinfo.down.my);
8022 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
8023 skiplist = eina_list_append(skiplist, bd);
8024 e_resist_container_border_position(bd->zone->container, skiplist,
8025 bd->x, bd->y, bd->w, bd->h,
8027 &new_x, &new_y, &new_w, &new_h);
8028 eina_list_free(skiplist);
8030 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
8032 /* if (e_config->window_out_of_vscreen_limits_partly) */
8034 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
8037 skiplist = eina_list_append(skiplist, bd);
8038 e_resist_container_border_position(bd->zone->container, skiplist,
8039 bd->x, bd->y, bd->w, bd->h,
8041 &new_x, &new_y, &new_w, &new_h);
8042 eina_list_free(skiplist);
8045 bd->shelf_fix.x = 0;
8046 bd->shelf_fix.y = 0;
8047 bd->shelf_fix.modified = 0;
8048 e_border_move(bd, new_x, new_y);
8049 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
8051 else if (bd->resize_mode != RESIZE_NONE)
8053 if ((bd->client.netwm.sync.request) &&
8054 (bd->client.netwm.sync.alarm))
8056 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
8058 E_Border_Pending_Move_Resize *pnd;
8060 if (bd->pending_move_resize)
8062 bd->changes.pos = 1;
8063 bd->changes.size = 1;
8065 _e_border_client_move_resize_send(bd);
8067 EINA_LIST_FREE(bd->pending_move_resize, pnd)
8070 bd->client.netwm.sync.wait = 0;
8072 /* sync.wait is incremented when resize_handle sends
8073 * sync-request and decremented by sync-alarm cb. so
8074 * we resize here either on initial resize, timeout or
8075 * when no new resize-request was added by sync-alarm cb.
8077 if (!bd->client.netwm.sync.wait)
8078 _e_border_resize_handle(bd);
8081 _e_border_resize_handle(bd);
8087 if ((bd->drag.x == -1) && (bd->drag.y == -1))
8089 bd->drag.x = ev->root.x;
8090 bd->drag.y = ev->root.y;
8096 dx = bd->drag.x - ev->root.x;
8097 dy = bd->drag.y - ev->root.y;
8098 if (((dx * dx) + (dy * dy)) >
8099 (e_config->drag_resist * e_config->drag_resist))
8102 if (bd->icon_object)
8104 Evas_Object *o = NULL;
8105 Evas_Coord x, y, w, h;
8106 const char *drag_types[] = { "enlightenment/border" };
8108 e_object_ref(E_OBJECT(bd));
8109 evas_object_geometry_get(bd->icon_object,
8111 drag_border = e_drag_new(bd->zone->container,
8112 bd->x + bd->fx.x + x,
8113 bd->y + bd->fx.y + y,
8114 drag_types, 1, bd, -1,
8116 _e_border_cb_drag_finished);
8117 o = e_border_icon_add(bd, drag_border->evas);
8120 /* FIXME: fallback icon for drag */
8121 o = evas_object_rectangle_add(drag_border->evas);
8122 evas_object_color_set(o, 255, 255, 255, 255);
8124 e_drag_object_set(drag_border, o);
8126 e_drag_resize(drag_border, w, h);
8127 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
8133 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
8135 return ECORE_CALLBACK_PASS_ON;
8139 _e_border_cb_grab_replay(void *data __UNUSED__,
8143 Ecore_Event_Mouse_Button *ev;
8145 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
8147 if ((e_config->pass_click_on)
8148 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
8149 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
8154 bd = e_border_find_by_window(ev->event_window);
8157 if (bd->cur_mouse_action)
8158 return ECORE_CALLBACK_DONE;
8159 if (ev->event_window == bd->win)
8161 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
8162 E_OBJECT(bd), ev, NULL))
8163 return ECORE_CALLBACK_PASS_ON;
8167 return ECORE_CALLBACK_DONE;
8171 _e_border_cb_drag_finished(E_Drag *drag,
8172 int dropped __UNUSED__)
8177 e_object_unref(E_OBJECT(bd));
8181 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8183 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
8184 int ev_type __UNUSED__,
8187 E_Event_Desk_Window_Profile_Change *e;
8192 EINA_LIST_FOREACH(borders, l, bd)
8194 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
8196 bd->client.e.fetch.profile_list = 1;
8200 return ECORE_CALLBACK_PASS_ON;
8204 #ifdef _F_ZONE_WINDOW_ROTATION_
8206 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
8207 int ev_type __UNUSED__,
8210 E_Event_Zone_Rotation_Change_Begin *e = ev;
8212 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8213 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
8215 if (!_e_border_rotation_zone_set(e->zone))
8217 /* there is no border which supports window manager rotation */
8218 e_zone_rotation_update_cancel(e->zone);
8220 return ECORE_CALLBACK_PASS_ON;
8224 _e_border_cb_rotation_sync_job(void *data)
8226 E_Zone *zone = data;
8228 E_Border_Rotation_Info *info = NULL;
8230 ELBF(ELBT_ROT, 0, zone->id, "DO ROTATION SYNC_JOB rot.list:%p(%d) wait_prepare_done:%d zone_block_count:%d",
8231 rot.list, eina_list_count(rot.list), rot.wait_prepare_done, zone->rot.block_count);
8234 EINA_LIST_FOREACH(rot.list, l, info)
8235 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
8237 ELBF(ELBT_ROT, 0, zone->id, "SYNC_JOB list(%d) wait_prepare_done:%d zone_block_count:%d",
8238 eina_list_count(rot.list), rot.wait_prepare_done, zone->rot.block_count);
8240 if (!rot.wait_prepare_done)
8242 _e_border_rotation_change_request(zone);
8249 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
8250 ecore_job_del(rot.sync_job);
8251 rot.sync_job = NULL;
8256 _e_border_cb_rotation_async_job(void *data)
8258 E_Zone *zone = data;
8260 if (rot.list) goto end;
8262 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
8264 if (!rot.wait_prepare_done)
8266 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8267 rot.async_list = NULL;
8274 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
8275 ecore_job_del(rot.async_job);
8276 rot.async_job = NULL;
8281 _e_border_rotation_change_prepare_timeout(void *data)
8283 E_Zone *zone = data;
8284 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8286 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8288 if ((zone) && (rot.wait_prepare_done))
8292 _e_border_rotation_change_request(zone);
8293 if (rot.prepare_timer)
8294 ecore_timer_del(rot.prepare_timer);
8295 rot.prepare_timer = NULL;
8296 rot.wait_prepare_done = EINA_FALSE;
8299 return ECORE_CALLBACK_CANCEL;
8303 _e_border_rotation_change_request(E_Zone *zone)
8305 if (!e_config->wm_win_rotation) return;
8306 if (!rot.list) return;
8307 if (eina_list_count(rot.list) <= 0) return;
8308 /* pending rotation problem occurred while launching app by the tray */
8309 //if (zone->rot.block_count) return;
8311 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8312 rot.prepare_timer = NULL;
8313 rot.wait_prepare_done = EINA_FALSE;
8315 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8318 ecore_timer_del(rot.done_timer);
8319 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8320 rot.done_timer = ecore_timer_add(5.0f,
8321 _e_border_rotation_change_done_timeout,
8326 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8329 E_Border_Rotation_Info *info =NULL;
8332 EINA_LIST_FOREACH (list, l, info)
8334 if (!info->bd) continue;
8335 if ((info->bd->client.e.state.rot.wait_for_done) &&
8336 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8338 _e_border_event_border_rotation_change_begin_send(info->bd);
8341 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8342 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8344 info->x = x; info->y = y;
8345 info->w = w; info->h = h;
8347 ELBF(ELBT_ROT, 1, info->bd->client.win,
8348 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8349 info->ang, info->win_resize, info->w, info->h);
8352 SECURE_SLOGD("[ROTATION] SEND PREP_ROT, win:0x%08x a%d resize%d %dx%d",
8353 info->bd->client.win, info->ang, info->win_resize,
8357 ecore_x_e_window_rotation_change_prepare_send
8358 (info->bd->client.win, info->ang,
8359 info->win_resize, info->w, info->h);
8361 if (!info->bd->client.e.state.rot.pending_change_request)
8363 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8365 SECURE_SLOGD("[ROTATION] SEND REQ_ROT, win:0x%08x, rot:%d",
8366 info->bd->client.win, info->ang);
8368 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8370 info->bd->client.e.state.rot.wait_for_done = 1;
8371 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8377 EINA_LIST_FREE(list, info)
8383 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8385 E_Border_Rotation_Info *info = NULL;
8387 if (send_request) _e_border_rotation_change_request(zone);
8390 EINA_LIST_FREE(rot.list, info)
8397 _e_border_rotation_list_remove(E_Border *bd)
8399 Eina_List *l = NULL;
8400 E_Border_Rotation_Info *info = NULL;
8401 E_Event_Border_Rotation_Change_End *ev = NULL;
8402 Eina_Bool found = EINA_FALSE;
8404 if (!e_config->wm_win_rotation) return;
8406 EINA_LIST_FOREACH(rot.list, l, info)
8410 rot.list = eina_list_remove(rot.list, info);
8416 if (bd->client.e.state.rot.wait_for_done)
8418 bd->client.e.state.rot.wait_for_done = 0;
8420 /* if we make the border event in the _e_border_free function,
8421 * then we may meet a crash problem, only work this at least e_border_hide.
8423 if (!e_object_is_del(E_OBJECT(bd)))
8425 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8429 e_object_ref(E_OBJECT(bd));
8430 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8432 _e_border_event_border_rotation_change_end_free,
8438 (eina_list_count(rot.list) == 0))
8440 _e_border_rotation_change_done();
8446 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8448 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8449 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8450 _e_border_rotation_change_done();
8451 return ECORE_CALLBACK_CANCEL;
8455 _e_border_rotation_change_done(void)
8457 E_Manager *m = NULL;
8458 E_Border_Rotation_Info *info = NULL;
8460 if (!e_config->wm_win_rotation) return;
8462 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8463 rot.prepare_timer = NULL;
8465 rot.wait_prepare_done = EINA_FALSE;
8467 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8468 rot.done_timer = NULL;
8470 EINA_LIST_FREE(rot.list, info)
8474 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8475 if (info->bd->client.e.state.rot.pending_show)
8477 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8478 e_border_show(info->bd);
8479 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8480 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
8481 _e_border_check_stack(info->bd);
8483 info->bd->client.e.state.rot.pending_show = 0;
8485 info->bd->client.e.state.rot.wait_for_done = 0;
8490 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8493 rot.async_list = NULL;
8495 m = e_manager_current_get();
8496 e_manager_comp_screen_unlock(m);
8497 e_zone_rotation_update_done(e_util_zone_current_get(m));
8501 _prev_angle_get(Ecore_X_Window win)
8503 int ret, count = 0, ang = -1;
8504 unsigned char* data = NULL;
8506 ret = ecore_x_window_prop_property_get
8507 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8508 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8510 if ((ret) && (data) && (count))
8511 ang = ((int *)data)[0];
8512 if (data) free(data);
8516 /* get proper rotation value using preferred rotation and list of available rotations */
8518 _e_border_rotation_get(E_Border *bd,
8522 int current_ang = bd->client.e.state.rot.curr;
8524 Eina_Bool found = EINA_FALSE;
8525 Eina_Bool found_curr_ang = EINA_FALSE;
8527 if (!e_config->wm_win_rotation) return ang;
8528 if (!bd->client.e.state.rot.app_set) return ang;
8530 if (bd->client.e.state.rot.preferred_rot != -1)
8532 ang = bd->client.e.state.rot.preferred_rot;
8533 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8535 else if ((bd->client.e.state.rot.available_rots) &&
8536 (bd->client.e.state.rot.count))
8538 for (i = 0; i < bd->client.e.state.rot.count; i++)
8540 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8546 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8547 found_curr_ang = EINA_TRUE;
8550 /* do nothing. this window wants to maintain current state.
8551 * for example, window's available_rots: 0, 90, 270,
8552 * current zone rotation request: 180. the WM does nothing
8557 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8558 ang = bd->client.e.state.rot.curr;
8560 ang = bd->client.e.state.rot.available_rots[0];
8565 /* In this case, border doesn't have a list of
8566 * available rotations, thus WM should request
8567 * rotation with '0' degree to the application.
8576 _e_border_rotation_angle_get(E_Border *bd)
8578 E_Zone *zone = bd->zone;
8583 if (!e_config->wm_win_rotation) return ret;
8584 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8586 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8588 // the window with "ECORE_X_WINDOW_TYPE_NORMAL" type
8589 // should follow the state of rotation of zone.
8591 (bd->parent->visible) &&
8592 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL))
8593 will_ang = bd->parent->client.e.state.rot.curr;
8594 else will_ang = zone->rot.curr;
8596 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8598 ELBF(ELBT_ROT, 1, bd->client.win,
8599 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8600 (rot.vkbd == bd) ? "vkbd" : "prediction",
8601 bd->parent ? bd->parent->client.win : 0,
8602 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8603 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8604 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8608 will_ang = bd->parent->client.e.state.rot.curr;
8609 if ((!bd->parent->client.e.state.rot.support) &&
8610 (!bd->parent->client.e.state.rot.app_set))
8617 if ((!bd->client.e.state.rot.app_set) &&
8618 (!bd->client.e.state.rot.support))
8620 /* hack for magnifier and keyboard popup */
8621 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8622 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8624 ELB(ELBT_BD, "MAG", bd->client.win);
8626 if ((rot.vkbd) && (rot.vkbd->visible))
8627 will_ang = rot.vkbd->client.e.state.rot.curr;
8631 if (bd->client.e.state.rot.app_set)
8633 /* utility type window should be rotated according to
8634 * rotation of the transient_for window.
8637 (bd->parent->visible) &&
8638 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8640 will_ang = bd->parent->client.e.state.rot.curr;
8641 if ((!bd->parent->client.e.state.rot.support) &&
8642 (!bd->parent->client.e.state.rot.app_set))
8644 /* if transient_for window doesn't support rotation feature,
8645 * then this window should't be rotated.
8646 * TODO: need to check whether window supports '0' degree or not.
8649 ELBF(ELBT_ROT, 0, bd->client.win,
8650 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8651 will_ang, bd->parent->client.win);
8655 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8656 ELBF(ELBT_ROT, 0, bd->client.win,
8657 "GET ROT ang:%d Transient_For:0x%08x",
8658 will_ang, bd->parent->client.win);
8663 will_ang = _e_border_rotation_get(bd, will_ang);
8664 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8665 will_ang, bd->parent ? bd->parent->client.win : 0,
8666 bd->client.netwm.type);
8672 _ang = _prev_angle_get(bd->client.win);
8674 bd->client.e.state.rot.curr = _ang;
8675 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8678 if (bd->client.e.state.rot.curr != will_ang)
8686 _e_border_rotation_zone_set(E_Zone *zone)
8688 E_Border_List *l = NULL;
8689 E_Border *bd = NULL;
8690 Eina_Bool ret = EINA_FALSE;
8692 if (!e_config->wm_win_rotation) return EINA_FALSE;
8694 l = e_container_border_list_last(zone->container);
8697 /* step 1. make the list needs to be rotated. */
8698 while ((bd = e_container_border_list_prev(l)))
8702 // if this window has parent and window type isn't "ECORE_X_WINDOW_TYPE_NORMAL",
8703 // it will be rotated when parent do rotate itself.
8706 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL)) continue;
8708 // default type is "E_BORDER_ROTATION_TYPE_NORMAL",
8709 // but it can be changed to "E_BORDER_ROTATION_TYPE_DEPENDENT" by illume according to its policy.
8710 // if it's not normal type window, will be rotated by illume.
8712 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8714 if ((!bd->visible) ||
8715 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8716 bd->x, bd->y, bd->w, bd->h))) continue;
8718 if (_e_border_rotatable_check(bd, zone->rot.curr))
8720 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8721 bd->client.e.state.rot.curr, zone->rot.curr);
8723 ret = e_border_rotation_set(bd, zone->rot.curr);
8726 if (l) e_container_border_list_free(l);
8732 _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending)
8734 E_Zone *zone = bd->zone;
8735 E_Border_Rotation_Info *info = NULL;
8736 Eina_List *list, *l;
8739 if (rotation < 0) return EINA_FALSE;
8740 if (pending) *pending = EINA_FALSE;
8742 /* step 1. check if rotation */
8743 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8745 /* step 2. add to async/sync list */
8746 if ((!zone->rot.block_count) &&
8747 (!bd->client.e.state.deiconify_approve.pending_bd) &&
8749 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8751 // send rotation change request later.
8752 // and no need to wait message of rotation done.
8755 info = E_NEW(E_Border_Rotation_Info, 1);
8756 if (!info) return EINA_FALSE;
8757 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8759 info->ang = rotation;
8760 rot.async_list = eina_list_append(rot.async_list, info);
8762 // add job for sending event.
8765 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8766 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8772 info = E_NEW(E_Border_Rotation_Info, 1);
8773 if (!info) return EINA_FALSE;
8774 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8776 info->ang = rotation;
8777 rot.list = eina_list_append(rot.list, info);
8779 // add job for sending event.
8782 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8783 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8786 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8788 // but, DO NOT lock the screen when rotation block state.
8789 if ((!zone->rot.block_count) &&
8790 ((eina_list_count(rot.list) == 2)))
8791 e_manager_comp_screen_lock(e_manager_current_get());
8794 if (pending) *pending = EINA_TRUE;
8796 /* step 3. search rotatable window in this window's child */
8797 list = _e_border_sub_borders_new(bd);
8798 EINA_LIST_FOREACH(list, l, child)
8800 // the window which type is "ECORE_X_WINDOW_TYPE_NORMAL" will be rotated itself.
8801 // it shouldn't be rotated by rotation state of parent window.
8802 if (child->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) continue;
8803 if (_e_border_rotatable_check(child, rotation))
8805 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8806 bd->client.e.state.rot.curr, rotation);
8807 e_border_rotation_set(child, rotation);
8811 /* step 4. if there is vkbd window, send message to prepare rotation */
8812 if (_e_border_is_vkbd(bd))
8814 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8815 if (rot.prepare_timer)
8816 ecore_timer_del(rot.prepare_timer);
8817 rot.prepare_timer = NULL;
8820 ecore_timer_del(rot.done_timer);
8821 rot.done_timer = NULL;
8823 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8824 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8827 rot.prepare_timer = ecore_timer_add(4.0f,
8828 _e_border_rotation_change_prepare_timeout,
8831 rot.wait_prepare_done = EINA_TRUE;
8834 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8835 bd->client.e.state.rot.curr = rotation;
8840 // check if border is rotatable in ang.
8842 _e_border_rotatable_check(E_Border *bd, int ang)
8844 Eina_Bool ret = EINA_FALSE;
8846 if (!bd) return ret;
8847 if (ang < 0) return ret;
8848 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8849 if (e_object_is_del(E_OBJECT(bd))) return ret;
8851 // same with current angle of window, then false return.
8852 if (ang == bd->client.e.state.rot.curr) return ret;
8854 /* basically WM allows only fullscreen window to rotate */
8855 if (bd->client.e.state.rot.preferred_rot == -1)
8859 if (bd->client.e.state.rot.app_set)
8861 if (bd->client.e.state.rot.available_rots &&
8862 bd->client.e.state.rot.count)
8864 Eina_Bool found = EINA_FALSE;
8865 for (i = 0; i < bd->client.e.state.rot.count; i++)
8867 if (bd->client.e.state.rot.available_rots[i] == ang)
8872 if (found) ret = EINA_TRUE;
8877 ELB(ELBT_ROT, "DO ROT", 0);
8881 // if it has preferred rotation angle,
8882 // it will be rotated at border's evaluation time.
8884 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8889 /* check whether virtual keyboard is visible on the zone */
8891 _e_border_is_vkbd(E_Border *bd)
8893 if (!e_config->wm_win_rotation) return EINA_FALSE;
8895 if ((rot.vkbd_ctrl_win) &&
8897 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8898 (rot.vkbd->zone == bd->zone) &&
8899 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8900 bd->zone->w, bd->zone->h,
8901 rot.vkbd->x, rot.vkbd->y,
8902 rot.vkbd->w, rot.vkbd->h)))
8910 _e_border_rotation_change_floating_pos(E_Border *bd, int *x, int *y)
8913 int min_title_width=96;
8915 if (!bd) return EINA_FALSE;
8916 if (!x || !y) return EINA_FALSE;
8921 // Portrait -> Landscape, x= pre_x*2, y=pre_y/2
8922 // Landscape -> Portrait, x= pre_x/2, y=pre_y*2
8923 // guaranteeing the minimum size of titlebar shown, min_title_width
8924 // so user can initiate drag&drop action after rotation changed.
8925 if (bd->client.e.state.rot.curr == 0)
8927 if (bd->client.e.state.rot.prev == 90)
8929 new_x = (bd->zone->h - bd->h - bd->y) / 2;
8932 else if (bd->client.e.state.rot.prev == 270)
8935 new_y = (bd->zone->w - bd->w - bd->x) * 2;
8937 else if (bd->client.e.state.rot.prev == 180)
8939 new_x = bd->zone->w - bd->x - bd->w;
8940 new_y = bd->zone->h - bd->y - bd->h;
8943 if(new_x + bd->w < min_title_width)
8945 new_x = min_title_width - bd->w;
8947 else if(new_x > bd->zone->w - min_title_width)
8949 new_x = bd->zone->w - min_title_width;
8952 else if (bd->client.e.state.rot.curr == 90)
8954 if (bd->client.e.state.rot.prev == 0)
8957 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8959 else if (bd->client.e.state.rot.prev == 270)
8961 new_x = bd->zone->w - bd->x - bd->w;
8962 new_y = bd->zone->h - bd->y - bd->h;
8964 else if (bd->client.e.state.rot.prev == 180)
8966 new_x = (bd->zone->h - bd->y - bd->h) / 2;
8967 new_y = bd->zone->h - (2 * (bd->zone->w - bd->x - bd->w)) - bd->w;
8970 if(new_y > bd->zone->h - min_title_width)
8972 new_y = bd->zone->h - min_title_width;
8974 else if(new_y < min_title_width - bd->w)
8976 new_y = min_title_width - bd->w;
8979 else if (bd->client.e.state.rot.curr == 270)
8981 if (bd->client.e.state.rot.prev == 0)
8983 new_x = bd->zone->w - bd->h - (bd->y / 2);
8986 else if (bd->client.e.state.rot.prev == 90)
8988 new_x = bd->zone->w - bd->x - bd->w;
8989 new_y = bd->zone->h - bd->y - bd->h;
8991 else if (bd->client.e.state.rot.prev == 180)
8993 new_x = bd->zone->w - bd->x - bd->w;
8994 new_y = bd->zone->h - bd->y - bd->h;
8996 new_x = bd->zone->w - bd->h - ((bd->zone->h - bd->y - bd->h) / 2);
8997 new_y = (bd->zone->w - bd->x - bd->w) * 2;
9000 if(new_y > bd->zone->h - min_title_width)
9002 new_y = bd->zone->h - min_title_width;
9004 else if( new_y + bd->w < min_title_width)
9006 new_y = min_title_width - bd->w ;
9009 else if (bd->client.e.state.rot.curr == 180)
9011 if (bd->client.e.state.rot.prev == 0)
9013 new_x = bd->zone->w - bd->x - bd->w;
9014 new_y = bd->zone->h - bd->y - bd->h;
9016 else if (bd->client.e.state.rot.prev == 90)
9018 new_x = bd->zone->w - ((bd->zone->h - bd->h - bd->y) / 2) - bd->h;
9019 new_y = bd->zone->h - (2 * bd->x) - bd->w;
9021 else if (bd->client.e.state.rot.prev == 270)
9023 new_x = bd->zone->w - (bd->y / 2) - bd->h;
9024 new_y = bd->zone->h - ((bd->zone->w - bd->w - bd->x) * 2) - bd->w;
9027 if(new_x + bd->w < min_title_width)
9029 new_x = min_title_width - bd->w;
9031 else if(new_x > bd->zone->w - min_title_width)
9033 new_x = bd->zone->w - min_title_width;
9037 ELBF(ELBT_ROT, 0, bd->client.win,
9038 "Floating Mode. ANGLE (%d->%d), POS (%d,%d) -> (%d,%d)",
9039 bd->client.e.state.rot.prev, bd->client.e.state.rot.curr,
9040 bd->x, bd->y, new_x, new_y);
9042 if ((new_x == *x) &&
9054 #define SIZE_EQUAL_TO_ZONE(a, z) \
9055 ((((a)->w) == ((z)->w)) && \
9056 (((a)->h) == ((z)->h)))
9058 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
9060 E_Zone *zone = bd->zone;
9063 Eina_Bool move = EINA_FALSE;
9064 Eina_Bool hint = EINA_FALSE;
9065 Eina_Bool resize = EINA_FALSE;
9072 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
9074 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
9075 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
9076 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
9078 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
9079 &_x, &_y, &_w, &_h, &move);
9082 if (((move) && ((bd->x !=_x) || (bd->y !=_y))) ||
9083 (bd->w != _w) || (bd->h != _h))
9086 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
9087 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d resize:%d",
9088 bd->client.icccm.name, _x, _y, _w, _h, resize);
9093 _x = bd->x; _y = bd->y;
9094 _w = bd->w; _h = bd->h;
9096 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)
9097 move = _e_border_rotation_change_floating_pos(bd, &_x, &_y);
9101 rot_dif = bd->client.e.state.rot.prev - rotation;
9102 if (rot_dif < 0) rot_dif = -rot_dif;
9111 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
9112 EINA_TRUE, EINA_TRUE);
9113 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
9114 bd->client.icccm.name, _x, _y, _w, _h);
9119 if (!resize && move)
9120 _e_border_move_internal(bd, _x, _y, EINA_TRUE);
9135 _e_border_cb_window_configure(void *data __UNUSED__,
9136 int ev_type __UNUSED__,
9139 Ecore_X_Event_Window_Configure *e = ev;
9140 E_Border_Rotation_Info *info = NULL;
9142 Eina_Bool found = EINA_FALSE;
9144 if (!e) return ECORE_CALLBACK_PASS_ON;
9145 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
9147 E_Border *bd = e_border_find_by_client_window(e->win);
9148 if (!bd) return ECORE_CALLBACK_PASS_ON;
9150 if (bd->client.e.state.rot.pending_change_request)
9152 if ((e->w == bd->w) && (e->h == bd->h))
9154 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
9155 bd->client.e.state.rot.pending_change_request = 0;
9157 if ((bd->client.e.state.rot.wait_for_done) &&
9158 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
9160 EINA_LIST_FOREACH(rot.list, l, info)
9161 if (info->bd == bd) found = EINA_TRUE;
9162 // send request message if it's async rotation window,
9163 // even if wait prepare done.
9164 if ((found) && (rot.wait_prepare_done)) goto end;
9166 ELBF(ELBT_ROT, 0, bd->client.win,
9167 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
9168 bd->client.e.state.rot.curr,
9171 SECURE_SLOGD("[ROTATION] SEND REQ_ROT(CONFIGURE_NOTI), win:0x%08x, rot:%d",
9172 bd->client.win, bd->client.e.state.rot.curr);
9174 ecore_x_e_window_rotation_change_request_send(bd->client.win,
9175 bd->client.e.state.rot.curr);
9176 bd->client.e.state.rot.wait_for_done = 1;
9177 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
9182 return ECORE_CALLBACK_PASS_ON;
9186 _e_border_rotation_geom_get(E_Border *bd,
9195 if (!e_config->wm_win_rotation) return EINA_FALSE;
9197 Eina_Bool res = EINA_FALSE;
9198 Eina_Bool _move = EINA_TRUE;
9208 if (move) *move = EINA_TRUE;
9210 if (bd->client.e.state.rot.geom_hint)
9215 _w = bd->client.e.state.rot.geom[0].w;
9216 _h = bd->client.e.state.rot.geom[0].h;
9217 if (_w == 0) _w = bd->w;
9218 if (_h == 0) _h = bd->h;
9219 _x = 0; _y = zone->h - _h;
9222 _w = bd->client.e.state.rot.geom[1].w;
9223 _h = bd->client.e.state.rot.geom[1].h;
9224 if (_w == 0) _w = bd->w;
9225 if (_h == 0) _h = bd->h;
9226 _x = zone->w - _w; _y = 0;
9229 _w = bd->client.e.state.rot.geom[2].w;
9230 _h = bd->client.e.state.rot.geom[2].h;
9231 if (_w == 0) _w = bd->w;
9232 if (_h == 0) _h = bd->h;
9236 _w = bd->client.e.state.rot.geom[3].w;
9237 _h = bd->client.e.state.rot.geom[3].h;
9238 if (_w == 0) _w = bd->w;
9239 if (_h == 0) _h = bd->h;
9249 if (!((rot.vkbd) && (rot.vkbd == bd)))
9253 if (move) *move = EINA_FALSE;
9261 _x = 0; _y = 0; _w = 0; _h = 0;
9266 if (move) _move = *move;
9268 ELBF(ELBT_ROT, 1, bd->client.win,
9269 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
9270 ang, _x, _y, _w, _h, _move);
9278 _e_border_post_move_resize_job(void *data)
9282 bd = (E_Border *)data;
9288 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9289 ecore_x_window_move(tmp->win,
9291 bd->client_inset.l +
9293 tmp->client.e.state.video_position.x,
9295 bd->client_inset.t +
9297 tmp->client.e.state.video_position.y);
9299 if (bd->client.e.state.video)
9303 parent = bd->client.e.state.video_parent_border;
9304 ecore_x_window_move(bd->win,
9306 parent->client_inset.l +
9308 bd->client.e.state.video_position.x,
9310 parent->client_inset.t +
9312 bd->client.e.state.video_position.y);
9314 else if ((bd->post_move) && (bd->post_resize))
9316 ecore_x_window_move_resize(bd->win,
9321 else if (bd->post_move)
9323 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
9325 else if (bd->post_resize)
9327 ecore_x_window_resize(bd->win, bd->w, bd->h);
9330 if (bd->client.e.state.video)
9332 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
9334 bd->client.e.state.video_parent_border->x +
9335 bd->client.e.state.video_parent_border->client_inset.l +
9336 bd->client.e.state.video_parent_border->fx.x +
9337 bd->client.e.state.video_position.x,
9338 bd->client.e.state.video_parent_border->y +
9339 bd->client.e.state.video_parent_border->client_inset.t +
9340 bd->client.e.state.video_parent_border->fx.y +
9341 bd->client.e.state.video_position.y,
9349 bd->post_job = NULL;
9355 bd->post_resize = 0;
9356 bd->post_job = NULL;
9357 return ECORE_CALLBACK_CANCEL;
9361 _e_border_container_layout_hook(E_Container *con)
9363 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
9367 _e_border_eval0(E_Border *bd)
9369 int change_urgent = 0;
9371 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9372 Eina_Bool need_desk_set = EINA_FALSE;
9374 #ifdef _F_ZONE_WINDOW_ROTATION_
9375 Eina_Bool need_rotation_set = EINA_FALSE;
9377 if ((e_config->wm_win_rotation) &&
9378 (bd->client.icccm.fetch.transient_for))
9380 if (((rot.vkbd) && (rot.vkbd == bd)) ||
9381 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
9383 need_rotation_set = EINA_TRUE;
9384 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
9389 if (e_object_is_del(E_OBJECT(bd)))
9391 CRI("_e_border_eval(%p) with deleted border!\n", bd);
9396 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
9398 bd->changes.border = 0;
9400 /* fetch any info queued to be fetched */
9401 if (bd->client.netwm.fetch.state)
9403 e_hints_window_state_get(bd);
9404 bd->client.netwm.fetch.state = 0;
9407 if (bd->client.icccm.fetch.client_leader)
9409 /* TODO: What do to if the client leader isn't mapped yet? */
9410 E_Border *bd_leader = NULL;
9412 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
9413 if (bd->client.icccm.client_leader)
9414 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
9417 if (bd->leader != bd_leader)
9419 bd->leader->group = eina_list_remove(bd->leader->group, bd);
9420 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9426 /* If this border is the leader of the group, don't register itself */
9427 if ((bd_leader) && (bd_leader != bd))
9429 bd_leader->group = eina_list_append(bd_leader->group, bd);
9430 bd->leader = bd_leader;
9431 /* Only set the window modal to the leader it there is no parent */
9432 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9433 ((!bd->parent) || (bd->parent->modal != bd)))
9435 bd->leader->modal = bd;
9436 if (bd->leader->focused)
9437 e_border_focus_set(bd, 1, 1);
9443 EINA_LIST_FOREACH(bd->leader->group, l, child)
9445 if ((child != bd) && (child->focused))
9446 e_border_focus_set(bd, 1, 1);
9451 bd->client.icccm.fetch.client_leader = 0;
9454 if (bd->client.icccm.fetch.title)
9456 char *title = ecore_x_icccm_title_get(bd->client.win);
9457 eina_stringshare_replace(&bd->client.icccm.title, title);
9458 if (title) free(title);
9461 edje_object_part_text_set(bd->bg_object, "e.text.title",
9462 bd->client.icccm.title);
9463 bd->client.icccm.fetch.title = 0;
9466 if (bd->client.netwm.fetch.name)
9469 ecore_x_netwm_name_get(bd->client.win, &name);
9470 eina_stringshare_replace(&bd->client.netwm.name, name);
9471 if (name) free(name);
9474 edje_object_part_text_set(bd->bg_object, "e.text.title",
9475 bd->client.netwm.name);
9476 bd->client.netwm.fetch.name = 0;
9479 if (bd->client.icccm.fetch.name_class)
9481 const char *pname, *pclass;
9482 char *nname, *nclass;
9484 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9485 pname = bd->client.icccm.name;
9486 pclass = bd->client.icccm.class;
9487 bd->client.icccm.name = eina_stringshare_add(nname);
9488 bd->client.icccm.class = eina_stringshare_add(nclass);
9489 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9490 e_bindings_mapping_change_enable(EINA_FALSE);
9491 #ifdef _F_ZONE_WINDOW_ROTATION_
9492 if (e_config->wm_win_rotation)
9494 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9496 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9497 (!strcmp(bd->client.icccm.class, "ISF")))
9499 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9500 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9503 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9504 (!strcmp(bd->client.icccm.class, "ISF")))
9506 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9507 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9508 rot.vkbd_prediction = bd;
9510 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9511 (!strcmp(bd->client.icccm.class, "ISF")))
9513 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9514 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9516 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9517 (!strcmp(bd->client.icccm.class, "ISF")))
9519 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9520 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9525 if (nname) free(nname);
9526 if (nclass) free(nclass);
9528 if (!((bd->client.icccm.name == pname) &&
9529 (bd->client.icccm.class == pclass)))
9530 bd->changes.icon = 1;
9532 if (pname) eina_stringshare_del(pname);
9533 if (pclass) eina_stringshare_del(pclass);
9534 bd->client.icccm.fetch.name_class = 0;
9535 bd->changes.icon = 1;
9538 if (bd->client.icccm.fetch.state)
9540 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9541 bd->client.icccm.fetch.state = 0;
9544 if (bd->client.e.fetch.state)
9546 e_hints_window_e_state_get(bd);
9547 bd->client.e.fetch.state = 0;
9550 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9551 if (bd->client.e.fetch.profile_list)
9553 const char **profiles = NULL;
9557 if (bd->client.e.state.profile)
9558 eina_stringshare_del(bd->client.e.state.profile);
9559 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9561 if (str) eina_stringshare_del(str);
9563 bd->client.e.state.profile = NULL;
9564 bd->client.e.state.profiles = NULL;
9565 bd->client.e.state.profile_list = 0;
9567 if (ecore_x_e_window_profile_list_get(bd->client.win,
9570 bd->client.e.state.profile_list = 1;
9571 for (i = 0; i < num; i++)
9573 str = eina_stringshare_add(profiles[i]);
9574 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9577 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9578 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9580 need_desk_set = EINA_TRUE;
9584 if (strcmp(bd->desk->window_profile,
9585 e_config->desktop_default_window_profile) != 0)
9587 ecore_x_e_window_profile_set(bd->client.win,
9588 bd->desk->window_profile);
9594 for (i = 0; i < num; i++)
9595 if (profiles[i]) free(profiles[i]);
9599 bd->client.e.fetch.profile_list = 0;
9602 #ifdef _F_ZONE_WINDOW_ROTATION_
9603 if ((e_config->wm_win_rotation) &&
9604 (bd->client.e.fetch.rot.support))
9607 unsigned int support = 0;
9609 ret = ecore_x_window_prop_card32_get
9611 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9614 bd->client.e.state.rot.support = 0;
9615 if ((ret == 1) && (support == 1))
9616 bd->client.e.state.rot.support = 1;
9618 if (bd->client.e.state.rot.support)
9619 need_rotation_set = EINA_TRUE;
9621 bd->client.e.fetch.rot.support = 0;
9623 if ((e_config->wm_win_rotation) &&
9624 (bd->client.e.fetch.rot.geom_hint))
9626 Eina_Rectangle r[4];
9628 bd->client.e.state.rot.geom_hint = 0;
9629 for (i = 0; i < 4; i++)
9631 r[i].x = bd->client.e.state.rot.geom[i].x;
9632 r[i].y = bd->client.e.state.rot.geom[i].y;
9633 r[i].w = bd->client.e.state.rot.geom[i].w;
9634 r[i].h = bd->client.e.state.rot.geom[i].h;
9636 bd->client.e.state.rot.geom[i].x = 0;
9637 bd->client.e.state.rot.geom[i].y = 0;
9638 bd->client.e.state.rot.geom[i].w = 0;
9639 bd->client.e.state.rot.geom[i].h = 0;
9642 for (i = 0; i < 4; i++)
9644 x = 0; y = 0; w = 0; h = 0;
9645 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9647 bd->client.e.state.rot.geom_hint = 1;
9648 bd->client.e.state.rot.geom[i].x = x;
9649 bd->client.e.state.rot.geom[i].y = y;
9650 bd->client.e.state.rot.geom[i].w = w;
9651 bd->client.e.state.rot.geom[i].h = h;
9653 if (!((r[i].x == x) && (r[i].y == y) &&
9654 (r[i].w == w) && (r[i].h == h)))
9656 need_rotation_set = EINA_TRUE;
9660 bd->client.e.fetch.rot.geom_hint = 0;
9662 if ((e_config->wm_win_rotation) &&
9663 (bd->client.e.fetch.rot.app_set))
9665 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9666 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9667 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9669 if (_prev_app_set != bd->client.e.state.rot.app_set)
9670 need_rotation_set = EINA_TRUE;
9672 bd->client.e.fetch.rot.app_set = 0;
9674 if ((e_config->wm_win_rotation) &&
9675 (bd->client.e.fetch.rot.preferred_rot))
9677 int r = 0, _prev_preferred_rot;
9678 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9679 bd->client.e.state.rot.preferred_rot = -1;
9680 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9682 bd->client.e.state.rot.preferred_rot = r;
9683 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9687 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9690 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9691 need_rotation_set = EINA_TRUE;
9693 bd->client.e.fetch.rot.preferred_rot = 0;
9695 if ((e_config->wm_win_rotation) &&
9696 (bd->client.e.fetch.rot.available_rots))
9698 Eina_Bool res, diff = EINA_FALSE;
9700 unsigned int count = 0, i = 0;
9701 int _prev_rots[4] = { -1, };
9703 if (bd->client.e.state.rot.available_rots)
9706 bd->client.e.state.rot.available_rots,
9707 (sizeof(int) * bd->client.e.state.rot.count));
9709 E_FREE(bd->client.e.state.rot.available_rots);
9712 bd->client.e.state.rot.count = 0;
9714 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9716 if ((res) && (count > 0) && (rots))
9718 bd->client.e.state.rot.available_rots = rots;
9719 bd->client.e.state.rot.count = count;
9721 for (i = 0; i < count; i++)
9723 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9724 if ((!diff) && (_prev_rots[i] != rots[i]))
9726 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9727 count, i, _prev_rots[i], rots[i]);
9734 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9738 if (diff) need_rotation_set = EINA_TRUE;
9739 bd->client.e.fetch.rot.available_rots = 0;
9742 if (bd->client.netwm.fetch.type)
9744 e_hints_window_type_get(bd);
9745 if ((!bd->lock_border) || (!bd->client.border.name))
9746 bd->client.border.changed = 1;
9748 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9750 if (!bd->client.netwm.state.skip_pager)
9752 bd->client.netwm.state.skip_pager = 1;
9753 bd->client.netwm.update.state = 1;
9755 if (!bd->client.netwm.state.skip_taskbar)
9757 bd->client.netwm.state.skip_taskbar = 1;
9758 bd->client.netwm.update.state = 1;
9761 bd->client.netwm.fetch.type = 0;
9763 if (bd->client.icccm.fetch.machine)
9765 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9767 if ((!machine) && (bd->client.icccm.client_leader))
9768 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9770 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9771 if (machine) free(machine);
9773 bd->client.icccm.fetch.machine = 0;
9776 if (bd->client.icccm.fetch.command)
9778 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9782 for (i = 0; i < bd->client.icccm.command.argc; i++)
9783 free(bd->client.icccm.command.argv[i]);
9784 free(bd->client.icccm.command.argv);
9786 bd->client.icccm.command.argc = 0;
9787 bd->client.icccm.command.argv = NULL;
9788 ecore_x_icccm_command_get(bd->client.win,
9789 &(bd->client.icccm.command.argc),
9790 &(bd->client.icccm.command.argv));
9791 if ((bd->client.icccm.client_leader) &&
9792 (!bd->client.icccm.command.argv))
9793 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9794 &(bd->client.icccm.command.argc),
9795 &(bd->client.icccm.command.argv));
9796 bd->client.icccm.fetch.command = 0;
9799 if (bd->client.icccm.fetch.hints)
9801 Eina_Bool accepts_focus, is_urgent;
9803 accepts_focus = EINA_TRUE;
9804 is_urgent = EINA_FALSE;
9805 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9806 if (ecore_x_icccm_hints_get(bd->client.win,
9808 &bd->client.icccm.initial_state,
9809 &bd->client.icccm.icon_pixmap,
9810 &bd->client.icccm.icon_mask,
9811 &bd->client.icccm.icon_window,
9812 &bd->client.icccm.window_group,
9815 bd->client.icccm.accepts_focus = accepts_focus;
9816 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9818 bd->client.icccm.urgent = is_urgent;
9820 /* If this is a new window, set the state as requested. */
9821 if ((bd->new_client) &&
9822 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9824 e_border_iconify(bd);
9825 e_border_hide(bd, 1);
9828 bd->client.icccm.fetch.hints = 0;
9831 if (bd->client.icccm.fetch.size_pos_hints)
9833 Eina_Bool request_pos;
9835 request_pos = EINA_FALSE;
9836 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9838 &bd->client.icccm.gravity,
9839 &bd->client.icccm.min_w,
9840 &bd->client.icccm.min_h,
9841 &bd->client.icccm.max_w,
9842 &bd->client.icccm.max_h,
9843 &bd->client.icccm.base_w,
9844 &bd->client.icccm.base_h,
9845 &bd->client.icccm.step_w,
9846 &bd->client.icccm.step_h,
9847 &bd->client.icccm.min_aspect,
9848 &bd->client.icccm.max_aspect))
9850 bd->client.icccm.request_pos = request_pos;
9855 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9856 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9857 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9858 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9859 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9860 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9861 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9862 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9863 // if doing a resize, fix it up
9864 if (bd->resize_mode != RESIZE_NONE)
9866 int x, y, w, h, new_w, new_h;
9874 e_border_resize_limit(bd, &new_w, &new_h);
9875 if ((bd->resize_mode == RESIZE_TL) ||
9876 (bd->resize_mode == RESIZE_L) ||
9877 (bd->resize_mode == RESIZE_BL))
9879 if ((bd->resize_mode == RESIZE_TL) ||
9880 (bd->resize_mode == RESIZE_T) ||
9881 (bd->resize_mode == RESIZE_TR))
9883 e_border_move_resize(bd, x, y, new_w, new_h);
9885 bd->client.icccm.fetch.size_pos_hints = 0;
9888 if (bd->client.icccm.fetch.protocol)
9891 Ecore_X_WM_Protocol *proto;
9893 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9896 for (i = 0; i < num; i++)
9898 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9899 bd->client.icccm.delete_request = 1;
9900 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9901 bd->client.icccm.take_focus = 1;
9902 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9903 bd->client.netwm.ping = 1;
9904 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9906 bd->client.netwm.sync.request = 1;
9907 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9908 &bd->client.netwm.sync.counter))
9909 bd->client.netwm.sync.request = 0;
9914 if (bd->client.netwm.ping)
9918 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9919 bd->ping_poller = NULL;
9921 bd->client.icccm.fetch.protocol = 0;
9923 if (bd->client.icccm.fetch.transient_for)
9925 /* TODO: What do to if the transient for isn't mapped yet? */
9926 E_Border *bd_parent = NULL;
9927 #ifdef _F_DEICONIFY_APPROVE_
9928 Eina_Bool change_parent = EINA_FALSE;
9931 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9932 if (bd->client.icccm.transient_for)
9933 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9934 /* If we already have a parent, remove it */
9937 if (bd_parent != bd->parent)
9939 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9940 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9946 if ((bd_parent) && (bd_parent != bd) &&
9947 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9949 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9950 bd->parent = bd_parent;
9951 #ifdef _F_DEICONIFY_APPROVE_
9952 change_parent = EINA_TRUE;
9957 e_border_layer_set(bd, bd->parent->layer);
9958 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9960 Ecore_X_Window_Attributes attr;
9961 bd->parent->modal = bd;
9962 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9963 bd->parent->saved.event_mask = attr.event_mask.mine;
9964 bd->parent->lock_close = 1;
9965 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9966 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9969 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9970 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9974 #ifdef _F_DEICONIFY_APPROVE_
9977 bd->client.e.state.deiconify_approve.render_done = 0;
9979 E_Border *ancestor_bd;
9980 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9981 if ((ancestor_bd) &&
9982 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9984 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9985 bd->client.e.state.deiconify_approve.ancestor = NULL;
9987 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9988 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9990 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9992 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9993 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9994 e_border_uniconify(ancestor_bd);
10000 bd->client.icccm.fetch.transient_for = 0;
10003 if (bd->client.icccm.fetch.window_role)
10005 char *role = ecore_x_icccm_window_role_get(bd->client.win);
10006 eina_stringshare_replace(&bd->client.icccm.window_role, role);
10007 if (role) free(role);
10009 bd->client.icccm.fetch.window_role = 0;
10012 if (bd->client.icccm.fetch.icon_name)
10014 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
10015 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
10016 if (icon_name) free(icon_name);
10018 bd->client.icccm.fetch.icon_name = 0;
10021 if (bd->client.netwm.fetch.icon_name)
10024 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
10025 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
10026 if (icon_name) free(icon_name);
10028 bd->client.netwm.fetch.icon_name = 0;
10031 if (bd->client.netwm.fetch.icon)
10034 if (bd->client.netwm.icons)
10036 for (i = 0; i < bd->client.netwm.num_icons; i++)
10038 free(bd->client.netwm.icons[i].data);
10039 bd->client.netwm.icons[i].data = NULL;
10041 free(bd->client.netwm.icons);
10043 bd->client.netwm.icons = NULL;
10044 bd->client.netwm.num_icons = 0;
10045 if (ecore_x_netwm_icons_get(bd->client.win,
10046 &bd->client.netwm.icons,
10047 &bd->client.netwm.num_icons))
10049 // unless the rest of e17 uses border icons OTHER than icon #0
10050 // then free the rest that we don't need anymore.
10051 for (i = 1; i < bd->client.netwm.num_icons; i++)
10053 free(bd->client.netwm.icons[i].data);
10054 bd->client.netwm.icons[i].data = NULL;
10056 bd->client.netwm.num_icons = 1;
10057 bd->changes.icon = 1;
10059 bd->client.netwm.fetch.icon = 0;
10061 if (bd->client.netwm.fetch.user_time)
10063 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
10064 bd->client.netwm.fetch.user_time = 0;
10066 if (bd->client.netwm.fetch.strut)
10068 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
10069 &bd->client.netwm.strut.left,
10070 &bd->client.netwm.strut.right,
10071 &bd->client.netwm.strut.top,
10072 &bd->client.netwm.strut.bottom,
10073 &bd->client.netwm.strut.left_start_y,
10074 &bd->client.netwm.strut.left_end_y,
10075 &bd->client.netwm.strut.right_start_y,
10076 &bd->client.netwm.strut.right_end_y,
10077 &bd->client.netwm.strut.top_start_x,
10078 &bd->client.netwm.strut.top_end_x,
10079 &bd->client.netwm.strut.bottom_start_x,
10080 &bd->client.netwm.strut.bottom_end_x))
10082 ecore_x_netwm_strut_get(bd->client.win,
10083 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
10084 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
10086 bd->client.netwm.strut.left_start_y = 0;
10087 bd->client.netwm.strut.left_end_y = 0;
10088 bd->client.netwm.strut.right_start_y = 0;
10089 bd->client.netwm.strut.right_end_y = 0;
10090 bd->client.netwm.strut.top_start_x = 0;
10091 bd->client.netwm.strut.top_end_x = 0;
10092 bd->client.netwm.strut.bottom_start_x = 0;
10093 bd->client.netwm.strut.bottom_end_x = 0;
10095 bd->client.netwm.fetch.strut = 0;
10097 if (bd->client.qtopia.fetch.soft_menu)
10099 e_hints_window_qtopia_soft_menu_get(bd);
10100 bd->client.qtopia.fetch.soft_menu = 0;
10103 if (bd->client.qtopia.fetch.soft_menus)
10105 e_hints_window_qtopia_soft_menus_get(bd);
10106 bd->client.qtopia.fetch.soft_menus = 0;
10109 if (bd->client.vkbd.fetch.state)
10111 e_hints_window_virtual_keyboard_state_get(bd);
10112 bd->client.vkbd.fetch.state = 0;
10115 if (bd->client.vkbd.fetch.vkbd)
10117 e_hints_window_virtual_keyboard_get(bd);
10118 bd->client.vkbd.fetch.vkbd = 0;
10121 if (bd->client.illume.conformant.fetch.conformant)
10123 bd->client.illume.conformant.conformant =
10124 ecore_x_e_illume_conformant_get(bd->client.win);
10125 bd->client.illume.conformant.fetch.conformant = 0;
10127 if (bd->client.illume.quickpanel.fetch.state)
10129 bd->client.illume.quickpanel.state =
10130 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
10131 bd->client.illume.quickpanel.fetch.state = 0;
10133 if (bd->client.illume.quickpanel.fetch.quickpanel)
10135 bd->client.illume.quickpanel.quickpanel =
10136 ecore_x_e_illume_quickpanel_get(bd->client.win);
10137 bd->client.illume.quickpanel.fetch.quickpanel = 0;
10139 if (bd->client.illume.quickpanel.fetch.priority.major)
10141 bd->client.illume.quickpanel.priority.major =
10142 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
10143 bd->client.illume.quickpanel.fetch.priority.major = 0;
10145 if (bd->client.illume.quickpanel.fetch.priority.minor)
10147 bd->client.illume.quickpanel.priority.minor =
10148 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
10149 bd->client.illume.quickpanel.fetch.priority.minor = 0;
10151 if (bd->client.illume.quickpanel.fetch.zone)
10153 bd->client.illume.quickpanel.zone =
10154 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
10155 bd->client.illume.quickpanel.fetch.zone = 0;
10157 if (bd->client.illume.drag.fetch.drag)
10159 bd->client.illume.drag.drag =
10160 ecore_x_e_illume_drag_get(bd->client.win);
10161 bd->client.illume.drag.fetch.drag = 0;
10163 if (bd->client.illume.drag.fetch.locked)
10165 bd->client.illume.drag.locked =
10166 ecore_x_e_illume_drag_locked_get(bd->client.win);
10167 bd->client.illume.drag.fetch.locked = 0;
10169 if (bd->client.illume.win_state.fetch.state)
10171 bd->client.illume.win_state.state =
10172 ecore_x_e_illume_window_state_get(bd->client.win);
10173 bd->client.illume.win_state.fetch.state = 0;
10175 if (bd->changes.shape)
10177 Ecore_X_Rectangle *rects;
10180 bd->changes.shape = 0;
10181 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
10184 int cw = 0, ch = 0;
10186 /* This doesn't fix the race, but makes it smaller. we detect
10187 * this and if cw and ch != client w/h then mark this as needing
10188 * a shape change again to fixup next event loop.
10190 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10191 if ((cw != bd->client.w) || (ch != bd->client.h))
10192 bd->changes.shape = 1;
10194 (rects[0].x == 0) &&
10195 (rects[0].y == 0) &&
10196 ((int)rects[0].width == cw) &&
10197 ((int)rects[0].height == ch))
10199 if (bd->client.shaped)
10201 bd->client.shaped = 0;
10202 if (!bd->bordername)
10203 bd->client.border.changed = 1;
10208 if (!bd->client.shaped)
10210 bd->client.shaped = 1;
10211 if (!bd->bordername)
10212 bd->client.border.changed = 1;
10219 // FIXME: no rects i think can mean... totally empty window
10220 bd->client.shaped = 0;
10221 if (!bd->bordername)
10222 bd->client.border.changed = 1;
10224 bd->need_shape_merge = 1;
10226 if (bd->changes.shape_input)
10228 Ecore_X_Rectangle *rects;
10231 bd->changes.shape_input = 0;
10232 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
10235 int cw = 0, ch = 0;
10237 /* This doesn't fix the race, but makes it smaller. we detect
10238 * this and if cw and ch != client w/h then mark this as needing
10239 * a shape change again to fixup next event loop.
10241 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10242 if ((cw != bd->client.w) || (ch != bd->client.h))
10243 bd->changes.shape_input = 1;
10245 (rects[0].x == 0) &&
10246 (rects[0].y == 0) &&
10247 ((int)rects[0].width == cw) &&
10248 ((int)rects[0].height == ch))
10250 if (bd->shaped_input)
10252 bd->shaped_input = 0;
10253 if (!bd->bordername)
10254 bd->client.border.changed = 1;
10259 if (!bd->shaped_input)
10261 bd->shaped_input = 1;
10262 if (!bd->bordername)
10263 bd->client.border.changed = 1;
10270 bd->shaped_input = 1;
10271 if (!bd->bordername)
10272 bd->client.border.changed = 1;
10274 bd->need_shape_merge = 1;
10276 if (bd->client.mwm.fetch.hints)
10280 bd->client.mwm.exists =
10281 ecore_x_mwm_hints_get(bd->client.win,
10282 &bd->client.mwm.func,
10283 &bd->client.mwm.decor,
10284 &bd->client.mwm.input);
10285 pb = bd->client.mwm.borderless;
10286 bd->client.mwm.borderless = 0;
10287 if (bd->client.mwm.exists)
10289 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
10290 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
10291 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
10292 bd->client.mwm.borderless = 1;
10294 if (bd->client.mwm.borderless != pb)
10296 if ((!bd->lock_border) || (!bd->client.border.name))
10297 bd->client.border.changed = 1;
10299 bd->client.mwm.fetch.hints = 0;
10302 if (bd->client.e.fetch.video_parent)
10304 /* unlinking child/parent */
10305 if (bd->client.e.state.video_parent_border != NULL)
10307 bd->client.e.state.video_parent_border->client.e.state.video_child =
10309 (bd->client.e.state.video_parent_border->client.e.state.video_child,
10313 ecore_x_window_prop_card32_get(bd->client.win,
10314 ECORE_X_ATOM_E_VIDEO_PARENT,
10315 &bd->client.e.state.video_parent,
10318 /* linking child/parent */
10319 if (bd->client.e.state.video_parent != 0)
10324 EINA_LIST_FOREACH(borders, l, tmp)
10325 if (tmp->client.win == bd->client.e.state.video_parent)
10327 /* fprintf(stderr, "child added to parent \\o/\n"); */
10328 bd->client.e.state.video_parent_border = tmp;
10329 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
10331 if (bd->desk != tmp->desk)
10332 e_border_desk_set(bd, tmp->desk);
10337 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
10339 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
10342 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
10344 unsigned int xy[2];
10346 ecore_x_window_prop_card32_get(bd->client.win,
10347 ECORE_X_ATOM_E_VIDEO_POSITION,
10350 bd->client.e.state.video_position.x = xy[0];
10351 bd->client.e.state.video_position.y = xy[1];
10352 bd->client.e.state.video_position.updated = 1;
10353 bd->client.e.fetch.video_position = 0;
10354 bd->x = bd->client.e.state.video_position.x;
10355 bd->y = bd->client.e.state.video_position.y;
10357 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
10359 if (bd->client.netwm.update.state)
10361 e_hints_window_state_set(bd);
10362 /* Some stats might change the border, like modal */
10363 if (((!bd->lock_border) || (!bd->client.border.name)) &&
10364 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10366 bd->client.border.changed = 1;
10370 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10372 bd->parent->modal = bd;
10373 if (bd->parent->focused)
10374 e_border_focus_set(bd, 1, 1);
10377 else if (bd->leader)
10379 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10381 bd->leader->modal = bd;
10382 if (bd->leader->focused)
10383 e_border_focus_set(bd, 1, 1);
10389 EINA_LIST_FOREACH(bd->leader->group, l, child)
10391 if ((child != bd) && (child->focused))
10392 e_border_focus_set(bd, 1, 1);
10397 bd->client.netwm.update.state = 0;
10400 if (bd->new_client)
10402 E_Event_Border_Add *ev;
10403 E_Exec_Instance *inst;
10405 ev = E_NEW(E_Event_Border_Add, 1);
10407 e_object_ref(E_OBJECT(bd));
10408 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
10409 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
10411 if ((!bd->lock_border) || (!bd->client.border.name))
10412 bd->client.border.changed = 1;
10417 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
10418 ((bd->client.icccm.client_leader > 0) &&
10419 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10422 if (!strncmp(str, "E_START|", 8))
10426 id = atoi(str + 8);
10427 if (id > 0) bd->client.netwm.startup_id = id;
10432 /* It's ok not to have fetch flag, should only be set on startup
10433 * * and not changed. */
10434 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10436 if (bd->client.icccm.client_leader)
10438 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10439 bd->client.netwm.pid = -1;
10442 bd->client.netwm.pid = -1;
10445 if (!bd->re_manage)
10447 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10448 bd->client.netwm.pid);
10449 if ((inst) && (inst->used == 0))
10455 zone = e_container_zone_number_get(bd->zone->container,
10457 if (zone) e_border_zone_set(bd, zone);
10458 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10460 if (desk) e_border_desk_set(bd, desk);
10461 e_exec_instance_found(inst);
10464 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10466 E_Border *bdl = NULL;
10471 if (bd->leader) bdl = bd->leader;
10478 bl = e_container_border_list_first(bd->zone->container);
10479 while ((child = e_container_border_list_next(bl)))
10481 if (child == bd) continue;
10482 if (e_object_is_del(E_OBJECT(child))) continue;
10483 if ((bd->client.icccm.client_leader) &&
10484 (child->client.icccm.client_leader ==
10485 bd->client.icccm.client_leader))
10491 e_container_border_list_free(bl);
10496 e_border_zone_set(bd, bdl->zone);
10498 e_border_desk_set(bd, bdl->desk);
10500 e_border_stick(bd);
10506 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10509 E_Container *con = bd->zone->container;
10510 E_Desk *desk = NULL;
10513 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10515 desk = e_container_desk_window_profile_get(con, str);
10518 if (bd->desk != desk)
10520 bd->client.e.state.profile = eina_stringshare_add(str);
10521 if (bd->zone != desk->zone)
10522 e_border_zone_set(bd, desk->zone);
10523 e_border_desk_set(bd, desk);
10531 /* PRE_POST_FETCH calls e_remember apply for new client */
10532 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10533 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10534 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10536 #ifdef _F_ZONE_WINDOW_ROTATION_
10537 if (e_config->wm_win_rotation)
10539 if ((need_rotation_set) &&
10540 (bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_NORMAL))
10542 Eina_Bool hint = EINA_FALSE;
10544 int x, y, w, h, move;
10546 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10547 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10549 if (bd->client.e.state.rot.changes == -1)
10551 ang = bd->client.e.state.rot.curr;
10553 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10556 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10557 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10558 bd->client.icccm.name, x, y, w, h);
10561 else bd->changed = 1;
10566 if (bd->need_reparent)
10569 ecore_x_window_save_set_add(bd->client.win);
10570 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10573 if ((bd->new_client) && (bd->internal) &&
10574 (bd->internal_ecore_evas))
10575 ecore_evas_show(bd->internal_ecore_evas);
10576 ecore_x_window_show(bd->client.win);
10578 bd->need_reparent = 0;
10581 if ((bd->client.border.changed) && (!bd->shaded) &&
10582 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10584 const char *bordername;
10586 if (bd->fullscreen)
10587 bordername = "borderless";
10588 else if (bd->bordername)
10589 bordername = bd->bordername;
10590 else if ((bd->client.mwm.borderless) || (bd->borderless))
10591 bordername = "borderless";
10592 else if (((bd->client.icccm.transient_for != 0) ||
10593 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10594 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10595 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10596 bordername = "noresize_dialog";
10597 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10598 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10599 bordername = "noresize";
10600 else if (bd->client.shaped)
10601 bordername = "shaped";
10602 else if ((!bd->client.icccm.accepts_focus) &&
10603 (!bd->client.icccm.take_focus))
10604 bordername = "nofocus";
10605 else if (bd->client.icccm.urgent)
10606 bordername = "urgent";
10607 else if ((bd->client.icccm.transient_for != 0) ||
10608 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10609 bordername = "dialog";
10610 else if (bd->client.netwm.state.modal)
10611 bordername = "modal";
10612 else if ((bd->client.netwm.state.skip_taskbar) ||
10613 (bd->client.netwm.state.skip_pager))
10614 bordername = "skipped";
10615 else if ((bd->internal) && (bd->client.icccm.class) &&
10616 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10617 bordername = "internal_fileman";
10619 bordername = e_config->theme_default_border_style;
10620 if (!bordername) bordername = "default";
10622 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10628 bd->changes.border = 1;
10629 eina_stringshare_replace(&bd->client.border.name, bordername);
10633 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10634 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10635 bd->changes.size = 1;
10636 evas_object_del(bd->bg_object);
10638 o = edje_object_add(bd->bg_evas);
10639 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10640 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10641 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10643 if (bd->client.border.name != e_config->theme_default_border_style)
10645 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10646 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10650 ok = e_theme_edje_object_set(o, "base/theme/borders",
10651 "e/widgets/border/default/border");
10654 /* Reset default border style to default */
10655 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10656 e_config_save_queue();
10664 const char *shape_option, *argb_option;
10669 if ((e_config->use_composite) && (!bd->client.argb))
10671 argb_option = edje_object_data_get(o, "argb");
10672 if ((argb_option) && (!strcmp(argb_option, "1")))
10675 if (use_argb != bd->argb)
10676 _e_border_frame_replace(bd, use_argb);
10683 shape_option = edje_object_data_get(o, "shaped");
10684 if ((shape_option) && (!strcmp(shape_option, "1")))
10688 if (bd->client.netwm.name)
10689 edje_object_part_text_set(o, "e.text.title",
10690 bd->client.netwm.name);
10691 else if (bd->client.icccm.title)
10692 edje_object_part_text_set(o, "e.text.title",
10693 bd->client.icccm.title);
10697 evas_object_del(o);
10698 bd->bg_object = NULL;
10701 _e_border_client_inset_calc(bd);
10703 bd->w += (bd->client_inset.l + bd->client_inset.r);
10704 bd->h += (bd->client_inset.t + bd->client_inset.b);
10705 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10706 bd->changes.size = 1;
10707 /* really needed ? */
10708 ecore_x_window_move(bd->client.shell_win,
10709 bd->client_inset.l,
10710 bd->client_inset.t);
10712 if (bd->maximized != E_MAXIMIZE_NONE)
10714 E_Maximize maximized = bd->maximized;
10716 /* to force possible resizes */
10717 bd->maximized = E_MAXIMIZE_NONE;
10719 _e_border_maximize(bd, maximized);
10721 /* restore maximized state */
10722 bd->maximized = maximized;
10724 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10725 bd->maximized & E_MAXIMIZE_VERTICAL);
10729 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10730 _e_border_cb_signal_bind, bd);
10733 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10734 if (bd->icon_object)
10735 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10738 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10740 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10742 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10743 // FIXME: in eval -do differently
10744 // edje_object_message_signal_process(bd->bg_object);
10745 // e_border_frame_recalc(bd);
10747 evas_object_move(bd->bg_object, 0, 0);
10748 evas_object_resize(bd->bg_object, bd->w, bd->h);
10749 evas_object_show(bd->bg_object);
10752 bd->client.border.changed = 0;
10754 if (bd->icon_object)
10758 evas_object_show(bd->icon_object);
10759 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10762 evas_object_hide(bd->icon_object);
10766 if (rem_change) e_remember_update(bd);
10770 E_Event_Border_Urgent_Change *ev;
10772 if (bd->client.icccm.urgent)
10773 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10775 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10777 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10779 e_object_ref(E_OBJECT(bd));
10780 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10781 _e_border_event_border_urgent_change_free, NULL);
10784 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10787 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10789 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10791 E_Border* temp_bd = NULL;
10792 E_Border* top_focusable_bd = NULL;
10793 Eina_Bool is_fully_obscured = EINA_FALSE;
10794 Ecore_X_XRegion *visible_region = NULL;
10795 Ecore_X_XRegion *win_region = NULL;
10796 Ecore_X_Rectangle visible_rect, win_rect;
10799 // set the entire visible region as a root geometry
10800 visible_rect.x = bd->zone->x;
10801 visible_rect.y = bd->zone->y;
10802 visible_rect.width = bd->zone->w;
10803 visible_rect.height = bd->zone->h;
10805 visible_region = ecore_x_xregion_new();
10806 if (!visible_region) return;
10808 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10810 bl = e_container_border_list_last(bd->zone->container);
10811 while ((temp_bd = e_container_border_list_prev(bl)))
10813 if (temp_bd == bd) break;
10815 if (temp_bd == focused) continue;
10816 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10817 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10818 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10819 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10820 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10821 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10822 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10823 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10824 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10826 if (!top_focusable_bd)
10828 top_focusable_bd = temp_bd;
10831 win_rect.x = temp_bd->x;
10832 win_rect.y = temp_bd->y;
10833 win_rect.width = temp_bd->w;
10834 win_rect.height = temp_bd->h;
10836 // if it stick out or is bigger than the entire visible region,
10837 // clip it by the entire visible's geometry.
10838 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10839 win_rect.width, win_rect.height,
10840 visible_rect.x, visible_rect.y,
10841 (int)(visible_rect.width), (int)(visible_rect.height));
10843 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10845 win_region = ecore_x_xregion_new();
10848 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10849 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10850 ecore_x_xregion_free(win_region);
10853 if (ecore_x_xregion_is_empty(visible_region))
10855 is_fully_obscured = EINA_TRUE;
10863 if (is_fully_obscured == EINA_TRUE)
10865 e_border_focus_set(top_focusable_bd, 1, 1);
10869 e_border_focus_set(bd, 1, 1);
10872 if (visible_region) ecore_x_xregion_free(visible_region);
10873 e_container_border_list_free(bl);
10877 _e_border_latest_stacked_focus(E_Border *bd)
10880 int root_w, root_h;
10882 root_w = bd->zone->w;
10883 root_h = bd->zone->h;
10886 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10888 if (bd == temp_bd) continue;
10889 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10890 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10892 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10893 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10894 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10895 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10896 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10897 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10898 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10900 _e_border_latest_stacked_focus_check_set(temp_bd);
10907 _e_border_check_stack (E_Border *bd)
10909 E_Border* temp_bd = NULL;
10910 E_Border* top_bd = NULL;
10911 int passed_focus = 0;
10913 int root_w = bd->zone->w;
10914 int root_h = bd->zone->h;
10917 bl = e_container_border_list_last(bd->zone->container);
10918 while ((temp_bd = e_container_border_list_prev(bl)))
10920 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10921 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10922 if ((temp_bd != bd) &&
10923 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10925 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10926 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10927 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10928 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10929 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10930 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10931 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10937 e_border_focus_set_with_pointer(bd);
10944 e_border_focus_set_with_pointer(top_bd);
10953 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10955 if (!bd->lock_focus_out)
10957 e_border_focus_latest_set(bd);
10969 if (temp_bd == focused)
10975 e_container_border_list_free(bl);
10979 _e_border_focus_top_stack_set(E_Border* bd)
10982 int root_w, root_h;
10984 root_w = bd->zone->w;
10985 root_h = bd->zone->h;
10988 bl = e_container_border_list_last(bd->zone->container);
10989 while ((temp_bd = e_container_border_list_prev(bl)))
10991 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10992 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10993 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10995 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10996 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10997 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10998 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10999 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
11000 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
11001 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
11003 if (!temp_bd->focused)
11005 /* this border is the top of the latest stack */
11006 e_border_focus_set (temp_bd, 1, 1);
11011 e_container_border_list_free(bl);
11016 _e_border_eval(E_Border *bd)
11018 E_Event_Border_Property *event;
11019 E_Border_Pending_Move_Resize *pnd;
11020 int rem_change = 0;
11021 int send_event = 1;
11023 if (e_object_is_del(E_OBJECT(bd)))
11025 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
11030 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
11032 if (bd->new_client)
11034 int zx = 0, zy = 0, zw = 0, zh = 0;
11037 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
11040 * Limit maximum size of windows to useful geometry
11042 // TODO: temoporary limited maximize algorithm
11054 if ((rw != bd->w) || (rh != bd->h))
11058 e_border_resize (bd, bd->w, bd->h);
11064 bd->x -= bd->client_inset.l;
11065 bd->y -= bd->client_inset.t;
11066 bd->changes.pos = 1;
11069 else if ((!bd->placed) && (bd->client.icccm.request_pos))
11072 Ecore_X_Window_Attributes *att;
11075 att = &bd->client.initial_attributes;
11076 bw = att->border * 2;
11077 switch (bd->client.icccm.gravity)
11079 case ECORE_X_GRAVITY_N:
11080 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
11084 case ECORE_X_GRAVITY_NE:
11085 bd->x = (att->x - (bw)) - (bd->client_inset.l);
11089 case ECORE_X_GRAVITY_E:
11090 bd->x = (att->x - (bw)) - (bd->client_inset.l);
11091 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
11094 case ECORE_X_GRAVITY_SE:
11095 bd->x = (att->x - (bw)) - (bd->client_inset.l);
11096 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11099 case ECORE_X_GRAVITY_S:
11100 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
11101 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11104 case ECORE_X_GRAVITY_SW:
11106 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11109 case ECORE_X_GRAVITY_W:
11111 bd->y = (att->y - (bw)) - (bd->client_inset.t);
11114 case ECORE_X_GRAVITY_CENTER:
11115 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
11116 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
11119 case ECORE_X_GRAVITY_NW:
11126 * This ensures that windows that like to open with a x/y
11127 * position smaller than returned by e_zone_useful_geometry_get()
11128 * are moved to useful positions.
11131 if (e_config->geometry_auto_move)
11139 if (bd->x + bd->w > zx + zw)
11140 bd->x = zx + zw - bd->w;
11142 if (bd->y + bd->h > zy + zh)
11143 bd->y = zy + zh - bd->h;
11146 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
11148 bd->changes.pos = 1;
11154 bd->changes.pos = 1;
11160 /* FIXME: special placement for dialogs etc. etc. etc goes
11162 /* FIXME: what if parent is not on this desktop - or zone? */
11163 if ((bd->parent) && (bd->parent->visible))
11165 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
11166 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
11167 bd->changes.pos = 1;
11171 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
11173 /* TODO: Place in center of group */
11176 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11178 bd->x = zx + ((zw - bd->w) / 2);
11179 bd->y = zy + ((zh - bd->h) / 2);
11180 bd->changes.pos = 1;
11186 Eina_List *skiplist = NULL;
11190 new_x = zx + (rand() % (zw - bd->w));
11194 new_y = zy + (rand() % (zh - bd->h));
11198 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
11200 skiplist = eina_list_append(skiplist, bd);
11202 e_place_desk_region_smart(bd->desk, skiplist,
11203 bd->x, bd->y, bd->w, bd->h,
11206 e_place_zone_region_smart(bd->zone, skiplist,
11207 bd->x, bd->y, bd->w, bd->h,
11209 eina_list_free(skiplist);
11211 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
11213 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
11218 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
11219 bd->client_inset.t, &new_x, &new_y);
11223 bd->changes.pos = 1;
11226 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11228 if ((!bd->lock_client_location) && (pnd->move))
11232 bd->changes.pos = 1;
11234 if (pnd->without_border)
11236 bd->x -= bd->client_inset.l;
11237 bd->y -= bd->client_inset.t;
11240 if ((!bd->lock_client_size) && (pnd->resize))
11242 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
11243 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
11244 bd->client.w = pnd->w;
11245 bd->client.h = pnd->h;
11246 bd->changes.size = 1;
11252 /* Recreate state */
11253 e_hints_window_init(bd);
11254 if ((bd->client.e.state.centered) &&
11255 ((!bd->remember) ||
11256 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
11258 bd->x = zx + (zw - bd->w) / 2;
11259 bd->y = zy + (zh - bd->h) / 2;
11260 bd->changes.pos = 1;
11264 _e_border_client_move_resize_send(bd);
11266 /* if the explicit geometry request asks for the app to be
11267 * in another zone - well move it there */
11271 zone = e_container_zone_at_point_get(bd->zone->container,
11272 bd->x + (bd->w / 2),
11273 bd->y + (bd->h / 2));
11275 zone = e_container_zone_at_point_get(bd->zone->container,
11279 zone = e_container_zone_at_point_get(bd->zone->container,
11283 zone = e_container_zone_at_point_get(bd->zone->container,
11285 bd->y + bd->h - 1);
11287 zone = e_container_zone_at_point_get(bd->zone->container,
11289 bd->y + bd->h - 1);
11290 if ((zone) && (zone != bd->zone))
11291 e_border_zone_set(bd, zone);
11295 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
11297 /* effect changes to the window border itself */
11298 if ((bd->changes.shading))
11300 /* show at start of unshade (but don't hide until end of shade) */
11302 ecore_x_window_raise(bd->client.shell_win);
11303 bd->changes.shading = 0;
11306 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
11309 ecore_x_window_lower(bd->client.shell_win);
11311 ecore_x_window_raise(bd->client.shell_win);
11312 bd->changes.shaded = 0;
11315 else if ((bd->changes.shaded) && (bd->changes.pos))
11318 ecore_x_window_lower(bd->client.shell_win);
11320 ecore_x_window_raise(bd->client.shell_win);
11321 bd->changes.size = 1;
11322 bd->changes.shaded = 0;
11325 else if ((bd->changes.shaded) && (bd->changes.size))
11328 ecore_x_window_lower(bd->client.shell_win);
11330 ecore_x_window_raise(bd->client.shell_win);
11331 bd->changes.shaded = 0;
11334 else if (bd->changes.shaded)
11337 ecore_x_window_lower(bd->client.shell_win);
11339 ecore_x_window_raise(bd->client.shell_win);
11340 bd->changes.size = 1;
11341 bd->changes.shaded = 0;
11345 if (bd->changes.size)
11347 int x = 0, y = 0, xx = 0, yy = 0;
11349 if ((bd->shaded) && (!bd->shading))
11351 evas_obscured_clear(bd->bg_evas);
11355 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
11356 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
11358 evas_obscured_clear(bd->bg_evas);
11359 evas_obscured_rectangle_add(bd->bg_evas,
11360 bd->client_inset.l, bd->client_inset.t, xx, yy);
11364 if (bd->shade.dir == E_DIRECTION_UP)
11366 y = yy - bd->client.h;
11368 else if (bd->shade.dir == E_DIRECTION_LEFT)
11370 x = xx - bd->client.w;
11375 if (bd->client.e.state.video)
11377 if (bd->client.e.state.video_position.updated)
11379 ecore_x_window_move(bd->win,
11380 bd->client.e.state.video_parent_border->x +
11381 bd->client.e.state.video_parent_border->client_inset.l +
11382 bd->client.e.state.video_parent_border->fx.x +
11383 bd->client.e.state.video_position.x,
11384 bd->client.e.state.video_parent_border->y +
11385 bd->client.e.state.video_parent_border->client_inset.t +
11386 bd->client.e.state.video_parent_border->fx.y +
11387 bd->client.e.state.video_position.y);
11388 bd->client.e.state.video_position.updated = 0;
11391 else if (!bd->changes.pos)
11393 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11394 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11395 bd->post_resize = 1;
11402 ecore_x_window_move_resize(bd->win,
11407 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
11408 ecore_x_window_move(tmp->win,
11409 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
11410 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
11413 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
11415 if ((!bd->shaded) || (bd->shading))
11416 ecore_x_window_move_resize(bd->client.shell_win,
11417 bd->client_inset.l, bd->client_inset.t, xx, yy);
11419 if (bd->internal_ecore_evas)
11420 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
11421 else if (!bd->client.e.state.video)
11422 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11424 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11425 evas_object_resize(bd->bg_object, bd->w, bd->h);
11426 e_container_shape_resize(bd->shape, bd->w, bd->h);
11427 if (bd->changes.pos)
11428 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11430 _e_border_client_move_resize_send(bd);
11432 bd->changes.pos = 0;
11433 bd->changes.size = 0;
11436 else if (bd->changes.pos)
11438 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11439 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11442 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11444 _e_border_client_move_resize_send(bd);
11446 bd->changes.pos = 0;
11450 if (bd->changes.reset_gravity)
11452 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11453 bd->changes.reset_gravity = 0;
11457 if (bd->need_shape_merge)
11459 _e_border_shape_input_rectangle_set(bd);
11460 if ((bd->shaped) || (bd->client.shaped))
11462 Ecore_X_Window twin, twin2;
11465 twin = ecore_x_window_override_new
11466 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11468 ecore_x_window_shape_window_set(twin, bd->bg_win);
11471 Ecore_X_Rectangle rects[4];
11475 rects[0].width = bd->w;
11476 rects[0].height = bd->client_inset.t;
11478 rects[1].y = bd->client_inset.t;
11479 rects[1].width = bd->client_inset.l;
11480 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11481 rects[2].x = bd->w - bd->client_inset.r;
11482 rects[2].y = bd->client_inset.t;
11483 rects[2].width = bd->client_inset.r;
11484 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11486 rects[3].y = bd->h - bd->client_inset.b;
11487 rects[3].width = bd->w;
11488 rects[3].height = bd->client_inset.b;
11489 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11491 twin2 = ecore_x_window_override_new
11492 (bd->zone->container->scratch_win, 0, 0,
11493 bd->w - bd->client_inset.l - bd->client_inset.r,
11494 bd->h - bd->client_inset.t - bd->client_inset.b);
11497 if ((bd->shading) || (bd->shaded))
11499 if (bd->shade.dir == E_DIRECTION_UP)
11500 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11501 else if (bd->shade.dir == E_DIRECTION_LEFT)
11502 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11504 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11506 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11507 bd->w - bd->client_inset.l - bd->client_inset.r,
11508 bd->h - bd->client_inset.t - bd->client_inset.b);
11509 ecore_x_window_shape_window_add_xy(twin, twin2,
11510 bd->client_inset.l,
11511 bd->client_inset.t);
11512 ecore_x_window_free(twin2);
11513 ecore_x_window_shape_window_set(bd->win, twin);
11514 ecore_x_window_free(twin);
11517 ecore_x_window_shape_mask_set(bd->win, 0);
11518 // bd->need_shape_export = 1;
11519 bd->need_shape_merge = 0;
11522 if (bd->need_shape_export)
11524 Ecore_X_Rectangle *rects, *orects;
11527 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11533 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11537 orects = bd->shape_rects;
11539 for (i = 0; i < num; i++)
11541 if (rects[i].x < 0)
11543 rects[i].width -= rects[i].x;
11546 if ((rects[i].x + (int)rects[i].width) > bd->w)
11547 rects[i].width = rects[i].width - rects[i].x;
11548 if (rects[i].y < 0)
11550 rects[i].height -= rects[i].y;
11553 if ((rects[i].y + (int)rects[i].height) > bd->h)
11554 rects[i].height = rects[i].height - rects[i].y;
11556 if ((orects[i].x != rects[i].x) ||
11557 (orects[i].y != rects[i].y) ||
11558 (orects[i].width != rects[i].width) ||
11559 (orects[i].height != rects[i].height))
11568 if (bd->client.shaped)
11569 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11571 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11572 E_FREE(bd->shape_rects);
11573 bd->shape_rects = rects;
11574 bd->shape_rects_num = num;
11575 e_container_shape_rects_set(bd->shape, rects, num);
11582 E_FREE(bd->shape_rects);
11583 bd->shape_rects = NULL;
11584 bd->shape_rects_num = 0;
11585 e_container_shape_rects_set(bd->shape, NULL, 0);
11587 bd->need_shape_export = 0;
11590 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11594 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11595 if ((!bd->placed) && (!bd->re_manage) &&
11596 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11597 (!((bd->client.icccm.transient_for != 0) ||
11598 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11599 (!bdmove) && (!bdresize))
11601 /* Set this window into moving state */
11603 bd->cur_mouse_action = e_action_find("window_move");
11604 if (bd->cur_mouse_action)
11606 if ((!bd->cur_mouse_action->func.end_mouse) &&
11607 (!bd->cur_mouse_action->func.end))
11608 bd->cur_mouse_action = NULL;
11609 if (bd->cur_mouse_action)
11611 bd->x = x - (bd->w >> 1);
11612 bd->y = y - (bd->client_inset.t >> 1);
11614 bd->changes.pos = 1;
11616 _e_border_client_move_resize_send(bd);
11621 _e_border_show(bd);
11623 if (bd->cur_mouse_action)
11625 bd->moveinfo.down.x = bd->x + bd->fx.x;
11626 bd->moveinfo.down.y = bd->y + bd->fx.y;
11627 bd->moveinfo.down.w = bd->w;
11628 bd->moveinfo.down.h = bd->h;
11629 bd->mouse.current.mx = x;
11630 bd->mouse.current.my = y;
11631 bd->moveinfo.down.button = 0;
11632 bd->moveinfo.down.mx = x;
11633 bd->moveinfo.down.my = y;
11636 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11637 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11638 if (e_config->border_raise_on_mouse_action)
11639 e_border_raise(bd);
11640 e_border_focus_set(bd, 1, 1);
11642 bd->changes.visible = 0;
11646 if (bd->changes.icon)
11650 efreet_desktop_free(bd->desktop);
11651 bd->desktop = NULL;
11653 if (bd->icon_object)
11655 evas_object_del(bd->icon_object);
11656 bd->icon_object = NULL;
11658 if (bd->remember && bd->remember->prop.desktop_file)
11660 const char *desktop = bd->remember->prop.desktop_file;
11662 bd->desktop = efreet_desktop_get(desktop);
11664 bd->desktop = efreet_util_desktop_name_find(desktop);
11668 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11669 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11670 bd->client.icccm.class);
11674 /* libreoffice and maybe others match window class
11675 with .desktop file name */
11676 if (bd->client.icccm.class)
11679 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11680 bd->desktop = efreet_util_desktop_file_id_find(buf);
11685 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11686 bd->client.netwm.pid);
11687 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11689 if (!bd->desktop && bd->client.icccm.name)
11691 /* this works for most cases as fallback. useful when app is
11692 run from a shell */
11693 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11695 if (!bd->desktop && bd->client.icccm.transient_for)
11697 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11698 if (bd2 && bd2->desktop)
11700 efreet_desktop_ref(bd2->desktop);
11701 bd->desktop = bd2->desktop;
11706 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11707 bd->desktop->orig_path);
11710 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11711 if ((bd->focused) && (bd->icon_object))
11712 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11715 evas_object_show(bd->icon_object);
11716 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11719 evas_object_hide(bd->icon_object);
11722 E_Event_Border_Icon_Change *ev;
11724 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11726 e_object_ref(E_OBJECT(bd));
11727 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11728 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11729 _e_border_event_border_icon_change_free, NULL);
11731 bd->changes.icon = 0;
11734 bd->new_client = 0;
11736 bd->changes.stack = 0;
11737 bd->changes.prop = 0;
11739 if (bd->client.e.state.rot.changes != -1)
11741 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11742 bd->client.e.state.rot.changes = -1;
11745 if ((bd->take_focus) || (bd->want_focus))
11747 bd->take_focus = 0;
11748 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11749 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11750 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11753 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11756 bd->want_focus = 0;
11757 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11758 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11759 _e_border_check_stack(bd);
11762 e_border_focus_set_with_pointer(bd);
11764 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11766 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11767 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11768 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11769 e_border_focused_get())))
11771 e_border_focus_set_with_pointer(bd);
11776 /* focus window by default when it is the only one on desk */
11777 E_Border *bd2 = NULL;
11779 EINA_LIST_FOREACH(focus_stack, l, bd2)
11781 if (bd == bd2) continue;
11782 if ((!bd2->iconic) && (bd2->visible) &&
11783 ((bd->desk == bd2->desk) || bd2->sticky))
11789 e_border_focus_set_with_pointer(bd);
11794 if (bd->need_maximize)
11797 max = bd->maximized;
11798 bd->maximized = E_MAXIMIZE_NONE;
11799 e_border_maximize(bd, max);
11800 bd->need_maximize = 0;
11803 if (bd->need_fullscreen)
11805 e_border_fullscreen(bd, e_config->fullscreen_policy);
11806 bd->need_fullscreen = 0;
11810 e_remember_update(bd);
11812 if (send_event) // FIXME: send only if a property changed - above need to
11813 { // check on that. for now - always send.
11814 event = E_NEW(E_Event_Border_Property, 1);
11815 event->border = bd;
11816 e_object_ref(E_OBJECT(bd));
11817 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11819 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11823 _e_border_moveinfo_gather(E_Border *bd,
11824 const char *source)
11826 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11827 else if (e_util_glob_match(source, "mouse,*,2"))
11828 bd->moveinfo.down.button = 2;
11829 else if (e_util_glob_match(source, "mouse,*,3"))
11830 bd->moveinfo.down.button = 3;
11831 else bd->moveinfo.down.button = 0;
11832 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11834 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11835 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11839 bd->moveinfo.down.mx = bd->mouse.current.mx;
11840 bd->moveinfo.down.my = bd->mouse.current.my;
11845 _e_border_resize_handle(E_Border *bd)
11848 int new_x, new_y, new_w, new_h;
11850 Eina_List *skiplist = NULL;
11857 if ((bd->resize_mode == RESIZE_TR) ||
11858 (bd->resize_mode == RESIZE_R) ||
11859 (bd->resize_mode == RESIZE_BR))
11861 if ((bd->moveinfo.down.button >= 1) &&
11862 (bd->moveinfo.down.button <= 3))
11863 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11864 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11866 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11868 else if ((bd->resize_mode == RESIZE_TL) ||
11869 (bd->resize_mode == RESIZE_L) ||
11870 (bd->resize_mode == RESIZE_BL))
11872 if ((bd->moveinfo.down.button >= 1) &&
11873 (bd->moveinfo.down.button <= 3))
11874 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11875 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11877 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11880 if ((bd->resize_mode == RESIZE_TL) ||
11881 (bd->resize_mode == RESIZE_T) ||
11882 (bd->resize_mode == RESIZE_TR))
11884 if ((bd->moveinfo.down.button >= 1) &&
11885 (bd->moveinfo.down.button <= 3))
11886 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11887 (bd->mouse.current.my - bd->moveinfo.down.my);
11889 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11891 else if ((bd->resize_mode == RESIZE_BL) ||
11892 (bd->resize_mode == RESIZE_B) ||
11893 (bd->resize_mode == RESIZE_BR))
11895 if ((bd->moveinfo.down.button >= 1) &&
11896 (bd->moveinfo.down.button <= 3))
11897 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11898 (bd->mouse.current.my - bd->moveinfo.down.my);
11900 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11906 if ((bd->resize_mode == RESIZE_TL) ||
11907 (bd->resize_mode == RESIZE_L) ||
11908 (bd->resize_mode == RESIZE_BL))
11910 if ((bd->resize_mode == RESIZE_TL) ||
11911 (bd->resize_mode == RESIZE_T) ||
11912 (bd->resize_mode == RESIZE_TR))
11915 skiplist = eina_list_append(skiplist, bd);
11916 e_resist_container_border_position(bd->zone->container, skiplist,
11917 bd->x, bd->y, bd->w, bd->h,
11919 &new_x, &new_y, &new_w, &new_h);
11920 eina_list_free(skiplist);
11924 e_border_resize_limit(bd, &new_w, &new_h);
11925 if ((bd->resize_mode == RESIZE_TL) ||
11926 (bd->resize_mode == RESIZE_L) ||
11927 (bd->resize_mode == RESIZE_BL))
11928 new_x += (w - new_w);
11929 if ((bd->resize_mode == RESIZE_TL) ||
11930 (bd->resize_mode == RESIZE_T) ||
11931 (bd->resize_mode == RESIZE_TR))
11932 new_y += (h - new_h);
11934 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11938 _e_border_shade_animator(void *data)
11940 E_Border *bd = data;
11942 double dur = bd->client.h / e_config->border_shade_speed;
11944 dt = ecore_loop_time_get() - bd->shade.start;
11947 if (val < 0.0) val = 0.0;
11948 else if (val > 1.0) val = 1.0;
11950 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11953 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11954 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11956 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11959 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11960 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11962 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11965 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11966 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11968 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11971 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 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_ACCELERATE_LOTS)
11977 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11978 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11980 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11983 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11984 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11986 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11989 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11990 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11992 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11995 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11996 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11998 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
12001 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
12002 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
12007 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
12008 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
12011 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
12012 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
12013 else if (bd->shade.val > .999)
12014 bd->shade.val = 1.0;
12016 if (bd->shade.dir == E_DIRECTION_UP)
12017 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
12018 else if (bd->shade.dir == E_DIRECTION_DOWN)
12020 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
12021 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
12022 bd->changes.pos = 1;
12024 else if (bd->shade.dir == E_DIRECTION_LEFT)
12025 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
12026 else if (bd->shade.dir == E_DIRECTION_RIGHT)
12028 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
12029 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
12030 bd->changes.pos = 1;
12033 if ((bd->shaped) || (bd->client.shaped))
12035 bd->need_shape_merge = 1;
12036 bd->need_shape_export = 1;
12038 if (bd->shaped_input)
12040 bd->need_shape_merge = 1;
12042 bd->changes.size = 1;
12048 E_Event_Border_Resize *ev;
12051 bd->shaded = !(bd->shaded);
12052 bd->changes.size = 1;
12053 bd->changes.shaded = 1;
12054 bd->changes.shading = 1;
12056 bd->shade.anim = NULL;
12059 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
12061 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
12062 edje_object_message_signal_process(bd->bg_object);
12063 e_border_frame_recalc(bd);
12065 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
12066 ev = E_NEW(E_Event_Border_Resize, 1);
12068 e_object_ref(E_OBJECT(bd));
12069 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
12070 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
12071 return ECORE_CALLBACK_CANCEL;
12073 return ECORE_CALLBACK_RENEW;
12077 _e_border_event_border_resize_free(void *data __UNUSED__,
12080 E_Event_Border_Resize *e;
12083 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
12084 e_object_unref(E_OBJECT(e->border));
12089 _e_border_event_border_move_free(void *data __UNUSED__,
12092 E_Event_Border_Move *e;
12095 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
12096 e_object_unref(E_OBJECT(e->border));
12101 _e_border_event_border_add_free(void *data __UNUSED__,
12104 E_Event_Border_Add *e;
12107 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
12108 e_object_unref(E_OBJECT(e->border));
12113 _e_border_event_border_remove_free(void *data __UNUSED__,
12116 E_Event_Border_Remove *e;
12119 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
12120 e_object_unref(E_OBJECT(e->border));
12125 _e_border_event_border_show_free(void *data __UNUSED__,
12128 E_Event_Border_Show *e;
12131 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
12132 e_object_unref(E_OBJECT(e->border));
12137 _e_border_event_border_hide_free(void *data __UNUSED__,
12140 E_Event_Border_Hide *e;
12143 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
12144 e_object_unref(E_OBJECT(e->border));
12149 _e_border_event_border_iconify_free(void *data __UNUSED__,
12152 E_Event_Border_Iconify *e;
12155 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
12156 e_object_unref(E_OBJECT(e->border));
12161 _e_border_event_border_uniconify_free(void *data __UNUSED__,
12164 E_Event_Border_Uniconify *e;
12167 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
12168 e_object_unref(E_OBJECT(e->border));
12173 _e_border_event_border_stick_free(void *data __UNUSED__,
12176 E_Event_Border_Stick *e;
12179 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
12180 e_object_unref(E_OBJECT(e->border));
12185 _e_border_event_border_unstick_free(void *data __UNUSED__,
12188 E_Event_Border_Unstick *e;
12191 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
12192 e_object_unref(E_OBJECT(e->border));
12197 _e_border_event_border_zone_set_free(void *data __UNUSED__,
12200 E_Event_Border_Zone_Set *e;
12203 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
12204 e_object_unref(E_OBJECT(e->border));
12205 e_object_unref(E_OBJECT(e->zone));
12210 _e_border_event_border_desk_set_free(void *data __UNUSED__,
12213 E_Event_Border_Desk_Set *e;
12216 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
12217 e_object_unref(E_OBJECT(e->border));
12218 e_object_unref(E_OBJECT(e->desk));
12223 _e_border_event_border_stack_free(void *data __UNUSED__,
12226 E_Event_Border_Stack *e;
12229 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
12230 e_object_unref(E_OBJECT(e->border));
12233 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
12234 e_object_unref(E_OBJECT(e->stack));
12240 _e_border_event_border_icon_change_free(void *data __UNUSED__,
12243 E_Event_Border_Icon_Change *e;
12246 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
12247 e_object_unref(E_OBJECT(e->border));
12252 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
12255 E_Event_Border_Urgent_Change *e;
12258 e_object_unref(E_OBJECT(e->border));
12263 _e_border_event_border_focus_in_free(void *data __UNUSED__,
12266 E_Event_Border_Focus_In *e;
12269 e_object_unref(E_OBJECT(e->border));
12274 _e_border_event_border_focus_out_free(void *data __UNUSED__,
12277 E_Event_Border_Focus_Out *e;
12280 e_object_unref(E_OBJECT(e->border));
12285 _e_border_event_border_property_free(void *data __UNUSED__,
12288 E_Event_Border_Property *e;
12291 e_object_unref(E_OBJECT(e->border));
12296 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
12299 E_Event_Border_Fullscreen *e;
12302 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
12303 e_object_unref(E_OBJECT(e->border));
12308 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
12311 E_Event_Border_Unfullscreen *e;
12314 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
12315 e_object_unref(E_OBJECT(e->border));
12319 #ifdef _F_ZONE_WINDOW_ROTATION_
12321 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
12324 E_Event_Border_Rotation_Change_Begin *e;
12326 e_object_unref(E_OBJECT(e->border));
12331 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
12334 E_Event_Border_Rotation_Change_Cancel *e;
12336 e_object_unref(E_OBJECT(e->border));
12341 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
12344 E_Event_Border_Rotation_Change_End *e;
12346 e_object_unref(E_OBJECT(e->border));
12351 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
12353 E_Event_Border_Rotation_Change_Begin *ev = NULL;
12354 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
12358 e_object_ref(E_OBJECT(bd));
12359 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
12361 _e_border_event_border_rotation_change_begin_free,
12368 _e_border_zone_update(E_Border *bd)
12374 /* still within old zone - leave it there */
12375 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12376 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
12377 #if _F_BORDER_CLIP_TO_ZONE_
12379 _e_border_shape_input_clip_to_zone(bd);
12384 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12385 /* find a new zone */
12386 con = bd->zone->container;
12387 EINA_LIST_FOREACH(con->zones, l, zone)
12389 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12390 zone->x, zone->y, zone->w, zone->h))
12392 e_border_zone_set(bd, zone);
12393 #if _F_BORDER_CLIP_TO_ZONE_
12394 _e_border_shape_input_clip_to_zone(bd);
12395 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12402 _e_border_resize_begin(E_Border *bd)
12406 if (!bd->lock_user_stacking)
12408 if (e_config->border_raise_on_mouse_action)
12409 e_border_raise(bd);
12411 if ((bd->shaded) || (bd->shading) ||
12412 (bd->fullscreen) || (bd->lock_user_size))
12415 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12416 ret = e_grabinput_get(bd->win, 0, bd->win);
12418 ret = e_grabinput_get(bd->win, 0, 0);
12420 if (grabbed && !ret)
12426 if (bd->client.netwm.sync.request)
12428 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12429 bd->client.netwm.sync.serial = 1;
12430 bd->client.netwm.sync.wait = 0;
12431 bd->client.netwm.sync.send_time = ecore_loop_time_get();
12434 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12441 _e_border_resize_end(E_Border *bd)
12445 e_grabinput_release(bd->win, bd->win);
12448 if (bd->client.netwm.sync.alarm)
12450 E_Border_Pending_Move_Resize *pnd;
12452 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12453 bd->client.netwm.sync.alarm = 0;
12454 /* resize to last geometry if sync alarm for it was not yet handled */
12455 if (bd->pending_move_resize)
12458 bd->changes.pos = 1;
12459 bd->changes.size = 1;
12460 _e_border_client_move_resize_send(bd);
12463 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12467 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12471 /* If this border was maximized, we need to unset Maximized state or
12472 * on restart, E still thinks it's maximized */
12473 if (bd->maximized != E_MAXIMIZE_NONE)
12474 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12475 bd->maximized & E_MAXIMIZE_NONE);
12480 _e_border_resize_update(E_Border *bd)
12482 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12486 _e_border_move_begin(E_Border *bd)
12489 if (!bd->lock_user_stacking)
12491 if (e_config->border_raise_on_mouse_action)
12492 e_border_raise(bd);
12494 if ((bd->fullscreen) || (bd->lock_user_location))
12497 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12498 ret = e_grabinput_get(bd->win, 0, bd->win);
12500 ret = e_grabinput_get(bd->win, 0, 0);
12502 if (grabbed && !ret)
12508 if (bd->client.netwm.sync.request)
12510 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12511 bd->client.netwm.sync.serial = 0;
12512 bd->client.netwm.sync.wait = 0;
12513 bd->client.netwm.sync.time = ecore_loop_time_get();
12516 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12523 _e_border_move_end(E_Border *bd)
12527 e_grabinput_release(bd->win, bd->win);
12531 if (bd->client.netwm.sync.alarm)
12533 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12534 bd->client.netwm.sync.alarm = 0;
12537 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12544 _e_border_move_update(E_Border *bd)
12546 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12550 _e_border_cb_ping_poller(void *data)
12560 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12561 if (bd->kill_timer)
12563 ecore_timer_del(bd->kill_timer);
12564 bd->kill_timer = NULL;
12570 /* if time between last ping and now is greater
12571 * than half the ping interval... */
12572 if ((ecore_loop_time_get() - bd->ping) >
12573 ((e_config->ping_clients_interval *
12574 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12579 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12580 /* FIXME: if below dialog is up - hide it now */
12582 if (bd->delete_requested)
12584 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12585 e_border_act_kill_begin(bd);
12589 bd->ping_poller = NULL;
12591 return ECORE_CALLBACK_CANCEL;
12595 _e_border_cb_kill_timer(void *data)
12600 // dont wait until it's hung -
12603 if (bd->client.netwm.pid > 1)
12604 kill(bd->client.netwm.pid, SIGKILL);
12606 bd->kill_timer = NULL;
12607 return ECORE_CALLBACK_CANCEL;
12611 _e_border_pointer_resize_begin(E_Border *bd)
12613 switch (bd->resize_mode)
12616 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12620 e_pointer_type_push(bd->pointer, bd, "resize_t");
12624 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12628 e_pointer_type_push(bd->pointer, bd, "resize_r");
12632 e_pointer_type_push(bd->pointer, bd, "resize_br");
12636 e_pointer_type_push(bd->pointer, bd, "resize_b");
12640 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12644 e_pointer_type_push(bd->pointer, bd, "resize_l");
12650 _e_border_pointer_resize_end(E_Border *bd)
12652 switch (bd->resize_mode)
12655 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12659 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12663 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12667 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12671 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12675 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12679 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12683 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12689 _e_border_pointer_move_begin(E_Border *bd)
12691 e_pointer_type_push(bd->pointer, bd, "move");
12695 _e_border_pointer_move_end(E_Border *bd)
12697 e_pointer_type_pop(bd->pointer, bd, "move");
12700 static Eina_List *_e_border_hooks = NULL;
12701 static int _e_border_hooks_delete = 0;
12702 static int _e_border_hooks_walking = 0;
12705 _e_border_hooks_clean(void)
12710 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12714 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12721 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12727 _e_border_hooks_walking++;
12728 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12730 if (bh->delete_me) continue;
12731 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12733 _e_border_hooks_walking--;
12734 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12735 _e_border_hooks_clean();
12738 EAPI E_Border_Hook *
12739 e_border_hook_add(E_Border_Hook_Point hookpoint,
12740 void (*func)(void *data,
12746 bh = E_NEW(E_Border_Hook, 1);
12747 if (!bh) return NULL;
12748 bh->hookpoint = hookpoint;
12751 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12756 e_border_hook_del(E_Border_Hook *bh)
12759 if (_e_border_hooks_walking == 0)
12761 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12765 _e_border_hooks_delete++;
12769 e_border_focus_track_freeze(void)
12771 focus_track_frozen++;
12775 e_border_focus_track_thaw(void)
12777 focus_track_frozen--;
12781 e_border_under_pointer_get(E_Desk *desk,
12784 E_Border *bd = NULL, *cbd;
12788 /* We need to ensure that we can get the container window for the
12789 * zone of either the given desk or the desk of the excluded
12790 * window, so return if neither is given */
12792 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12794 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12798 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12800 if (!cbd) continue;
12801 /* If a border was specified which should be excluded from the list
12802 * (because it will be closed shortly for example), skip */
12803 if ((exclude) && (cbd == exclude)) continue;
12804 if ((desk) && (cbd->desk != desk)) continue;
12805 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12807 /* If the layer is higher, the position of the window is higher
12808 * (always on top vs always below) */
12809 if (!bd || (cbd->layer > bd->layer))
12819 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12826 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12827 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12828 (y - warp_y) > 5 || (y - warp_y) < -5)
12830 /* User moved the mouse, so stop warping */
12835 /* We just use the same warp speed as configured
12836 * for the windowlist */
12837 spd = e_config->winlist_warp_speed;
12840 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12841 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12842 if (warp_x == x && warp_y == y)
12844 warp_x = warp_to_x;
12845 warp_y = warp_to_y;
12849 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12850 return ECORE_CALLBACK_RENEW;
12853 ecore_timer_del(warp_timer);
12855 return ECORE_CALLBACK_CANCEL;
12859 e_border_pointer_warp_to_center(E_Border *bd)
12863 /* Do not slide pointer when disabled (probably breaks focus
12864 * on sloppy/mouse focus but requested by users). */
12865 if (!e_config->pointer_slide) return 0;
12866 /* Only warp the pointer if it is not already in the area of
12867 * the given border */
12868 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12869 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12870 (y >= bd->y) && (y <= (bd->y + bd->h)))
12873 warp_to_x = bd->x + (bd->w / 2);
12874 if (warp_to_x < (bd->zone->x + 1))
12875 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12876 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12877 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12879 warp_to_y = bd->y + (bd->h / 2);
12880 if (warp_to_y < (bd->zone->y + 1))
12881 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12882 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12883 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12886 warp_to_win = bd->zone->container->win;
12887 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12889 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12894 e_border_comp_hidden_set(E_Border *bd,
12900 E_OBJECT_CHECK(bd);
12901 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12903 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12906 ecore_x_window_hide(tmp->win);
12908 ecore_x_window_show(tmp->win);
12911 if (bd->comp_hidden == hidden) return;
12913 bd->comp_hidden = hidden;
12915 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12917 ecore_x_composite_window_events_disable(bd->win);
12918 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12922 _e_border_shape_input_rectangle_set(bd);
12923 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12928 e_border_tmp_input_hidden_push(E_Border *bd)
12933 E_OBJECT_CHECK(bd);
12934 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12936 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12937 e_border_tmp_input_hidden_push(tmp);
12939 bd->tmp_input_hidden++;
12940 if (bd->tmp_input_hidden != 1) return;
12942 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12944 ecore_x_composite_window_events_disable(bd->win);
12945 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12949 _e_border_shape_input_rectangle_set(bd);
12950 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12955 e_border_tmp_input_hidden_pop(E_Border *bd)
12960 E_OBJECT_CHECK(bd);
12961 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12963 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12964 e_border_tmp_input_hidden_pop(tmp);
12966 bd->tmp_input_hidden--;
12967 if (bd->tmp_input_hidden != 0) return;
12969 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12971 ecore_x_composite_window_events_disable(bd->win);
12972 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12976 _e_border_shape_input_rectangle_set(bd);
12977 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12982 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12984 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12986 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12987 ((bd->parent->focused) &&
12988 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12993 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12994 e_desk_show(bd->desk);
12996 if (!bd->lock_user_iconify)
12997 e_border_uniconify(bd);
12999 if ((!bd->iconic) && (!bd->sticky))
13000 e_desk_show(bd->desk);
13001 if (!bd->lock_user_stacking) e_border_raise(bd);
13002 if (!bd->lock_focus_out)
13004 /* XXX ooffice does send this request for
13005 config dialogs when the main window gets focus.
13006 causing the pointer to jump back and forth. */
13007 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
13008 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
13009 ecore_x_pointer_warp(bd->zone->container->win,
13010 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
13011 e_border_focus_set(bd, 1, 1);
13016 #ifdef _F_DEICONIFY_APPROVE_
13018 _e_border_window_pending_destroy_event_free(void *data __UNUSED__,
13021 Ecore_X_Event_Window_Destroy *e;
13028 _e_border_window_pending_hide_event_free(void *data __UNUSED__,
13031 Ecore_X_Event_Window_Hide *e;
13038 _e_border_window_pending_hide_event_send(E_Border *bd)
13040 Ecore_X_Event_Window_Hide *e;
13044 e = E_NEW(Ecore_X_Event_Window_Hide, 1);
13047 e->win = bd->client.e.state.pending_event.hide.win;
13048 e->event_win = bd->client.e.state.pending_event.hide.event_win;
13049 e->time = ecore_x_current_time_get();
13050 e->send_event = bd->client.e.state.pending_event.hide.send_event;
13052 ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e,
13053 _e_border_window_pending_hide_event_free, NULL);
13055 ELB(ELBT_BD, "Send pended HIDE event", e->win);
13060 _e_border_window_pending_destroy_event_send(E_Border *bd)
13062 Ecore_X_Event_Window_Destroy *e;
13066 e = E_NEW(Ecore_X_Event_Window_Destroy, 1);
13069 e->win = bd->client.e.state.pending_event.destroy.win;
13070 e->event_win = bd->client.e.state.pending_event.destroy.event_win;
13071 e->time = ecore_x_current_time_get();
13073 ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e,
13074 _e_border_window_pending_destroy_event_free, NULL);
13076 ELB(ELBT_BD, "Send pended DESTROY event", e->win);
13081 _e_border_msg_handler(void *data,
13088 E_Manager *man = (E_Manager *)obj;
13089 E_Manager_Comp_Source *src = (E_Manager_Comp_Source *)msgdata;
13091 // handle only comp.manager msg
13092 if (strncmp(name, "comp.manager", sizeof("comp.manager"))) return;
13094 if (!strncmp(info, "visibility.src", sizeof("visibility.src")))
13096 Ecore_X_Window win;
13100 win = e_manager_comp_src_window_get(man, src);
13101 bd = e_border_find_by_window(win);
13104 if (!bd->client.e.state.deiconify_approve.pending_bd) return;
13106 visible = e_manager_comp_src_visible_get(man, src);
13109 E_Border *pending_bd = bd->client.e.state.deiconify_approve.pending_bd;
13110 if (!pending_bd->client.e.state.pending_event.pending)
13112 bd->client.e.state.deiconify_approve.pending_bd = NULL;
13116 pending_bd->client.e.state.pending_event.done = 1;
13117 pending_bd->client.e.state.pending_event.hold_bd = NULL;
13119 if (pending_bd->client.e.state.pending_event.hide.pending)
13121 _e_border_window_pending_hide_event_send(pending_bd);
13123 // clear hide event data
13124 pending_bd->client.e.state.pending_event.hide.pending = 0;
13125 pending_bd->client.e.state.pending_event.hide.win = 0;
13126 pending_bd->client.e.state.pending_event.hide.event_win = 0;
13127 pending_bd->client.e.state.pending_event.hide.send_event = 0;
13130 if (pending_bd->client.e.state.pending_event.destroy.pending)
13132 _e_border_window_pending_destroy_event_send(pending_bd);
13134 // clear destroy event data
13135 pending_bd->client.e.state.pending_event.destroy.pending = 0;
13136 pending_bd->client.e.state.pending_event.destroy.win = 0;
13137 pending_bd->client.e.state.pending_event.destroy.event_win = 0;
13140 bd->client.e.state.deiconify_approve.pending_bd = NULL;
13141 ELBF(ELBT_ROT, 0, bd->client.win, "RESET pending_bd:%x", bd->client.e.state.deiconify_approve.pending_bd);
13146 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/