2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * This file is a modified version of BSD licensed file and
5 * licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://floralicense.org/license/
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * Please, see the COPYING file for the original copyright owner and
22 //#define INOUTDEBUG_MOUSE 1
23 //#define INOUTDEBUG_FOCUS 1
25 /* These are compatible with netwm */
35 #define RESIZE_NONE 11
37 /* local subsystem functions */
38 static void _e_border_pri_raise(E_Border *bd);
39 static void _e_border_pri_norm(E_Border *bd);
40 static void _e_border_free(E_Border *bd);
41 static void _e_border_del(E_Border *bd);
43 #ifdef PRINT_LOTS_OF_DEBUG
44 #define E_PRINT_BORDER_INFO(X) \
45 _e_border_print(X, __PRETTY_FUNC__)
47 static void _e_border_print(E_Border *bd,
51 /* FIXME: these likely belong in a separate icccm/client handler */
52 /* and the border needs to become a dumb object that just does what its */
54 static Eina_Bool _e_border_cb_window_show_request(void *data,
57 static Eina_Bool _e_border_cb_window_destroy(void *data,
60 static Eina_Bool _e_border_cb_window_hide(void *data,
63 static Eina_Bool _e_border_cb_window_reparent(void *data,
66 static Eina_Bool _e_border_cb_window_configure_request(void *data,
69 static Eina_Bool _e_border_cb_window_resize_request(void *data,
72 static Eina_Bool _e_border_cb_window_gravity(void *data,
75 static Eina_Bool _e_border_cb_window_stack_request(void *data,
78 static Eina_Bool _e_border_cb_window_property(void *data,
81 static Eina_Bool _e_border_cb_window_colormap(void *data,
84 static Eina_Bool _e_border_cb_window_shape(void *data,
87 static Eina_Bool _e_border_cb_window_focus_in(void *data,
90 static Eina_Bool _e_border_cb_window_focus_out(void *data,
93 static Eina_Bool _e_border_cb_client_message(void *data,
97 static Eina_Bool _e_border_cb_window_state_request(void *data,
100 static Eina_Bool _e_border_cb_window_move_resize_request(void *data,
103 static Eina_Bool _e_border_cb_desktop_change(void *data,
106 static Eina_Bool _e_border_cb_sync_alarm(void *data,
109 static Eina_Bool _e_border_cb_efreet_cache_update(void *data,
112 static Eina_Bool _e_border_cb_config_icon_theme(void *data,
116 static Eina_Bool _e_border_cb_pointer_warp(void *data,
119 static void _e_border_cb_signal_bind(void *data,
121 const char *emission,
123 static Eina_Bool _e_border_cb_mouse_in(void *data,
126 static Eina_Bool _e_border_cb_mouse_out(void *data,
129 static Eina_Bool _e_border_cb_mouse_wheel(void *data,
132 static Eina_Bool _e_border_cb_mouse_down(void *data,
135 static Eina_Bool _e_border_cb_mouse_up(void *data,
138 static Eina_Bool _e_border_cb_mouse_move(void *data,
141 static Eina_Bool _e_border_cb_grab_replay(void *data,
144 static void _e_border_cb_drag_finished(E_Drag *drag,
146 #ifdef _F_USE_DESK_WINDOW_PROFILE_
147 static Eina_Bool _e_border_cb_desk_window_profile_change(void *data,
151 #ifdef _F_ZONE_WINDOW_ROTATION_
152 static Eina_Bool _e_border_cb_zone_rotation_change_begin(void *data,
155 static void _e_border_cb_rotation_sync_job(void *data);
156 static void _e_border_cb_rotation_async_job(void *data);
157 static Eina_Bool _e_border_rotation_change_prepare_timeout(void *data);
158 static void _e_border_rotation_change_request(E_Zone *zone);
159 static void _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush);
160 static Eina_Bool _e_border_rotation_change_done_timeout(void *data);
161 static void _e_border_rotation_change_done(void);
162 static Eina_Bool _e_border_rotation_geom_get(E_Border *bd,
170 static void _e_border_rotation_list_remove(E_Border *bd);
171 static Eina_Bool _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h);
172 static int _e_border_rotation_angle_get(E_Border *bd);
173 static Eina_Bool _e_border_rotation_zone_set(E_Zone *zone);
174 static Eina_Bool _e_border_rotatable_check(E_Border *bd, int ang);
175 static Eina_Bool _e_border_is_vkbd(E_Border *bd);
176 static Eina_Bool _e_border_cb_window_configure(void *data,
179 static Eina_Bool _e_border_vkbd_show_prepare_timeout(void *data);
180 static Eina_Bool _e_border_vkbd_hide_prepare_timeout(void *data);
181 static void _e_border_vkbd_show(E_Border *bd);
182 static void _e_border_vkbd_hide(E_Border *bd);
183 static Eina_Bool _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending);
185 static void _e_border_move_resize_internal(E_Border *bd,
190 Eina_Bool without_border,
193 static void _e_border_eval(E_Border *bd);
194 static void _e_border_eval0(E_Border *bd);
195 static void _e_border_container_layout_hook(E_Container *con);
197 static void _e_border_moveinfo_gather(E_Border *bd,
199 static void _e_border_resize_handle(E_Border *bd);
201 static Eina_Bool _e_border_shade_animator(void *data);
203 static void _e_border_event_border_add_free(void *data,
205 static void _e_border_event_border_remove_free(void *data,
207 static void _e_border_event_border_zone_set_free(void *data,
209 static void _e_border_event_border_desk_set_free(void *data,
211 static void _e_border_event_border_stack_free(void *data,
213 static void _e_border_event_border_icon_change_free(void *data,
215 static void _e_border_event_border_urgent_change_free(void *data,
217 static void _e_border_event_border_focus_in_free(void *data,
219 static void _e_border_event_border_focus_out_free(void *data,
221 static void _e_border_event_border_resize_free(void *data,
223 static void _e_border_event_border_move_free(void *data,
225 static void _e_border_event_border_show_free(void *data,
227 static void _e_border_event_border_hide_free(void *data,
229 static void _e_border_event_border_iconify_free(void *data,
231 static void _e_border_event_border_uniconify_free(void *data,
233 static void _e_border_event_border_stick_free(void *data,
235 static void _e_border_event_border_unstick_free(void *data,
237 static void _e_border_event_border_property_free(void *data,
239 static void _e_border_event_border_fullscreen_free(void *data,
241 static void _e_border_event_border_unfullscreen_free(void *data,
243 #ifdef _F_ZONE_WINDOW_ROTATION_
244 static void _e_border_event_border_rotation_change_begin_free(void *data,
246 static void _e_border_event_border_rotation_change_cancel_free(void *data,
248 static void _e_border_event_border_rotation_change_end_free(void *data,
250 static void _e_border_event_border_rotation_change_begin_send(E_Border *bd);
253 static void _e_border_zone_update(E_Border *bd);
255 static int _e_border_resize_begin(E_Border *bd);
256 static int _e_border_resize_end(E_Border *bd);
257 static void _e_border_resize_update(E_Border *bd);
259 static int _e_border_move_begin(E_Border *bd);
260 static int _e_border_move_end(E_Border *bd);
261 static void _e_border_move_update(E_Border *bd);
263 static Eina_Bool _e_border_cb_ping_poller(void *data);
264 static Eina_Bool _e_border_cb_kill_timer(void *data);
266 static void _e_border_pointer_resize_begin(E_Border *bd);
267 static void _e_border_pointer_resize_end(E_Border *bd);
268 static void _e_border_pointer_move_begin(E_Border *bd);
269 static void _e_border_pointer_move_end(E_Border *bd);
271 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
274 static void _e_border_client_move_resize_send(E_Border *bd);
276 static void _e_border_frame_replace(E_Border *bd,
279 static void _e_border_shape_input_rectangle_set(E_Border* bd);
280 static void _e_border_show(E_Border *bd);
281 static void _e_border_hide(E_Border *bd);
284 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
285 static void _e_border_latest_stacked_focus (E_Border* bd);
286 static void _e_border_check_stack (E_Border *bd);
287 static void _e_border_focus_top_stack_set (E_Border* bd);
289 #if _F_BORDER_CLIP_TO_ZONE_
290 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
291 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
292 /* local subsystem globals */
293 static Eina_List *handlers = NULL;
294 static Eina_List *borders = NULL;
295 static Eina_Hash *borders_hash = NULL;
296 static E_Border *focused = NULL;
297 static E_Border *focusing = NULL;
298 static Eina_List *focus_next = NULL;
299 static Ecore_X_Time focus_time = 0;
301 static E_Border *bdresize = NULL;
302 static E_Border *bdmove = NULL;
303 static E_Drag *drag_border = NULL;
305 static int grabbed = 0;
307 static Eina_List *focus_stack = NULL;
308 static Eina_List *raise_stack = NULL;
310 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
311 static int screen_size_index = -1;
313 static int focus_track_frozen = 0;
315 static int warp_to = 0;
316 static int warp_to_x = 0;
317 static int warp_to_y = 0;
318 static int warp_x = 0;
319 static int warp_y = 0;
320 static Ecore_X_Window warp_to_win;
321 static Ecore_Timer *warp_timer = NULL;
323 #ifdef _F_ZONE_WINDOW_ROTATION_
324 typedef struct _E_Border_Rotation E_Border_Rotation;
325 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
327 struct _E_Border_Rotation
330 Eina_List *async_list;
332 Eina_Bool wait_prepare_done;
333 Ecore_Timer *prepare_timer;
334 Ecore_Timer *done_timer;
336 Ecore_Job *async_job;
338 Ecore_X_Window vkbd_ctrl_win;
340 E_Border *vkbd_prediction;
342 /* vkbd show/hide preprare */
343 Eina_Bool vkbd_show_prepare_done;
344 Ecore_Timer *vkbd_show_prepare_timer;
345 Ecore_Timer *vkbd_show_timer;
347 Eina_Bool vkbd_hide_prepare_done;
348 Ecore_Timer *vkbd_hide_prepare_timer;
349 Ecore_Timer *vkbd_hide_timer;
355 struct _E_Border_Rotation_Info
360 Eina_Bool win_resize;
363 static E_Border_Rotation rot =
386 EAPI int E_EVENT_BORDER_ADD = 0;
387 EAPI int E_EVENT_BORDER_REMOVE = 0;
388 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
389 EAPI int E_EVENT_BORDER_DESK_SET = 0;
390 EAPI int E_EVENT_BORDER_RESIZE = 0;
391 EAPI int E_EVENT_BORDER_MOVE = 0;
392 EAPI int E_EVENT_BORDER_SHOW = 0;
393 EAPI int E_EVENT_BORDER_HIDE = 0;
394 EAPI int E_EVENT_BORDER_ICONIFY = 0;
395 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
396 EAPI int E_EVENT_BORDER_STICK = 0;
397 EAPI int E_EVENT_BORDER_UNSTICK = 0;
398 EAPI int E_EVENT_BORDER_STACK = 0;
399 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
400 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
401 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
402 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
403 EAPI int E_EVENT_BORDER_PROPERTY = 0;
404 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
405 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
406 #ifdef _F_ZONE_WINDOW_ROTATION_
407 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
408 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
409 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
410 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
413 #define GRAV_SET(bd, grav) \
414 ecore_x_window_gravity_set(bd->bg_win, grav); \
415 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
416 ecore_x_window_gravity_set(bd->client.win, grav);
419 _e_border_sub_borders_new(E_Border *bd)
421 Eina_List *list = NULL, *l;
425 EINA_LIST_FOREACH(bd->transients, l, child)
427 if (!eina_list_data_find(list, child))
428 list = eina_list_append(list, child);
430 bl = e_container_border_list_first(bd->zone->container);
431 while ((child = e_container_border_list_next(bl)))
433 if (e_object_is_del(E_OBJECT(child))) continue;
434 if (child == bd) continue;
436 if ((bd->client.icccm.client_leader) &&
437 (child->client.icccm.client_leader ==
438 bd->client.icccm.client_leader))
440 printf("bd %s in group with %s\n",
441 e_border_name_get(child),
442 e_border_name_get(bd));
443 if (!eina_list_data_find(list, child))
444 list = eina_list_append(list, child);
448 e_container_border_list_free(bl);
452 /* externally accessible functions */
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
461 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
468 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
469 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
470 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
471 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
472 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
473 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
474 #ifdef _F_ZONE_WINDOW_ROTATION_
475 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
478 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
480 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
481 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
482 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
483 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
484 #ifdef _F_USE_DESK_WINDOW_PROFILE_
485 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
487 #ifdef _F_ZONE_WINDOW_ROTATION_
488 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
491 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
493 E_EVENT_BORDER_ADD = ecore_event_type_new();
494 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
495 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
496 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
497 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
498 E_EVENT_BORDER_MOVE = ecore_event_type_new();
499 E_EVENT_BORDER_SHOW = ecore_event_type_new();
500 E_EVENT_BORDER_HIDE = ecore_event_type_new();
501 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
502 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
503 E_EVENT_BORDER_STICK = ecore_event_type_new();
504 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
505 E_EVENT_BORDER_STACK = ecore_event_type_new();
506 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
507 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
508 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
509 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
510 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
511 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
512 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
513 #ifdef _F_ZONE_WINDOW_ROTATION_
514 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
515 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
516 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
517 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
526 e_border_shutdown(void)
528 E_FREE_LIST(handlers, ecore_event_handler_del);
530 if (borders_hash) eina_hash_free(borders_hash);
532 e_int_border_menu_hooks_clear();
538 e_border_new(E_Container *con,
544 Ecore_X_Window_Attributes *att;
545 unsigned int managed, desk[2];
548 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
549 if (!bd) return NULL;
550 ecore_x_window_shadow_tree_flush();
551 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
555 /* FIXME: ewww - round trip */
556 bd->client.argb = ecore_x_window_argb_get(win);
558 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
561 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
562 ecore_x_window_shape_events_select(bd->win, 1);
564 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
565 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
567 bd->bg_ecore_evas = e_canvas_new(bd->win,
568 0, 0, bd->w, bd->h, 1, 0,
570 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
571 e_canvas_add(bd->bg_ecore_evas);
572 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
573 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
574 ecore_x_window_shape_events_select(bd->bg_win, 1);
575 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
576 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
578 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
580 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
581 ecore_x_window_container_manage(bd->client.shell_win);
582 if (!internal) ecore_x_window_client_manage(win);
583 /* FIXME: Round trip. XCB */
584 /* fetch needed to avoid grabbing the server as window may vanish */
585 att = &bd->client.initial_attributes;
586 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
588 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
589 e_canvas_del(bd->bg_ecore_evas);
590 ecore_evas_free(bd->bg_ecore_evas);
591 ecore_x_window_free(bd->client.shell_win);
592 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
593 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
594 ecore_x_window_free(bd->win);
599 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
600 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
602 /* FIXME: if first_map is 1 then we should ignore the first hide event
603 * or ensure the window is already hidden and events flushed before we
604 * create a border for it */
607 // printf("##- FIRST MAP\n");
612 // needed to be 1 for internal windw and on restart.
613 // bd->ignore_first_unmap = 2;
616 bd->client.win = win;
617 bd->zone = e_zone_current_get(con);
619 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
621 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
622 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
623 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
624 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
625 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
626 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
628 bd->client.icccm.title = NULL;
629 bd->client.icccm.name = NULL;
630 bd->client.icccm.class = NULL;
631 bd->client.icccm.icon_name = NULL;
632 bd->client.icccm.machine = NULL;
633 bd->client.icccm.min_w = 1;
634 bd->client.icccm.min_h = 1;
635 bd->client.icccm.max_w = 32767;
636 bd->client.icccm.max_h = 32767;
637 bd->client.icccm.base_w = 0;
638 bd->client.icccm.base_h = 0;
639 bd->client.icccm.step_w = -1;
640 bd->client.icccm.step_h = -1;
641 bd->client.icccm.min_aspect = 0.0;
642 bd->client.icccm.max_aspect = 0.0;
643 bd->client.icccm.accepts_focus = 1;
645 bd->client.netwm.pid = 0;
646 bd->client.netwm.name = NULL;
647 bd->client.netwm.icon_name = NULL;
648 bd->client.netwm.desktop = 0;
649 bd->client.netwm.state.modal = 0;
650 bd->client.netwm.state.sticky = 0;
651 bd->client.netwm.state.shaded = 0;
652 bd->client.netwm.state.hidden = 0;
653 bd->client.netwm.state.maximized_v = 0;
654 bd->client.netwm.state.maximized_h = 0;
655 bd->client.netwm.state.skip_taskbar = 0;
656 bd->client.netwm.state.skip_pager = 0;
657 bd->client.netwm.state.fullscreen = 0;
658 bd->client.netwm.state.stacking = E_STACKING_NONE;
659 bd->client.netwm.action.move = 0;
660 bd->client.netwm.action.resize = 0;
661 bd->client.netwm.action.minimize = 0;
662 bd->client.netwm.action.shade = 0;
663 bd->client.netwm.action.stick = 0;
664 bd->client.netwm.action.maximized_h = 0;
665 bd->client.netwm.action.maximized_v = 0;
666 bd->client.netwm.action.fullscreen = 0;
667 bd->client.netwm.action.change_desktop = 0;
668 bd->client.netwm.action.close = 0;
669 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
675 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
676 bd->client.icccm.fetch.command = 1;
679 Eina_Bool video_parent = EINA_FALSE;
680 Eina_Bool video_position = EINA_FALSE;
683 for (i = 0; i < at_num; i++)
685 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
686 bd->client.icccm.fetch.title = 1;
687 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
688 bd->client.icccm.fetch.name_class = 1;
689 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
690 bd->client.icccm.fetch.icon_name = 1;
691 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
692 bd->client.icccm.fetch.machine = 1;
693 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
694 bd->client.icccm.fetch.hints = 1;
695 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
696 bd->client.icccm.fetch.size_pos_hints = 1;
697 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
698 bd->client.icccm.fetch.protocol = 1;
699 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
700 bd->client.mwm.fetch.hints = 1;
701 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
703 bd->client.icccm.fetch.transient_for = 1;
704 bd->client.netwm.fetch.type = 1;
706 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
707 bd->client.icccm.fetch.client_leader = 1;
708 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
709 bd->client.icccm.fetch.window_role = 1;
710 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
711 bd->client.icccm.fetch.state = 1;
713 /* netwm, loop again, netwm will ignore some icccm, so we
714 * have to be sure that netwm is checked after */
715 for (i = 0; i < at_num; i++)
717 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
720 bd->client.icccm.fetch.title = 0;
721 bd->client.netwm.fetch.name = 1;
723 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
726 bd->client.icccm.fetch.icon_name = 0;
727 bd->client.netwm.fetch.icon_name = 1;
729 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
731 bd->client.netwm.fetch.icon = 1;
733 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
735 bd->client.netwm.fetch.user_time = 1;
737 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
739 DBG("ECORE_X_ATOM_NET_WM_STRUT");
740 bd->client.netwm.fetch.strut = 1;
742 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
744 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
745 bd->client.netwm.fetch.strut = 1;
747 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
750 bd->client.mwm.fetch.hints = 0;
752 bd->client.netwm.fetch.type = 1;
754 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
756 bd->client.netwm.fetch.state = 1;
759 /* other misc atoms */
760 for (i = 0; i < at_num; i++)
762 /* loop to check for own atoms */
763 if (atoms[i] == E_ATOM_WINDOW_STATE)
765 bd->client.e.fetch.state = 1;
767 /* loop to check for qtopia atoms */
768 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
769 bd->client.qtopia.fetch.soft_menu = 1;
770 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
771 bd->client.qtopia.fetch.soft_menus = 1;
772 /* loop to check for vkbd atoms */
773 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
774 bd->client.vkbd.fetch.state = 1;
775 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
776 bd->client.vkbd.fetch.vkbd = 1;
777 /* loop to check for illume atoms */
778 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
779 bd->client.illume.conformant.fetch.conformant = 1;
780 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
781 bd->client.illume.quickpanel.fetch.state = 1;
782 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
783 bd->client.illume.quickpanel.fetch.quickpanel = 1;
784 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
785 bd->client.illume.quickpanel.fetch.priority.major = 1;
786 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
787 bd->client.illume.quickpanel.fetch.priority.minor = 1;
788 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
789 bd->client.illume.quickpanel.fetch.zone = 1;
790 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
791 bd->client.illume.drag.fetch.locked = 1;
792 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
793 bd->client.illume.drag.fetch.drag = 1;
794 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
795 bd->client.illume.win_state.fetch.state = 1;
796 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
797 video_parent = EINA_TRUE;
798 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
799 video_position = EINA_TRUE;
800 #ifdef _F_USE_DESK_WINDOW_PROFILE_
801 /* loop to check for window profile list atom */
802 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
803 bd->client.e.fetch.profile_list = 1;
805 #ifdef _F_ZONE_WINDOW_ROTATION_
806 /* loop to check for wm rotation */
807 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
809 if (e_config->wm_win_rotation)
810 bd->client.e.fetch.rot.support = 1;
812 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
813 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
814 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
815 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
817 if (e_config->wm_win_rotation)
818 bd->client.e.fetch.rot.geom_hint = 1;
820 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
822 if (e_config->wm_win_rotation)
823 bd->client.e.fetch.rot.app_set = 1;
825 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
827 if (e_config->wm_win_rotation)
828 bd->client.e.fetch.rot.preferred_rot = 1;
830 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
832 if (e_config->wm_win_rotation)
833 bd->client.e.fetch.rot.available_rots = 1;
836 #ifdef _F_DEICONIFY_APPROVE_
837 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
839 bd->client.e.state.deiconify_approve.support = 1;
843 if (video_position && video_parent)
845 bd->client.e.state.video = 1;
846 bd->client.e.fetch.video_parent = 1;
847 bd->client.e.fetch.video_position = 1;
848 ecore_x_window_lower(bd->win);
849 ecore_x_composite_window_events_disable(bd->win);
850 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
851 fprintf(stderr, "We found a video window \\o/ %x\n", win);
856 bd->client.border.changed = 1;
858 bd->client.w = att->w;
859 bd->client.h = att->h;
861 bd->w = bd->client.w;
862 bd->h = bd->client.h;
864 bd->resize_mode = RESIZE_NONE;
866 bd->saved.layer = bd->layer;
867 bd->changes.icon = 1;
868 bd->changes.size = 1;
869 bd->changes.shape = 1;
870 bd->changes.shape_input = 1;
872 bd->offer_resistance = 1;
874 /* just to friggin make java happy - we're DELAYING the reparent until
877 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
878 bd->need_reparent = 1;
880 ecore_x_window_border_width_set(win, 0);
881 ecore_x_window_show(bd->event_win);
882 ecore_x_window_show(bd->client.shell_win);
883 bd->shape = e_container_shape_add(con);
888 #ifdef _F_ZONE_WINDOW_ROTATION_
889 bd->client.e.state.rot.preferred_rot = -1;
890 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
891 bd->client.e.state.rot.changes = -1;
892 bd->client.e.state.rot.pending_show = 0;
893 bd->client.e.state.rot.curr = 0;
894 bd->client.e.state.rot.prev = 0;
897 // bd->zone = e_zone_current_get(con);
898 bd->desk = e_desk_current_get(bd->zone);
899 e_container_border_add(bd);
900 borders = eina_list_append(borders, bd);
901 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
905 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
906 "optimisations failing due to bizarre client behavior. will\n"
908 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
909 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
912 ELBF(ELBT_BD, 0, bd->client.win,
913 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
914 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
916 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
917 printf("optimisations failing due to bizarre client behavior. will\n");
918 printf("work around.\n");
919 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
920 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
923 ELBF(ELBT_BD, 0, bd->client.win,
924 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
925 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
928 #ifdef _F_ZONE_WINDOW_ROTATION_
929 if ((rot.vkbd) && (rot.vkbd == bd2))
931 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
932 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
933 rot.vkbd_hide_prepare_done);
935 if (rot.vkbd_hide_prepare_timer)
937 ecore_timer_del(rot.vkbd_hide_prepare_timer);
938 rot.vkbd_hide_prepare_timer = NULL;
940 e_object_unref(E_OBJECT(bd2));
943 _e_border_vkbd_hide(rot.vkbd);
945 if (rot.vkbd_ctrl_win)
947 ELB(ELBT_BD, "SET KBD_OFF", 0);
948 ecore_x_e_virtual_keyboard_state_set
949 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
951 rot.vkbd_hide_prepare_done = EINA_FALSE;
953 if (rot.vkbd_hide_timer)
954 ecore_timer_del(rot.vkbd_hide_timer);
955 rot.vkbd_hide_timer = NULL;
957 rot.vkbd_show_prepare_done = EINA_FALSE;
958 if (rot.vkbd_show_prepare_timer)
959 ecore_timer_del(rot.vkbd_show_prepare_timer);
960 rot.vkbd_show_prepare_timer = NULL;
961 if (rot.vkbd_show_timer)
962 ecore_timer_del(rot.vkbd_show_timer);
963 rot.vkbd_show_timer = NULL;
968 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
969 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
970 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
972 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
973 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
974 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
976 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
977 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
978 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
980 unsigned int zgeom[4];
982 zgeom[0] = bd->zone->x;
983 zgeom[1] = bd->zone->y;
984 zgeom[2] = bd->zone->w;
985 zgeom[3] = bd->zone->h;
986 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
988 e_desk_xy_get(bd->desk, &deskx, &desky);
991 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
992 #ifdef _F_USE_DESK_WINDOW_PROFILE_
993 if (strcmp(bd->desk->window_profile,
994 e_config->desktop_default_window_profile) != 0)
996 ecore_x_e_window_profile_set(bd->client.win,
997 bd->desk->window_profile);
1001 focus_stack = eina_list_append(focus_stack, bd);
1003 bd->pointer = e_pointer_window_new(bd->win, 0);
1008 e_border_res_change_geometry_save(E_Border *bd)
1011 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1013 if (bd->pre_res_change.valid) return;
1014 bd->pre_res_change.valid = 1;
1015 bd->pre_res_change.x = bd->x;
1016 bd->pre_res_change.y = bd->y;
1017 bd->pre_res_change.w = bd->w;
1018 bd->pre_res_change.h = bd->h;
1019 bd->pre_res_change.saved.x = bd->saved.x;
1020 bd->pre_res_change.saved.y = bd->saved.y;
1021 bd->pre_res_change.saved.w = bd->saved.w;
1022 bd->pre_res_change.saved.h = bd->saved.h;
1026 e_border_res_change_geometry_restore(E_Border *bd)
1030 unsigned char valid : 1;
1039 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1040 if (!bd->pre_res_change.valid) return;
1041 if (bd->new_client) return;
1043 ecore_x_window_shadow_tree_flush();
1044 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1048 e_border_unfullscreen(bd);
1049 e_border_fullscreen(bd, e_config->fullscreen_policy);
1051 else if (bd->maximized != E_MAXIMIZE_NONE)
1055 max = bd->maximized;
1056 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1057 e_border_maximize(bd, max);
1061 int x, y, w, h, zx, zy, zw, zh;
1063 bd->saved.x = bd->pre_res_change.saved.x;
1064 bd->saved.y = bd->pre_res_change.saved.y;
1065 bd->saved.w = bd->pre_res_change.saved.w;
1066 bd->saved.h = bd->pre_res_change.saved.h;
1068 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1070 if (bd->saved.w > zw)
1072 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1073 bd->saved.x = zx + zw - bd->saved.w;
1075 if (bd->saved.h > zh)
1077 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1078 bd->saved.y = zy + zh - bd->saved.h;
1080 x = bd->pre_res_change.x;
1081 y = bd->pre_res_change.y;
1082 w = bd->pre_res_change.w;
1083 h = bd->pre_res_change.h;
1088 if ((x + w) > (zx + zw))
1090 if ((y + h) > (zy + zh))
1092 e_border_move_resize(bd, x, y, w, h);
1094 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1098 e_border_zone_set(E_Border *bd,
1101 E_Event_Border_Zone_Set *ev;
1104 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1105 E_OBJECT_CHECK(zone);
1106 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1108 if (bd->zone == zone) return;
1110 /* if the window does not lie in the new zone, move it so that it does */
1111 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1114 /* first guess -- get offset from old zone, and apply to new zone */
1115 x = zone->x + (bd->x - bd->zone->x);
1116 y = zone->y + (bd->y - bd->zone->y);
1118 /* keep window from hanging off bottom and left */
1119 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1120 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1122 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1123 if (x < zone->x) x = zone->x;
1124 if (y < zone->y) y = zone->y;
1126 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1128 /* still not in zone at all, so just move it to closest edge */
1129 if (x < zone->x) x = zone->x;
1130 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1131 if (y < zone->y) y = zone->y;
1132 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1134 e_border_move(bd, x, y);
1139 if (bd->desk->zone != bd->zone)
1140 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1142 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1144 e_object_ref(E_OBJECT(bd));
1145 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1147 e_object_ref(E_OBJECT(zone));
1149 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1151 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1152 // XXXXXXXXXXXXXXXXXXXXXXXXX
1153 // XXX ZZZZZZZZZZZZZZZZZZZzz
1154 // need to adjust this if zone pos/size changes
1156 unsigned int zgeom[4];
1158 zgeom[0] = bd->zone->x;
1159 zgeom[1] = bd->zone->y;
1160 zgeom[2] = bd->zone->w;
1161 zgeom[3] = bd->zone->h;
1162 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1164 e_remember_update(bd);
1168 e_border_desk_set(E_Border *bd,
1171 E_Event_Border_Desk_Set *ev;
1175 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1176 E_OBJECT_CHECK(desk);
1177 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1178 if (bd->desk == desk) return;
1179 ecore_x_window_shadow_tree_flush();
1182 bd->desk->fullscreen_borders--;
1183 desk->fullscreen_borders++;
1185 old_desk = bd->desk;
1187 e_border_zone_set(bd, desk->zone);
1189 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1190 e_hints_window_desktop_set(bd);
1192 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1194 e_object_ref(E_OBJECT(bd));
1195 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1196 ev->desk = old_desk;
1197 e_object_ref(E_OBJECT(old_desk));
1198 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1200 if (bd->ignore_first_unmap != 1)
1202 if ((bd->desk->visible) || (bd->sticky))
1205 e_border_hide(bd, 1);
1208 if (e_config->transient.desktop)
1212 Eina_List *list = _e_border_sub_borders_new(bd);
1214 EINA_LIST_FOREACH(list, l, child)
1216 e_border_desk_set(child, bd->desk);
1218 eina_list_free(list);
1220 e_remember_update(bd);
1223 #ifdef _F_ZONE_WINDOW_ROTATION_
1225 _e_border_vkbd_state_check(E_Border *bd,
1228 Eina_Bool res = EINA_TRUE;
1229 if (!e_config->wm_win_rotation) return EINA_FALSE;
1230 if ((rot.vkbd) && (rot.vkbd == bd))
1234 if ((rot.vkbd_hide_prepare_done) ||
1235 (rot.vkbd_hide_prepare_timer))
1240 if ((rot.vkbd_show_prepare_done) ||
1241 (rot.vkbd_show_prepare_timer))
1249 _e_border_vkbd_show_timeout(void *data)
1251 E_Border *bd = data;
1252 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1253 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1255 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1257 if (rot.vkbd_ctrl_win)
1259 ELB(ELBT_BD, "SET KBD_ON", 0);
1260 ecore_x_e_virtual_keyboard_state_set
1261 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1266 rot.vkbd_show_prepare_done = EINA_FALSE;
1268 if (rot.vkbd_show_prepare_timer)
1269 ecore_timer_del(rot.vkbd_show_prepare_timer);
1270 rot.vkbd_show_prepare_timer = NULL;
1272 if (rot.vkbd_show_timer)
1273 ecore_timer_del(rot.vkbd_show_timer);
1274 rot.vkbd_show_timer = NULL;
1276 return ECORE_CALLBACK_CANCEL;
1280 _e_border_vkbd_hide_timeout(void *data)
1282 E_Border *bd = data;
1283 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1284 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1286 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1288 if (rot.vkbd_ctrl_win)
1290 ELB(ELBT_BD, "SET KBD_OFF", 0);
1291 ecore_x_e_virtual_keyboard_state_set
1292 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1295 e_object_unref(E_OBJECT(bd));
1298 rot.vkbd_hide_prepare_done = EINA_FALSE;
1300 if (rot.vkbd_hide_prepare_timer)
1301 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1302 rot.vkbd_hide_prepare_timer = NULL;
1304 if (rot.vkbd_hide_timer)
1305 ecore_timer_del(rot.vkbd_hide_timer);
1306 rot.vkbd_hide_timer = NULL;
1308 return ECORE_CALLBACK_CANCEL;
1312 _e_border_vkbd_show(E_Border *bd)
1314 if (!e_config->wm_win_rotation) return;
1315 rot.vkbd_show_prepare_done = EINA_TRUE;
1316 if (rot.vkbd_show_prepare_timer)
1317 ecore_timer_del(rot.vkbd_show_prepare_timer);
1318 rot.vkbd_show_prepare_timer = NULL;
1319 if (rot.vkbd_show_timer)
1320 ecore_timer_del(rot.vkbd_show_timer);
1321 rot.vkbd_show_timer = NULL;
1322 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1325 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1330 _e_border_vkbd_hide(E_Border *bd)
1332 if (!e_config->wm_win_rotation) return;
1333 rot.vkbd_hide_prepare_done = EINA_TRUE;
1334 if (rot.vkbd_hide_prepare_timer)
1335 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1336 rot.vkbd_hide_prepare_timer = NULL;
1337 if (rot.vkbd_hide_timer)
1338 ecore_timer_del(rot.vkbd_hide_timer);
1339 rot.vkbd_hide_timer = NULL;
1340 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1342 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1343 e_border_hide(bd, 0);
1344 if (!e_object_is_del(E_OBJECT(bd)))
1346 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1347 e_object_del(E_OBJECT(bd));
1349 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1354 _e_border_vkbd_show_prepare_timeout(void *data)
1356 E_Border *bd = data;
1357 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1358 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1360 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1361 _e_border_vkbd_show(bd);
1363 return ECORE_CALLBACK_CANCEL;
1367 _e_border_vkbd_hide_prepare_timeout(void *data)
1369 E_Border *bd = data;
1370 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1371 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1373 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1374 _e_border_vkbd_hide(bd);
1376 return ECORE_CALLBACK_CANCEL;
1381 e_border_show(E_Border *bd)
1383 E_Event_Border_Show *ev;
1384 unsigned int visible;
1387 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1388 if (bd->visible) return;
1389 #ifdef _F_ZONE_WINDOW_ROTATION_
1390 // newly created window that has to be rotated will be show after rotation done.
1391 // so, skip at this time. it will be called again after GETTING ROT_DONE.
1393 if ((bd->new_client) &&
1394 (bd->client.e.state.rot.changes != -1))
1396 // if this window is in withdrawn state, show this window right now.
1397 // that's because the window in withdrawn state can't render its canvas.
1398 // eventually, this window will not send the message of rotation done,
1399 // even if e17 request to rotation this window.
1400 if (bd->client.icccm.state != ECORE_X_WINDOW_STATE_HINT_NORMAL)
1401 e_hints_window_visible_set(bd);
1403 bd->client.e.state.rot.pending_show = 1;
1407 if ((e_config->wm_win_rotation) &&
1408 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1410 (!rot.vkbd_show_prepare_done))
1412 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1413 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1414 if (rot.vkbd_show_prepare_timer)
1415 ecore_timer_del(rot.vkbd_show_prepare_timer);
1416 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1417 _e_border_vkbd_show_prepare_timeout,
1421 ELB(ELBT_BD, "SHOW", bd->client.win);
1423 ecore_x_window_shadow_tree_flush();
1424 e_container_shape_show(bd->shape);
1425 if (!bd->need_reparent)
1426 ecore_x_window_show(bd->client.win);
1427 e_hints_window_visible_set(bd);
1430 bd->changes.visible = 1;
1433 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1434 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1436 ev = E_NEW(E_Event_Border_Show, 1);
1438 e_object_ref(E_OBJECT(bd));
1439 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1440 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1442 #ifdef _F_ZONE_WINDOW_ROTATION_
1443 if ((e_config->wm_win_rotation) &&
1444 ((bd->client.e.state.rot.support) ||
1445 (bd->client.e.state.rot.app_set)))
1447 ELB(ELBT_ROT, "CHECK", bd->client.win);
1448 int rotation = _e_border_rotation_angle_get(bd);
1449 if (rotation != -1) e_border_rotation_set(bd, rotation);
1455 e_border_hide(E_Border *bd,
1458 unsigned int visible;
1461 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1463 #ifdef _F_ZONE_WINDOW_ROTATION_
1464 if ((e_config->wm_win_rotation) &&
1465 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1467 (!rot.vkbd_hide_prepare_done) &&
1470 Eina_Bool need_prepare = EINA_TRUE;
1471 E_Border *child = NULL;
1474 if (e_object_is_del(E_OBJECT(bd->parent)))
1475 need_prepare = EINA_FALSE;
1478 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1479 if (bd->parent->modal == bd)
1481 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1482 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1483 bd->parent->lock_close = 0;
1484 bd->parent->saved.event_mask = 0;
1485 bd->parent->modal = NULL;
1491 need_prepare = EINA_FALSE;
1493 EINA_LIST_FREE(bd->transients, child)
1495 child->parent = NULL;
1498 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1502 e_object_ref(E_OBJECT(bd));
1503 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1504 if (rot.vkbd_hide_prepare_timer)
1505 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1506 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1507 _e_border_vkbd_hide_prepare_timeout,
1513 e_object_ref(E_OBJECT(bd));
1515 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1516 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1518 /* cleanup code from _e_border_vkbd_hide() */
1519 rot.vkbd_hide_prepare_done = EINA_TRUE;
1520 if (rot.vkbd_hide_prepare_timer)
1521 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1522 rot.vkbd_hide_prepare_timer = NULL;
1523 if (rot.vkbd_hide_timer)
1524 ecore_timer_del(rot.vkbd_hide_timer);
1525 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1528 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1530 if (!bd->visible) goto send_event;
1531 ecore_x_window_shadow_tree_flush();
1533 _e_border_move_end(bd);
1534 if (bd->resize_mode != RESIZE_NONE)
1536 _e_border_pointer_resize_end(bd);
1537 bd->resize_mode = RESIZE_NONE;
1538 _e_border_resize_end(bd);
1541 e_container_shape_hide(bd->shape);
1542 if (!bd->iconic) e_hints_window_hidden_set(bd);
1545 bd->changes.visible = 1;
1547 if (!bd->need_reparent)
1549 if ((bd->focused) ||
1550 (e_grabinput_last_focus_win_get() == bd->client.win))
1552 e_border_focus_set(bd, 0, 1);
1560 con = e_container_current_get(e_manager_current_get());
1561 zone = e_zone_current_get(con);
1562 desk = e_desk_current_get(zone);
1565 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1566 e_border_focus_set(bd->parent, 1, 1);
1567 else if (e_config->focus_revert_on_hide_or_close)
1569 /* When using pointer focus, the border under the
1570 * pointer (if any) gets focused, in sloppy/click
1571 * focus the last focused window on the current
1572 * desk gets focus */
1573 if (e_config->focus_policy == E_FOCUS_MOUSE)
1575 pbd = e_border_under_pointer_get(desk, bd);
1577 e_border_focus_set(pbd, 1, 1);
1579 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1580 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1581 (e_config->focus_policy == E_FOCUS_CLICK))
1582 _e_border_latest_stacked_focus(bd);
1586 e_desk_last_focused_focus(desk);
1596 /* Make sure that this border isn't deleted */
1597 bd->await_hide_event++;
1599 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1600 ecore_x_window_hide(bd->client.win);
1605 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1607 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1614 #ifdef _F_ZONE_WINDOW_ROTATION_
1615 _e_border_rotation_list_remove(bd);
1618 E_Event_Border_Hide *ev;
1620 ev = E_NEW(E_Event_Border_Hide, 1);
1622 e_object_ref(E_OBJECT(bd));
1623 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1624 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1629 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1633 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1634 setpriority(PRIO_PROCESS, pid, newpri);
1635 // shouldnt need to do this as default ionice class is "none" (0), and
1636 // this inherits io priority FROM nice level
1637 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1638 // IOPRIO_PRIO_VALUE(2, 5));
1642 char *file, buf[PATH_MAX];
1646 // yes - this is /proc specific... so this may not work on some
1647 // os's - works on linux. too bad for others.
1648 files = ecore_file_ls("/proc");
1649 EINA_LIST_FREE(files, file)
1651 if (isdigit(file[0]))
1653 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1654 f = fopen(buf, "r");
1659 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1665 _pri_adj(pid2, set, adj, EINA_TRUE,
1666 adj_children, do_children);
1668 _pri_adj(pid2, set, adj, use_adj,
1669 adj_children, do_children);
1681 _e_border_pri_raise(E_Border *bd)
1683 if (bd->client.netwm.pid <= 0) return;
1684 if (bd->client.netwm.pid == getpid()) return;
1685 _pri_adj(bd->client.netwm.pid,
1686 e_config->priority - 1, -1, EINA_FALSE,
1687 // EINA_TRUE, EINA_TRUE);
1688 EINA_TRUE, EINA_FALSE);
1689 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1690 // bd->client.netwm.pid, e_border_name_get(bd));
1694 _e_border_pri_norm(E_Border *bd)
1696 if (bd->client.netwm.pid <= 0) return;
1697 if (bd->client.netwm.pid == getpid()) return;
1698 _pri_adj(bd->client.netwm.pid,
1699 e_config->priority, 1, EINA_FALSE,
1700 // EINA_TRUE, EINA_TRUE);
1701 EINA_TRUE, EINA_FALSE);
1702 // printf("WIN: pid %i, title %s (NORMAL)\n",
1703 // bd->client.netwm.pid, e_border_name_get(bd));
1707 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1710 Ecore_Evas *bg_ecore_evas;
1716 bg_ecore_evas = bd->bg_ecore_evas;
1718 /* unregister old frame window */
1719 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1720 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1722 e_focus_setdown(bd);
1723 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1724 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1726 if (bd->icon_object)
1727 evas_object_del(bd->icon_object);
1729 evas_object_del(bd->bg_object);
1730 e_canvas_del(bg_ecore_evas);
1731 ecore_evas_free(bg_ecore_evas);
1734 e_object_del(E_OBJECT(bd->pointer));
1736 /* create new frame */
1738 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1739 bd->x, bd->y, bd->w, bd->h);
1742 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1743 bd->x, bd->y, bd->w, bd->h);
1744 ecore_x_window_shape_events_select(bd->win, 1);
1747 ecore_x_window_configure(bd->win,
1748 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1749 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1751 win, ECORE_X_WINDOW_STACK_BELOW);
1753 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1754 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1757 bd->bg_ecore_evas = e_canvas_new(bd->win,
1758 0, 0, bd->w, bd->h, 1, 0,
1761 e_canvas_add(bd->bg_ecore_evas);
1762 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1764 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1765 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1766 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1768 ecore_x_window_shape_events_select(bd->bg_win, 1);
1770 /* move client with shell win over to new frame */
1771 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1772 bd->client_inset.l, bd->client_inset.t);
1774 bd->pointer = e_pointer_window_new(bd->win, 0);
1776 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1777 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1784 ecore_evas_show(bd->bg_ecore_evas);
1785 ecore_x_window_show(bd->win);
1787 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1788 ecore_x_window_show(tmp->win);
1791 bd->bg_object = edje_object_add(bd->bg_evas);
1792 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1793 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1795 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1797 /* cleanup old frame */
1798 ecore_x_window_free(win);
1802 _e_border_client_move_resize_send(E_Border *bd)
1804 if (bd->internal_ecore_evas)
1805 ecore_evas_managed_move(bd->internal_ecore_evas,
1806 bd->x + bd->fx.x + bd->client_inset.l,
1807 bd->y + bd->fx.y + bd->client_inset.t);
1809 ecore_x_icccm_move_resize_send(bd->client.win,
1810 bd->x + bd->fx.x + bd->client_inset.l,
1811 bd->y + bd->fx.y + bd->client_inset.t,
1817 _e_border_pending_move_resize_add(E_Border *bd,
1824 Eina_Bool without_border,
1825 unsigned int serial)
1827 E_Border_Pending_Move_Resize *pnd;
1829 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1831 pnd->resize = resize;
1833 pnd->without_border = without_border;
1838 pnd->serial = serial;
1839 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1843 _e_border_move_internal(E_Border *bd,
1846 Eina_Bool without_border)
1848 E_Event_Border_Move *ev;
1851 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1853 ecore_x_window_shadow_tree_flush();
1856 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1862 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1864 if (e_config->allow_manip)
1867 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1872 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1877 else if (e_config->allow_manip)
1885 x -= bd->client_inset.l;
1886 y -= bd->client_inset.t;
1888 if (bd->move_intercept_cb)
1891 px = bd->x, py = bd->y;
1892 bd->move_intercept_cb(bd, x, y);
1893 if ((bd->x == px) && (bd->y == py)) return;
1895 else if ((x == bd->x) && (y == bd->y)) return;
1896 bd->pre_res_change.valid = 0;
1900 bd->changes.pos = 1;
1902 if (bd->client.netwm.sync.request)
1904 bd->client.netwm.sync.wait++;
1905 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1908 _e_border_client_move_resize_send(bd);
1909 _e_border_move_update(bd);
1910 ev = E_NEW(E_Event_Border_Move, 1);
1912 e_object_ref(E_OBJECT(bd));
1913 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1914 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1915 _e_border_zone_update(bd);
1919 * Move window to coordinates that already account border decorations.
1921 * This call will consider given position already accounts border
1922 * decorations, so it will not be considered later. This will just
1923 * work properly with borders that have being evaluated and border
1924 * decorations are known (border->client_inset).
1926 * @parm x horizontal position to place window.
1927 * @parm y vertical position to place window.
1929 * @see e_border_move_without_border()
1932 e_border_move(E_Border *bd,
1939 _e_border_move_internal(bd, x, y, 0);
1944 * Set a callback which will be called just prior to updating the
1945 * move coordinates for a border
1948 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1950 bd->move_intercept_cb = cb;
1954 * Move window to coordinates that do not account border decorations yet.
1956 * This call will consider given position does not account border
1957 * decoration, so these values (border->client_inset) will be
1958 * accounted automatically. This is specially useful when it is a new
1959 * client and has not be evaluated yet, in this case
1960 * border->client_inset will be zeroed and no information is known. It
1961 * will mark pending requests so border will be accounted on
1962 * evalutation phase.
1964 * @parm x horizontal position to place window.
1965 * @parm y vertical position to place window.
1967 * @see e_border_move()
1970 e_border_move_without_border(E_Border *bd,
1977 _e_border_move_internal(bd, x, y, 1);
1981 e_border_center(E_Border *bd)
1985 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1987 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1988 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1992 e_border_center_pos_get(E_Border *bd,
1998 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2000 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
2001 if (x) *x = zx + (zw - bd->w) / 2;
2002 if (y) *y = zy + (zh - bd->h) / 2;
2006 e_border_fx_offset(E_Border *bd,
2011 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2013 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2017 bd->changes.pos = 1;
2020 if (bd->moving) _e_border_move_update(bd);
2024 _e_border_move_resize_internal(E_Border *bd,
2029 Eina_Bool without_border,
2032 E_Event_Border_Move *mev;
2033 E_Event_Border_Resize *rev;
2036 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2038 ecore_x_window_shadow_tree_flush();
2042 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2048 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2050 if (e_config->allow_manip)
2053 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2059 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2066 if (e_config->allow_manip)
2074 x -= bd->client_inset.l;
2075 y -= bd->client_inset.t;
2076 w += (bd->client_inset.l + bd->client_inset.r);
2077 h += (bd->client_inset.t + bd->client_inset.b);
2080 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2081 (w == bd->w) && (h == bd->h))
2084 bd->pre_res_change.valid = 0;
2087 bd->changes.pos = 1;
2093 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2094 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2096 if ((bd->shaped) || (bd->client.shaped))
2098 bd->need_shape_merge = 1;
2099 bd->need_shape_export = 1;
2101 if (bd->shaped_input)
2103 bd->need_shape_merge = 1;
2106 if (bd->internal_ecore_evas)
2109 bd->changes.size = 1;
2113 if (bdresize && bd->client.netwm.sync.request)
2115 bd->client.netwm.sync.wait++;
2116 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2117 * when no move is intended. The border geometry is set above anyways.
2119 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2120 bd->client.netwm.sync.serial);
2121 ecore_x_netwm_sync_request_send(bd->client.win,
2122 bd->client.netwm.sync.serial++);
2127 bd->changes.size = 1;
2131 _e_border_client_move_resize_send(bd);
2133 _e_border_resize_update(bd);
2136 mev = E_NEW(E_Event_Border_Move, 1);
2138 e_object_ref(E_OBJECT(bd));
2139 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2140 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2143 rev = E_NEW(E_Event_Border_Resize, 1);
2145 e_object_ref(E_OBJECT(bd));
2146 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2147 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2148 _e_border_zone_update(bd);
2152 * Move and resize window to values that already account border decorations.
2154 * This call will consider given values already accounts border
2155 * decorations, so it will not be considered later. This will just
2156 * work properly with borders that have being evaluated and border
2157 * decorations are known (border->client_inset).
2159 * @parm x horizontal position to place window.
2160 * @parm y vertical position to place window.
2161 * @parm w horizontal window size.
2162 * @parm h vertical window size.
2164 * @see e_border_move_resize_without_border()
2167 e_border_move_resize(E_Border *bd,
2176 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2180 * Move and resize window to values that do not account border decorations yet.
2182 * This call will consider given values already accounts border
2183 * decorations, so it will not be considered later. This will just
2184 * work properly with borders that have being evaluated and border
2185 * decorations are known (border->client_inset).
2187 * @parm x horizontal position to place window.
2188 * @parm y vertical position to place window.
2189 * @parm w horizontal window size.
2190 * @parm h vertical window size.
2192 * @see e_border_move_resize()
2195 e_border_move_resize_without_border(E_Border *bd,
2204 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2208 * Resize window to values that already account border decorations.
2210 * This call will consider given size already accounts border
2211 * decorations, so it will not be considered later. This will just
2212 * work properly with borders that have being evaluated and border
2213 * decorations are known (border->client_inset).
2215 * @parm w horizontal window size.
2216 * @parm h vertical window size.
2218 * @see e_border_resize_without_border()
2221 e_border_resize(E_Border *bd,
2228 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2231 #ifdef _F_ZONE_WINDOW_ROTATION_
2233 e_border_rotation_set(E_Border *bd, int rotation)
2235 return _e_border_rotation_set_internal(bd, rotation, NULL);
2240 * Resize window to values that do not account border decorations yet.
2242 * This call will consider given size does not account border
2243 * decoration, so these values (border->client_inset) will be
2244 * accounted automatically. This is specially useful when it is a new
2245 * client and has not be evaluated yet, in this case
2246 * border->client_inset will be zeroed and no information is known. It
2247 * will mark pending requests so border will be accounted on
2248 * evalutation phase.
2250 * @parm w horizontal window size.
2251 * @parm h vertical window size.
2253 * @see e_border_resize()
2256 e_border_resize_without_border(E_Border *bd,
2263 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2267 e_border_layer_set(E_Border *bd,
2273 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2275 ecore_x_window_shadow_tree_flush();
2277 oldraise = e_config->transient.raise;
2281 bd->saved.layer = layer;
2285 if (e_config->transient.layer)
2289 Eina_List *list = _e_border_sub_borders_new(bd);
2291 /* We need to set raise to one, else the child wont
2292 * follow to the new layer. It should be like this,
2293 * even if the user usually doesn't want to raise
2296 e_config->transient.raise = 1;
2297 EINA_LIST_FOREACH(list, l, child)
2299 e_border_layer_set(child, layer);
2303 e_config->transient.raise = oldraise;
2307 e_border_raise(E_Border *bd)
2309 E_Event_Border_Stack *ev;
2310 E_Border *last = NULL, *child;
2314 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2316 ecore_x_window_shadow_tree_flush();
2318 if (e_config->transient.raise)
2320 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2321 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2324 Eina_List *list = _e_border_sub_borders_new(bd);
2326 EINA_LIST_REVERSE_FOREACH(list, l, child)
2328 /* Don't stack iconic transients. If the user wants these shown,
2329 * thats another option.
2334 e_border_stack_below(child, last);
2339 /* First raise the border to find out which border we will end up above */
2340 above = e_container_border_raise(child);
2344 /* We ended up above a border, now we must stack this border to
2345 * generate the stacking event, and to check if this transient
2346 * has other transients etc.
2348 e_border_stack_above(child, above);
2352 /* If we didn't end up above any border, we are on the bottom! */
2353 e_border_lower(child);
2359 eina_list_free(list);
2360 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2364 EINA_LIST_FOREACH(bd->transients, l, child)
2366 /* Don't stack iconic transients. If the user wants these shown,
2367 * thats another option.
2371 child->layer = bd->layer;
2372 if (!last) last = child;
2373 e_border_raise (child);
2380 ev = E_NEW(E_Event_Border_Stack, 1);
2382 e_object_ref(E_OBJECT(bd));
2386 e_container_border_stack_below(bd, last);
2388 e_object_ref(E_OBJECT(last));
2389 ev->type = E_STACKING_BELOW;
2395 /* If we don't have any children, raise this border */
2396 above = e_container_border_raise(bd);
2397 e_border_raise_latest_set(bd);
2400 /* We ended up above a border */
2402 e_object_ref(E_OBJECT(above));
2403 ev->type = E_STACKING_ABOVE;
2407 /* No border to raise above, same as a lower! */
2409 ev->type = E_STACKING_ABOVE;
2413 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2414 e_remember_update(bd);
2418 e_border_lower(E_Border *bd)
2420 E_Event_Border_Stack *ev;
2421 E_Border *last = NULL, *child;
2425 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2427 ecore_x_window_shadow_tree_flush();
2429 if (e_config->transient.lower)
2431 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2432 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2435 Eina_List *list = _e_border_sub_borders_new(bd);
2437 EINA_LIST_REVERSE_FOREACH(list, l, child)
2439 /* Don't stack iconic transients. If the user wants these shown,
2440 * thats another option.
2445 e_border_stack_below(child, last);
2450 /* First lower the border to find out which border we will end up below */
2451 below = e_container_border_lower(child);
2455 /* We ended up below a border, now we must stack this border to
2456 * generate the stacking event, and to check if this transient
2457 * has other transients etc.
2459 e_border_stack_below(child, below);
2463 /* If we didn't end up below any border, we are on top! */
2464 e_border_raise(child);
2470 eina_list_free(list);
2472 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2476 EINA_LIST_FOREACH(bd->transients, l, child)
2478 /* Don't stack iconic transients. If the user wants these shown,
2479 * thats another option.
2483 child->layer = bd->layer;
2484 e_border_lower (child);
2492 ev = E_NEW(E_Event_Border_Stack, 1);
2494 e_object_ref(E_OBJECT(bd));
2498 e_container_border_stack_below(bd, last);
2500 e_object_ref(E_OBJECT(last));
2501 ev->type = E_STACKING_BELOW;
2507 /* If we don't have any children, lower this border */
2508 below = e_container_border_lower(bd);
2511 /* We ended up below a border */
2513 e_object_ref(E_OBJECT(below));
2514 ev->type = E_STACKING_BELOW;
2518 /* No border to hide under, same as a raise! */
2520 ev->type = E_STACKING_BELOW;
2524 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2525 e_remember_update(bd);
2529 e_border_stack_above(E_Border *bd,
2532 /* TODO: Should stack above allow the border to change level */
2533 E_Event_Border_Stack *ev;
2534 E_Border *last = NULL, *child;
2538 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2540 ecore_x_window_shadow_tree_flush();
2542 if (e_config->transient.raise)
2544 Eina_List *list = _e_border_sub_borders_new(bd);
2546 EINA_LIST_REVERSE_FOREACH(list, l, child)
2548 /* Don't stack iconic transients. If the user wants these shown,
2549 * thats another option.
2554 e_border_stack_below(child, last);
2556 e_border_stack_above(child, above);
2560 eina_list_free(list);
2563 ev = E_NEW(E_Event_Border_Stack, 1);
2565 e_object_ref(E_OBJECT(bd));
2569 e_container_border_stack_below(bd, last);
2571 e_object_ref(E_OBJECT(last));
2572 ev->type = E_STACKING_BELOW;
2576 e_container_border_stack_above(bd, above);
2578 e_object_ref(E_OBJECT(above));
2579 ev->type = E_STACKING_ABOVE;
2582 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2583 e_remember_update(bd);
2587 e_border_stack_below(E_Border *bd,
2590 /* TODO: Should stack below allow the border to change level */
2591 E_Event_Border_Stack *ev;
2592 E_Border *last = NULL, *child;
2596 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2598 ecore_x_window_shadow_tree_flush();
2600 if (e_config->transient.lower)
2602 Eina_List *list = _e_border_sub_borders_new(bd);
2604 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2606 /* Don't stack iconic transients. If the user wants these shown,
2607 * thats another option.
2612 e_border_stack_below(child, last);
2614 e_border_stack_below(child, below);
2618 eina_list_free(list);
2621 ev = E_NEW(E_Event_Border_Stack, 1);
2623 e_object_ref(E_OBJECT(bd));
2627 e_container_border_stack_below(bd, last);
2629 e_object_ref(E_OBJECT(last));
2630 ev->type = E_STACKING_BELOW;
2634 e_container_border_stack_below(bd, below);
2636 e_object_ref(E_OBJECT(below));
2637 ev->type = E_STACKING_BELOW;
2640 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2641 e_remember_update(bd);
2645 e_border_focus_latest_set(E_Border *bd)
2647 focus_stack = eina_list_remove(focus_stack, bd);
2648 focus_stack = eina_list_prepend(focus_stack, bd);
2652 e_border_raise_latest_set(E_Border *bd)
2654 raise_stack = eina_list_remove(raise_stack, bd);
2655 raise_stack = eina_list_prepend(raise_stack, bd);
2659 * Sets the focus to the given border if necessary
2660 * There are 3 cases of different focus_policy-configurations:
2662 * - E_FOCUS_CLICK: just set the focus, the most simple one
2664 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2665 * warp the pointer to the window. If this fails (because
2666 * the pointer is already in the window), just set the focus.
2668 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2669 * last window which was focused, if the mouse is on the
2670 * desktop. So, we need to look if there is another window
2671 * under the pointer and warp to pointer to the right
2672 * one if so (also, we set the focus afterwards). In case
2673 * there is no window under pointer, the pointer is on the
2674 * desktop and so we just set the focus.
2677 * This function is to be called when setting the focus was not
2678 * explicitly triggered by the user (by moving the mouse or
2679 * clicking for example), but implicitly (by closing a window,
2680 * the last focused window should get focus).
2684 e_border_focus_set_with_pointer(E_Border *bd)
2686 #ifdef PRINT_LOTS_OF_DEBUG
2687 E_PRINT_BORDER_INFO(bd);
2689 /* note: this is here as it seems there are enough apps that do not even
2690 * expect us to emulate a look of focus but not actually set x input
2691 * focus as we do - so simply abort any focuse set on such windows */
2692 /* be strict about accepting focus hint */
2693 if ((!bd->client.icccm.accepts_focus) &&
2694 (!bd->client.icccm.take_focus)) return;
2695 if (bd->lock_focus_out) return;
2697 e_border_focus_set(bd, 1, 1);
2699 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2700 if (!bd->visible) return;
2702 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2704 if (!e_border_under_pointer_get(bd->desk, bd))
2706 e_border_pointer_warp_to_center(bd);
2711 e_border_pointer_warp_to_center(bd);
2716 e_border_focus_set(E_Border *bd,
2720 E_Border *bd_unfocus = NULL;
2721 Eina_Bool focus_changed = EINA_FALSE;
2724 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2725 /* note: this is here as it seems there are enough apps that do not even
2726 * expect us to emulate a look of focus but not actually set x input
2727 * focus as we do - so simply abort any focuse set on such windows */
2728 /* be strict about accepting focus hint */
2729 if ((!bd->client.icccm.accepts_focus) &&
2730 (!bd->client.icccm.take_focus))
2732 if ((set) && (focus) && (bd->lock_focus_out)) return;
2734 /* dont focus an iconified window. that's silly! */
2739 e_border_uniconify(bd);
2740 if (!focus_track_frozen)
2741 e_border_focus_latest_set(bd);
2744 else if (!bd->visible)
2748 /* FIXME: hack for deskflip animation:
2749 * dont update focus when sliding previous desk */
2750 else if ((!bd->sticky) &&
2751 (bd->desk != e_desk_current_get(bd->desk->zone)))
2757 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2759 e_border_focus_set(bd->modal, focus, set);
2762 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2764 e_border_focus_set(bd->leader->modal, focus, set);
2772 if (bd->visible && bd->changes.visible)
2777 else if ((!bd->focused) ||
2778 (focus_next && (bd != eina_list_data_get(focus_next))))
2782 if ((l = eina_list_data_find_list(focus_next, bd)))
2783 focus_next = eina_list_promote_list(focus_next, l);
2785 focus_next = eina_list_prepend(focus_next, bd);
2787 if ((bd->client.icccm.take_focus) &&
2788 (bd->client.icccm.accepts_focus))
2790 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2791 /* TODO what if the client didn't take focus ? */
2793 else if (!bd->client.icccm.accepts_focus)
2795 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2797 else if (!bd->client.icccm.take_focus)
2799 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2800 /* e_border_focus_set(bd, 1, 0); */
2810 if (focused) bd_unfocus = focused;
2811 if (focusing == bd) focusing = NULL;
2816 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2818 if ((bd2->fullscreen) &&
2820 (bd2->zone == bd->zone) &&
2821 ((bd2->desk == bd->desk) ||
2822 (bd2->sticky) || (bd->sticky)))
2824 Eina_Bool unfocus_is_parent = EINA_FALSE;
2825 E_Border *bd_parent;
2827 bd_parent = bd->parent;
2830 if (bd_parent == bd2)
2832 unfocus_is_parent = EINA_TRUE;
2835 bd_parent = bd->parent;
2837 if ((!unfocus_is_parent) &&
2838 (!e_config->allow_above_fullscreen))
2840 e_border_iconify(bd2);
2845 focus_changed = EINA_TRUE;
2851 focus_next = eina_list_remove(focus_next, bd);
2852 if (bd == focusing) focusing = NULL;
2854 if ((bd->focused) &&
2855 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2857 Eina_Bool wasfocused = EINA_FALSE;
2860 /* should always be the case. anyway */
2864 wasfocused = EINA_TRUE;
2867 if ((set) && (!focus_next) && (!focusing))
2869 e_grabinput_focus(bd->zone->container->bg_win,
2870 E_FOCUS_METHOD_PASSIVE);
2872 if ((bd->fullscreen) && (wasfocused))
2874 Eina_Bool have_vis_child = EINA_FALSE;
2878 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2881 (bd2->zone == bd->zone) &&
2882 ((bd2->desk == bd->desk) ||
2883 (bd2->sticky) || (bd->sticky)))
2885 if (bd2->parent == bd)
2887 have_vis_child = EINA_TRUE;
2892 if ((!have_vis_child) &&
2893 (!e_config->allow_above_fullscreen))
2894 e_border_iconify(bd);
2900 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2901 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2903 E_Event_Border_Focus_Out *ev;
2905 bd_unfocus->focused = 0;
2906 e_focus_event_focus_out(bd_unfocus);
2908 if (bd_unfocus->raise_timer)
2909 ecore_timer_del(bd_unfocus->raise_timer);
2910 bd_unfocus->raise_timer = NULL;
2912 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2913 if (bd_unfocus->icon_object)
2914 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2916 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2917 ev->border = bd_unfocus;
2918 e_object_ref(E_OBJECT(bd_unfocus));
2920 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2921 _e_border_event_border_focus_out_free, NULL);
2922 if ((bd_unfocus->fullscreen) &&
2923 (bd != bd_unfocus) &&
2924 (bd->zone == bd_unfocus->zone) &&
2925 ((bd->desk == bd_unfocus->desk) ||
2926 (bd->sticky) || (bd_unfocus->sticky)))
2928 Eina_Bool unfocus_is_parent = EINA_FALSE;
2929 E_Border *bd_parent;
2931 bd_parent = bd->parent;
2934 if (bd_parent == bd_unfocus)
2936 unfocus_is_parent = EINA_TRUE;
2939 bd_parent = bd->parent;
2941 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2943 e_border_iconify(bd_unfocus);
2950 E_Event_Border_Focus_In *ev;
2952 e_focus_event_focus_in(bd);
2954 if (!focus_track_frozen)
2955 e_border_focus_latest_set(bd);
2957 e_hints_active_window_set(bd->zone->container->manager, bd);
2959 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2960 if (bd->icon_object)
2961 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2963 ev = E_NEW(E_Event_Border_Focus_In, 1);
2965 e_object_ref(E_OBJECT(bd));
2967 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2968 _e_border_event_border_focus_in_free, NULL);
2973 e_border_shade(E_Border *bd,
2976 E_Event_Border_Resize *ev;
2981 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2982 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2983 ((bd->maximized) && (!e_config->allow_manip))) return;
2984 if ((bd->client.border.name) &&
2985 (!strcmp("borderless", bd->client.border.name))) return;
2987 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2988 ecore_x_window_hide(tmp->win);
2990 ecore_x_window_shadow_tree_flush();
2992 bd->shade.x = bd->x;
2993 bd->shade.y = bd->y;
2994 bd->shade.dir = dir;
2996 e_hints_window_shaded_set(bd, 1);
2997 e_hints_window_shade_direction_set(bd, dir);
2999 if (e_config->border_shade_animate)
3001 bd->shade.start = ecore_loop_time_get();
3003 bd->changes.shading = 1;
3006 if (bd->shade.dir == E_DIRECTION_UP ||
3007 bd->shade.dir == E_DIRECTION_LEFT)
3008 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3010 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3012 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3013 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
3017 if (bd->shade.dir == E_DIRECTION_UP)
3019 bd->h = bd->client_inset.t + bd->client_inset.b;
3021 else if (bd->shade.dir == E_DIRECTION_DOWN)
3023 bd->h = bd->client_inset.t + bd->client_inset.b;
3024 bd->y = bd->y + bd->client.h;
3025 bd->changes.pos = 1;
3027 else if (bd->shade.dir == E_DIRECTION_LEFT)
3029 bd->w = bd->client_inset.l + bd->client_inset.r;
3031 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3033 bd->w = bd->client_inset.l + bd->client_inset.r;
3034 bd->x = bd->x + bd->client.w;
3035 bd->changes.pos = 1;
3038 if ((bd->shaped) || (bd->client.shaped))
3040 bd->need_shape_merge = 1;
3041 bd->need_shape_export = 1;
3043 if (bd->shaped_input)
3045 bd->need_shape_merge = 1;
3048 bd->changes.size = 1;
3050 bd->changes.shaded = 1;
3052 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3053 e_border_frame_recalc(bd);
3054 ev = E_NEW(E_Event_Border_Resize, 1);
3056 /* The resize is added in the animator when animation complete */
3057 /* For non-animated, we add it immediately with the new size */
3058 e_object_ref(E_OBJECT(bd));
3059 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3060 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3063 e_remember_update(bd);
3067 e_border_unshade(E_Border *bd,
3070 E_Event_Border_Resize *ev;
3075 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3076 if ((!bd->shaded) || (bd->shading))
3079 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3080 ecore_x_window_show(tmp->win);
3082 ecore_x_window_shadow_tree_flush();
3084 bd->shade.dir = dir;
3086 e_hints_window_shaded_set(bd, 0);
3087 e_hints_window_shade_direction_set(bd, dir);
3089 if (bd->shade.dir == E_DIRECTION_UP ||
3090 bd->shade.dir == E_DIRECTION_LEFT)
3092 bd->shade.x = bd->x;
3093 bd->shade.y = bd->y;
3097 bd->shade.x = bd->x - bd->client.w;
3098 bd->shade.y = bd->y - bd->client.h;
3100 if (e_config->border_shade_animate)
3102 bd->shade.start = ecore_loop_time_get();
3104 bd->changes.shading = 1;
3107 if (bd->shade.dir == E_DIRECTION_UP)
3109 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3110 ecore_x_window_move_resize(bd->client.win, 0,
3111 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3113 bd->client.w, bd->client.h);
3115 else if (bd->shade.dir == E_DIRECTION_LEFT)
3117 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3118 ecore_x_window_move_resize(bd->client.win,
3119 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3121 0, bd->client.w, bd->client.h);
3124 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3126 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3127 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3131 if (bd->shade.dir == E_DIRECTION_UP)
3133 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3135 else if (bd->shade.dir == E_DIRECTION_DOWN)
3137 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3138 bd->y = bd->y - bd->client.h;
3139 bd->changes.pos = 1;
3141 else if (bd->shade.dir == E_DIRECTION_LEFT)
3143 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3145 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3147 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3148 bd->x = bd->x - bd->client.w;
3149 bd->changes.pos = 1;
3151 if ((bd->shaped) || (bd->client.shaped))
3153 bd->need_shape_merge = 1;
3154 bd->need_shape_export = 1;
3156 if (bd->shaped_input)
3158 bd->need_shape_merge = 1;
3161 bd->changes.size = 1;
3163 bd->changes.shaded = 1;
3165 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3166 e_border_frame_recalc(bd);
3167 ev = E_NEW(E_Event_Border_Resize, 1);
3169 /* The resize is added in the animator when animation complete */
3170 /* For non-animated, we add it immediately with the new size */
3171 e_object_ref(E_OBJECT(bd));
3172 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3173 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3176 e_remember_update(bd);
3180 _e_border_client_inset_calc(E_Border *bd)
3183 Evas_Coord cx, cy, cw, ch;
3187 evas_object_resize(bd->bg_object, 1000, 1000);
3188 edje_object_message_signal_process(bd->bg_object);
3189 edje_object_calc_force(bd->bg_object);
3190 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3191 bd->client_inset.l = cx;
3192 bd->client_inset.r = 1000 - (cx + cw);
3193 bd->client_inset.t = cy;
3194 bd->client_inset.b = 1000 - (cy + ch);
3198 bd->client_inset.l = 0;
3199 bd->client_inset.r = 0;
3200 bd->client_inset.t = 0;
3201 bd->client_inset.b = 0;
3204 ecore_x_netwm_frame_size_set(bd->client.win,
3205 bd->client_inset.l, bd->client_inset.r,
3206 bd->client_inset.t, bd->client_inset.b);
3207 ecore_x_e_frame_size_set(bd->client.win,
3208 bd->client_inset.l, bd->client_inset.r,
3209 bd->client_inset.t, bd->client_inset.b);
3213 _e_border_maximize(E_Border *bd, E_Maximize max)
3215 int x1, yy1, x2, y2;
3218 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3222 zx = zy = zw = zh = 0;
3224 switch (max & E_MAXIMIZE_TYPE)
3226 case E_MAXIMIZE_NONE:
3230 case E_MAXIMIZE_FULLSCREEN:
3236 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3237 _e_border_client_inset_calc(bd);
3239 e_border_resize_limit(bd, &w, &h);
3240 /* center x-direction */
3241 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3242 /* center y-direction */
3243 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3245 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3246 cy = bd->zone->y + (bd->zone->h / 2);
3249 switch (max & E_MAXIMIZE_DIRECTION)
3251 case E_MAXIMIZE_BOTH:
3252 e_border_move_resize(bd, x1, yy1, w, h);
3255 case E_MAXIMIZE_VERTICAL:
3256 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3259 case E_MAXIMIZE_HORIZONTAL:
3260 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3263 case E_MAXIMIZE_LEFT:
3264 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3267 case E_MAXIMIZE_RIGHT:
3268 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3270 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3271 case E_MAXIMIZE_TOP:
3272 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3274 case E_MAXIMIZE_BOTTOM:
3275 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3281 case E_MAXIMIZE_SMART:
3282 case E_MAXIMIZE_EXPAND:
3284 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3296 if (bd->x < zx) // window left not useful coordinates
3298 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3299 x1 = zx + zw - bd->w;
3300 else // window normal position
3303 if (bd->y < zy) // window top not useful coordinates
3305 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3306 yy1 = zy + zh - bd->h;
3307 else // window normal position
3310 switch (max & E_MAXIMIZE_DIRECTION)
3312 case E_MAXIMIZE_BOTH:
3313 e_border_move_resize(bd, zx, zy, zw, zh);
3316 case E_MAXIMIZE_VERTICAL:
3317 e_border_move_resize(bd, x1, zy, w, zh);
3320 case E_MAXIMIZE_HORIZONTAL:
3321 e_border_move_resize(bd, zx, yy1, zw, h);
3324 case E_MAXIMIZE_LEFT:
3325 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3328 case E_MAXIMIZE_RIGHT:
3329 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3333 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3336 case E_MAXIMIZE_FILL:
3339 x2 = bd->zone->x + bd->zone->w;
3340 y2 = bd->zone->y + bd->zone->h;
3342 /* walk through all shelves */
3343 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3345 /* walk through all windows */
3346 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3352 e_border_resize_limit(bd, &w, &h);
3353 /* center x-direction */
3354 x1 = x1 + (pw - w) / 2;
3355 /* center y-direction */
3356 yy1 = yy1 + (ph - h) / 2;
3358 switch (max & E_MAXIMIZE_DIRECTION)
3360 case E_MAXIMIZE_BOTH:
3361 e_border_move_resize(bd, x1, yy1, w, h);
3364 case E_MAXIMIZE_VERTICAL:
3365 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3368 case E_MAXIMIZE_HORIZONTAL:
3369 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3372 case E_MAXIMIZE_LEFT:
3373 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3376 case E_MAXIMIZE_RIGHT:
3377 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3385 e_border_maximize(E_Border *bd,
3389 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3391 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3393 if ((bd->shaded) || (bd->shading)) return;
3394 ecore_x_window_shadow_tree_flush();
3396 e_border_unfullscreen(bd);
3397 /* Only allow changes in vertical/ horizontal maximization */
3398 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3399 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3402 bd->need_maximize = 1;
3403 bd->maximized &= ~E_MAXIMIZE_TYPE;
3404 bd->maximized |= max;
3408 bd->pre_res_change.valid = 0;
3409 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3411 /* Horizontal hasn't been set */
3412 bd->saved.x = bd->x - bd->zone->x;
3413 bd->saved.w = bd->w;
3415 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3417 /* Vertical hasn't been set */
3418 bd->saved.y = bd->y - bd->zone->y;
3419 bd->saved.h = bd->h;
3422 bd->saved.zone = bd->zone->num;
3423 e_hints_window_size_set(bd);
3427 _e_border_maximize(bd, max);
3430 /* Remove previous type */
3431 bd->maximized &= ~E_MAXIMIZE_TYPE;
3432 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3433 bd->maximized |= max;
3435 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3436 bd->maximized & E_MAXIMIZE_VERTICAL);
3437 e_remember_update(bd);
3441 e_border_unmaximize(E_Border *bd,
3445 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3446 if (!(max & E_MAXIMIZE_DIRECTION))
3448 CRI("BUG: Unmaximize call without direction!");
3452 if ((bd->shaded) || (bd->shading)) return;
3453 ecore_x_window_shadow_tree_flush();
3454 /* Remove directions not used */
3455 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3456 /* Can only remove existing maximization directions */
3458 if (bd->maximized & E_MAXIMIZE_TYPE)
3460 bd->pre_res_change.valid = 0;
3461 bd->need_maximize = 0;
3463 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3467 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3468 _e_border_client_inset_calc(bd);
3471 bd->maximized = E_MAXIMIZE_NONE;
3472 _e_border_move_resize_internal(bd,
3473 bd->zone->x + bd->saved.x,
3474 bd->zone->y + bd->saved.y,
3475 bd->saved.w, bd->saved.h, 0, 1);
3476 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3477 e_hints_window_size_unset(bd);
3488 if (max & E_MAXIMIZE_VERTICAL)
3490 /* Remove vertical */
3492 y = bd->saved.y + bd->zone->y;
3493 bd->saved.h = bd->saved.y = 0;
3494 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3495 bd->maximized &= ~E_MAXIMIZE_LEFT;
3496 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3498 if (max & E_MAXIMIZE_HORIZONTAL)
3500 /* Remove horizontal */
3502 x = bd->saved.x + bd->zone->x;
3503 bd->saved.w = bd->saved.x = 0;
3504 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3507 e_border_resize_limit(bd, &w, &h);
3509 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3511 bd->maximized = E_MAXIMIZE_NONE;
3512 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3513 e_hints_window_size_unset(bd);
3514 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3518 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3519 e_hints_window_size_set(bd);
3522 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3523 bd->maximized & E_MAXIMIZE_VERTICAL);
3525 e_remember_update(bd);
3529 e_border_fullscreen(E_Border *bd,
3530 E_Fullscreen policy)
3532 E_Event_Border_Fullscreen *ev;
3535 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3537 if ((bd->shaded) || (bd->shading)) return;
3538 ecore_x_window_shadow_tree_flush();
3541 bd->need_fullscreen = 1;
3544 if (!bd->fullscreen)
3546 bd->pre_res_change.valid = 0;
3548 bd->saved.x = bd->x - bd->zone->x;
3549 bd->saved.y = bd->y - bd->zone->y;
3550 bd->saved.w = bd->client.w;
3551 bd->saved.h = bd->client.h;
3552 bd->saved.maximized = bd->maximized;
3553 bd->saved.zone = bd->zone->num;
3556 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3557 e_hints_window_size_set(bd);
3559 bd->client_inset.l = 0;
3560 bd->client_inset.r = 0;
3561 bd->client_inset.t = 0;
3562 bd->client_inset.b = 0;
3564 bd->desk->fullscreen_borders++;
3566 /* e_zone_fullscreen_set(bd->zone, 1); */
3567 bd->saved.layer = bd->layer;
3568 if (!e_config->allow_above_fullscreen)
3569 e_border_layer_set(bd, 250);
3571 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3572 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3574 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3576 else if (policy == E_FULLSCREEN_ZOOM)
3578 Ecore_X_Randr_Screen_Size_MM *sizes;
3579 int num_sizes, i, best_size_index = 0;
3581 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3583 &screen_size.height,
3585 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3589 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3590 int best_dist = INT_MAX, dist;
3592 for (i = 0; i < num_sizes; i++)
3594 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3596 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3597 if (dist < best_dist)
3599 best_size.width = sizes[i].width;
3600 best_size.height = sizes[i].height;
3602 best_size_index = i;
3606 if (((best_size.width != -1) && (best_size.height != -1)) &&
3607 ((best_size.width != screen_size.width) ||
3608 (best_size.height != screen_size.height)))
3610 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3612 screen_size_index = best_size_index;
3613 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3617 screen_size.width = -1;
3618 screen_size.height = -1;
3619 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3624 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3628 e_hints_window_fullscreen_set(bd, 1);
3629 e_hints_window_size_unset(bd);
3630 bd->client.border.changed = 1;
3633 bd->fullscreen_policy = policy;
3635 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3637 e_object_ref(E_OBJECT(bd));
3638 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3639 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3641 e_remember_update(bd);
3645 e_border_unfullscreen(E_Border *bd)
3647 E_Event_Border_Unfullscreen *ev;
3650 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3651 if ((bd->shaded) || (bd->shading)) return;
3652 ecore_x_window_shadow_tree_flush();
3655 bd->pre_res_change.valid = 0;
3657 bd->need_fullscreen = 0;
3658 bd->desk->fullscreen_borders--;
3660 if ((screen_size.width != -1) && (screen_size.height != -1))
3662 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3664 screen_size.width = -1;
3665 screen_size.height = -1;
3667 e_border_move_resize(bd,
3668 bd->saved.x + bd->zone->x,
3669 bd->saved.y + bd->zone->y,
3670 bd->saved.w, bd->saved.h);
3672 if (bd->saved.maximized)
3673 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3674 bd->saved.maximized);
3676 e_border_layer_set(bd, bd->saved.layer);
3678 e_hints_window_fullscreen_set(bd, 0);
3679 bd->client.border.changed = 1;
3682 bd->fullscreen_policy = 0;
3684 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3686 e_object_ref(E_OBJECT(bd));
3687 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3688 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3690 e_remember_update(bd);
3694 e_border_iconify(E_Border *bd)
3696 E_Event_Border_Iconify *ev;
3697 unsigned int iconic;
3700 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3701 if (bd->shading) return;
3702 ecore_x_window_shadow_tree_flush();
3706 e_border_hide(bd, 1);
3707 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3708 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3711 e_hints_window_iconic_set(bd);
3712 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3714 ev = E_NEW(E_Event_Border_Iconify, 1);
3716 e_object_ref(E_OBJECT(bd));
3717 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3718 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3720 if (e_config->transient.iconify)
3724 Eina_List *list = _e_border_sub_borders_new(bd);
3726 EINA_LIST_FOREACH(list, l, child)
3728 e_border_iconify(child);
3730 eina_list_free(list);
3732 e_remember_update(bd);
3735 #ifdef _F_DEICONIFY_APPROVE_
3737 _e_border_uniconify_timeout(void *data)
3744 if (!e_object_is_del(E_OBJECT(bd)))
3746 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3747 bd->client.e.state.deiconify_approve.render_done = 1;
3748 if (bd->client.e.state.deiconify_approve.req_list)
3750 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3752 child_bd->client.e.state.deiconify_approve.render_done = 1;
3753 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3756 bd->client.e.state.deiconify_approve.req_list = NULL;
3757 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3758 e_border_uniconify(bd);
3761 return ECORE_CALLBACK_CANCEL;
3765 _e_border_deiconify_approve_send_pending_end(void *data)
3767 E_Border *bd = (E_Border *)data;
3769 if (e_config->deiconify_approve)
3771 if (!e_object_is_del(E_OBJECT(bd)))
3773 bd->client.e.state.deiconify_approve.pending_job = NULL;
3775 ELBF(ELBT_BD, 0, bd->client.win,
3776 "SEND DEICONIFY_APPROVE. (PENDING_END) ancestor:%x",
3779 ecore_x_client_message32_send(bd->client.win,
3780 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3781 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3782 bd->client.win, 0, 0, 0, 0);
3784 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3790 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor, Eina_Bool pending_ancestor)
3792 if (!bd || !bd_ancestor) return;
3794 if (e_config->deiconify_approve)
3796 if (e_config->transient.iconify)
3800 Eina_List *list = _e_border_sub_borders_new(bd);
3801 EINA_LIST_FOREACH(list, l, child)
3803 Eina_Bool pending = EINA_FALSE;
3804 Eina_Bool p = EINA_FALSE;
3806 #ifdef _F_ZONE_WINDOW_ROTATION_
3807 if ((e_config->wm_win_rotation) &&
3808 ((child->client.e.state.rot.support) ||
3809 (child->client.e.state.rot.app_set)))
3811 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3812 int rotation = _e_border_rotation_angle_get(bd);
3813 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3816 if ((pending_ancestor) || (pending)) p = EINA_TRUE;
3818 _e_border_deiconify_approve_send(child, bd_ancestor, p);
3819 if (child->client.e.state.deiconify_approve.support)
3823 ELBF(ELBT_BD, 0, child->client.win,
3824 "SEND DEICONIFY_APPROVE. ancestor:%x pending(%d,%d)",
3825 bd_ancestor->client.win,
3826 pending_ancestor, pending);
3828 ecore_x_client_message32_send(child->client.win,
3829 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3830 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3831 child->client.win, 0, 0, 0, 0);
3832 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3833 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3837 /* queue a deiconify send job to give the chance to other jobs */
3838 ELBF(ELBT_BD, 0, child->client.win,
3839 "SEND DEICONIFY_APPROVE. (PENDING) ancestor:%x",
3840 bd_ancestor->client.win);
3841 child->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, child);
3845 eina_list_free(list);
3851 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3853 Eina_Bool pending = EINA_FALSE;
3855 if (e_config->deiconify_approve)
3857 #ifdef _F_ZONE_WINDOW_ROTATION_
3858 if ((e_config->wm_win_rotation) &&
3859 ((bd->client.e.state.rot.support) ||
3860 (bd->client.e.state.rot.app_set)))
3862 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3863 int rotation = _e_border_rotation_angle_get(bd);
3864 if (rotation != -1) _e_border_rotation_set_internal(bd, rotation, &pending);
3868 if (e_config->transient.iconify)
3870 _e_border_deiconify_approve_send(bd, bd, pending);
3873 if (bd->client.e.state.deiconify_approve.support)
3877 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE.");
3878 ecore_x_client_message32_send(bd->client.win,
3879 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3880 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3881 bd->client.win, 0, 0, 0, 0);
3882 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3886 /* queue a deiconify send job to give the chance to other jobs */
3887 ELBF(ELBT_BD, 0, bd->client.win, "SEND DEICONIFY_APPROVE. (PENDING)");
3888 bd->client.e.state.deiconify_approve.pending_job = ecore_job_add(_e_border_deiconify_approve_send_pending_end, bd);
3896 e_border_uniconify(E_Border *bd)
3899 E_Event_Border_Uniconify *ev;
3900 unsigned int iconic;
3903 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3905 #ifdef _F_DEICONIFY_APPROVE_
3906 if (e_config->deiconify_approve)
3908 if (bd->client.e.state.deiconify_approve.support)
3910 if (bd->client.e.state.deiconify_approve.wait_timer)
3912 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3915 if (bd->client.e.state.deiconify_approve.render_done == 0)
3917 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3918 _e_border_deiconify_approve_send_all_transient(bd);
3922 bd->client.e.state.deiconify_approve.render_done = 0;
3926 #if _F_ZONE_WINDOW_ROTATION_
3927 if (!bd->client.win)
3929 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3934 if (bd->shading) return;
3935 ecore_x_window_shadow_tree_flush();
3940 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3941 desk = e_desk_current_get(bd->desk->zone);
3942 #ifdef _F_USE_EXTENDED_ICONIFY_
3943 if (e_manager_comp_evas_get(bd->zone->container->manager))
3945 if (bd->await_hide_event > 0)
3946 bd->await_hide_event--;
3949 e_border_desk_set(bd, desk);
3951 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3954 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3956 ev = E_NEW(E_Event_Border_Uniconify, 1);
3958 e_object_ref(E_OBJECT(bd));
3959 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3960 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3962 if (e_config->transient.iconify)
3966 Eina_List *list = _e_border_sub_borders_new(bd);
3968 EINA_LIST_FOREACH(list, l, child)
3970 e_border_uniconify(child);
3972 eina_list_free(list);
3974 e_remember_update(bd);
3978 e_border_stick(E_Border *bd)
3980 E_Event_Border_Stick *ev;
3983 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3984 if (bd->sticky) return;
3986 e_hints_window_sticky_set(bd, 1);
3989 if (e_config->transient.desktop)
3993 Eina_List *list = _e_border_sub_borders_new(bd);
3995 EINA_LIST_FOREACH(list, l, child)
3998 e_hints_window_sticky_set(child, 1);
3999 e_border_show(child);
4001 eina_list_free(list);
4004 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
4005 ev = E_NEW(E_Event_Border_Stick, 1);
4007 e_object_ref(E_OBJECT(bd));
4008 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
4009 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
4010 e_remember_update(bd);
4014 e_border_unstick(E_Border *bd)
4016 E_Event_Border_Unstick *ev;
4019 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4020 /* Set the desk before we unstick the border */
4021 if (!bd->sticky) return;
4023 e_hints_window_sticky_set(bd, 0);
4025 if (e_config->transient.desktop)
4029 Eina_List *list = _e_border_sub_borders_new(bd);
4031 EINA_LIST_FOREACH(list, l, child)
4034 e_hints_window_sticky_set(child, 0);
4036 eina_list_free(list);
4039 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
4040 ev = E_NEW(E_Event_Border_Unstick, 1);
4042 e_object_ref(E_OBJECT(bd));
4043 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
4044 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
4046 e_border_desk_set(bd, e_desk_current_get(bd->zone));
4047 e_remember_update(bd);
4051 e_border_pinned_set(E_Border *bd,
4059 bd->borderless = set;
4060 bd->user_skip_winlist = set;
4064 stacking = E_STACKING_BELOW;
4069 stacking = E_STACKING_NONE;
4072 e_border_layer_set(bd, layer);
4073 e_hints_window_stacking_set(bd, stacking);
4075 bd->client.border.changed = 1;
4081 e_border_find_by_client_window(Ecore_X_Window win)
4085 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4086 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4087 (bd->client.win == win))
4093 e_border_find_all_by_client_window(Ecore_X_Window win)
4097 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4098 if ((bd) && (bd->client.win == win))
4104 e_border_find_by_frame_window(Ecore_X_Window win)
4108 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4109 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4110 (bd->bg_win == win))
4116 e_border_find_by_window(Ecore_X_Window win)
4120 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4121 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4128 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4133 EINA_LIST_FOREACH(borders, l, bd)
4135 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4136 (bd->client.netwm.sync.alarm == al))
4143 e_border_focused_get(void)
4149 _e_border_shape_input_rectangle_set(E_Border* bd)
4153 if ((bd->visible) && (bd->shaped_input))
4155 Ecore_X_Rectangle rects[4];
4156 Ecore_X_Window twin, twin2;
4159 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4160 0, 0, bd->w, bd->h);
4163 rects[0].width = bd->w;
4164 rects[0].height = bd->client_inset.t;
4166 rects[1].y = bd->client_inset.t;
4167 rects[1].width = bd->client_inset.l;
4168 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4169 rects[2].x = bd->w - bd->client_inset.r;
4170 rects[2].y = bd->client_inset.t;
4171 rects[2].width = bd->client_inset.r;
4172 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4174 rects[3].y = bd->h - bd->client_inset.b;
4175 rects[3].width = bd->w;
4176 rects[3].height = bd->client_inset.b;
4177 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4179 twin2 = ecore_x_window_override_new
4180 (bd->zone->container->scratch_win, 0, 0,
4181 bd->w - bd->client_inset.l - bd->client_inset.r,
4182 bd->h - bd->client_inset.t - bd->client_inset.b);
4185 if ((bd->shading) || (bd->shaded))
4187 if (bd->shade.dir == E_DIRECTION_UP)
4188 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4190 else if (bd->shade.dir == E_DIRECTION_LEFT)
4191 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4194 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4196 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4197 bd->w - bd->client_inset.l - bd->client_inset.r,
4198 bd->h - bd->client_inset.t - bd->client_inset.b);
4199 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4201 bd->client_inset.t);
4202 ecore_x_window_shape_input_window_set(bd->win, twin);
4203 ecore_x_window_free(twin2);
4204 ecore_x_window_free(twin);
4208 if (bd->visible) // not shaped input
4210 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4211 ecore_x_composite_window_events_enable(bd->win);
4213 ecore_x_composite_window_events_disable(bd->win);
4217 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4218 ecore_x_composite_window_events_enable(bd->win);
4220 ecore_x_composite_window_events_disable(bd->win);
4226 e_border_idler_before(void)
4235 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4237 EINA_LIST_FOREACH(man->containers, cl, con)
4242 // pass 1 - eval0. fetch properties on new or on change and
4243 // call hooks to decide what to do - maybe move/resize
4244 bl = e_container_border_list_last(con);
4245 while ((bd = e_container_border_list_prev(bl)))
4247 if (bd->changed) _e_border_eval0(bd);
4249 e_container_border_list_free(bl);
4251 // layout hook - this is where a hook gets to figure out what to
4253 _e_border_container_layout_hook(con);
4255 // pass 2 - show windows needing show
4256 bl = e_container_border_list_last(con);
4257 while ((bd = e_container_border_list_prev(bl)))
4259 if ((bd->changes.visible) && (bd->visible) &&
4260 (!bd->new_client) && (!bd->changes.pos) &&
4261 (!bd->changes.size))
4264 bd->changes.visible = 0;
4267 e_container_border_list_free(bl);
4269 // pass 3 - hide windows needing hide and eval (main eval)
4270 bl = e_container_border_list_first(con);
4271 while ((bd = e_container_border_list_next(bl)))
4273 if (e_object_is_del(E_OBJECT(bd))) continue;
4275 if ((bd->changes.visible) && (!bd->visible))
4278 bd->changes.visible = 0;
4281 if (bd->changed) _e_border_eval(bd);
4283 if ((bd->changes.visible) && (bd->visible))
4286 bd->changes.visible = 0;
4289 e_container_border_list_free(bl);
4295 E_Border *bd = NULL, *bd2;
4297 EINA_LIST_FREE(focus_next, bd2)
4298 if ((!bd) && (bd2->visible)) bd = bd2;
4302 /* TODO revert focus when lost here ? */
4308 /* already focused. but anyway dont be so strict, this
4309 fcks up illume setting focus on internal windows */
4314 focus_time = ecore_x_current_time_get();
4318 if ((bd->client.icccm.take_focus) &&
4319 (bd->client.icccm.accepts_focus))
4321 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4322 /* TODO what if the client didn't take focus ? */
4324 else if (!bd->client.icccm.accepts_focus)
4326 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4328 else if (!bd->client.icccm.take_focus)
4330 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4331 /* e_border_focus_set(bd, 1, 0); */
4335 #ifdef _F_ZONE_WINDOW_ROTATION_
4336 if ((e_config->wm_win_rotation) &&
4339 Ecore_X_Event_Client_Message *msg = NULL;
4341 EINA_LIST_FREE(rot.msgs, msg)
4343 t = msg->message_type;
4344 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4346 if ((rot.vkbd_ctrl_win) &&
4347 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4350 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4351 if (rot.vkbd_show_prepare_timer)
4352 _e_border_vkbd_show(rot.vkbd);
4354 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4357 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4359 if ((rot.vkbd_ctrl_win) &&
4360 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4363 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4364 if (rot.vkbd_hide_prepare_timer)
4366 _e_border_vkbd_hide(rot.vkbd);
4367 rot.vkbd_hide_prepare_timer = NULL;
4368 e_object_unref(E_OBJECT(rot.vkbd));
4371 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4374 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4376 rot.vkbd_ctrl_win = msg->data.l[0];
4377 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4379 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4381 if ((rot.vkbd_ctrl_win) &&
4382 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4384 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4385 E_Manager *m = e_manager_current_get();
4386 E_Zone *zone = NULL;
4387 if (m) zone = e_util_zone_current_get(m);
4388 if ((zone) && (rot.wait_prepare_done))
4392 _e_border_rotation_change_request(zone);
4393 if (rot.prepare_timer)
4394 ecore_timer_del(rot.prepare_timer);
4395 rot.prepare_timer = NULL;
4396 rot.wait_prepare_done = EINA_FALSE;
4405 rot.fetch = EINA_FALSE;
4411 e_border_client_list(void)
4413 /* FIXME: This should be a somewhat ordered list */
4417 static Ecore_X_Window action_input_win = 0;
4418 static E_Border *action_border = NULL;
4419 static Ecore_Event_Handler *action_handler_key = NULL;
4420 static Ecore_Event_Handler *action_handler_mouse = NULL;
4421 static Ecore_Timer *action_timer = NULL;
4422 static Ecore_X_Rectangle action_orig;
4425 _e_border_show(E_Border *bd)
4430 ecore_evas_show(bd->bg_ecore_evas);
4438 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4440 _e_border_shape_input_rectangle_set(bd);
4442 // ecore_x_composite_window_events_enable(bd->win);
4443 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4446 ecore_x_window_show(bd->win);
4448 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4449 ecore_x_window_show(tmp->win);
4453 _e_border_hide(E_Border *bd)
4458 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4460 ecore_x_window_hide(bd->win);
4461 ecore_evas_hide(bd->bg_ecore_evas);
4463 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4464 ecore_x_window_hide(tmp->win);
4468 ecore_x_composite_window_events_disable(bd->win);
4469 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4474 _e_border_action_input_win_del(void)
4476 if (!action_input_win)
4479 e_grabinput_release(action_input_win, action_input_win);
4480 ecore_x_window_free(action_input_win);
4481 action_input_win = 0;
4486 _e_border_action_input_win_new(E_Border *bd)
4488 if (!action_input_win)
4490 Ecore_X_Window parent = bd->zone->container->win;
4491 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4492 if (!action_input_win)
4496 ecore_x_window_show(action_input_win);
4497 if (e_grabinput_get(action_input_win, 0, action_input_win))
4500 _e_border_action_input_win_del();
4505 _e_border_action_finish(void)
4507 _e_border_action_input_win_del();
4511 ecore_timer_del(action_timer);
4512 action_timer = NULL;
4515 if (action_handler_key)
4517 ecore_event_handler_del(action_handler_key);
4518 action_handler_key = NULL;
4521 if (action_handler_mouse)
4523 ecore_event_handler_del(action_handler_mouse);
4524 action_handler_mouse = NULL;
4527 action_border = NULL;
4531 _e_border_action_init(E_Border *bd)
4533 action_orig.x = bd->x;
4534 action_orig.y = bd->y;
4535 action_orig.width = bd->w;
4536 action_orig.height = bd->h;
4542 _e_border_action_restore_orig(E_Border *bd)
4544 if (action_border != bd)
4547 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4551 _e_border_key_down_modifier_apply(int modifier,
4554 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4556 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4569 _e_border_action_move_timeout(void *data __UNUSED__)
4571 _e_border_move_end(action_border);
4572 _e_border_action_finish();
4573 return ECORE_CALLBACK_CANCEL;
4577 _e_border_action_move_timeout_add(void)
4580 ecore_timer_del(action_timer);
4581 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4585 _e_border_move_key_down(void *data __UNUSED__,
4586 int type __UNUSED__,
4589 Ecore_Event_Key *ev = event;
4592 if (ev->event_window != action_input_win)
4593 return ECORE_CALLBACK_PASS_ON;
4596 fputs("ERROR: no action_border!\n", stderr);
4600 x = action_border->x;
4601 y = action_border->y;
4603 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4604 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4605 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4606 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4607 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4608 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4609 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4610 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4611 else if (strcmp(ev->key, "Return") == 0)
4613 else if (strcmp(ev->key, "Escape") == 0)
4615 _e_border_action_restore_orig(action_border);
4618 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4619 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4622 e_border_move(action_border, x, y);
4623 _e_border_action_move_timeout_add();
4625 return ECORE_CALLBACK_PASS_ON;
4628 _e_border_move_end(action_border);
4629 _e_border_action_finish();
4630 return ECORE_CALLBACK_DONE;
4634 _e_border_move_mouse_down(void *data __UNUSED__,
4635 int type __UNUSED__,
4638 Ecore_Event_Mouse_Button *ev = event;
4640 if (ev->event_window != action_input_win)
4641 return ECORE_CALLBACK_PASS_ON;
4644 fputs("ERROR: no action_border!\n", stderr);
4646 _e_border_move_end(action_border);
4647 _e_border_action_finish();
4648 return ECORE_CALLBACK_DONE;
4652 e_border_act_move_keyboard(E_Border *bd)
4657 if (!_e_border_move_begin(bd))
4660 if (!_e_border_action_input_win_new(bd))
4662 _e_border_move_end(bd);
4666 _e_border_action_init(bd);
4667 _e_border_action_move_timeout_add();
4668 _e_border_move_update(bd);
4670 if (action_handler_key)
4671 ecore_event_handler_del(action_handler_key);
4672 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4674 if (action_handler_mouse)
4675 ecore_event_handler_del(action_handler_mouse);
4676 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4680 _e_border_action_resize_timeout(void *data __UNUSED__)
4682 _e_border_resize_end(action_border);
4683 _e_border_action_finish();
4684 return ECORE_CALLBACK_CANCEL;
4688 _e_border_action_resize_timeout_add(void)
4691 ecore_timer_del(action_timer);
4692 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4696 _e_border_resize_key_down(void *data __UNUSED__,
4697 int type __UNUSED__,
4700 Ecore_Event_Key *ev = event;
4703 if (ev->event_window != action_input_win)
4704 return ECORE_CALLBACK_PASS_ON;
4707 fputs("ERROR: no action_border!\n", stderr);
4711 w = action_border->w;
4712 h = action_border->h;
4714 dx = e_config->border_keyboard.resize.dx;
4715 if (dx < action_border->client.icccm.step_w)
4716 dx = action_border->client.icccm.step_w;
4717 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4718 if (dx < action_border->client.icccm.step_w)
4719 dx = action_border->client.icccm.step_w;
4721 dy = e_config->border_keyboard.resize.dy;
4722 if (dy < action_border->client.icccm.step_h)
4723 dy = action_border->client.icccm.step_h;
4724 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4725 if (dy < action_border->client.icccm.step_h)
4726 dy = action_border->client.icccm.step_h;
4728 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4730 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4732 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4734 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4736 else if (strcmp(ev->key, "Return") == 0)
4738 else if (strcmp(ev->key, "Escape") == 0)
4740 _e_border_action_restore_orig(action_border);
4743 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4744 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4747 e_border_resize_limit(action_border, &w, &h);
4748 e_border_resize(action_border, w, h);
4749 _e_border_action_resize_timeout_add();
4751 return ECORE_CALLBACK_PASS_ON;
4754 _e_border_resize_end(action_border);
4755 _e_border_action_finish();
4756 return ECORE_CALLBACK_DONE;
4760 _e_border_resize_mouse_down(void *data __UNUSED__,
4761 int type __UNUSED__,
4764 Ecore_Event_Mouse_Button *ev = event;
4766 if (ev->event_window != action_input_win)
4767 return ECORE_CALLBACK_PASS_ON;
4770 fputs("ERROR: no action_border!\n", stderr);
4772 _e_border_resize_end(action_border);
4773 _e_border_action_finish();
4774 return ECORE_CALLBACK_DONE;
4778 e_border_act_resize_keyboard(E_Border *bd)
4783 if (!_e_border_resize_begin(bd))
4786 if (!_e_border_action_input_win_new(bd))
4788 _e_border_resize_end(bd);
4792 _e_border_action_init(bd);
4793 _e_border_action_resize_timeout_add();
4794 _e_border_resize_update(bd);
4796 if (action_handler_key)
4797 ecore_event_handler_del(action_handler_key);
4798 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4800 if (action_handler_mouse)
4801 ecore_event_handler_del(action_handler_mouse);
4802 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4806 e_border_act_move_begin(E_Border *bd,
4807 Ecore_Event_Mouse_Button *ev)
4810 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4811 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4812 if (!_e_border_move_begin(bd))
4815 e_zone_edge_disable();
4817 _e_border_pointer_move_begin(bd);
4822 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4823 _e_border_moveinfo_gather(bd, source);
4828 e_border_act_move_end(E_Border *bd,
4829 Ecore_Event_Mouse_Button *ev __UNUSED__)
4832 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4833 if (!bd->moving) return;
4835 _e_border_pointer_move_end(bd);
4836 e_zone_edge_enable();
4837 _e_border_move_end(bd);
4838 e_zone_flip_coords_handle(bd->zone, -1, -1);
4842 e_border_act_resize_begin(E_Border *bd,
4843 Ecore_Event_Mouse_Button *ev)
4846 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4847 if (bd->lock_user_size) return;
4848 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4849 if (!_e_border_resize_begin(bd))
4851 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4853 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4855 bd->resize_mode = RESIZE_TL;
4856 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4860 bd->resize_mode = RESIZE_BL;
4861 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4866 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4868 bd->resize_mode = RESIZE_TR;
4869 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4873 bd->resize_mode = RESIZE_BR;
4874 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4877 _e_border_pointer_resize_begin(bd);
4882 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4883 _e_border_moveinfo_gather(bd, source);
4888 e_border_act_resize_end(E_Border *bd,
4889 Ecore_Event_Mouse_Button *ev __UNUSED__)
4892 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4893 if (bd->resize_mode != RESIZE_NONE)
4895 _e_border_pointer_resize_end(bd);
4896 bd->resize_mode = RESIZE_NONE;
4897 _e_border_resize_end(bd);
4898 bd->changes.reset_gravity = 1;
4904 e_border_act_menu_begin(E_Border *bd,
4905 Ecore_Event_Mouse_Button *ev,
4909 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4912 e_int_border_menu_show(bd,
4913 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4914 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4921 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4922 e_int_border_menu_show(bd, x, y, key, 0);
4927 e_border_act_close_begin(E_Border *bd)
4930 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4931 if (bd->lock_close) return;
4932 if (bd->client.icccm.delete_request)
4934 bd->delete_requested = 1;
4935 ecore_x_window_delete_request_send(bd->client.win);
4936 if (bd->client.netwm.ping)
4939 else if (e_config->kill_if_close_not_possible)
4941 e_border_act_kill_begin(bd);
4946 e_border_act_kill_begin(E_Border *bd)
4949 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4950 if (bd->internal) return;
4951 if (bd->lock_close) return;
4952 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4954 kill(bd->client.netwm.pid, SIGINT);
4955 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4956 _e_border_cb_kill_timer, bd);
4960 if (!bd->internal) ecore_x_kill(bd->client.win);
4965 e_border_icon_add(E_Border *bd,
4970 E_OBJECT_CHECK_RETURN(bd, NULL);
4971 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4976 if (!bd->internal_icon)
4978 o = e_icon_add(evas);
4979 e_util_icon_theme_set(o, "enlightenment");
4983 if (!bd->internal_icon_key)
4987 ext = strrchr(bd->internal_icon, '.');
4988 if ((ext) && ((!strcmp(ext, ".edj"))))
4990 o = edje_object_add(evas);
4991 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4992 e_util_icon_theme_set(o, "enlightenment");
4996 o = e_icon_add(evas);
4997 e_icon_file_set(o, bd->internal_icon);
5001 o = e_icon_add(evas);
5002 if (!e_util_icon_theme_set(o, bd->internal_icon))
5003 e_util_icon_theme_set(o, "enlightenment");
5008 o = edje_object_add(evas);
5009 edje_object_file_set(o, bd->internal_icon,
5010 bd->internal_icon_key);
5015 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
5017 if (bd->client.netwm.icons)
5019 o = e_icon_add(evas);
5020 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5021 bd->client.netwm.icons[0].width,
5022 bd->client.netwm.icons[0].height);
5023 e_icon_alpha_set(o, 1);
5029 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
5031 o = e_icon_add(evas);
5034 e_icon_fdo_icon_set(o, bd->desktop->icon);
5038 else if (bd->client.netwm.icons)
5040 o = e_icon_add(evas);
5041 e_icon_data_set(o, bd->client.netwm.icons[0].data,
5042 bd->client.netwm.icons[0].width,
5043 bd->client.netwm.icons[0].height);
5044 e_icon_alpha_set(o, 1);
5049 o = e_icon_add(evas);
5050 e_util_icon_theme_set(o, "unknown");
5055 e_border_button_bindings_ungrab_all(void)
5060 EINA_LIST_FOREACH(borders, l, bd)
5062 e_focus_setdown(bd);
5063 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5064 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5069 e_border_button_bindings_grab_all(void)
5074 EINA_LIST_FOREACH(borders, l, bd)
5076 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5077 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5083 e_border_focus_stack_get(void)
5089 e_border_raise_stack_get(void)
5095 e_border_lost_windows_get(E_Zone *zone)
5097 Eina_List *list = NULL, *l;
5099 int loss_overlap = 5;
5101 E_OBJECT_CHECK_RETURN(zone, NULL);
5102 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5103 EINA_LIST_FOREACH(borders, l, bd)
5108 if ((bd->zone != zone) ||
5109 (bd->zone->container != zone->container))
5112 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5113 bd->zone->y + loss_overlap,
5114 bd->zone->w - (2 * loss_overlap),
5115 bd->zone->h - (2 * loss_overlap),
5116 bd->x, bd->y, bd->w, bd->h))
5118 list = eina_list_append(list, bd);
5120 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5121 bd->zone->w, bd->zone->h,
5122 bd->x, bd->y, bd->w, bd->h)) &&
5125 Ecore_X_Rectangle *rect;
5128 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5134 for (i = 0; i < num; i++)
5136 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5137 bd->zone->y + loss_overlap,
5138 bd->zone->w - (2 * loss_overlap),
5139 bd->zone->h - (2 * loss_overlap),
5140 rect[i].x, rect[i].y,
5141 (int)rect[i].width, (int)rect[i].height))
5149 list = eina_list_append(list, bd);
5157 e_border_ping(E_Border *bd)
5160 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5161 if (!e_config->ping_clients) return;
5163 ecore_x_netwm_ping_send(bd->client.win);
5164 bd->ping = ecore_loop_time_get();
5165 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5166 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5167 e_config->ping_clients_interval,
5168 _e_border_cb_ping_poller, bd);
5172 e_border_move_cancel(void)
5176 if (bdmove->cur_mouse_action)
5181 e_object_ref(E_OBJECT(bd));
5182 if (bd->cur_mouse_action->func.end_mouse)
5183 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5184 else if (bd->cur_mouse_action->func.end)
5185 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5186 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5187 bd->cur_mouse_action = NULL;
5188 e_object_unref(E_OBJECT(bd));
5191 _e_border_move_end(bdmove);
5196 e_border_resize_cancel(void)
5200 if (bdresize->cur_mouse_action)
5205 e_object_ref(E_OBJECT(bd));
5206 if (bd->cur_mouse_action->func.end_mouse)
5207 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5208 else if (bd->cur_mouse_action->func.end)
5209 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5210 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5211 bd->cur_mouse_action = NULL;
5212 e_object_unref(E_OBJECT(bd));
5216 bdresize->resize_mode = RESIZE_NONE;
5217 _e_border_resize_end(bdresize);
5223 e_border_frame_recalc(E_Border *bd)
5225 if (!bd->bg_object) return;
5227 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5228 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5230 _e_border_client_inset_calc(bd);
5232 bd->w += (bd->client_inset.l + bd->client_inset.r);
5233 bd->h += (bd->client_inset.t + bd->client_inset.b);
5236 bd->changes.size = 1;
5237 if ((bd->shaped) || (bd->client.shaped))
5239 bd->need_shape_merge = 1;
5240 bd->need_shape_export = 1;
5242 if (bd->shaped_input)
5244 bd->need_shape_merge = 1;
5246 _e_border_client_move_resize_send(bd);
5250 e_border_immortal_windows_get(void)
5252 Eina_List *list = NULL, *l;
5255 EINA_LIST_FOREACH(borders, l, bd)
5258 list = eina_list_append(list, bd);
5264 e_border_name_get(const E_Border *bd)
5266 E_OBJECT_CHECK_RETURN(bd, "");
5267 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5268 if (bd->client.netwm.name)
5269 return bd->client.netwm.name;
5270 else if (bd->client.icccm.title)
5271 return bd->client.icccm.title;
5276 e_border_signal_move_begin(E_Border *bd,
5278 const char *src __UNUSED__)
5281 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5283 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5284 if (!_e_border_move_begin(bd)) return;
5286 _e_border_pointer_move_begin(bd);
5287 e_zone_edge_disable();
5288 _e_border_moveinfo_gather(bd, sig);
5289 if (bd->cur_mouse_action)
5291 if ((!bd->cur_mouse_action->func.end_mouse) &&
5292 (!bd->cur_mouse_action->func.end))
5293 bd->cur_mouse_action = NULL;
5295 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5297 bd->cur_mouse_action = e_action_find("window_move");
5298 if (bd->cur_mouse_action)
5299 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5303 e_border_signal_move_end(E_Border *bd,
5304 const char *sig __UNUSED__,
5305 const char *src __UNUSED__)
5308 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5309 if (!bd->moving) return;
5311 _e_border_pointer_move_end(bd);
5312 e_zone_edge_enable();
5313 _e_border_move_end(bd);
5314 e_zone_flip_coords_handle(bd->zone, -1, -1);
5318 e_border_resizing_get(E_Border *bd)
5320 E_OBJECT_CHECK_RETURN(bd, 0);
5321 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5322 if (bd->resize_mode == RESIZE_NONE) return 0;
5327 e_border_signal_resize_begin(E_Border *bd,
5330 const char *src __UNUSED__)
5332 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5333 int resize_mode = RESIZE_BR;
5336 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5338 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5339 if (!_e_border_resize_begin(bd))
5341 if (!strcmp(dir, "tl"))
5343 resize_mode = RESIZE_TL;
5344 grav = ECORE_X_GRAVITY_SE;
5346 else if (!strcmp(dir, "t"))
5348 resize_mode = RESIZE_T;
5349 grav = ECORE_X_GRAVITY_S;
5351 else if (!strcmp(dir, "tr"))
5353 resize_mode = RESIZE_TR;
5354 grav = ECORE_X_GRAVITY_SW;
5356 else if (!strcmp(dir, "r"))
5358 resize_mode = RESIZE_R;
5359 grav = ECORE_X_GRAVITY_W;
5361 else if (!strcmp(dir, "br"))
5363 resize_mode = RESIZE_BR;
5364 grav = ECORE_X_GRAVITY_NW;
5366 else if (!strcmp(dir, "b"))
5368 resize_mode = RESIZE_B;
5369 grav = ECORE_X_GRAVITY_N;
5371 else if (!strcmp(dir, "bl"))
5373 resize_mode = RESIZE_BL;
5374 grav = ECORE_X_GRAVITY_NE;
5376 else if (!strcmp(dir, "l"))
5378 resize_mode = RESIZE_L;
5379 grav = ECORE_X_GRAVITY_E;
5381 bd->resize_mode = resize_mode;
5382 _e_border_pointer_resize_begin(bd);
5383 _e_border_moveinfo_gather(bd, sig);
5385 if (bd->cur_mouse_action)
5387 if ((!bd->cur_mouse_action->func.end_mouse) &&
5388 (!bd->cur_mouse_action->func.end))
5389 bd->cur_mouse_action = NULL;
5391 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5393 bd->cur_mouse_action = e_action_find("window_resize");
5394 if (bd->cur_mouse_action)
5395 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5399 e_border_signal_resize_end(E_Border *bd,
5400 const char *dir __UNUSED__,
5401 const char *sig __UNUSED__,
5402 const char *src __UNUSED__)
5405 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5406 if (bd->resize_mode == RESIZE_NONE) return;
5407 _e_border_resize_handle(bd);
5408 _e_border_pointer_resize_end(bd);
5409 bd->resize_mode = RESIZE_NONE;
5410 _e_border_resize_end(bd);
5411 bd->changes.reset_gravity = 1;
5416 e_border_resize_limit(E_Border *bd,
5423 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5424 *w -= bd->client_inset.l + bd->client_inset.r;
5425 *h -= bd->client_inset.t + bd->client_inset.b;
5428 if ((bd->client.icccm.base_w >= 0) &&
5429 (bd->client.icccm.base_h >= 0))
5433 tw = *w - bd->client.icccm.base_w;
5434 th = *h - bd->client.icccm.base_h;
5437 a = (double)(tw) / (double)(th);
5438 if ((bd->client.icccm.min_aspect != 0.0) &&
5439 (a < bd->client.icccm.min_aspect))
5441 th = tw / bd->client.icccm.max_aspect;
5442 *h = th + bd->client.icccm.base_h;
5444 else if ((bd->client.icccm.max_aspect != 0.0) &&
5445 (a > bd->client.icccm.max_aspect))
5447 tw = th * bd->client.icccm.max_aspect;
5448 *w = tw + bd->client.icccm.base_w;
5453 a = (double)*w / (double)*h;
5454 if ((bd->client.icccm.min_aspect != 0.0) &&
5455 (a < bd->client.icccm.min_aspect))
5456 *h = *w / bd->client.icccm.min_aspect;
5457 else if ((bd->client.icccm.max_aspect != 0.0) &&
5458 (a > bd->client.icccm.max_aspect))
5459 *w = *h * bd->client.icccm.max_aspect;
5461 if (bd->client.icccm.step_w > 0)
5463 if (bd->client.icccm.base_w >= 0)
5464 *w = bd->client.icccm.base_w +
5465 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5466 bd->client.icccm.step_w);
5468 *w = bd->client.icccm.min_w +
5469 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5470 bd->client.icccm.step_w);
5472 if (bd->client.icccm.step_h > 0)
5474 if (bd->client.icccm.base_h >= 0)
5475 *h = bd->client.icccm.base_h +
5476 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5477 bd->client.icccm.step_h);
5479 *h = bd->client.icccm.min_h +
5480 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5481 bd->client.icccm.step_h);
5487 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5488 else if (*w < bd->client.icccm.min_w)
5489 *w = bd->client.icccm.min_w;
5490 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5491 else if (*h < bd->client.icccm.min_h)
5492 *h = bd->client.icccm.min_h;
5494 *w += bd->client_inset.l + bd->client_inset.r;
5495 *h += bd->client_inset.t + bd->client_inset.b;
5498 /* local subsystem functions */
5500 _e_border_free(E_Border *bd)
5502 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5505 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5507 bd->client.e.state.video_parent_border->client.e.state.video_child =
5509 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5512 if (bd->client.e.state.video_child)
5516 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5518 tmp->client.e.state.video_parent_border = NULL;
5523 efreet_desktop_free(bd->desktop);
5528 ecore_idle_enterer_del(bd->post_job);
5529 bd->post_job = NULL;
5533 e_object_del(E_OBJECT(bd->pointer));
5537 _e_border_resize_end(bd);
5539 _e_border_move_end(bd);
5540 /* TODO: Other states to end before dying? */
5542 if (bd->cur_mouse_action)
5544 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5545 bd->cur_mouse_action = NULL;
5548 E_FREE(bd->shape_rects);
5549 bd->shape_rects_num = 0;
5551 if (bd->dangling_ref_check)
5553 ecore_timer_del(bd->dangling_ref_check);
5554 bd->dangling_ref_check = NULL;
5559 ecore_timer_del(bd->kill_timer);
5560 bd->kill_timer = NULL;
5562 if (bd->ping_poller)
5564 ecore_poller_del(bd->ping_poller);
5565 bd->ping_poller = NULL;
5567 E_FREE_LIST(bd->pending_move_resize, free);
5569 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5570 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5572 if (bd->border_locks_dialog)
5574 e_object_del(E_OBJECT(bd->border_locks_dialog));
5575 bd->border_locks_dialog = NULL;
5577 if (bd->border_remember_dialog)
5579 e_object_del(E_OBJECT(bd->border_remember_dialog));
5580 bd->border_remember_dialog = NULL;
5582 if (bd->border_border_dialog)
5584 e_object_del(E_OBJECT(bd->border_border_dialog));
5585 bd->border_border_dialog = NULL;
5587 if (bd->border_prop_dialog)
5589 e_object_del(E_OBJECT(bd->border_prop_dialog));
5590 bd->border_prop_dialog = NULL;
5593 e_int_border_menu_del(bd);
5598 focus_next = eina_list_remove(focus_next, bd);
5600 if ((focused == bd) ||
5601 (e_grabinput_last_focus_win_get() == bd->client.win))
5603 if ((!focus_next) && (!focusing))
5605 e_grabinput_focus(bd->zone->container->bg_win,
5606 E_FOCUS_METHOD_PASSIVE);
5607 e_hints_active_window_set(bd->zone->container->manager, NULL);
5612 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5618 bd->remember = NULL;
5619 e_remember_unuse(rem);
5621 if (!bd->already_unparented)
5623 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5624 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5625 ecore_x_window_save_set_del(bd->client.win);
5626 bd->already_unparented = 1;
5628 if (bd->group) eina_list_free(bd->group);
5629 if (bd->transients) eina_list_free(bd->transients);
5630 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5631 if (bd->client.netwm.icons)
5634 for (i = 0; i < bd->client.netwm.num_icons; i++)
5635 free(bd->client.netwm.icons[i].data);
5636 free(bd->client.netwm.icons);
5638 if (bd->client.netwm.extra_types)
5639 free(bd->client.netwm.extra_types);
5640 if (bd->client.border.name)
5641 eina_stringshare_del(bd->client.border.name);
5643 eina_stringshare_del(bd->bordername);
5644 if (bd->client.icccm.name)
5645 eina_stringshare_del(bd->client.icccm.name);
5646 if (bd->client.icccm.class)
5648 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5649 e_bindings_mapping_change_enable(EINA_TRUE);
5650 eina_stringshare_del(bd->client.icccm.class);
5652 if (bd->client.icccm.title)
5653 eina_stringshare_del(bd->client.icccm.title);
5654 if (bd->client.icccm.icon_name)
5655 eina_stringshare_del(bd->client.icccm.icon_name);
5656 if (bd->client.icccm.machine)
5657 eina_stringshare_del(bd->client.icccm.machine);
5658 if (bd->client.icccm.window_role)
5659 eina_stringshare_del(bd->client.icccm.window_role);
5661 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5665 for (i = 0; i < bd->client.icccm.command.argc; i++)
5666 free(bd->client.icccm.command.argv[i]);
5667 free(bd->client.icccm.command.argv);
5669 if (bd->client.netwm.name)
5670 eina_stringshare_del(bd->client.netwm.name);
5671 if (bd->client.netwm.icon_name)
5672 eina_stringshare_del(bd->client.netwm.icon_name);
5673 e_object_del(E_OBJECT(bd->shape));
5674 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5675 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5676 if (bd->icon_object) evas_object_del(bd->icon_object);
5677 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5678 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5680 if (str) eina_stringshare_del(str);
5682 bd->client.e.state.profiles = NULL;
5683 if (bd->client.e.state.profile)
5684 eina_stringshare_del(bd->client.e.state.profile);
5685 bd->client.e.state.profile = NULL;
5687 #ifdef _F_ZONE_WINDOW_ROTATION_
5688 if (e_config->wm_win_rotation)
5690 bd->client.e.fetch.rot.app_set = 0;
5691 bd->client.e.state.rot.preferred_rot = -1;
5693 if (bd->client.e.state.rot.available_rots)
5694 E_FREE(bd->client.e.state.rot.available_rots);
5696 _e_border_rotation_list_remove(bd);
5697 if ((rot.vkbd) && (rot.vkbd == bd))
5699 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5701 if (rot.vkbd_ctrl_win)
5703 ELB(ELBT_BD, "SET KBD_OFF", 0);
5704 ecore_x_e_virtual_keyboard_state_set
5705 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5708 rot.vkbd_hide_prepare_done = EINA_FALSE;
5709 if (rot.vkbd_hide_prepare_timer)
5710 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5711 rot.vkbd_hide_prepare_timer = NULL;
5712 if (rot.vkbd_hide_timer)
5713 ecore_timer_del(rot.vkbd_hide_timer);
5714 rot.vkbd_hide_timer = NULL;
5716 rot.vkbd_show_prepare_done = EINA_FALSE;
5717 if (rot.vkbd_show_prepare_timer)
5718 ecore_timer_del(rot.vkbd_show_prepare_timer);
5719 rot.vkbd_show_prepare_timer = NULL;
5720 if (rot.vkbd_show_timer)
5721 ecore_timer_del(rot.vkbd_show_timer);
5722 rot.vkbd_show_timer = NULL;
5724 else if ((rot.vkbd_prediction) &&
5725 (rot.vkbd_prediction == bd))
5726 rot.vkbd_prediction = NULL;
5729 #ifdef _F_DEICONIFY_APPROVE_
5730 if (bd->client.e.state.deiconify_approve.pending_job)
5732 ecore_job_del(bd->client.e.state.deiconify_approve.pending_job);
5733 bd->client.e.state.deiconify_approve.pending_job = NULL;
5736 evas_object_del(bd->bg_object);
5737 e_canvas_del(bd->bg_ecore_evas);
5738 ecore_evas_free(bd->bg_ecore_evas);
5739 ecore_x_window_free(bd->client.shell_win);
5740 e_focus_setdown(bd);
5741 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5742 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5743 ecore_x_window_free(bd->win);
5745 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5746 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5747 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5748 borders = eina_list_remove(borders, bd);
5749 focus_stack = eina_list_remove(focus_stack, bd);
5750 raise_stack = eina_list_remove(raise_stack, bd);
5752 e_container_border_remove(bd);
5758 _e_border_del_dangling_ref_check(void *data)
5764 printf("EEK EEK border still around 1 second after being deleted!\n");
5765 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5766 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5767 bd->client.icccm.name, bd->client.icccm.class);
5768 // e_object_breadcrumb_debug(E_OBJECT(bd));
5775 _e_border_del(E_Border *bd)
5777 E_Event_Border_Remove *ev;
5780 #ifdef _F_BORDER_HOOK_PATCH_
5781 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5792 focus_next = eina_list_remove(focus_next, bd);
5794 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5796 if ((drag_border) && (drag_border->data == bd))
5798 e_object_del(E_OBJECT(drag_border));
5801 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5803 if (bd->border_locks_dialog)
5805 e_object_del(E_OBJECT(bd->border_locks_dialog));
5806 bd->border_locks_dialog = NULL;
5808 if (bd->border_remember_dialog)
5810 e_object_del(E_OBJECT(bd->border_remember_dialog));
5811 bd->border_remember_dialog = NULL;
5813 if (bd->border_border_dialog)
5815 e_object_del(E_OBJECT(bd->border_border_dialog));
5816 bd->border_border_dialog = NULL;
5818 if (bd->border_prop_dialog)
5820 e_object_del(E_OBJECT(bd->border_prop_dialog));
5821 bd->border_prop_dialog = NULL;
5824 e_int_border_menu_del(bd);
5826 if (bd->raise_timer)
5828 ecore_timer_del(bd->raise_timer);
5829 bd->raise_timer = NULL;
5831 if (!bd->already_unparented)
5833 ecore_x_window_reparent(bd->client.win,
5834 bd->zone->container->manager->root,
5835 bd->x + bd->client_inset.l,
5836 bd->y + bd->client_inset.t);
5837 ecore_x_window_save_set_del(bd->client.win);
5838 bd->already_unparented = 1;
5839 // bd->client.win = 0;
5841 bd->already_unparented = 1;
5843 if ((!bd->new_client) && (!stopping))
5845 ev = E_NEW(E_Event_Border_Remove, 1);
5847 e_object_ref(E_OBJECT(bd));
5848 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5849 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5854 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5855 if (bd->parent->modal == bd)
5857 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5858 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5859 bd->parent->lock_close = 0;
5860 bd->parent->saved.event_mask = 0;
5861 bd->parent->modal = NULL;
5865 EINA_LIST_FREE(bd->transients, child)
5867 child->parent = NULL;
5870 #ifdef _F_DEICONIFY_APPROVE_
5871 bd->client.e.state.deiconify_approve.render_done = 0;
5873 E_Border *ancestor_bd;
5874 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5875 if ((ancestor_bd) &&
5876 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5878 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5879 bd->client.e.state.deiconify_approve.ancestor = NULL;
5881 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5882 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5884 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5886 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5887 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5888 e_border_uniconify(ancestor_bd);
5893 if (bd->client.e.state.deiconify_approve.wait_timer)
5895 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5896 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5899 if (bd->client.e.state.deiconify_approve.req_list)
5901 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5903 child->client.e.state.deiconify_approve.render_done = 0;
5904 child->client.e.state.deiconify_approve.ancestor = NULL;
5909 #ifdef _F_ZONE_WINDOW_ROTATION_
5910 if (rot.list) _e_border_rotation_list_remove(bd);
5914 E_Border_Rotation_Info *info = NULL;
5916 EINA_LIST_FOREACH(rot.async_list, l, info)
5919 rot.async_list = eina_list_remove(rot.async_list, info);
5927 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5928 if (bd->leader->modal == bd)
5929 bd->leader->modal = NULL;
5932 EINA_LIST_FREE(bd->group, child)
5934 child->leader = NULL;
5938 #ifdef PRINT_LOTS_OF_DEBUG
5940 _e_border_print(E_Border *bd,
5949 "\tBorderless: %s\n",
5950 bd, bd->client.icccm.name, bd->client.icccm.title,
5951 bd->borderless ? "TRUE" : "FALSE");
5957 _e_border_cb_window_show_request(void *data __UNUSED__,
5958 int ev_type __UNUSED__,
5963 Ecore_X_Event_Window_Show_Request *e;
5966 bd = e_border_find_by_client_window(e->win);
5967 if (!bd) return ECORE_CALLBACK_PASS_ON;
5969 if ((e_config->wm_win_rotation) &&
5970 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
5972 (rot.vkbd_hide_prepare_timer))
5974 con = bd->zone->container;
5975 bd = e_border_new(con, e->win, 0, 0);
5980 if (!bd->lock_client_iconify)
5981 e_border_uniconify(bd);
5985 /* FIXME: make border "urgent" for a bit - it wants attention */
5986 /* e_border_show(bd); */
5987 if (!bd->lock_client_stacking)
5990 return ECORE_CALLBACK_PASS_ON;
5994 _e_border_cb_window_destroy(void *data __UNUSED__,
5995 int ev_type __UNUSED__,
5999 Ecore_X_Event_Window_Destroy *e;
6002 bd = e_border_find_by_client_window(e->win);
6003 if (!bd) return ECORE_CALLBACK_PASS_ON;
6004 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
6005 #ifdef _F_ZONE_WINDOW_ROTATION_
6006 if (e_config->wm_win_rotation)
6008 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6010 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
6011 if (!rot.vkbd_hide_prepare_timer)
6013 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6014 e_border_hide(bd, 0);
6015 if (!rot.vkbd_hide_prepare_timer)
6017 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6018 e_object_del(E_OBJECT(bd));
6021 return ECORE_CALLBACK_PASS_ON;
6025 e_border_hide(bd, 0);
6026 e_object_del(E_OBJECT(bd));
6027 return ECORE_CALLBACK_PASS_ON;
6031 _e_border_cb_window_hide(void *data __UNUSED__,
6032 int ev_type __UNUSED__,
6035 E_Border *bd = NULL;
6036 Ecore_X_Event_Window_Hide *e;
6039 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
6040 // not interested in hide events from windows other than the window in question
6041 if (e->win != e->event_win)
6043 bd = e_border_find_by_client_window(e->win);
6044 if (!bd) return ECORE_CALLBACK_PASS_ON;
6045 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
6049 (bd->zone->container->manager->root == e->event_win)))
6050 return ECORE_CALLBACK_PASS_ON;
6053 if (!bd) bd = e_border_find_by_client_window(e->win);
6054 // printf(" bd = %p\n", bd);
6057 if (ecore_x_window_visible_get(e->win))
6059 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
6060 ecore_x_window_hide(e->win);
6062 return ECORE_CALLBACK_PASS_ON;
6065 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
6066 if (bd->ignore_first_unmap > 0)
6068 bd->ignore_first_unmap--;
6069 return ECORE_CALLBACK_PASS_ON;
6071 /* Don't delete hidden or iconified windows */
6072 #ifdef _F_USE_EXTENDED_ICONIFY_
6073 if (bd->await_hide_event > 0)
6075 if ((bd->iconic) || (bd->await_hide_event > 0))
6078 // printf(" Don't delete hidden or iconified windows\n");
6079 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6080 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6081 if (bd->await_hide_event > 0)
6083 bd->await_hide_event--;
6087 // printf(" hide really\n");
6088 /* Only hide the border if it is visible */
6089 if (bd->visible) e_border_hide(bd, 1);
6094 // printf(" hide2\n");
6095 #ifdef _F_USE_EXTENDED_ICONIFY_
6103 #ifdef _F_ZONE_WINDOW_ROTATION_
6104 if (e_config->wm_win_rotation)
6106 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6108 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6109 if (!rot.vkbd_hide_prepare_timer)
6111 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6112 e_border_hide(bd, 0);
6113 if (!rot.vkbd_hide_prepare_timer)
6115 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6116 e_object_del(E_OBJECT(bd));
6119 return ECORE_CALLBACK_PASS_ON;
6123 e_border_hide(bd, 0);
6124 e_object_del(E_OBJECT(bd));
6126 return ECORE_CALLBACK_PASS_ON;
6130 _e_border_cb_window_reparent(void *data __UNUSED__,
6131 int ev_type __UNUSED__,
6132 void *ev __UNUSED__)
6136 Ecore_X_Event_Window_Reparent *e;
6139 bd = e_border_find_by_client_window(e->win);
6141 if (e->parent == bd->client.shell_win) return 1;
6142 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6146 e_border_hide(bd, 0);
6147 e_object_del(E_OBJECT(bd));
6149 return ECORE_CALLBACK_PASS_ON;
6153 _e_border_cb_window_configure_request(void *data __UNUSED__,
6154 int ev_type __UNUSED__,
6158 Ecore_X_Event_Window_Configure_Request *e;
6161 bd = e_border_find_by_client_window(e->win);
6164 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6165 if (!e_util_container_window_find(e->win))
6166 ecore_x_window_configure(e->win, e->value_mask,
6167 e->x, e->y, e->w, e->h, e->border,
6168 e->abovewin, e->detail);
6169 return ECORE_CALLBACK_PASS_ON;
6172 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6173 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6179 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6181 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6183 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6184 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6190 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6191 w = e->w + bd->client_inset.l + bd->client_inset.r;
6192 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6193 h = e->h + bd->client_inset.t + bd->client_inset.b;
6194 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6196 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6198 bd->saved.x = x - bd->zone->x;
6199 bd->saved.y = y - bd->zone->y;
6204 e_border_move_resize(bd, x, y, w, h);
6206 else if (!bd->lock_client_location)
6208 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6210 bd->saved.x = x - bd->zone->x;
6211 bd->saved.y = y - bd->zone->y;
6214 e_border_move(bd, x, y);
6216 else if (!bd->lock_client_size)
6218 if ((bd->shaded) || (bd->shading))
6224 if ((bd->shade.dir == E_DIRECTION_UP) ||
6225 (bd->shade.dir == E_DIRECTION_DOWN))
6227 e_border_resize(bd, w, bd->h);
6232 e_border_resize(bd, bd->w, h);
6238 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6244 e_border_resize(bd, w, h);
6250 if (!bd->lock_client_location)
6252 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6254 bd->saved.x = x - bd->zone->x;
6255 bd->saved.y = y - bd->zone->y;
6258 e_border_move(bd, x, y);
6262 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6263 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6269 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6270 w = e->w + bd->client_inset.l + bd->client_inset.r;
6271 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6272 h = e->h + bd->client_inset.t + bd->client_inset.b;
6273 #ifdef _F_ZONE_WINDOW_ROTATION_
6274 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6276 if (!bd->lock_client_size)
6278 if ((bd->shaded) || (bd->shading))
6284 if ((bd->shade.dir == E_DIRECTION_UP) ||
6285 (bd->shade.dir == E_DIRECTION_DOWN))
6287 e_border_resize(bd, w, bd->h);
6292 e_border_resize(bd, bd->w, h);
6298 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6303 zx = zy = zw = zh = 0;
6306 * This code does resize and move a window on a
6307 * X configure request into an useful geometry.
6308 * This is really useful for size jumping file dialogs.
6313 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6315 if (e_config->geometry_auto_resize_limit == 1)
6324 e_border_resize(bd, w, h);
6326 if (e_config->geometry_auto_move == 1)
6328 /* z{x,y,w,h} are only set here; FIXME! */
6331 // move window horizontal if resize to not useful geometry
6332 if (bd->x + bd->w > zx + zw)
6333 rx = zx + zw - bd->w;
6334 else if (bd->x < zx)
6337 // move window vertical if resize to not useful geometry
6338 if (bd->y + bd->h > zy + zh)
6339 ry = zy + zh - bd->h;
6340 else if (bd->y < zy)
6343 e_border_move(bd, rx, ry);
6349 if (!bd->lock_client_stacking)
6351 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6352 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6356 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6358 obd = e_border_find_by_client_window(e->abovewin);
6361 e_border_stack_above(bd, obd);
6365 ecore_x_window_configure(bd->win,
6366 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6367 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6369 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6370 /* FIXME: need to rebuiuld border list from current stacking */
6373 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6375 obd = e_border_find_by_client_window(e->abovewin);
6378 e_border_stack_below(bd, obd);
6382 ecore_x_window_configure(bd->win,
6383 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6384 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6386 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6387 /* FIXME: need to rebuiuld border list from current stacking */
6390 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6394 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6398 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6403 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6405 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6409 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6413 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6417 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6421 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6428 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6429 _e_border_client_move_resize_send(bd);
6430 return ECORE_CALLBACK_PASS_ON;
6434 _e_border_cb_window_resize_request(void *data __UNUSED__,
6435 int ev_type __UNUSED__,
6439 Ecore_X_Event_Window_Resize_Request *e;
6442 bd = e_border_find_by_client_window(e->win);
6445 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6446 ecore_x_window_resize(e->win, e->w, e->h);
6447 return ECORE_CALLBACK_PASS_ON;
6452 w = e->w + bd->client_inset.l + bd->client_inset.r;
6453 h = e->h + bd->client_inset.t + bd->client_inset.b;
6454 if ((bd->shaded) || (bd->shading))
6460 if ((bd->shade.dir == E_DIRECTION_UP) ||
6461 (bd->shade.dir == E_DIRECTION_DOWN))
6463 e_border_resize(bd, w, bd->h);
6468 e_border_resize(bd, bd->w, h);
6473 e_border_resize(bd, w, h);
6476 _e_border_client_move_resize_send(bd);
6477 return ECORE_CALLBACK_PASS_ON;
6481 _e_border_cb_window_gravity(void *data __UNUSED__,
6482 int ev_type __UNUSED__,
6483 void *ev __UNUSED__)
6486 // Ecore_X_Event_Window_Gravity *e;
6489 // bd = e_border_find_by_client_window(e->win);
6490 // if (!bd) return 1;
6495 _e_border_cb_window_stack_request(void *data __UNUSED__,
6496 int ev_type __UNUSED__,
6500 Ecore_X_Event_Window_Stack_Request *e;
6503 bd = e_border_find_by_client_window(e->win);
6506 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6507 if (!e_util_container_window_find(e->win))
6509 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6510 ecore_x_window_raise(e->win);
6511 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6512 ecore_x_window_lower(e->win);
6514 return ECORE_CALLBACK_PASS_ON;
6516 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6518 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6520 return ECORE_CALLBACK_PASS_ON;
6524 _e_border_cb_window_property(void *data __UNUSED__,
6525 int ev_type __UNUSED__,
6529 Ecore_X_Event_Window_Property *e;
6532 bd = e_border_find_by_client_window(e->win);
6533 if (!bd) return ECORE_CALLBACK_PASS_ON;
6534 if (e->atom == ECORE_X_ATOM_WM_NAME)
6536 if ((!bd->client.netwm.name) &&
6537 (!bd->client.netwm.fetch.name))
6539 bd->client.icccm.fetch.title = 1;
6543 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6545 bd->client.netwm.fetch.name = 1;
6548 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6550 bd->client.icccm.fetch.name_class = 1;
6553 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6555 if ((!bd->client.netwm.icon_name) &&
6556 (!bd->client.netwm.fetch.icon_name))
6558 bd->client.icccm.fetch.icon_name = 1;
6562 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6564 bd->client.netwm.fetch.icon_name = 1;
6567 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6569 bd->client.icccm.fetch.machine = 1;
6572 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6574 bd->client.icccm.fetch.protocol = 1;
6577 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6579 bd->client.icccm.fetch.hints = 1;
6582 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6584 bd->client.icccm.fetch.size_pos_hints = 1;
6587 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6590 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6591 (!bd->client.netwm.fetch.type))
6594 bd->client.mwm.fetch.hints = 1;
6600 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6602 bd->client.icccm.fetch.transient_for = 1;
6605 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6607 bd->client.icccm.fetch.client_leader = 1;
6610 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6612 bd->client.icccm.fetch.window_role = 1;
6615 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6617 bd->client.netwm.fetch.icon = 1;
6620 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6622 bd->client.qtopia.fetch.soft_menu = 1;
6625 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6627 bd->client.qtopia.fetch.soft_menus = 1;
6630 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6632 bd->client.vkbd.fetch.state = 1;
6635 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6637 bd->client.vkbd.fetch.vkbd = 1;
6640 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6642 bd->client.illume.conformant.fetch.conformant = 1;
6645 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6647 bd->client.illume.quickpanel.fetch.state = 1;
6650 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6652 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6655 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6657 bd->client.illume.quickpanel.fetch.priority.major = 1;
6660 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6662 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6665 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6667 bd->client.illume.quickpanel.fetch.zone = 1;
6670 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6672 bd->client.illume.drag.fetch.locked = 1;
6675 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6677 bd->client.illume.drag.fetch.drag = 1;
6680 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6682 bd->client.illume.win_state.fetch.state = 1;
6686 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6688 bd->client.netwm.fetch.user_time = 1;
6691 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6693 bd->client.netwm.fetch.strut = 1;
6696 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6698 bd->client.netwm.fetch.strut = 1;
6702 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6704 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6706 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6708 bd->client.e.fetch.video_position = 1;
6711 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6713 bd->client.e.fetch.video_parent = 1;
6716 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6718 bd->client.netwm.fetch.state = 1;
6721 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6722 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6724 bd->client.e.fetch.profile_list = 1;
6728 #ifdef _F_ZONE_WINDOW_ROTATION_
6729 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6731 if (e_config->wm_win_rotation)
6733 bd->client.e.fetch.rot.support = 1;
6737 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6738 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6739 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6740 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6742 if (e_config->wm_win_rotation)
6744 bd->client.e.fetch.rot.geom_hint = 1;
6748 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6750 if (e_config->wm_win_rotation)
6752 bd->client.e.fetch.rot.app_set = 1;
6756 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6758 if (e_config->wm_win_rotation)
6760 bd->client.e.fetch.rot.preferred_rot = 1;
6764 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6766 if (e_config->wm_win_rotation)
6768 bd->client.e.fetch.rot.available_rots = 1;
6774 return ECORE_CALLBACK_PASS_ON;
6778 _e_border_cb_window_colormap(void *data __UNUSED__,
6779 int ev_type __UNUSED__,
6783 Ecore_X_Event_Window_Colormap *e;
6786 bd = e_border_find_by_client_window(e->win);
6787 if (!bd) return ECORE_CALLBACK_PASS_ON;
6788 return ECORE_CALLBACK_PASS_ON;
6792 _e_border_cb_window_shape(void *data __UNUSED__,
6793 int ev_type __UNUSED__,
6797 Ecore_X_Event_Window_Shape *e;
6800 bd = e_border_find_by_client_window(e->win);
6802 if (e->type == ECORE_X_SHAPE_INPUT)
6806 bd->need_shape_merge = 1;
6807 // YYY bd->shaped_input = 1;
6808 bd->changes.shape_input = 1;
6812 return ECORE_CALLBACK_PASS_ON;
6817 bd->changes.shape = 1;
6819 return ECORE_CALLBACK_PASS_ON;
6821 bd = e_border_find_by_window(e->win);
6824 bd->need_shape_export = 1;
6826 return ECORE_CALLBACK_PASS_ON;
6828 bd = e_border_find_by_frame_window(e->win);
6831 bd->need_shape_merge = 1;
6833 return ECORE_CALLBACK_PASS_ON;
6835 return ECORE_CALLBACK_PASS_ON;
6839 _e_border_cb_window_focus_in(void *data __UNUSED__,
6840 int ev_type __UNUSED__,
6844 Ecore_X_Event_Window_Focus_In *e;
6847 bd = e_border_find_by_client_window(e->win);
6848 if (!bd) return ECORE_CALLBACK_PASS_ON;
6849 #ifdef INOUTDEBUG_FOCUS
6854 const char *modes[] = {
6856 "MODE_WHILE_GRABBED",
6860 const char *details[] = {
6864 "DETAIL_NON_LINEAR",
6865 "DETAIL_NON_LINEAR_VIRTUAL",
6867 "DETAIL_POINTER_ROOT",
6868 "DETAIL_DETAIL_NONE"
6872 ct[strlen(ct) - 1] = 0;
6873 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6878 details[e->detail]);
6880 DBG("%s cb focus in %d %d\n",
6881 e_border_name_get(bd),
6882 bd->client.icccm.accepts_focus,
6883 bd->client.icccm.take_focus);
6886 _e_border_pri_raise(bd);
6887 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6889 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6891 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6893 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6896 /* ignore focus in from !take_focus windows, we just gave it em */
6897 /* if (!bd->client.icccm.take_focus)
6898 * return ECORE_CALLBACK_PASS_ON; */
6900 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6901 if (e->time >= focus_time)
6902 e_border_focus_set(bd, 1, 0);
6903 return ECORE_CALLBACK_PASS_ON;
6907 _e_border_cb_window_focus_out(void *data __UNUSED__,
6908 int ev_type __UNUSED__,
6912 Ecore_X_Event_Window_Focus_Out *e;
6915 bd = e_border_find_by_client_window(e->win);
6916 if (!bd) return ECORE_CALLBACK_PASS_ON;
6917 #ifdef INOUTDEBUG_FOCUS
6922 const char *modes[] = {
6924 "MODE_WHILE_GRABBED",
6928 const char *details[] = {
6932 "DETAIL_NON_LINEAR",
6933 "DETAIL_NON_LINEAR_VIRTUAL",
6935 "DETAIL_POINTER_ROOT",
6936 "DETAIL_DETAIL_NONE"
6940 ct[strlen(ct) - 1] = 0;
6941 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6946 details[e->detail]);
6948 DBG("%s cb focus out %d %d",
6949 e_border_name_get(bd),
6950 bd->client.icccm.accepts_focus,
6951 bd->client.icccm.take_focus);
6954 _e_border_pri_norm(bd);
6955 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6957 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6958 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6959 return ECORE_CALLBACK_PASS_ON;
6960 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6961 return ECORE_CALLBACK_PASS_ON;
6963 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6965 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6966 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6967 return ECORE_CALLBACK_PASS_ON;
6968 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6969 return ECORE_CALLBACK_PASS_ON;
6970 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6971 return ECORE_CALLBACK_PASS_ON;
6972 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6973 return ECORE_CALLBACK_PASS_ON;
6975 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6977 /* for firefox/thunderbird (xul) menu walking */
6978 /* NB: why did i disable this before? */
6979 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6980 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6981 return ECORE_CALLBACK_PASS_ON;
6983 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6985 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6986 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6987 return ECORE_CALLBACK_PASS_ON;
6989 e_border_focus_set(bd, 0, 0);
6990 return ECORE_CALLBACK_PASS_ON;
6993 #if _F_BORDER_CLIP_TO_ZONE_
6995 _e_border_shape_input_clip_to_zone(E_Border *bd)
6997 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
7001 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
7002 bd->zone->w, bd->zone->h,
7003 bd->x, bd->y, bd->w, bd->h)))
7006 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
7007 E_RECTS_CLIP_TO_RECT(x, y, w, h,
7008 bd->zone->x, bd->zone->y,
7009 bd->zone->w, bd->zone->h);
7012 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
7013 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
7017 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
7018 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
7021 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
7024 _e_border_cb_client_message(void *data __UNUSED__,
7025 int ev_type __UNUSED__,
7028 Ecore_X_Event_Client_Message *e;
7032 #ifdef _F_DEICONIFY_APPROVE_
7033 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
7035 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
7037 bd = e_border_find_by_client_window(e->win);
7040 if (bd->client.e.state.deiconify_approve.support)
7042 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
7043 bd->client.e.state.deiconify_approve.render_done = 1;
7045 E_Border *ancestor_bd;
7046 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
7049 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
7050 bd->client.e.state.deiconify_approve.ancestor = NULL;
7057 ELBF(ELBT_BD, 0, bd->client.win,
7058 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
7060 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
7061 (ancestor_bd->client.e.state.deiconify_approve.render_done))
7063 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
7065 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
7066 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
7067 e_border_uniconify(ancestor_bd);
7071 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
7072 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7077 return ECORE_CALLBACK_PASS_ON;
7081 #ifdef _F_ZONE_WINDOW_ROTATION_
7082 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7084 bd = e_border_find_by_client_window(e->win);
7087 if (e_config->wm_win_rotation)
7089 Ecore_X_Event_Client_Message *msg = NULL;
7090 Ecore_X_Atom t = e->message_type;
7091 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7092 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7093 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7094 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7096 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7097 if (!msg) return ECORE_CALLBACK_PASS_ON;
7100 msg->message_type = e->message_type;
7101 msg->data.l[0] = e->data.l[0];
7102 msg->data.l[1] = e->data.l[1];
7103 msg->data.l[2] = e->data.l[2];
7104 msg->data.l[3] = e->data.l[3];
7105 msg->data.l[4] = e->data.l[4];
7106 rot.msgs = eina_list_append(rot.msgs, msg);
7108 rot.fetch = EINA_TRUE;
7111 return ECORE_CALLBACK_PASS_ON;
7114 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7116 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7117 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7119 if (e_config->wm_win_rotation)
7121 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7123 _e_border_rotation_list_remove(bd);
7125 if (bd->client.e.state.rot.pending_show)
7127 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7129 bd->client.e.state.rot.pending_show = 0;
7136 return ECORE_CALLBACK_PASS_ON;
7140 _e_border_cb_window_state_request(void *data __UNUSED__,
7141 int ev_type __UNUSED__,
7145 Ecore_X_Event_Window_State_Request *e;
7149 bd = e_border_find_by_client_window(e->win);
7150 if (!bd) return ECORE_CALLBACK_PASS_ON;
7152 for (i = 0; i < 2; i++)
7153 e_hints_window_state_update(bd, e->state[i], e->action);
7155 return ECORE_CALLBACK_PASS_ON;
7159 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7160 int ev_type __UNUSED__,
7164 Ecore_X_Event_Window_Move_Resize_Request *e;
7167 bd = e_border_find_by_client_window(e->win);
7168 if (!bd) return ECORE_CALLBACK_PASS_ON;
7170 if ((bd->shaded) || (bd->shading) ||
7171 (bd->fullscreen) || (bd->moving) ||
7172 (bd->resize_mode != RESIZE_NONE))
7173 return ECORE_CALLBACK_PASS_ON;
7175 if ((e->button >= 1) && (e->button <= 3))
7177 bd->mouse.last_down[e->button - 1].mx = e->x;
7178 bd->mouse.last_down[e->button - 1].my = e->y;
7179 bd->mouse.last_down[e->button - 1].x = bd->x;
7180 bd->mouse.last_down[e->button - 1].y = bd->y;
7181 bd->mouse.last_down[e->button - 1].w = bd->w;
7182 bd->mouse.last_down[e->button - 1].h = bd->h;
7186 bd->moveinfo.down.x = bd->x;
7187 bd->moveinfo.down.y = bd->y;
7188 bd->moveinfo.down.w = bd->w;
7189 bd->moveinfo.down.h = bd->h;
7191 bd->mouse.current.mx = e->x;
7192 bd->mouse.current.my = e->y;
7193 bd->moveinfo.down.button = e->button;
7194 bd->moveinfo.down.mx = e->x;
7195 bd->moveinfo.down.my = e->y;
7198 if (!bd->lock_user_stacking)
7201 if (e->direction == MOVE)
7203 bd->cur_mouse_action = e_action_find("window_move");
7204 if (bd->cur_mouse_action)
7206 if ((!bd->cur_mouse_action->func.end_mouse) &&
7207 (!bd->cur_mouse_action->func.end))
7208 bd->cur_mouse_action = NULL;
7209 if (bd->cur_mouse_action)
7211 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7212 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7215 return ECORE_CALLBACK_PASS_ON;
7218 if (!_e_border_resize_begin(bd))
7219 return ECORE_CALLBACK_PASS_ON;
7221 switch (e->direction)
7224 bd->resize_mode = RESIZE_TL;
7225 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7229 bd->resize_mode = RESIZE_T;
7230 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7234 bd->resize_mode = RESIZE_TR;
7235 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7239 bd->resize_mode = RESIZE_R;
7240 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7244 bd->resize_mode = RESIZE_BR;
7245 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7249 bd->resize_mode = RESIZE_B;
7250 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7254 bd->resize_mode = RESIZE_BL;
7255 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7259 bd->resize_mode = RESIZE_L;
7260 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7264 return ECORE_CALLBACK_PASS_ON;
7267 bd->cur_mouse_action = e_action_find("window_resize");
7268 if (bd->cur_mouse_action)
7270 if ((!bd->cur_mouse_action->func.end_mouse) &&
7271 (!bd->cur_mouse_action->func.end))
7272 bd->cur_mouse_action = NULL;
7274 if (bd->cur_mouse_action)
7275 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7277 return ECORE_CALLBACK_PASS_ON;
7281 _e_border_cb_desktop_change(void *data __UNUSED__,
7282 int ev_type __UNUSED__,
7286 Ecore_X_Event_Desktop_Change *e;
7289 bd = e_border_find_by_client_window(e->win);
7292 if (e->desk == 0xffffffff)
7294 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7298 desk = e_desk_at_pos_get(bd->zone, e->desk);
7300 e_border_desk_set(bd, desk);
7305 ecore_x_netwm_desktop_set(e->win, e->desk);
7307 return ECORE_CALLBACK_PASS_ON;
7311 _e_border_cb_sync_alarm(void *data __UNUSED__,
7312 int ev_type __UNUSED__,
7316 Ecore_X_Event_Sync_Alarm *e;
7317 unsigned int serial;
7320 bd = e_border_find_by_alarm(e->alarm);
7321 if (!bd) return ECORE_CALLBACK_PASS_ON;
7323 if (bd->client.netwm.sync.wait)
7324 bd->client.netwm.sync.wait--;
7326 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7328 E_Border_Pending_Move_Resize *pnd = NULL;
7330 /* skip pending for which we didn't get a reply */
7331 while (bd->pending_move_resize)
7333 pnd = bd->pending_move_resize->data;
7334 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7336 if (serial == pnd->serial)
7348 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7349 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7354 bd->changes.size = 1;
7355 bd->changes.pos = 1;
7358 evas_render(bd->bg_evas);
7360 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7361 &bd->mouse.current.mx,
7362 &bd->mouse.current.my);
7364 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7365 _e_border_resize_handle(bd);
7367 return ECORE_CALLBACK_PASS_ON;
7371 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7372 int ev_type __UNUSED__,
7373 void *ev __UNUSED__)
7378 /* mark all borders for desktop/icon updates */
7379 EINA_LIST_FOREACH(borders, l, bd)
7383 efreet_desktop_free(bd->desktop);
7386 bd->changes.icon = 1;
7390 e_init_status_set(_("Desktop files scan done"));
7393 return ECORE_CALLBACK_PASS_ON;
7397 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7398 int ev_type __UNUSED__,
7399 void *ev __UNUSED__)
7404 /* mark all borders for desktop/icon updates */
7405 EINA_LIST_FOREACH(borders, l, bd)
7407 bd->changes.icon = 1;
7410 return ECORE_CALLBACK_PASS_ON;
7414 _e_border_cb_pointer_warp(void *data __UNUSED__,
7415 int ev_type __UNUSED__,
7418 E_Event_Pointer_Warp *e;
7421 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7422 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7423 return ECORE_CALLBACK_PASS_ON;
7427 _e_border_cb_signal_bind(void *data,
7428 Evas_Object *obj __UNUSED__,
7429 const char *emission,
7435 if (e_dnd_active()) return;
7436 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7441 _e_border_cb_mouse_in(void *data,
7442 int type __UNUSED__,
7445 Ecore_X_Event_Mouse_In *ev;
7450 #ifdef INOUTDEBUG_MOUSE
7455 const char *modes[] = {
7457 "MODE_WHILE_GRABBED",
7461 const char *details[] = {
7465 "DETAIL_NON_LINEAR",
7466 "DETAIL_NON_LINEAR_VIRTUAL",
7468 "DETAIL_POINTER_ROOT",
7469 "DETAIL_DETAIL_NONE"
7473 ct[strlen(ct) - 1] = 0;
7474 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7475 ev->win, ev->event_win,
7478 details[ev->detail]);
7481 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7482 if (ev->event_win == bd->win)
7484 e_focus_event_mouse_in(bd);
7487 if ((ev->win != bd->win) &&
7488 (ev->win != bd->event_win) &&
7489 (ev->event_win != bd->win) &&
7490 (ev->event_win != bd->event_win))
7491 return ECORE_CALLBACK_PASS_ON;
7493 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7495 bd->mouse.current.mx = ev->root.x;
7496 bd->mouse.current.my = ev->root.y;
7497 if (!bd->bg_evas_in)
7499 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7500 bd->bg_evas_in = EINA_TRUE;
7502 return ECORE_CALLBACK_PASS_ON;
7506 _e_border_cb_mouse_out(void *data,
7507 int type __UNUSED__,
7510 Ecore_X_Event_Mouse_Out *ev;
7515 #ifdef INOUTDEBUG_MOUSE
7520 const char *modes[] = {
7522 "MODE_WHILE_GRABBED",
7526 const char *details[] = {
7530 "DETAIL_NON_LINEAR",
7531 "DETAIL_NON_LINEAR_VIRTUAL",
7533 "DETAIL_POINTER_ROOT",
7534 "DETAIL_DETAIL_NONE"
7538 ct[strlen(ct) - 1] = 0;
7539 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7540 ev->win, ev->event_win,
7543 details[ev->detail]);
7546 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7547 if (ev->event_win == bd->win)
7550 return ECORE_CALLBACK_PASS_ON;
7551 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7552 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7553 return ECORE_CALLBACK_PASS_ON;
7554 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7555 return ECORE_CALLBACK_PASS_ON;
7556 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7557 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7558 return ECORE_CALLBACK_PASS_ON;
7559 e_focus_event_mouse_out(bd);
7562 if ((ev->win != bd->win) &&
7563 (ev->win != bd->event_win) &&
7564 (ev->event_win != bd->win) &&
7565 (ev->event_win != bd->event_win))
7566 return ECORE_CALLBACK_PASS_ON;
7568 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7570 bd->mouse.current.mx = ev->root.x;
7571 bd->mouse.current.my = ev->root.y;
7574 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7575 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7576 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7578 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7579 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7580 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7581 bd->bg_evas_in = EINA_FALSE;
7584 return ECORE_CALLBACK_PASS_ON;
7588 _e_border_cb_mouse_wheel(void *data,
7589 int type __UNUSED__,
7592 Ecore_Event_Mouse_Wheel *ev;
7597 if ((ev->event_window == bd->win) ||
7598 (ev->event_window == bd->event_win))
7600 bd->mouse.current.mx = ev->root.x;
7601 bd->mouse.current.my = ev->root.y;
7602 if (!bd->cur_mouse_action)
7603 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7606 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7607 return ECORE_CALLBACK_PASS_ON;
7611 _e_border_cb_mouse_down(void *data,
7612 int type __UNUSED__,
7615 Ecore_Event_Mouse_Button *ev;
7620 if ((ev->event_window == bd->win) ||
7621 (ev->event_window == bd->event_win))
7623 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7625 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7626 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7627 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7628 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7629 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7630 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7634 bd->moveinfo.down.x = bd->x + bd->fx.x;
7635 bd->moveinfo.down.y = bd->y + bd->fx.y;
7636 bd->moveinfo.down.w = bd->w;
7637 bd->moveinfo.down.h = bd->h;
7639 bd->mouse.current.mx = ev->root.x;
7640 bd->mouse.current.my = ev->root.y;
7641 if (!bd->cur_mouse_action)
7643 bd->cur_mouse_action =
7644 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7646 if (bd->cur_mouse_action)
7648 if ((!bd->cur_mouse_action->func.end_mouse) &&
7649 (!bd->cur_mouse_action->func.end))
7650 bd->cur_mouse_action = NULL;
7651 if (bd->cur_mouse_action)
7652 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7655 e_focus_event_mouse_down(bd);
7657 if (ev->window != ev->event_window)
7661 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7665 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7667 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7668 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7669 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7670 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7671 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7672 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7676 bd->moveinfo.down.x = bd->x + bd->fx.x;
7677 bd->moveinfo.down.y = bd->y + bd->fx.y;
7678 bd->moveinfo.down.w = bd->w;
7679 bd->moveinfo.down.h = bd->h;
7681 bd->mouse.current.mx = ev->root.x;
7682 bd->mouse.current.my = ev->root.y;
7687 else if (bd->resize_mode != RESIZE_NONE)
7693 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7695 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7696 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7697 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7699 return ECORE_CALLBACK_PASS_ON;
7703 _e_border_cb_mouse_up(void *data,
7704 int type __UNUSED__,
7707 Ecore_Event_Mouse_Button *ev;
7712 if ((ev->event_window == bd->win) ||
7713 (ev->event_window == bd->event_win))
7715 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7717 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7718 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7719 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7720 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7722 bd->mouse.current.mx = ev->root.x;
7723 bd->mouse.current.my = ev->root.y;
7724 /* also we dont pass the same params that went in - then again that */
7725 /* should be ok as we are just ending the action if it has an end */
7726 if (bd->cur_mouse_action)
7728 if (bd->cur_mouse_action->func.end_mouse)
7729 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7730 else if (bd->cur_mouse_action->func.end)
7731 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7732 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7733 bd->cur_mouse_action = NULL;
7737 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7738 e_focus_event_mouse_up(bd);
7741 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7742 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7744 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7745 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7746 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7747 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7749 bd->mouse.current.mx = ev->root.x;
7750 bd->mouse.current.my = ev->root.y;
7754 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7755 return ECORE_CALLBACK_PASS_ON;
7759 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7761 #ifdef _F_BORDER_CLIP_TO_ZONE_
7762 int new_x_max, new_y_max;
7763 int new_x_min, new_y_min;
7764 int margin_x, margin_y;
7766 margin_x = bd->w - 100;
7767 margin_y = bd->h - 100;
7769 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7770 new_x_min = bd->zone->x - margin_x;
7771 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7772 new_y_min = bd->zone->y - margin_y;
7774 if (x >= new_x_max) *new_x = new_x_max;
7775 else if (x <= new_x_min) *new_x = new_x_min;
7777 if (y >= new_y_max) *new_y = new_y_max;
7778 else if (y <= new_y_min) *new_y = new_y_min;
7783 _e_border_cb_mouse_move(void *data,
7784 int type __UNUSED__,
7787 Ecore_Event_Mouse_Move *ev;
7792 if ((ev->window != bd->event_win) &&
7793 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7794 bd->mouse.current.mx = ev->root.x;
7795 bd->mouse.current.my = ev->root.y;
7798 int x, y, new_x, new_y;
7800 Eina_List *skiplist = NULL;
7802 // FIXME: remove? sync what for when only moving?
7803 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7804 bd->client.netwm.sync.wait = 0;
7805 if ((bd->client.netwm.sync.request) &&
7806 (bd->client.netwm.sync.alarm) &&
7807 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7809 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7811 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7812 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7813 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7814 (bd->mouse.current.my - bd->moveinfo.down.my);
7818 x = bd->moveinfo.down.x +
7819 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7820 y = bd->moveinfo.down.y +
7821 (bd->mouse.current.my - bd->moveinfo.down.my);
7826 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7827 skiplist = eina_list_append(skiplist, bd);
7828 e_resist_container_border_position(bd->zone->container, skiplist,
7829 bd->x, bd->y, bd->w, bd->h,
7831 &new_x, &new_y, &new_w, &new_h);
7832 eina_list_free(skiplist);
7834 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7836 /* if (e_config->window_out_of_vscreen_limits_partly) */
7838 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7841 skiplist = eina_list_append(skiplist, bd);
7842 e_resist_container_border_position(bd->zone->container, skiplist,
7843 bd->x, bd->y, bd->w, bd->h,
7845 &new_x, &new_y, &new_w, &new_h);
7846 eina_list_free(skiplist);
7849 bd->shelf_fix.x = 0;
7850 bd->shelf_fix.y = 0;
7851 bd->shelf_fix.modified = 0;
7852 e_border_move(bd, new_x, new_y);
7853 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7855 else if (bd->resize_mode != RESIZE_NONE)
7857 if ((bd->client.netwm.sync.request) &&
7858 (bd->client.netwm.sync.alarm))
7860 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7862 E_Border_Pending_Move_Resize *pnd;
7864 if (bd->pending_move_resize)
7866 bd->changes.pos = 1;
7867 bd->changes.size = 1;
7869 _e_border_client_move_resize_send(bd);
7871 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7874 bd->client.netwm.sync.wait = 0;
7876 /* sync.wait is incremented when resize_handle sends
7877 * sync-request and decremented by sync-alarm cb. so
7878 * we resize here either on initial resize, timeout or
7879 * when no new resize-request was added by sync-alarm cb.
7881 if (!bd->client.netwm.sync.wait)
7882 _e_border_resize_handle(bd);
7885 _e_border_resize_handle(bd);
7891 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7893 bd->drag.x = ev->root.x;
7894 bd->drag.y = ev->root.y;
7900 dx = bd->drag.x - ev->root.x;
7901 dy = bd->drag.y - ev->root.y;
7902 if (((dx * dx) + (dy * dy)) >
7903 (e_config->drag_resist * e_config->drag_resist))
7906 if (bd->icon_object)
7908 Evas_Object *o = NULL;
7909 Evas_Coord x, y, w, h;
7910 const char *drag_types[] = { "enlightenment/border" };
7912 e_object_ref(E_OBJECT(bd));
7913 evas_object_geometry_get(bd->icon_object,
7915 drag_border = e_drag_new(bd->zone->container,
7916 bd->x + bd->fx.x + x,
7917 bd->y + bd->fx.y + y,
7918 drag_types, 1, bd, -1,
7920 _e_border_cb_drag_finished);
7921 o = e_border_icon_add(bd, drag_border->evas);
7924 /* FIXME: fallback icon for drag */
7925 o = evas_object_rectangle_add(drag_border->evas);
7926 evas_object_color_set(o, 255, 255, 255, 255);
7928 e_drag_object_set(drag_border, o);
7930 e_drag_resize(drag_border, w, h);
7931 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7937 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7939 return ECORE_CALLBACK_PASS_ON;
7943 _e_border_cb_grab_replay(void *data __UNUSED__,
7947 Ecore_Event_Mouse_Button *ev;
7949 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7951 if ((e_config->pass_click_on)
7952 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7953 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7958 bd = e_border_find_by_window(ev->event_window);
7961 if (bd->cur_mouse_action)
7962 return ECORE_CALLBACK_DONE;
7963 if (ev->event_window == bd->win)
7965 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7966 E_OBJECT(bd), ev, NULL))
7967 return ECORE_CALLBACK_PASS_ON;
7971 return ECORE_CALLBACK_DONE;
7975 _e_border_cb_drag_finished(E_Drag *drag,
7976 int dropped __UNUSED__)
7981 e_object_unref(E_OBJECT(bd));
7985 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7987 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7988 int ev_type __UNUSED__,
7991 E_Event_Desk_Window_Profile_Change *e;
7996 EINA_LIST_FOREACH(borders, l, bd)
7998 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
8000 bd->client.e.fetch.profile_list = 1;
8004 return ECORE_CALLBACK_PASS_ON;
8008 #ifdef _F_ZONE_WINDOW_ROTATION_
8010 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
8011 int ev_type __UNUSED__,
8014 E_Event_Zone_Rotation_Change_Begin *e = ev;
8016 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8017 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
8019 if (!_e_border_rotation_zone_set(e->zone))
8021 /* there is no border which supports window manager rotation */
8022 e_zone_rotation_update_cancel(e->zone);
8024 return ECORE_CALLBACK_PASS_ON;
8028 _e_border_cb_rotation_sync_job(void *data)
8030 E_Zone *zone = data;
8032 E_Border_Rotation_Info *info = NULL;
8034 ELB(ELBT_ROT, "DO ROTATION SYNC_JOB", zone->id);
8038 EINA_LIST_FOREACH(rot.list, l, info)
8039 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
8040 if (!rot.wait_prepare_done)
8042 _e_border_rotation_change_request(zone);
8049 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
8050 ecore_job_del(rot.sync_job);
8051 rot.sync_job = NULL;
8056 _e_border_cb_rotation_async_job(void *data)
8058 E_Zone *zone = data;
8060 if (rot.list) goto end;
8062 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
8064 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8065 rot.async_list = NULL;
8071 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
8072 ecore_job_del(rot.async_job);
8073 rot.async_job = NULL;
8078 _e_border_rotation_change_prepare_timeout(void *data)
8080 E_Zone *zone = data;
8081 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8083 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8085 if ((zone) && (rot.wait_prepare_done))
8089 _e_border_rotation_change_request(zone);
8090 if (rot.prepare_timer)
8091 ecore_timer_del(rot.prepare_timer);
8092 rot.prepare_timer = NULL;
8093 rot.wait_prepare_done = EINA_FALSE;
8096 return ECORE_CALLBACK_CANCEL;
8100 _e_border_rotation_change_request(E_Zone *zone)
8102 if (!e_config->wm_win_rotation) return;
8103 if (!rot.list) return;
8104 if (eina_list_count(rot.list) <= 0) return;
8105 if (zone->rot.block_count) return;
8107 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8108 rot.prepare_timer = NULL;
8109 rot.wait_prepare_done = EINA_FALSE;
8111 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8114 ecore_timer_del(rot.done_timer);
8115 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8116 rot.done_timer = ecore_timer_add(5.0f,
8117 _e_border_rotation_change_done_timeout,
8122 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8125 E_Border_Rotation_Info *info =NULL;
8128 EINA_LIST_FOREACH (list, l, info)
8130 if (!info->bd) continue;
8131 if ((info->bd->client.e.state.rot.wait_for_done) &&
8132 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8134 _e_border_event_border_rotation_change_begin_send(info->bd);
8137 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8138 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8140 info->x = x; info->y = y;
8141 info->w = w; info->h = h;
8143 ELBF(ELBT_ROT, 1, info->bd->client.win,
8144 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8145 info->ang, info->win_resize, info->w, info->h);
8147 ecore_x_e_window_rotation_change_prepare_send
8148 (info->bd->client.win, info->ang,
8149 info->win_resize, info->w, info->h);
8151 if (!info->bd->client.e.state.rot.pending_change_request)
8153 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8154 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8156 info->bd->client.e.state.rot.wait_for_done = 1;
8157 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8163 EINA_LIST_FREE(list, info)
8169 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8171 E_Border_Rotation_Info *info = NULL;
8173 if (send_request) _e_border_rotation_change_request(zone);
8176 EINA_LIST_FREE(rot.list, info)
8183 _e_border_rotation_list_remove(E_Border *bd)
8185 Eina_List *l = NULL;
8186 E_Border_Rotation_Info *info = NULL;
8187 E_Event_Border_Rotation_Change_End *ev = NULL;
8188 Eina_Bool found = EINA_FALSE;
8190 if (!e_config->wm_win_rotation) return;
8192 EINA_LIST_FOREACH(rot.list, l, info)
8196 rot.list = eina_list_remove(rot.list, info);
8202 if (bd->client.e.state.rot.wait_for_done)
8204 bd->client.e.state.rot.wait_for_done = 0;
8206 /* if we make the border event in the _e_border_free function,
8207 * then we may meet a crash problem, only work this at least e_border_hide.
8209 if (!e_object_is_del(E_OBJECT(bd)))
8211 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8215 e_object_ref(E_OBJECT(bd));
8216 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8218 _e_border_event_border_rotation_change_end_free,
8224 (eina_list_count(rot.list) == 0))
8226 _e_border_rotation_change_done();
8232 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8234 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8235 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8236 _e_border_rotation_change_done();
8237 return ECORE_CALLBACK_CANCEL;
8241 _e_border_rotation_change_done(void)
8243 E_Manager *m = NULL;
8244 E_Border_Rotation_Info *info = NULL;
8246 if (!e_config->wm_win_rotation) return;
8248 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8249 rot.prepare_timer = NULL;
8251 rot.wait_prepare_done = EINA_FALSE;
8253 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8254 rot.done_timer = NULL;
8256 EINA_LIST_FREE(rot.list, info)
8260 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8261 if (info->bd->client.e.state.rot.pending_show)
8263 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8264 e_border_show(info->bd);
8265 info->bd->client.e.state.rot.pending_show = 0;
8267 info->bd->client.e.state.rot.wait_for_done = 0;
8272 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8275 rot.async_list = NULL;
8277 m = e_manager_current_get();
8278 e_manager_comp_screen_unlock(m);
8279 e_zone_rotation_update_done(e_util_zone_current_get(m));
8283 _prev_angle_get(Ecore_X_Window win)
8285 int ret, count = 0, ang = -1;
8286 unsigned char* data = NULL;
8288 ret = ecore_x_window_prop_property_get
8289 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8290 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8292 if ((ret) && (data) && (count))
8293 ang = ((int *)data)[0];
8294 if (data) free(data);
8298 /* get proper rotation value using preferred rotation and list of available rotations */
8300 _e_border_rotation_get(E_Border *bd,
8304 int current_ang = bd->client.e.state.rot.curr;
8306 Eina_Bool found = EINA_FALSE;
8307 Eina_Bool found_curr_ang = EINA_FALSE;
8309 if (!e_config->wm_win_rotation) return ang;
8310 if (!bd->client.e.state.rot.app_set) return ang;
8312 if (bd->client.e.state.rot.preferred_rot != -1)
8314 ang = bd->client.e.state.rot.preferred_rot;
8315 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8317 else if ((bd->client.e.state.rot.available_rots) &&
8318 (bd->client.e.state.rot.count))
8320 for (i = 0; i < bd->client.e.state.rot.count; i++)
8322 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8328 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8329 found_curr_ang = EINA_TRUE;
8332 /* do nothing. this window wants to maintain current state.
8333 * for example, window's available_rots: 0, 90, 270,
8334 * current zone rotation request: 180. the WM does nothing
8339 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8340 ang = bd->client.e.state.rot.curr;
8342 ang = bd->client.e.state.rot.available_rots[0];
8347 /* In this case, border doesn't have a list of
8348 * available rotations, thus WM should request
8349 * rotation with '0' degree to the application.
8358 _e_border_rotation_angle_get(E_Border *bd)
8360 E_Zone *zone = bd->zone;
8365 if (!e_config->wm_win_rotation) return ret;
8366 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8368 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8370 // the window with "ECORE_X_WINDOW_TYPE_NORMAL" type
8371 // should follow the state of rotation of zone.
8373 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL))
8374 will_ang = bd->parent->client.e.state.rot.curr;
8375 else will_ang = zone->rot.curr;
8377 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8379 ELBF(ELBT_ROT, 1, bd->client.win,
8380 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8381 (rot.vkbd == bd) ? "vkbd" : "prediction",
8382 bd->parent ? bd->parent->client.win : 0,
8383 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8384 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8385 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8389 will_ang = bd->parent->client.e.state.rot.curr;
8390 if ((!bd->parent->client.e.state.rot.support) &&
8391 (!bd->parent->client.e.state.rot.app_set))
8398 if ((!bd->client.e.state.rot.app_set) &&
8399 (!bd->client.e.state.rot.support))
8401 /* hack for magnifier and keyboard popup */
8402 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8403 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8405 ELB(ELBT_BD, "MAG", bd->client.win);
8407 if ((rot.vkbd) && (rot.vkbd->visible))
8408 will_ang = rot.vkbd->client.e.state.rot.curr;
8412 if (bd->client.e.state.rot.app_set)
8414 /* utility type window should be rotated according to
8415 * rotation of the transient_for window.
8418 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8420 will_ang = bd->parent->client.e.state.rot.curr;
8421 if ((!bd->parent->client.e.state.rot.support) &&
8422 (!bd->parent->client.e.state.rot.app_set))
8424 /* if transient_for window doesn't support rotation feature,
8425 * then this window should't be rotated.
8426 * TODO: need to check whether window supports '0' degree or not.
8429 ELBF(ELBT_ROT, 0, bd->client.win,
8430 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8431 will_ang, bd->parent->client.win);
8435 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8436 ELBF(ELBT_ROT, 0, bd->client.win,
8437 "GET ROT ang:%d Transient_For:0x%08x",
8438 will_ang, bd->parent->client.win);
8443 will_ang = _e_border_rotation_get(bd, will_ang);
8444 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8445 will_ang, bd->parent ? bd->parent->client.win : 0,
8446 bd->client.netwm.type);
8452 _ang = _prev_angle_get(bd->client.win);
8454 bd->client.e.state.rot.curr = _ang;
8455 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8458 if (bd->client.e.state.rot.curr != will_ang)
8466 _e_border_rotation_zone_set(E_Zone *zone)
8468 E_Border_List *l = NULL;
8469 E_Border *bd = NULL;
8470 Eina_Bool ret = EINA_FALSE;
8472 if (!e_config->wm_win_rotation) return EINA_FALSE;
8474 l = e_container_border_list_last(zone->container);
8477 /* step 1. make the list needs to be rotated. */
8478 while ((bd = e_container_border_list_prev(l)))
8482 // if this window has parent and window type isn't "ECORE_X_WINDOW_TYPE_NORMAL",
8483 // it will be rotated when parent do rotate itself.
8486 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL)) continue;
8488 // default type is "E_BORDER_ROTATION_TYPE_NORMAL",
8489 // but it can be changed to "E_BORDER_ROTATION_TYPE_DEPENDENT" by illume according to its policy.
8490 // if it's not normal type window, will be rotated by illume.
8492 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8494 if ((!bd->visible) ||
8495 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8496 bd->x, bd->y, bd->w, bd->h))) continue;
8498 if (_e_border_rotatable_check(bd, zone->rot.curr))
8500 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8501 bd->client.e.state.rot.curr, zone->rot.curr);
8503 ret = e_border_rotation_set(bd, zone->rot.curr);
8506 if (l) e_container_border_list_free(l);
8512 _e_border_rotation_set_internal(E_Border *bd, int rotation, Eina_Bool *pending)
8514 E_Zone *zone = bd->zone;
8515 E_Border_Rotation_Info *info = NULL;
8516 Eina_List *list, *l;
8519 if (rotation < 0) return EINA_FALSE;
8520 if (pending) *pending = EINA_FALSE;
8522 /* step 1. check if rotation */
8523 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8525 /* step 2. add to async/sync list */
8526 if ((!zone->rot.block_count) &&
8528 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8530 // send rotation change request later.
8531 // and no need to wait message of rotation done.
8534 info = E_NEW(E_Border_Rotation_Info, 1);
8535 if (!info) return EINA_FALSE;
8536 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8538 info->ang = rotation;
8539 rot.async_list = eina_list_append(rot.async_list, info);
8541 // add job for sending event.
8544 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8545 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8551 info = E_NEW(E_Border_Rotation_Info, 1);
8552 if (!info) return EINA_FALSE;
8553 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8555 info->ang = rotation;
8556 rot.list = eina_list_append(rot.list, info);
8558 // add job for sending event.
8561 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8562 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8565 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8567 // but, DO NOT lock the screen when rotation block state.
8568 if ((!zone->rot.block_count) &&
8569 ((eina_list_count(rot.list) == 2)))
8570 e_manager_comp_screen_lock(e_manager_current_get());
8573 if (pending) *pending = EINA_TRUE;
8575 /* step 3. search rotatable window in this window's child */
8576 list = _e_border_sub_borders_new(bd);
8577 EINA_LIST_FOREACH(list, l, child)
8579 // the window which type is "ECORE_X_WINDOW_TYPE_NORMAL" will be rotated itself.
8580 // it shouldn't be rotated by rotation state of parent window.
8581 if (child->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) continue;
8582 if (_e_border_rotatable_check(child, rotation))
8584 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8585 bd->client.e.state.rot.curr, rotation);
8586 e_border_rotation_set(child, rotation);
8590 /* step 4. if there is vkbd window, send message to prepare rotation */
8591 if (_e_border_is_vkbd(bd))
8593 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8594 if (rot.prepare_timer)
8595 ecore_timer_del(rot.prepare_timer);
8596 rot.prepare_timer = NULL;
8599 ecore_timer_del(rot.done_timer);
8600 rot.done_timer = NULL;
8602 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8603 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8606 rot.prepare_timer = ecore_timer_add(4.0f,
8607 _e_border_rotation_change_prepare_timeout,
8610 rot.wait_prepare_done = EINA_TRUE;
8613 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8614 bd->client.e.state.rot.curr = rotation;
8619 // check if border is rotatable in ang.
8621 _e_border_rotatable_check(E_Border *bd, int ang)
8623 Eina_Bool ret = EINA_FALSE;
8625 if (!bd) return ret;
8626 if (ang < 0) return ret;
8627 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8628 if (e_object_is_del(E_OBJECT(bd))) return ret;
8630 // same with current angle of window, then false return.
8631 if (ang == bd->client.e.state.rot.curr) return ret;
8633 /* basically WM allows only fullscreen window to rotate */
8634 if (bd->client.e.state.rot.preferred_rot == -1)
8638 if (bd->client.e.state.rot.app_set)
8640 if (bd->client.e.state.rot.available_rots &&
8641 bd->client.e.state.rot.count)
8643 Eina_Bool found = EINA_FALSE;
8644 for (i = 0; i < bd->client.e.state.rot.count; i++)
8646 if (bd->client.e.state.rot.available_rots[i] == ang)
8651 if (found) ret = EINA_TRUE;
8656 ELB(ELBT_ROT, "DO ROT", 0);
8660 // if it has preferred rotation angle,
8661 // it will be rotated at border's evaluation time.
8663 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8668 /* check whether virtual keyboard is visible on the zone */
8670 _e_border_is_vkbd(E_Border *bd)
8672 if (!e_config->wm_win_rotation) return EINA_FALSE;
8674 if ((rot.vkbd_ctrl_win) &&
8676 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8677 (rot.vkbd->visible) &&
8678 (rot.vkbd->zone == bd->zone) &&
8679 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8680 bd->zone->w, bd->zone->h,
8681 rot.vkbd->x, rot.vkbd->y,
8682 rot.vkbd->w, rot.vkbd->h)))
8690 _e_border_rotation_change_floating_pos(E_Border *bd, int *x, int *y)
8693 int min_title_width=96;
8695 if (!bd) return EINA_FALSE;
8696 if (!x || !y) return EINA_FALSE;
8701 // Portrait -> Landscape, x= pre_x*2, y=pre_y/2
8702 // Landscape -> Portrait, x= pre_x/2, y=pre_y*2
8703 // guaranteeing the minimum size of titlebar shown, min_title_width
8704 // so user can initiate drag&drop action after rotation changed.
8705 if (bd->client.e.state.rot.curr == 0)
8707 if (bd->client.e.state.rot.prev == 90)
8709 new_x = (bd->zone->h - bd->h - bd->y) / 2;
8712 else if (bd->client.e.state.rot.prev == 270)
8715 new_y = (bd->zone->w - bd->w - bd->x) * 2;
8717 else if (bd->client.e.state.rot.prev == 180)
8719 new_x = bd->zone->w - bd->x - bd->w;
8720 new_y = bd->zone->h - bd->y - bd->h;
8723 if(new_x + bd->w < min_title_width)
8725 new_x = min_title_width - bd->w;
8727 else if(new_x > bd->zone->w - min_title_width)
8729 new_x = bd->zone->w - min_title_width;
8732 else if (bd->client.e.state.rot.curr == 90)
8734 if (bd->client.e.state.rot.prev == 0)
8737 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8739 else if (bd->client.e.state.rot.prev == 270)
8741 new_x = bd->zone->w - bd->x - bd->w;
8742 new_y = bd->zone->h - bd->y - bd->h;
8744 else if (bd->client.e.state.rot.prev == 180)
8746 new_x = (bd->zone->h - bd->y - bd->h) / 2;
8747 new_y = bd->zone->h - (2 * (bd->zone->w - bd->x - bd->w)) - bd->w;
8750 if(new_y > bd->zone->h - min_title_width)
8752 new_y = bd->zone->h - min_title_width;
8754 else if(new_y < min_title_width - bd->w)
8756 new_y = min_title_width - bd->w;
8759 else if (bd->client.e.state.rot.curr == 270)
8761 if (bd->client.e.state.rot.prev == 0)
8763 new_x = bd->zone->w - bd->h - (bd->y / 2);
8766 else if (bd->client.e.state.rot.prev == 90)
8768 new_x = bd->zone->w - bd->x - bd->w;
8769 new_y = bd->zone->h - bd->y - bd->h;
8771 else if (bd->client.e.state.rot.prev == 180)
8773 new_x = bd->zone->w - bd->x - bd->w;
8774 new_y = bd->zone->h - bd->y - bd->h;
8776 new_x = bd->zone->w - bd->h - ((bd->zone->h - bd->y - bd->h) / 2);
8777 new_y = (bd->zone->w - bd->x - bd->w) * 2;
8780 if(new_y > bd->zone->h - min_title_width)
8782 new_y = bd->zone->h - min_title_width;
8784 else if( new_y + bd->w < min_title_width)
8786 new_y = min_title_width - bd->w ;
8789 else if (bd->client.e.state.rot.curr == 180)
8791 if (bd->client.e.state.rot.prev == 0)
8793 new_x = bd->zone->w - bd->x - bd->w;
8794 new_y = bd->zone->h - bd->y - bd->h;
8796 else if (bd->client.e.state.rot.prev == 90)
8798 new_x = bd->zone->w - ((bd->zone->h - bd->h - bd->y) / 2) - bd->h;
8799 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8801 else if (bd->client.e.state.rot.prev == 270)
8803 new_x = bd->zone->w - (bd->y / 2) - bd->h;
8804 new_y = bd->zone->h - ((bd->zone->w - bd->w - bd->x) * 2) - bd->w;
8807 if(new_x + bd->w < min_title_width)
8809 new_x = min_title_width - bd->w;
8811 else if(new_x > bd->zone->w - min_title_width)
8813 new_x = bd->zone->w - min_title_width;
8817 ELBF(ELBT_ROT, 0, bd->client.win,
8818 "Floating Mode. ANGLE (%d->%d), POS (%d,%d) -> (%d,%d)",
8819 bd->client.e.state.rot.prev, bd->client.e.state.rot.curr,
8820 bd->x, bd->y, new_x, new_y);
8822 if ((new_x == *x) &&
8834 #define SIZE_EQUAL_TO_ZONE(a, z) \
8835 ((((a)->w) == ((z)->w)) && \
8836 (((a)->h) == ((z)->h)))
8838 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
8840 E_Zone *zone = bd->zone;
8843 Eina_Bool move = EINA_FALSE;
8844 Eina_Bool hint = EINA_FALSE;
8845 Eina_Bool resize = EINA_FALSE;
8852 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
8854 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
8855 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
8856 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
8858 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
8859 &_x, &_y, &_w, &_h, &move);
8862 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
8864 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8865 bd->client.icccm.name, _x, _y, _w, _h);
8869 _x = bd->x; _y = bd->y;
8870 _w = bd->w; _h = bd->h;
8872 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)
8873 move = _e_border_rotation_change_floating_pos(bd, &_x, &_y);
8877 rot_dif = bd->client.e.state.rot.prev - rotation;
8878 if (rot_dif < 0) rot_dif = -rot_dif;
8887 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
8888 EINA_TRUE, EINA_TRUE);
8889 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
8890 bd->client.icccm.name, _x, _y, _w, _h);
8895 if (!resize && move)
8896 _e_border_move_internal(bd, _x, _y, EINA_TRUE);
8911 _e_border_cb_window_configure(void *data __UNUSED__,
8912 int ev_type __UNUSED__,
8915 Ecore_X_Event_Window_Configure *e = ev;
8916 E_Border_Rotation_Info *info = NULL;
8918 Eina_Bool found = EINA_FALSE;
8920 if (!e) return ECORE_CALLBACK_PASS_ON;
8921 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8923 E_Border *bd = e_border_find_by_client_window(e->win);
8924 if (!bd) return ECORE_CALLBACK_PASS_ON;
8926 if (bd->client.e.state.rot.pending_change_request)
8928 if ((e->w == bd->w) && (e->h == bd->h))
8930 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
8931 bd->client.e.state.rot.pending_change_request = 0;
8933 if ((bd->client.e.state.rot.wait_for_done) &&
8934 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
8936 // if this window is rotation dependent window and zone is blocked to rotate,
8937 // then skip here, request will be sent after cancel block.
8938 if ((bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT) &&
8939 (bd->zone->rot.block_count)) goto end;
8941 EINA_LIST_FOREACH(rot.list, l, info)
8942 if (info->bd == bd) found = EINA_TRUE;
8943 // send request message if it's async rotation window,
8944 // even if wait prepare done.
8945 if ((found) && (rot.wait_prepare_done)) goto end;
8947 ELBF(ELBT_ROT, 0, bd->client.win,
8948 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8949 bd->client.e.state.rot.curr,
8951 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8952 bd->client.e.state.rot.curr);
8953 bd->client.e.state.rot.wait_for_done = 1;
8954 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
8959 return ECORE_CALLBACK_PASS_ON;
8963 _e_border_rotation_geom_get(E_Border *bd,
8972 if (!e_config->wm_win_rotation) return EINA_FALSE;
8974 Eina_Bool res = EINA_FALSE;
8975 Eina_Bool _move = EINA_TRUE;
8985 if (move) *move = EINA_TRUE;
8987 if (bd->client.e.state.rot.geom_hint)
8992 _w = bd->client.e.state.rot.geom[0].w;
8993 _h = bd->client.e.state.rot.geom[0].h;
8994 if (_w == 0) _w = bd->w;
8995 if (_h == 0) _h = bd->h;
8996 _x = 0; _y = zone->h - _h;
8999 _w = bd->client.e.state.rot.geom[1].w;
9000 _h = bd->client.e.state.rot.geom[1].h;
9001 if (_w == 0) _w = bd->w;
9002 if (_h == 0) _h = bd->h;
9003 _x = zone->w - _w; _y = 0;
9006 _w = bd->client.e.state.rot.geom[2].w;
9007 _h = bd->client.e.state.rot.geom[2].h;
9008 if (_w == 0) _w = bd->w;
9009 if (_h == 0) _h = bd->h;
9013 _w = bd->client.e.state.rot.geom[3].w;
9014 _h = bd->client.e.state.rot.geom[3].h;
9015 if (_w == 0) _w = bd->w;
9016 if (_h == 0) _h = bd->h;
9026 if (!((rot.vkbd) && (rot.vkbd == bd)))
9030 if (move) *move = EINA_FALSE;
9038 _x = 0; _y = 0; _w = 0; _h = 0;
9043 if (move) _move = *move;
9045 ELBF(ELBT_ROT, 1, bd->client.win,
9046 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
9047 ang, _x, _y, _w, _h, _move);
9055 _e_border_post_move_resize_job(void *data)
9059 bd = (E_Border *)data;
9065 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9066 ecore_x_window_move(tmp->win,
9068 bd->client_inset.l +
9070 tmp->client.e.state.video_position.x,
9072 bd->client_inset.t +
9074 tmp->client.e.state.video_position.y);
9076 if (bd->client.e.state.video)
9080 parent = bd->client.e.state.video_parent_border;
9081 ecore_x_window_move(bd->win,
9083 parent->client_inset.l +
9085 bd->client.e.state.video_position.x,
9087 parent->client_inset.t +
9089 bd->client.e.state.video_position.y);
9091 else if ((bd->post_move) && (bd->post_resize))
9093 ecore_x_window_move_resize(bd->win,
9098 else if (bd->post_move)
9100 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
9102 else if (bd->post_resize)
9104 ecore_x_window_resize(bd->win, bd->w, bd->h);
9107 if (bd->client.e.state.video)
9109 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
9111 bd->client.e.state.video_parent_border->x +
9112 bd->client.e.state.video_parent_border->client_inset.l +
9113 bd->client.e.state.video_parent_border->fx.x +
9114 bd->client.e.state.video_position.x,
9115 bd->client.e.state.video_parent_border->y +
9116 bd->client.e.state.video_parent_border->client_inset.t +
9117 bd->client.e.state.video_parent_border->fx.y +
9118 bd->client.e.state.video_position.y,
9126 bd->post_job = NULL;
9132 bd->post_resize = 0;
9133 bd->post_job = NULL;
9134 return ECORE_CALLBACK_CANCEL;
9138 _e_border_container_layout_hook(E_Container *con)
9140 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
9144 _e_border_eval0(E_Border *bd)
9146 int change_urgent = 0;
9148 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9149 Eina_Bool need_desk_set = EINA_FALSE;
9151 #ifdef _F_ZONE_WINDOW_ROTATION_
9152 Eina_Bool need_rotation_set = EINA_FALSE;
9154 if ((e_config->wm_win_rotation) &&
9155 (bd->client.icccm.fetch.transient_for))
9157 if (((rot.vkbd) && (rot.vkbd == bd)) ||
9158 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
9160 need_rotation_set = EINA_TRUE;
9161 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
9166 if (e_object_is_del(E_OBJECT(bd)))
9168 CRI("_e_border_eval(%p) with deleted border!\n", bd);
9173 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
9175 bd->changes.border = 0;
9177 /* fetch any info queued to be fetched */
9178 if (bd->client.netwm.fetch.state)
9180 e_hints_window_state_get(bd);
9181 bd->client.netwm.fetch.state = 0;
9184 if (bd->client.icccm.fetch.client_leader)
9186 /* TODO: What do to if the client leader isn't mapped yet? */
9187 E_Border *bd_leader = NULL;
9189 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
9190 if (bd->client.icccm.client_leader)
9191 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
9194 if (bd->leader != bd_leader)
9196 bd->leader->group = eina_list_remove(bd->leader->group, bd);
9197 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9203 /* If this border is the leader of the group, don't register itself */
9204 if ((bd_leader) && (bd_leader != bd))
9206 bd_leader->group = eina_list_append(bd_leader->group, bd);
9207 bd->leader = bd_leader;
9208 /* Only set the window modal to the leader it there is no parent */
9209 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9210 ((!bd->parent) || (bd->parent->modal != bd)))
9212 bd->leader->modal = bd;
9213 if (bd->leader->focused)
9214 e_border_focus_set(bd, 1, 1);
9220 EINA_LIST_FOREACH(bd->leader->group, l, child)
9222 if ((child != bd) && (child->focused))
9223 e_border_focus_set(bd, 1, 1);
9228 bd->client.icccm.fetch.client_leader = 0;
9231 if (bd->client.icccm.fetch.title)
9233 char *title = ecore_x_icccm_title_get(bd->client.win);
9234 eina_stringshare_replace(&bd->client.icccm.title, title);
9235 if (title) free(title);
9238 edje_object_part_text_set(bd->bg_object, "e.text.title",
9239 bd->client.icccm.title);
9240 bd->client.icccm.fetch.title = 0;
9243 if (bd->client.netwm.fetch.name)
9246 ecore_x_netwm_name_get(bd->client.win, &name);
9247 eina_stringshare_replace(&bd->client.netwm.name, name);
9248 if (name) free(name);
9251 edje_object_part_text_set(bd->bg_object, "e.text.title",
9252 bd->client.netwm.name);
9253 bd->client.netwm.fetch.name = 0;
9256 if (bd->client.icccm.fetch.name_class)
9258 const char *pname, *pclass;
9259 char *nname, *nclass;
9261 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9262 pname = bd->client.icccm.name;
9263 pclass = bd->client.icccm.class;
9264 bd->client.icccm.name = eina_stringshare_add(nname);
9265 bd->client.icccm.class = eina_stringshare_add(nclass);
9266 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9267 e_bindings_mapping_change_enable(EINA_FALSE);
9268 #ifdef _F_ZONE_WINDOW_ROTATION_
9269 if (e_config->wm_win_rotation)
9271 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9273 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9274 (!strcmp(bd->client.icccm.class, "ISF")))
9276 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9277 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9280 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9281 (!strcmp(bd->client.icccm.class, "ISF")))
9283 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9284 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9285 rot.vkbd_prediction = bd;
9287 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9288 (!strcmp(bd->client.icccm.class, "ISF")))
9290 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9291 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9293 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9294 (!strcmp(bd->client.icccm.class, "ISF")))
9296 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9297 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9302 if (nname) free(nname);
9303 if (nclass) free(nclass);
9305 if (!((bd->client.icccm.name == pname) &&
9306 (bd->client.icccm.class == pclass)))
9307 bd->changes.icon = 1;
9309 if (pname) eina_stringshare_del(pname);
9310 if (pclass) eina_stringshare_del(pclass);
9311 bd->client.icccm.fetch.name_class = 0;
9312 bd->changes.icon = 1;
9315 if (bd->client.icccm.fetch.state)
9317 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9318 bd->client.icccm.fetch.state = 0;
9321 if (bd->client.e.fetch.state)
9323 e_hints_window_e_state_get(bd);
9324 bd->client.e.fetch.state = 0;
9327 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9328 if (bd->client.e.fetch.profile_list)
9330 const char **profiles = NULL;
9334 if (bd->client.e.state.profile)
9335 eina_stringshare_del(bd->client.e.state.profile);
9336 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9338 if (str) eina_stringshare_del(str);
9340 bd->client.e.state.profile = NULL;
9341 bd->client.e.state.profiles = NULL;
9342 bd->client.e.state.profile_list = 0;
9344 if (ecore_x_e_window_profile_list_get(bd->client.win,
9347 bd->client.e.state.profile_list = 1;
9348 for (i = 0; i < num; i++)
9350 str = eina_stringshare_add(profiles[i]);
9351 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9354 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9355 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9357 need_desk_set = EINA_TRUE;
9361 if (strcmp(bd->desk->window_profile,
9362 e_config->desktop_default_window_profile) != 0)
9364 ecore_x_e_window_profile_set(bd->client.win,
9365 bd->desk->window_profile);
9371 for (i = 0; i < num; i++)
9372 if (profiles[i]) free(profiles[i]);
9376 bd->client.e.fetch.profile_list = 0;
9379 #ifdef _F_ZONE_WINDOW_ROTATION_
9380 if ((e_config->wm_win_rotation) &&
9381 (bd->client.e.fetch.rot.support))
9384 unsigned int support = 0;
9386 ret = ecore_x_window_prop_card32_get
9388 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9391 bd->client.e.state.rot.support = 0;
9392 if ((ret == 1) && (support == 1))
9393 bd->client.e.state.rot.support = 1;
9395 if (bd->client.e.state.rot.support)
9396 need_rotation_set = EINA_TRUE;
9398 bd->client.e.fetch.rot.support = 0;
9400 if ((e_config->wm_win_rotation) &&
9401 (bd->client.e.fetch.rot.geom_hint))
9403 Eina_Rectangle r[4];
9405 bd->client.e.state.rot.geom_hint = 0;
9406 for (i = 0; i < 4; i++)
9408 r[i].x = bd->client.e.state.rot.geom[i].x;
9409 r[i].y = bd->client.e.state.rot.geom[i].y;
9410 r[i].w = bd->client.e.state.rot.geom[i].w;
9411 r[i].h = bd->client.e.state.rot.geom[i].h;
9413 bd->client.e.state.rot.geom[i].x = 0;
9414 bd->client.e.state.rot.geom[i].y = 0;
9415 bd->client.e.state.rot.geom[i].w = 0;
9416 bd->client.e.state.rot.geom[i].h = 0;
9419 for (i = 0; i < 4; i++)
9421 x = 0; y = 0; w = 0; h = 0;
9422 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9424 bd->client.e.state.rot.geom_hint = 1;
9425 bd->client.e.state.rot.geom[i].x = x;
9426 bd->client.e.state.rot.geom[i].y = y;
9427 bd->client.e.state.rot.geom[i].w = w;
9428 bd->client.e.state.rot.geom[i].h = h;
9430 if (!((r[i].x == x) && (r[i].y == y) &&
9431 (r[i].w == w) && (r[i].h == h)))
9433 need_rotation_set = EINA_TRUE;
9437 bd->client.e.fetch.rot.geom_hint = 0;
9439 if ((e_config->wm_win_rotation) &&
9440 (bd->client.e.fetch.rot.app_set))
9442 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9443 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9444 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9446 if (_prev_app_set != bd->client.e.state.rot.app_set)
9447 need_rotation_set = EINA_TRUE;
9449 bd->client.e.fetch.rot.app_set = 0;
9451 if ((e_config->wm_win_rotation) &&
9452 (bd->client.e.fetch.rot.preferred_rot))
9454 int r = 0, _prev_preferred_rot;
9455 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9456 bd->client.e.state.rot.preferred_rot = -1;
9457 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9459 bd->client.e.state.rot.preferred_rot = r;
9460 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9464 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9467 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9468 need_rotation_set = EINA_TRUE;
9470 bd->client.e.fetch.rot.preferred_rot = 0;
9472 if ((e_config->wm_win_rotation) &&
9473 (bd->client.e.fetch.rot.available_rots))
9475 Eina_Bool res, diff = EINA_FALSE;
9477 unsigned int count = 0, i = 0;
9478 int _prev_rots[4] = { -1, };
9480 if (bd->client.e.state.rot.available_rots)
9483 bd->client.e.state.rot.available_rots,
9484 (sizeof(int) * bd->client.e.state.rot.count));
9486 E_FREE(bd->client.e.state.rot.available_rots);
9489 bd->client.e.state.rot.count = 0;
9491 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9493 if ((res) && (count > 0) && (rots))
9495 bd->client.e.state.rot.available_rots = rots;
9496 bd->client.e.state.rot.count = count;
9498 for (i = 0; i < count; i++)
9500 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9501 if ((!diff) && (_prev_rots[i] != rots[i]))
9503 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9504 count, i, _prev_rots[i], rots[i]);
9511 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9515 if (diff) need_rotation_set = EINA_TRUE;
9516 bd->client.e.fetch.rot.available_rots = 0;
9519 if (bd->client.netwm.fetch.type)
9521 e_hints_window_type_get(bd);
9522 if ((!bd->lock_border) || (!bd->client.border.name))
9523 bd->client.border.changed = 1;
9525 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9527 if (!bd->client.netwm.state.skip_pager)
9529 bd->client.netwm.state.skip_pager = 1;
9530 bd->client.netwm.update.state = 1;
9532 if (!bd->client.netwm.state.skip_taskbar)
9534 bd->client.netwm.state.skip_taskbar = 1;
9535 bd->client.netwm.update.state = 1;
9538 bd->client.netwm.fetch.type = 0;
9540 if (bd->client.icccm.fetch.machine)
9542 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9544 if ((!machine) && (bd->client.icccm.client_leader))
9545 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9547 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9548 if (machine) free(machine);
9550 bd->client.icccm.fetch.machine = 0;
9553 if (bd->client.icccm.fetch.command)
9555 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9559 for (i = 0; i < bd->client.icccm.command.argc; i++)
9560 free(bd->client.icccm.command.argv[i]);
9561 free(bd->client.icccm.command.argv);
9563 bd->client.icccm.command.argc = 0;
9564 bd->client.icccm.command.argv = NULL;
9565 ecore_x_icccm_command_get(bd->client.win,
9566 &(bd->client.icccm.command.argc),
9567 &(bd->client.icccm.command.argv));
9568 if ((bd->client.icccm.client_leader) &&
9569 (!bd->client.icccm.command.argv))
9570 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9571 &(bd->client.icccm.command.argc),
9572 &(bd->client.icccm.command.argv));
9573 bd->client.icccm.fetch.command = 0;
9576 if (bd->client.icccm.fetch.hints)
9578 Eina_Bool accepts_focus, is_urgent;
9580 accepts_focus = EINA_TRUE;
9581 is_urgent = EINA_FALSE;
9582 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9583 if (ecore_x_icccm_hints_get(bd->client.win,
9585 &bd->client.icccm.initial_state,
9586 &bd->client.icccm.icon_pixmap,
9587 &bd->client.icccm.icon_mask,
9588 &bd->client.icccm.icon_window,
9589 &bd->client.icccm.window_group,
9592 bd->client.icccm.accepts_focus = accepts_focus;
9593 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9595 bd->client.icccm.urgent = is_urgent;
9597 /* If this is a new window, set the state as requested. */
9598 if ((bd->new_client) &&
9599 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9601 e_border_iconify(bd);
9602 e_border_hide(bd, 1);
9605 bd->client.icccm.fetch.hints = 0;
9608 if (bd->client.icccm.fetch.size_pos_hints)
9610 Eina_Bool request_pos;
9612 request_pos = EINA_FALSE;
9613 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9615 &bd->client.icccm.gravity,
9616 &bd->client.icccm.min_w,
9617 &bd->client.icccm.min_h,
9618 &bd->client.icccm.max_w,
9619 &bd->client.icccm.max_h,
9620 &bd->client.icccm.base_w,
9621 &bd->client.icccm.base_h,
9622 &bd->client.icccm.step_w,
9623 &bd->client.icccm.step_h,
9624 &bd->client.icccm.min_aspect,
9625 &bd->client.icccm.max_aspect))
9627 bd->client.icccm.request_pos = request_pos;
9632 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9633 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9634 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9635 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9636 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9637 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9638 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9639 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9640 // if doing a resize, fix it up
9641 if (bd->resize_mode != RESIZE_NONE)
9643 int x, y, w, h, new_w, new_h;
9651 e_border_resize_limit(bd, &new_w, &new_h);
9652 if ((bd->resize_mode == RESIZE_TL) ||
9653 (bd->resize_mode == RESIZE_L) ||
9654 (bd->resize_mode == RESIZE_BL))
9656 if ((bd->resize_mode == RESIZE_TL) ||
9657 (bd->resize_mode == RESIZE_T) ||
9658 (bd->resize_mode == RESIZE_TR))
9660 e_border_move_resize(bd, x, y, new_w, new_h);
9662 bd->client.icccm.fetch.size_pos_hints = 0;
9665 if (bd->client.icccm.fetch.protocol)
9668 Ecore_X_WM_Protocol *proto;
9670 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9673 for (i = 0; i < num; i++)
9675 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9676 bd->client.icccm.delete_request = 1;
9677 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9678 bd->client.icccm.take_focus = 1;
9679 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9680 bd->client.netwm.ping = 1;
9681 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9683 bd->client.netwm.sync.request = 1;
9684 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9685 &bd->client.netwm.sync.counter))
9686 bd->client.netwm.sync.request = 0;
9691 if (bd->client.netwm.ping)
9695 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9696 bd->ping_poller = NULL;
9698 bd->client.icccm.fetch.protocol = 0;
9700 if (bd->client.icccm.fetch.transient_for)
9702 /* TODO: What do to if the transient for isn't mapped yet? */
9703 E_Border *bd_parent = NULL;
9704 #ifdef _F_DEICONIFY_APPROVE_
9705 Eina_Bool change_parent = EINA_FALSE;
9708 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9709 if (bd->client.icccm.transient_for)
9710 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9711 /* If we already have a parent, remove it */
9714 if (bd_parent != bd->parent)
9716 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9717 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9723 if ((bd_parent) && (bd_parent != bd) &&
9724 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9726 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9727 bd->parent = bd_parent;
9728 #ifdef _F_DEICONIFY_APPROVE_
9729 change_parent = EINA_TRUE;
9734 e_border_layer_set(bd, bd->parent->layer);
9735 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9737 Ecore_X_Window_Attributes attr;
9738 bd->parent->modal = bd;
9739 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9740 bd->parent->saved.event_mask = attr.event_mask.mine;
9741 bd->parent->lock_close = 1;
9742 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9743 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9746 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9747 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9751 #ifdef _F_DEICONIFY_APPROVE_
9754 bd->client.e.state.deiconify_approve.render_done = 0;
9756 E_Border *ancestor_bd;
9757 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9758 if ((ancestor_bd) &&
9759 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9761 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9762 bd->client.e.state.deiconify_approve.ancestor = NULL;
9764 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9765 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9767 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9769 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9770 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9771 e_border_uniconify(ancestor_bd);
9777 bd->client.icccm.fetch.transient_for = 0;
9780 if (bd->client.icccm.fetch.window_role)
9782 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9783 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9784 if (role) free(role);
9786 bd->client.icccm.fetch.window_role = 0;
9789 if (bd->client.icccm.fetch.icon_name)
9791 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9792 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9793 if (icon_name) free(icon_name);
9795 bd->client.icccm.fetch.icon_name = 0;
9798 if (bd->client.netwm.fetch.icon_name)
9801 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9802 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9803 if (icon_name) free(icon_name);
9805 bd->client.netwm.fetch.icon_name = 0;
9808 if (bd->client.netwm.fetch.icon)
9811 if (bd->client.netwm.icons)
9813 for (i = 0; i < bd->client.netwm.num_icons; i++)
9815 free(bd->client.netwm.icons[i].data);
9816 bd->client.netwm.icons[i].data = NULL;
9818 free(bd->client.netwm.icons);
9820 bd->client.netwm.icons = NULL;
9821 bd->client.netwm.num_icons = 0;
9822 if (ecore_x_netwm_icons_get(bd->client.win,
9823 &bd->client.netwm.icons,
9824 &bd->client.netwm.num_icons))
9826 // unless the rest of e17 uses border icons OTHER than icon #0
9827 // then free the rest that we don't need anymore.
9828 for (i = 1; i < bd->client.netwm.num_icons; i++)
9830 free(bd->client.netwm.icons[i].data);
9831 bd->client.netwm.icons[i].data = NULL;
9833 bd->client.netwm.num_icons = 1;
9834 bd->changes.icon = 1;
9836 bd->client.netwm.fetch.icon = 0;
9838 if (bd->client.netwm.fetch.user_time)
9840 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9841 bd->client.netwm.fetch.user_time = 0;
9843 if (bd->client.netwm.fetch.strut)
9845 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9846 &bd->client.netwm.strut.left,
9847 &bd->client.netwm.strut.right,
9848 &bd->client.netwm.strut.top,
9849 &bd->client.netwm.strut.bottom,
9850 &bd->client.netwm.strut.left_start_y,
9851 &bd->client.netwm.strut.left_end_y,
9852 &bd->client.netwm.strut.right_start_y,
9853 &bd->client.netwm.strut.right_end_y,
9854 &bd->client.netwm.strut.top_start_x,
9855 &bd->client.netwm.strut.top_end_x,
9856 &bd->client.netwm.strut.bottom_start_x,
9857 &bd->client.netwm.strut.bottom_end_x))
9859 ecore_x_netwm_strut_get(bd->client.win,
9860 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9861 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9863 bd->client.netwm.strut.left_start_y = 0;
9864 bd->client.netwm.strut.left_end_y = 0;
9865 bd->client.netwm.strut.right_start_y = 0;
9866 bd->client.netwm.strut.right_end_y = 0;
9867 bd->client.netwm.strut.top_start_x = 0;
9868 bd->client.netwm.strut.top_end_x = 0;
9869 bd->client.netwm.strut.bottom_start_x = 0;
9870 bd->client.netwm.strut.bottom_end_x = 0;
9872 bd->client.netwm.fetch.strut = 0;
9874 if (bd->client.qtopia.fetch.soft_menu)
9876 e_hints_window_qtopia_soft_menu_get(bd);
9877 bd->client.qtopia.fetch.soft_menu = 0;
9880 if (bd->client.qtopia.fetch.soft_menus)
9882 e_hints_window_qtopia_soft_menus_get(bd);
9883 bd->client.qtopia.fetch.soft_menus = 0;
9886 if (bd->client.vkbd.fetch.state)
9888 e_hints_window_virtual_keyboard_state_get(bd);
9889 bd->client.vkbd.fetch.state = 0;
9892 if (bd->client.vkbd.fetch.vkbd)
9894 e_hints_window_virtual_keyboard_get(bd);
9895 bd->client.vkbd.fetch.vkbd = 0;
9898 if (bd->client.illume.conformant.fetch.conformant)
9900 bd->client.illume.conformant.conformant =
9901 ecore_x_e_illume_conformant_get(bd->client.win);
9902 bd->client.illume.conformant.fetch.conformant = 0;
9904 if (bd->client.illume.quickpanel.fetch.state)
9906 bd->client.illume.quickpanel.state =
9907 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9908 bd->client.illume.quickpanel.fetch.state = 0;
9910 if (bd->client.illume.quickpanel.fetch.quickpanel)
9912 bd->client.illume.quickpanel.quickpanel =
9913 ecore_x_e_illume_quickpanel_get(bd->client.win);
9914 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9916 if (bd->client.illume.quickpanel.fetch.priority.major)
9918 bd->client.illume.quickpanel.priority.major =
9919 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9920 bd->client.illume.quickpanel.fetch.priority.major = 0;
9922 if (bd->client.illume.quickpanel.fetch.priority.minor)
9924 bd->client.illume.quickpanel.priority.minor =
9925 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9926 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9928 if (bd->client.illume.quickpanel.fetch.zone)
9930 bd->client.illume.quickpanel.zone =
9931 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9932 bd->client.illume.quickpanel.fetch.zone = 0;
9934 if (bd->client.illume.drag.fetch.drag)
9936 bd->client.illume.drag.drag =
9937 ecore_x_e_illume_drag_get(bd->client.win);
9938 bd->client.illume.drag.fetch.drag = 0;
9940 if (bd->client.illume.drag.fetch.locked)
9942 bd->client.illume.drag.locked =
9943 ecore_x_e_illume_drag_locked_get(bd->client.win);
9944 bd->client.illume.drag.fetch.locked = 0;
9946 if (bd->client.illume.win_state.fetch.state)
9948 bd->client.illume.win_state.state =
9949 ecore_x_e_illume_window_state_get(bd->client.win);
9950 bd->client.illume.win_state.fetch.state = 0;
9952 if (bd->changes.shape)
9954 Ecore_X_Rectangle *rects;
9957 bd->changes.shape = 0;
9958 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9963 /* This doesn't fix the race, but makes it smaller. we detect
9964 * this and if cw and ch != client w/h then mark this as needing
9965 * a shape change again to fixup next event loop.
9967 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9968 if ((cw != bd->client.w) || (ch != bd->client.h))
9969 bd->changes.shape = 1;
9971 (rects[0].x == 0) &&
9972 (rects[0].y == 0) &&
9973 ((int)rects[0].width == cw) &&
9974 ((int)rects[0].height == ch))
9976 if (bd->client.shaped)
9978 bd->client.shaped = 0;
9979 if (!bd->bordername)
9980 bd->client.border.changed = 1;
9985 if (!bd->client.shaped)
9987 bd->client.shaped = 1;
9988 if (!bd->bordername)
9989 bd->client.border.changed = 1;
9996 // FIXME: no rects i think can mean... totally empty window
9997 bd->client.shaped = 0;
9998 if (!bd->bordername)
9999 bd->client.border.changed = 1;
10001 bd->need_shape_merge = 1;
10003 if (bd->changes.shape_input)
10005 Ecore_X_Rectangle *rects;
10008 bd->changes.shape_input = 0;
10009 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
10012 int cw = 0, ch = 0;
10014 /* This doesn't fix the race, but makes it smaller. we detect
10015 * this and if cw and ch != client w/h then mark this as needing
10016 * a shape change again to fixup next event loop.
10018 ecore_x_window_size_get(bd->client.win, &cw, &ch);
10019 if ((cw != bd->client.w) || (ch != bd->client.h))
10020 bd->changes.shape_input = 1;
10022 (rects[0].x == 0) &&
10023 (rects[0].y == 0) &&
10024 ((int)rects[0].width == cw) &&
10025 ((int)rects[0].height == ch))
10027 if (bd->shaped_input)
10029 bd->shaped_input = 0;
10030 if (!bd->bordername)
10031 bd->client.border.changed = 1;
10036 if (!bd->shaped_input)
10038 bd->shaped_input = 1;
10039 if (!bd->bordername)
10040 bd->client.border.changed = 1;
10047 bd->shaped_input = 1;
10048 if (!bd->bordername)
10049 bd->client.border.changed = 1;
10051 bd->need_shape_merge = 1;
10053 if (bd->client.mwm.fetch.hints)
10057 bd->client.mwm.exists =
10058 ecore_x_mwm_hints_get(bd->client.win,
10059 &bd->client.mwm.func,
10060 &bd->client.mwm.decor,
10061 &bd->client.mwm.input);
10062 pb = bd->client.mwm.borderless;
10063 bd->client.mwm.borderless = 0;
10064 if (bd->client.mwm.exists)
10066 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
10067 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
10068 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
10069 bd->client.mwm.borderless = 1;
10071 if (bd->client.mwm.borderless != pb)
10073 if ((!bd->lock_border) || (!bd->client.border.name))
10074 bd->client.border.changed = 1;
10076 bd->client.mwm.fetch.hints = 0;
10079 if (bd->client.e.fetch.video_parent)
10081 /* unlinking child/parent */
10082 if (bd->client.e.state.video_parent_border != NULL)
10084 bd->client.e.state.video_parent_border->client.e.state.video_child =
10086 (bd->client.e.state.video_parent_border->client.e.state.video_child,
10090 ecore_x_window_prop_card32_get(bd->client.win,
10091 ECORE_X_ATOM_E_VIDEO_PARENT,
10092 &bd->client.e.state.video_parent,
10095 /* linking child/parent */
10096 if (bd->client.e.state.video_parent != 0)
10101 EINA_LIST_FOREACH(borders, l, tmp)
10102 if (tmp->client.win == bd->client.e.state.video_parent)
10104 /* fprintf(stderr, "child added to parent \\o/\n"); */
10105 bd->client.e.state.video_parent_border = tmp;
10106 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
10108 if (bd->desk != tmp->desk)
10109 e_border_desk_set(bd, tmp->desk);
10114 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
10116 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
10119 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
10121 unsigned int xy[2];
10123 ecore_x_window_prop_card32_get(bd->client.win,
10124 ECORE_X_ATOM_E_VIDEO_POSITION,
10127 bd->client.e.state.video_position.x = xy[0];
10128 bd->client.e.state.video_position.y = xy[1];
10129 bd->client.e.state.video_position.updated = 1;
10130 bd->client.e.fetch.video_position = 0;
10131 bd->x = bd->client.e.state.video_position.x;
10132 bd->y = bd->client.e.state.video_position.y;
10134 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
10136 if (bd->client.netwm.update.state)
10138 e_hints_window_state_set(bd);
10139 /* Some stats might change the border, like modal */
10140 if (((!bd->lock_border) || (!bd->client.border.name)) &&
10141 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10143 bd->client.border.changed = 1;
10147 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10149 bd->parent->modal = bd;
10150 if (bd->parent->focused)
10151 e_border_focus_set(bd, 1, 1);
10154 else if (bd->leader)
10156 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10158 bd->leader->modal = bd;
10159 if (bd->leader->focused)
10160 e_border_focus_set(bd, 1, 1);
10166 EINA_LIST_FOREACH(bd->leader->group, l, child)
10168 if ((child != bd) && (child->focused))
10169 e_border_focus_set(bd, 1, 1);
10174 bd->client.netwm.update.state = 0;
10177 if (bd->new_client)
10179 E_Event_Border_Add *ev;
10180 E_Exec_Instance *inst;
10182 ev = E_NEW(E_Event_Border_Add, 1);
10184 e_object_ref(E_OBJECT(bd));
10185 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
10186 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
10188 if ((!bd->lock_border) || (!bd->client.border.name))
10189 bd->client.border.changed = 1;
10194 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
10195 ((bd->client.icccm.client_leader > 0) &&
10196 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10199 if (!strncmp(str, "E_START|", 8))
10203 id = atoi(str + 8);
10204 if (id > 0) bd->client.netwm.startup_id = id;
10209 /* It's ok not to have fetch flag, should only be set on startup
10210 * * and not changed. */
10211 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10213 if (bd->client.icccm.client_leader)
10215 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10216 bd->client.netwm.pid = -1;
10219 bd->client.netwm.pid = -1;
10222 if (!bd->re_manage)
10224 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10225 bd->client.netwm.pid);
10226 if ((inst) && (inst->used == 0))
10232 zone = e_container_zone_number_get(bd->zone->container,
10234 if (zone) e_border_zone_set(bd, zone);
10235 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10237 if (desk) e_border_desk_set(bd, desk);
10238 e_exec_instance_found(inst);
10241 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10243 E_Border *bdl = NULL;
10248 if (bd->leader) bdl = bd->leader;
10255 bl = e_container_border_list_first(bd->zone->container);
10256 while ((child = e_container_border_list_next(bl)))
10258 if (child == bd) continue;
10259 if (e_object_is_del(E_OBJECT(child))) continue;
10260 if ((bd->client.icccm.client_leader) &&
10261 (child->client.icccm.client_leader ==
10262 bd->client.icccm.client_leader))
10268 e_container_border_list_free(bl);
10273 e_border_zone_set(bd, bdl->zone);
10275 e_border_desk_set(bd, bdl->desk);
10277 e_border_stick(bd);
10283 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10286 E_Container *con = bd->zone->container;
10287 E_Desk *desk = NULL;
10290 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10292 desk = e_container_desk_window_profile_get(con, str);
10295 if (bd->desk != desk)
10297 bd->client.e.state.profile = eina_stringshare_add(str);
10298 if (bd->zone != desk->zone)
10299 e_border_zone_set(bd, desk->zone);
10300 e_border_desk_set(bd, desk);
10308 /* PRE_POST_FETCH calls e_remember apply for new client */
10309 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10310 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10311 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10313 #ifdef _F_ZONE_WINDOW_ROTATION_
10314 if (e_config->wm_win_rotation)
10316 if (need_rotation_set)
10318 Eina_Bool hint = EINA_FALSE;
10320 int x, y, w, h, move;
10322 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10323 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10325 if (bd->client.e.state.rot.changes != -1)
10327 ang = bd->client.e.state.rot.changes;
10330 else ang = bd->client.e.state.rot.curr;
10332 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10335 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10336 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10337 bd->client.icccm.name, x, y, w, h);
10343 if (bd->need_reparent)
10346 ecore_x_window_save_set_add(bd->client.win);
10347 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10350 if ((bd->new_client) && (bd->internal) &&
10351 (bd->internal_ecore_evas))
10352 ecore_evas_show(bd->internal_ecore_evas);
10353 ecore_x_window_show(bd->client.win);
10355 bd->need_reparent = 0;
10358 if ((bd->client.border.changed) && (!bd->shaded) &&
10359 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10361 const char *bordername;
10363 if (bd->fullscreen)
10364 bordername = "borderless";
10365 else if (bd->bordername)
10366 bordername = bd->bordername;
10367 else if ((bd->client.mwm.borderless) || (bd->borderless))
10368 bordername = "borderless";
10369 else if (((bd->client.icccm.transient_for != 0) ||
10370 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10371 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10372 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10373 bordername = "noresize_dialog";
10374 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10375 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10376 bordername = "noresize";
10377 else if (bd->client.shaped)
10378 bordername = "shaped";
10379 else if ((!bd->client.icccm.accepts_focus) &&
10380 (!bd->client.icccm.take_focus))
10381 bordername = "nofocus";
10382 else if (bd->client.icccm.urgent)
10383 bordername = "urgent";
10384 else if ((bd->client.icccm.transient_for != 0) ||
10385 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10386 bordername = "dialog";
10387 else if (bd->client.netwm.state.modal)
10388 bordername = "modal";
10389 else if ((bd->client.netwm.state.skip_taskbar) ||
10390 (bd->client.netwm.state.skip_pager))
10391 bordername = "skipped";
10392 else if ((bd->internal) && (bd->client.icccm.class) &&
10393 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10394 bordername = "internal_fileman";
10396 bordername = e_config->theme_default_border_style;
10397 if (!bordername) bordername = "default";
10399 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10405 bd->changes.border = 1;
10406 eina_stringshare_replace(&bd->client.border.name, bordername);
10410 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10411 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10412 bd->changes.size = 1;
10413 evas_object_del(bd->bg_object);
10415 o = edje_object_add(bd->bg_evas);
10416 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10417 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10418 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10420 if (bd->client.border.name != e_config->theme_default_border_style)
10422 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10423 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10427 ok = e_theme_edje_object_set(o, "base/theme/borders",
10428 "e/widgets/border/default/border");
10431 /* Reset default border style to default */
10432 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10433 e_config_save_queue();
10441 const char *shape_option, *argb_option;
10446 if ((e_config->use_composite) && (!bd->client.argb))
10448 argb_option = edje_object_data_get(o, "argb");
10449 if ((argb_option) && (!strcmp(argb_option, "1")))
10452 if (use_argb != bd->argb)
10453 _e_border_frame_replace(bd, use_argb);
10460 shape_option = edje_object_data_get(o, "shaped");
10461 if ((shape_option) && (!strcmp(shape_option, "1")))
10465 if (bd->client.netwm.name)
10466 edje_object_part_text_set(o, "e.text.title",
10467 bd->client.netwm.name);
10468 else if (bd->client.icccm.title)
10469 edje_object_part_text_set(o, "e.text.title",
10470 bd->client.icccm.title);
10474 evas_object_del(o);
10475 bd->bg_object = NULL;
10478 _e_border_client_inset_calc(bd);
10480 bd->w += (bd->client_inset.l + bd->client_inset.r);
10481 bd->h += (bd->client_inset.t + bd->client_inset.b);
10482 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10483 bd->changes.size = 1;
10484 /* really needed ? */
10485 ecore_x_window_move(bd->client.shell_win,
10486 bd->client_inset.l,
10487 bd->client_inset.t);
10489 if (bd->maximized != E_MAXIMIZE_NONE)
10491 E_Maximize maximized = bd->maximized;
10493 /* to force possible resizes */
10494 bd->maximized = E_MAXIMIZE_NONE;
10496 _e_border_maximize(bd, maximized);
10498 /* restore maximized state */
10499 bd->maximized = maximized;
10501 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10502 bd->maximized & E_MAXIMIZE_VERTICAL);
10506 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10507 _e_border_cb_signal_bind, bd);
10510 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10511 if (bd->icon_object)
10512 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10515 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10517 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10519 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10520 // FIXME: in eval -do differently
10521 // edje_object_message_signal_process(bd->bg_object);
10522 // e_border_frame_recalc(bd);
10524 evas_object_move(bd->bg_object, 0, 0);
10525 evas_object_resize(bd->bg_object, bd->w, bd->h);
10526 evas_object_show(bd->bg_object);
10529 bd->client.border.changed = 0;
10531 if (bd->icon_object)
10535 evas_object_show(bd->icon_object);
10536 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10539 evas_object_hide(bd->icon_object);
10543 if (rem_change) e_remember_update(bd);
10547 E_Event_Border_Urgent_Change *ev;
10549 if (bd->client.icccm.urgent)
10550 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10552 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10554 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10556 e_object_ref(E_OBJECT(bd));
10557 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10558 _e_border_event_border_urgent_change_free, NULL);
10561 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10564 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10566 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10568 E_Border* temp_bd = NULL;
10569 E_Border* top_focusable_bd = NULL;
10570 Eina_Bool is_fully_obscured = EINA_FALSE;
10571 Ecore_X_XRegion *visible_region = NULL;
10572 Ecore_X_XRegion *win_region = NULL;
10573 Ecore_X_Rectangle visible_rect, win_rect;
10576 // set the entire visible region as a root geometry
10577 visible_rect.x = bd->zone->x;
10578 visible_rect.y = bd->zone->y;
10579 visible_rect.width = bd->zone->w;
10580 visible_rect.height = bd->zone->h;
10582 visible_region = ecore_x_xregion_new();
10583 if (!visible_region) return;
10585 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10587 bl = e_container_border_list_last(bd->zone->container);
10588 while ((temp_bd = e_container_border_list_prev(bl)))
10590 if (temp_bd == bd) break;
10592 if (temp_bd == focused) continue;
10593 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10594 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10595 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10596 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10597 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10598 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10599 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10600 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10601 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10603 if (!top_focusable_bd)
10605 top_focusable_bd = temp_bd;
10608 win_rect.x = temp_bd->x;
10609 win_rect.y = temp_bd->y;
10610 win_rect.width = temp_bd->w;
10611 win_rect.height = temp_bd->h;
10613 // if it stick out or is bigger than the entire visible region,
10614 // clip it by the entire visible's geometry.
10615 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10616 win_rect.width, win_rect.height,
10617 visible_rect.x, visible_rect.y,
10618 (int)(visible_rect.width), (int)(visible_rect.height));
10620 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10622 win_region = ecore_x_xregion_new();
10625 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10626 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10627 ecore_x_xregion_free(win_region);
10630 if (ecore_x_xregion_is_empty(visible_region))
10632 is_fully_obscured = EINA_TRUE;
10640 if (is_fully_obscured == EINA_TRUE)
10642 e_border_focus_set(top_focusable_bd, 1, 1);
10646 e_border_focus_set(bd, 1, 1);
10649 if (visible_region) ecore_x_xregion_free(visible_region);
10650 e_container_border_list_free(bl);
10654 _e_border_latest_stacked_focus(E_Border *bd)
10657 int root_w, root_h;
10659 root_w = bd->zone->w;
10660 root_h = bd->zone->h;
10663 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10665 if (bd == temp_bd) continue;
10666 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10667 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10669 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10670 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10671 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10672 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10673 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10674 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10675 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10677 _e_border_latest_stacked_focus_check_set(temp_bd);
10684 _e_border_check_stack (E_Border *bd)
10686 E_Border* temp_bd = NULL;
10687 E_Border* top_bd = NULL;
10688 int passed_focus = 0;
10690 int root_w = bd->zone->w;
10691 int root_h = bd->zone->h;
10694 bl = e_container_border_list_last(bd->zone->container);
10695 while ((temp_bd = e_container_border_list_prev(bl)))
10697 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10698 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10699 if ((temp_bd != bd) &&
10700 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10702 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10703 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10704 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10705 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10706 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10707 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10708 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10714 e_border_focus_set_with_pointer(bd);
10721 e_border_focus_set_with_pointer(top_bd);
10730 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10732 if (!bd->lock_focus_out)
10734 e_border_focus_latest_set(bd);
10746 if (temp_bd == focused)
10752 e_container_border_list_free(bl);
10756 _e_border_focus_top_stack_set(E_Border* bd)
10759 int root_w, root_h;
10761 root_w = bd->zone->w;
10762 root_h = bd->zone->h;
10765 bl = e_container_border_list_last(bd->zone->container);
10766 while ((temp_bd = e_container_border_list_prev(bl)))
10768 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10769 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10770 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10772 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10773 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10774 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10775 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10776 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10777 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10778 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10780 if (!temp_bd->focused)
10782 /* this border is the top of the latest stack */
10783 e_border_focus_set (temp_bd, 1, 1);
10788 e_container_border_list_free(bl);
10793 _e_border_eval(E_Border *bd)
10795 E_Event_Border_Property *event;
10796 E_Border_Pending_Move_Resize *pnd;
10797 int rem_change = 0;
10798 int send_event = 1;
10800 if (e_object_is_del(E_OBJECT(bd)))
10802 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10807 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10809 if (bd->new_client)
10811 int zx = 0, zy = 0, zw = 0, zh = 0;
10814 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10817 * Limit maximum size of windows to useful geometry
10819 // TODO: temoporary limited maximize algorithm
10831 if ((rw != bd->w) || (rh != bd->h))
10835 e_border_resize (bd, bd->w, bd->h);
10841 bd->x -= bd->client_inset.l;
10842 bd->y -= bd->client_inset.t;
10843 bd->changes.pos = 1;
10846 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10849 Ecore_X_Window_Attributes *att;
10852 att = &bd->client.initial_attributes;
10853 bw = att->border * 2;
10854 switch (bd->client.icccm.gravity)
10856 case ECORE_X_GRAVITY_N:
10857 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10861 case ECORE_X_GRAVITY_NE:
10862 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10866 case ECORE_X_GRAVITY_E:
10867 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10868 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10871 case ECORE_X_GRAVITY_SE:
10872 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10873 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10876 case ECORE_X_GRAVITY_S:
10877 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10878 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10881 case ECORE_X_GRAVITY_SW:
10883 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10886 case ECORE_X_GRAVITY_W:
10888 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10891 case ECORE_X_GRAVITY_CENTER:
10892 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10893 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10896 case ECORE_X_GRAVITY_NW:
10903 * This ensures that windows that like to open with a x/y
10904 * position smaller than returned by e_zone_useful_geometry_get()
10905 * are moved to useful positions.
10908 if (e_config->geometry_auto_move)
10916 if (bd->x + bd->w > zx + zw)
10917 bd->x = zx + zw - bd->w;
10919 if (bd->y + bd->h > zy + zh)
10920 bd->y = zy + zh - bd->h;
10923 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10925 bd->changes.pos = 1;
10931 bd->changes.pos = 1;
10937 /* FIXME: special placement for dialogs etc. etc. etc goes
10939 /* FIXME: what if parent is not on this desktop - or zone? */
10940 if ((bd->parent) && (bd->parent->visible))
10942 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10943 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10944 bd->changes.pos = 1;
10948 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10950 /* TODO: Place in center of group */
10953 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10955 bd->x = zx + ((zw - bd->w) / 2);
10956 bd->y = zy + ((zh - bd->h) / 2);
10957 bd->changes.pos = 1;
10963 Eina_List *skiplist = NULL;
10967 new_x = zx + (rand() % (zw - bd->w));
10971 new_y = zy + (rand() % (zh - bd->h));
10975 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10977 skiplist = eina_list_append(skiplist, bd);
10979 e_place_desk_region_smart(bd->desk, skiplist,
10980 bd->x, bd->y, bd->w, bd->h,
10983 e_place_zone_region_smart(bd->zone, skiplist,
10984 bd->x, bd->y, bd->w, bd->h,
10986 eina_list_free(skiplist);
10988 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10990 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10995 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10996 bd->client_inset.t, &new_x, &new_y);
11000 bd->changes.pos = 1;
11003 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11005 if ((!bd->lock_client_location) && (pnd->move))
11009 bd->changes.pos = 1;
11011 if (pnd->without_border)
11013 bd->x -= bd->client_inset.l;
11014 bd->y -= bd->client_inset.t;
11017 if ((!bd->lock_client_size) && (pnd->resize))
11019 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
11020 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
11021 bd->client.w = pnd->w;
11022 bd->client.h = pnd->h;
11023 bd->changes.size = 1;
11029 /* Recreate state */
11030 e_hints_window_init(bd);
11031 if ((bd->client.e.state.centered) &&
11032 ((!bd->remember) ||
11033 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
11035 bd->x = zx + (zw - bd->w) / 2;
11036 bd->y = zy + (zh - bd->h) / 2;
11037 bd->changes.pos = 1;
11041 _e_border_client_move_resize_send(bd);
11043 /* if the explicit geometry request asks for the app to be
11044 * in another zone - well move it there */
11048 zone = e_container_zone_at_point_get(bd->zone->container,
11049 bd->x + (bd->w / 2),
11050 bd->y + (bd->h / 2));
11052 zone = e_container_zone_at_point_get(bd->zone->container,
11056 zone = e_container_zone_at_point_get(bd->zone->container,
11060 zone = e_container_zone_at_point_get(bd->zone->container,
11062 bd->y + bd->h - 1);
11064 zone = e_container_zone_at_point_get(bd->zone->container,
11066 bd->y + bd->h - 1);
11067 if ((zone) && (zone != bd->zone))
11068 e_border_zone_set(bd, zone);
11072 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
11074 /* effect changes to the window border itself */
11075 if ((bd->changes.shading))
11077 /* show at start of unshade (but don't hide until end of shade) */
11079 ecore_x_window_raise(bd->client.shell_win);
11080 bd->changes.shading = 0;
11083 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
11086 ecore_x_window_lower(bd->client.shell_win);
11088 ecore_x_window_raise(bd->client.shell_win);
11089 bd->changes.shaded = 0;
11092 else if ((bd->changes.shaded) && (bd->changes.pos))
11095 ecore_x_window_lower(bd->client.shell_win);
11097 ecore_x_window_raise(bd->client.shell_win);
11098 bd->changes.size = 1;
11099 bd->changes.shaded = 0;
11102 else if ((bd->changes.shaded) && (bd->changes.size))
11105 ecore_x_window_lower(bd->client.shell_win);
11107 ecore_x_window_raise(bd->client.shell_win);
11108 bd->changes.shaded = 0;
11111 else if (bd->changes.shaded)
11114 ecore_x_window_lower(bd->client.shell_win);
11116 ecore_x_window_raise(bd->client.shell_win);
11117 bd->changes.size = 1;
11118 bd->changes.shaded = 0;
11122 if (bd->changes.size)
11124 int x = 0, y = 0, xx = 0, yy = 0;
11126 if ((bd->shaded) && (!bd->shading))
11128 evas_obscured_clear(bd->bg_evas);
11132 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
11133 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
11135 evas_obscured_clear(bd->bg_evas);
11136 evas_obscured_rectangle_add(bd->bg_evas,
11137 bd->client_inset.l, bd->client_inset.t, xx, yy);
11141 if (bd->shade.dir == E_DIRECTION_UP)
11143 y = yy - bd->client.h;
11145 else if (bd->shade.dir == E_DIRECTION_LEFT)
11147 x = xx - bd->client.w;
11152 if (bd->client.e.state.video)
11154 if (bd->client.e.state.video_position.updated)
11156 ecore_x_window_move(bd->win,
11157 bd->client.e.state.video_parent_border->x +
11158 bd->client.e.state.video_parent_border->client_inset.l +
11159 bd->client.e.state.video_parent_border->fx.x +
11160 bd->client.e.state.video_position.x,
11161 bd->client.e.state.video_parent_border->y +
11162 bd->client.e.state.video_parent_border->client_inset.t +
11163 bd->client.e.state.video_parent_border->fx.y +
11164 bd->client.e.state.video_position.y);
11165 bd->client.e.state.video_position.updated = 0;
11168 else if (!bd->changes.pos)
11170 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11171 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11172 bd->post_resize = 1;
11179 ecore_x_window_move_resize(bd->win,
11184 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
11185 ecore_x_window_move(tmp->win,
11186 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
11187 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
11190 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
11192 if ((!bd->shaded) || (bd->shading))
11193 ecore_x_window_move_resize(bd->client.shell_win,
11194 bd->client_inset.l, bd->client_inset.t, xx, yy);
11196 if (bd->internal_ecore_evas)
11197 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
11198 else if (!bd->client.e.state.video)
11199 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11201 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11202 evas_object_resize(bd->bg_object, bd->w, bd->h);
11203 e_container_shape_resize(bd->shape, bd->w, bd->h);
11204 if (bd->changes.pos)
11205 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11207 _e_border_client_move_resize_send(bd);
11209 bd->changes.pos = 0;
11210 bd->changes.size = 0;
11213 else if (bd->changes.pos)
11215 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11216 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11219 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11221 _e_border_client_move_resize_send(bd);
11223 bd->changes.pos = 0;
11227 if (bd->changes.reset_gravity)
11229 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11230 bd->changes.reset_gravity = 0;
11234 if (bd->need_shape_merge)
11236 _e_border_shape_input_rectangle_set(bd);
11237 if ((bd->shaped) || (bd->client.shaped))
11239 Ecore_X_Window twin, twin2;
11242 twin = ecore_x_window_override_new
11243 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11245 ecore_x_window_shape_window_set(twin, bd->bg_win);
11248 Ecore_X_Rectangle rects[4];
11252 rects[0].width = bd->w;
11253 rects[0].height = bd->client_inset.t;
11255 rects[1].y = bd->client_inset.t;
11256 rects[1].width = bd->client_inset.l;
11257 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11258 rects[2].x = bd->w - bd->client_inset.r;
11259 rects[2].y = bd->client_inset.t;
11260 rects[2].width = bd->client_inset.r;
11261 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11263 rects[3].y = bd->h - bd->client_inset.b;
11264 rects[3].width = bd->w;
11265 rects[3].height = bd->client_inset.b;
11266 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11268 twin2 = ecore_x_window_override_new
11269 (bd->zone->container->scratch_win, 0, 0,
11270 bd->w - bd->client_inset.l - bd->client_inset.r,
11271 bd->h - bd->client_inset.t - bd->client_inset.b);
11274 if ((bd->shading) || (bd->shaded))
11276 if (bd->shade.dir == E_DIRECTION_UP)
11277 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11278 else if (bd->shade.dir == E_DIRECTION_LEFT)
11279 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11281 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11283 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11284 bd->w - bd->client_inset.l - bd->client_inset.r,
11285 bd->h - bd->client_inset.t - bd->client_inset.b);
11286 ecore_x_window_shape_window_add_xy(twin, twin2,
11287 bd->client_inset.l,
11288 bd->client_inset.t);
11289 ecore_x_window_free(twin2);
11290 ecore_x_window_shape_window_set(bd->win, twin);
11291 ecore_x_window_free(twin);
11294 ecore_x_window_shape_mask_set(bd->win, 0);
11295 // bd->need_shape_export = 1;
11296 bd->need_shape_merge = 0;
11299 if (bd->need_shape_export)
11301 Ecore_X_Rectangle *rects, *orects;
11304 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11310 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11314 orects = bd->shape_rects;
11316 for (i = 0; i < num; i++)
11318 if (rects[i].x < 0)
11320 rects[i].width -= rects[i].x;
11323 if ((rects[i].x + (int)rects[i].width) > bd->w)
11324 rects[i].width = rects[i].width - rects[i].x;
11325 if (rects[i].y < 0)
11327 rects[i].height -= rects[i].y;
11330 if ((rects[i].y + (int)rects[i].height) > bd->h)
11331 rects[i].height = rects[i].height - rects[i].y;
11333 if ((orects[i].x != rects[i].x) ||
11334 (orects[i].y != rects[i].y) ||
11335 (orects[i].width != rects[i].width) ||
11336 (orects[i].height != rects[i].height))
11345 if (bd->client.shaped)
11346 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11348 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11349 E_FREE(bd->shape_rects);
11350 bd->shape_rects = rects;
11351 bd->shape_rects_num = num;
11352 e_container_shape_rects_set(bd->shape, rects, num);
11359 E_FREE(bd->shape_rects);
11360 bd->shape_rects = NULL;
11361 bd->shape_rects_num = 0;
11362 e_container_shape_rects_set(bd->shape, NULL, 0);
11364 bd->need_shape_export = 0;
11367 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11371 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11372 if ((!bd->placed) && (!bd->re_manage) &&
11373 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11374 (!((bd->client.icccm.transient_for != 0) ||
11375 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11376 (!bdmove) && (!bdresize))
11378 /* Set this window into moving state */
11380 bd->cur_mouse_action = e_action_find("window_move");
11381 if (bd->cur_mouse_action)
11383 if ((!bd->cur_mouse_action->func.end_mouse) &&
11384 (!bd->cur_mouse_action->func.end))
11385 bd->cur_mouse_action = NULL;
11386 if (bd->cur_mouse_action)
11388 bd->x = x - (bd->w >> 1);
11389 bd->y = y - (bd->client_inset.t >> 1);
11391 bd->changes.pos = 1;
11393 _e_border_client_move_resize_send(bd);
11398 _e_border_show(bd);
11400 if (bd->cur_mouse_action)
11402 bd->moveinfo.down.x = bd->x + bd->fx.x;
11403 bd->moveinfo.down.y = bd->y + bd->fx.y;
11404 bd->moveinfo.down.w = bd->w;
11405 bd->moveinfo.down.h = bd->h;
11406 bd->mouse.current.mx = x;
11407 bd->mouse.current.my = y;
11408 bd->moveinfo.down.button = 0;
11409 bd->moveinfo.down.mx = x;
11410 bd->moveinfo.down.my = y;
11413 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11414 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11415 if (e_config->border_raise_on_mouse_action)
11416 e_border_raise(bd);
11417 e_border_focus_set(bd, 1, 1);
11419 bd->changes.visible = 0;
11423 if (bd->changes.icon)
11427 efreet_desktop_free(bd->desktop);
11428 bd->desktop = NULL;
11430 if (bd->icon_object)
11432 evas_object_del(bd->icon_object);
11433 bd->icon_object = NULL;
11435 if (bd->remember && bd->remember->prop.desktop_file)
11437 const char *desktop = bd->remember->prop.desktop_file;
11439 bd->desktop = efreet_desktop_get(desktop);
11441 bd->desktop = efreet_util_desktop_name_find(desktop);
11445 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11446 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11447 bd->client.icccm.class);
11451 /* libreoffice and maybe others match window class
11452 with .desktop file name */
11453 if (bd->client.icccm.class)
11456 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11457 bd->desktop = efreet_util_desktop_file_id_find(buf);
11462 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11463 bd->client.netwm.pid);
11464 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11466 if (!bd->desktop && bd->client.icccm.name)
11468 /* this works for most cases as fallback. useful when app is
11469 run from a shell */
11470 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11472 if (!bd->desktop && bd->client.icccm.transient_for)
11474 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11475 if (bd2 && bd2->desktop)
11477 efreet_desktop_ref(bd2->desktop);
11478 bd->desktop = bd2->desktop;
11483 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11484 bd->desktop->orig_path);
11487 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11488 if ((bd->focused) && (bd->icon_object))
11489 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11492 evas_object_show(bd->icon_object);
11493 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11496 evas_object_hide(bd->icon_object);
11499 E_Event_Border_Icon_Change *ev;
11501 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11503 e_object_ref(E_OBJECT(bd));
11504 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11505 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11506 _e_border_event_border_icon_change_free, NULL);
11508 bd->changes.icon = 0;
11511 bd->new_client = 0;
11513 bd->changes.stack = 0;
11514 bd->changes.prop = 0;
11516 if (bd->client.e.state.rot.changes != -1)
11518 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11519 bd->client.e.state.rot.changes = -1;
11522 if ((bd->take_focus) || (bd->want_focus))
11524 bd->take_focus = 0;
11525 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11526 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11527 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11530 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11533 bd->want_focus = 0;
11534 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11535 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11536 _e_border_check_stack(bd);
11539 e_border_focus_set_with_pointer(bd);
11541 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11543 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11544 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11545 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11546 e_border_focused_get())))
11548 e_border_focus_set_with_pointer(bd);
11553 /* focus window by default when it is the only one on desk */
11554 E_Border *bd2 = NULL;
11556 EINA_LIST_FOREACH(focus_stack, l, bd2)
11558 if (bd == bd2) continue;
11559 if ((!bd2->iconic) && (bd2->visible) &&
11560 ((bd->desk == bd2->desk) || bd2->sticky))
11566 e_border_focus_set_with_pointer(bd);
11571 if (bd->need_maximize)
11574 max = bd->maximized;
11575 bd->maximized = E_MAXIMIZE_NONE;
11576 e_border_maximize(bd, max);
11577 bd->need_maximize = 0;
11580 if (bd->need_fullscreen)
11582 e_border_fullscreen(bd, e_config->fullscreen_policy);
11583 bd->need_fullscreen = 0;
11587 e_remember_update(bd);
11589 if (send_event) // FIXME: send only if a property changed - above need to
11590 { // check on that. for now - always send.
11591 event = E_NEW(E_Event_Border_Property, 1);
11592 event->border = bd;
11593 e_object_ref(E_OBJECT(bd));
11594 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11596 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11600 _e_border_moveinfo_gather(E_Border *bd,
11601 const char *source)
11603 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11604 else if (e_util_glob_match(source, "mouse,*,2"))
11605 bd->moveinfo.down.button = 2;
11606 else if (e_util_glob_match(source, "mouse,*,3"))
11607 bd->moveinfo.down.button = 3;
11608 else bd->moveinfo.down.button = 0;
11609 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11611 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11612 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11616 bd->moveinfo.down.mx = bd->mouse.current.mx;
11617 bd->moveinfo.down.my = bd->mouse.current.my;
11622 _e_border_resize_handle(E_Border *bd)
11625 int new_x, new_y, new_w, new_h;
11627 Eina_List *skiplist = NULL;
11634 if ((bd->resize_mode == RESIZE_TR) ||
11635 (bd->resize_mode == RESIZE_R) ||
11636 (bd->resize_mode == RESIZE_BR))
11638 if ((bd->moveinfo.down.button >= 1) &&
11639 (bd->moveinfo.down.button <= 3))
11640 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11641 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11643 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11645 else if ((bd->resize_mode == RESIZE_TL) ||
11646 (bd->resize_mode == RESIZE_L) ||
11647 (bd->resize_mode == RESIZE_BL))
11649 if ((bd->moveinfo.down.button >= 1) &&
11650 (bd->moveinfo.down.button <= 3))
11651 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11652 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11654 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11657 if ((bd->resize_mode == RESIZE_TL) ||
11658 (bd->resize_mode == RESIZE_T) ||
11659 (bd->resize_mode == RESIZE_TR))
11661 if ((bd->moveinfo.down.button >= 1) &&
11662 (bd->moveinfo.down.button <= 3))
11663 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11664 (bd->mouse.current.my - bd->moveinfo.down.my);
11666 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11668 else if ((bd->resize_mode == RESIZE_BL) ||
11669 (bd->resize_mode == RESIZE_B) ||
11670 (bd->resize_mode == RESIZE_BR))
11672 if ((bd->moveinfo.down.button >= 1) &&
11673 (bd->moveinfo.down.button <= 3))
11674 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11675 (bd->mouse.current.my - bd->moveinfo.down.my);
11677 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11683 if ((bd->resize_mode == RESIZE_TL) ||
11684 (bd->resize_mode == RESIZE_L) ||
11685 (bd->resize_mode == RESIZE_BL))
11687 if ((bd->resize_mode == RESIZE_TL) ||
11688 (bd->resize_mode == RESIZE_T) ||
11689 (bd->resize_mode == RESIZE_TR))
11692 skiplist = eina_list_append(skiplist, bd);
11693 e_resist_container_border_position(bd->zone->container, skiplist,
11694 bd->x, bd->y, bd->w, bd->h,
11696 &new_x, &new_y, &new_w, &new_h);
11697 eina_list_free(skiplist);
11701 e_border_resize_limit(bd, &new_w, &new_h);
11702 if ((bd->resize_mode == RESIZE_TL) ||
11703 (bd->resize_mode == RESIZE_L) ||
11704 (bd->resize_mode == RESIZE_BL))
11705 new_x += (w - new_w);
11706 if ((bd->resize_mode == RESIZE_TL) ||
11707 (bd->resize_mode == RESIZE_T) ||
11708 (bd->resize_mode == RESIZE_TR))
11709 new_y += (h - new_h);
11711 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11715 _e_border_shade_animator(void *data)
11717 E_Border *bd = data;
11719 double dur = bd->client.h / e_config->border_shade_speed;
11721 dt = ecore_loop_time_get() - bd->shade.start;
11724 if (val < 0.0) val = 0.0;
11725 else if (val > 1.0) val = 1.0;
11727 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11730 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11731 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11733 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11736 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11737 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11739 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11742 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11743 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11745 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11748 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11749 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11751 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11754 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11755 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11757 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11760 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11761 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11763 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11766 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11767 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11769 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11772 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11773 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11775 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11778 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11779 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11784 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11785 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11788 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11789 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11790 else if (bd->shade.val > .999)
11791 bd->shade.val = 1.0;
11793 if (bd->shade.dir == E_DIRECTION_UP)
11794 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11795 else if (bd->shade.dir == E_DIRECTION_DOWN)
11797 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11798 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11799 bd->changes.pos = 1;
11801 else if (bd->shade.dir == E_DIRECTION_LEFT)
11802 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11803 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11805 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11806 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11807 bd->changes.pos = 1;
11810 if ((bd->shaped) || (bd->client.shaped))
11812 bd->need_shape_merge = 1;
11813 bd->need_shape_export = 1;
11815 if (bd->shaped_input)
11817 bd->need_shape_merge = 1;
11819 bd->changes.size = 1;
11825 E_Event_Border_Resize *ev;
11828 bd->shaded = !(bd->shaded);
11829 bd->changes.size = 1;
11830 bd->changes.shaded = 1;
11831 bd->changes.shading = 1;
11833 bd->shade.anim = NULL;
11836 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11838 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11839 edje_object_message_signal_process(bd->bg_object);
11840 e_border_frame_recalc(bd);
11842 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11843 ev = E_NEW(E_Event_Border_Resize, 1);
11845 e_object_ref(E_OBJECT(bd));
11846 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11847 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11848 return ECORE_CALLBACK_CANCEL;
11850 return ECORE_CALLBACK_RENEW;
11854 _e_border_event_border_resize_free(void *data __UNUSED__,
11857 E_Event_Border_Resize *e;
11860 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11861 e_object_unref(E_OBJECT(e->border));
11866 _e_border_event_border_move_free(void *data __UNUSED__,
11869 E_Event_Border_Move *e;
11872 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11873 e_object_unref(E_OBJECT(e->border));
11878 _e_border_event_border_add_free(void *data __UNUSED__,
11881 E_Event_Border_Add *e;
11884 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11885 e_object_unref(E_OBJECT(e->border));
11890 _e_border_event_border_remove_free(void *data __UNUSED__,
11893 E_Event_Border_Remove *e;
11896 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11897 e_object_unref(E_OBJECT(e->border));
11902 _e_border_event_border_show_free(void *data __UNUSED__,
11905 E_Event_Border_Show *e;
11908 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11909 e_object_unref(E_OBJECT(e->border));
11914 _e_border_event_border_hide_free(void *data __UNUSED__,
11917 E_Event_Border_Hide *e;
11920 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11921 e_object_unref(E_OBJECT(e->border));
11926 _e_border_event_border_iconify_free(void *data __UNUSED__,
11929 E_Event_Border_Iconify *e;
11932 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11933 e_object_unref(E_OBJECT(e->border));
11938 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11941 E_Event_Border_Uniconify *e;
11944 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11945 e_object_unref(E_OBJECT(e->border));
11950 _e_border_event_border_stick_free(void *data __UNUSED__,
11953 E_Event_Border_Stick *e;
11956 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11957 e_object_unref(E_OBJECT(e->border));
11962 _e_border_event_border_unstick_free(void *data __UNUSED__,
11965 E_Event_Border_Unstick *e;
11968 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11969 e_object_unref(E_OBJECT(e->border));
11974 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11977 E_Event_Border_Zone_Set *e;
11980 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11981 e_object_unref(E_OBJECT(e->border));
11982 e_object_unref(E_OBJECT(e->zone));
11987 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11990 E_Event_Border_Desk_Set *e;
11993 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11994 e_object_unref(E_OBJECT(e->border));
11995 e_object_unref(E_OBJECT(e->desk));
12000 _e_border_event_border_stack_free(void *data __UNUSED__,
12003 E_Event_Border_Stack *e;
12006 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
12007 e_object_unref(E_OBJECT(e->border));
12010 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
12011 e_object_unref(E_OBJECT(e->stack));
12017 _e_border_event_border_icon_change_free(void *data __UNUSED__,
12020 E_Event_Border_Icon_Change *e;
12023 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
12024 e_object_unref(E_OBJECT(e->border));
12029 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
12032 E_Event_Border_Urgent_Change *e;
12035 e_object_unref(E_OBJECT(e->border));
12040 _e_border_event_border_focus_in_free(void *data __UNUSED__,
12043 E_Event_Border_Focus_In *e;
12046 e_object_unref(E_OBJECT(e->border));
12051 _e_border_event_border_focus_out_free(void *data __UNUSED__,
12054 E_Event_Border_Focus_Out *e;
12057 e_object_unref(E_OBJECT(e->border));
12062 _e_border_event_border_property_free(void *data __UNUSED__,
12065 E_Event_Border_Property *e;
12068 e_object_unref(E_OBJECT(e->border));
12073 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
12076 E_Event_Border_Fullscreen *e;
12079 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
12080 e_object_unref(E_OBJECT(e->border));
12085 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
12088 E_Event_Border_Unfullscreen *e;
12091 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
12092 e_object_unref(E_OBJECT(e->border));
12096 #ifdef _F_ZONE_WINDOW_ROTATION_
12098 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
12101 E_Event_Border_Rotation_Change_Begin *e;
12103 e_object_unref(E_OBJECT(e->border));
12108 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
12111 E_Event_Border_Rotation_Change_Cancel *e;
12113 e_object_unref(E_OBJECT(e->border));
12118 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
12121 E_Event_Border_Rotation_Change_End *e;
12123 e_object_unref(E_OBJECT(e->border));
12128 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
12130 E_Event_Border_Rotation_Change_Begin *ev = NULL;
12131 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
12135 e_object_ref(E_OBJECT(bd));
12136 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
12138 _e_border_event_border_rotation_change_begin_free,
12145 _e_border_zone_update(E_Border *bd)
12151 /* still within old zone - leave it there */
12152 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12153 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
12154 #if _F_BORDER_CLIP_TO_ZONE_
12156 _e_border_shape_input_clip_to_zone(bd);
12161 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12162 /* find a new zone */
12163 con = bd->zone->container;
12164 EINA_LIST_FOREACH(con->zones, l, zone)
12166 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12167 zone->x, zone->y, zone->w, zone->h))
12169 e_border_zone_set(bd, zone);
12170 #if _F_BORDER_CLIP_TO_ZONE_
12171 _e_border_shape_input_clip_to_zone(bd);
12172 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12179 _e_border_resize_begin(E_Border *bd)
12183 if (!bd->lock_user_stacking)
12185 if (e_config->border_raise_on_mouse_action)
12186 e_border_raise(bd);
12188 if ((bd->shaded) || (bd->shading) ||
12189 (bd->fullscreen) || (bd->lock_user_size))
12192 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12193 ret = e_grabinput_get(bd->win, 0, bd->win);
12195 ret = e_grabinput_get(bd->win, 0, 0);
12197 if (grabbed && !ret)
12203 if (bd->client.netwm.sync.request)
12205 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12206 bd->client.netwm.sync.serial = 1;
12207 bd->client.netwm.sync.wait = 0;
12208 bd->client.netwm.sync.send_time = ecore_loop_time_get();
12211 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12218 _e_border_resize_end(E_Border *bd)
12222 e_grabinput_release(bd->win, bd->win);
12225 if (bd->client.netwm.sync.alarm)
12227 E_Border_Pending_Move_Resize *pnd;
12229 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12230 bd->client.netwm.sync.alarm = 0;
12231 /* resize to last geometry if sync alarm for it was not yet handled */
12232 if (bd->pending_move_resize)
12235 bd->changes.pos = 1;
12236 bd->changes.size = 1;
12237 _e_border_client_move_resize_send(bd);
12240 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12244 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12248 /* If this border was maximized, we need to unset Maximized state or
12249 * on restart, E still thinks it's maximized */
12250 if (bd->maximized != E_MAXIMIZE_NONE)
12251 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12252 bd->maximized & E_MAXIMIZE_NONE);
12257 _e_border_resize_update(E_Border *bd)
12259 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12263 _e_border_move_begin(E_Border *bd)
12266 if (!bd->lock_user_stacking)
12268 if (e_config->border_raise_on_mouse_action)
12269 e_border_raise(bd);
12271 if ((bd->fullscreen) || (bd->lock_user_location))
12274 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12275 ret = e_grabinput_get(bd->win, 0, bd->win);
12277 ret = e_grabinput_get(bd->win, 0, 0);
12279 if (grabbed && !ret)
12285 if (bd->client.netwm.sync.request)
12287 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12288 bd->client.netwm.sync.serial = 0;
12289 bd->client.netwm.sync.wait = 0;
12290 bd->client.netwm.sync.time = ecore_loop_time_get();
12293 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12300 _e_border_move_end(E_Border *bd)
12304 e_grabinput_release(bd->win, bd->win);
12308 if (bd->client.netwm.sync.alarm)
12310 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12311 bd->client.netwm.sync.alarm = 0;
12314 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12321 _e_border_move_update(E_Border *bd)
12323 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12327 _e_border_cb_ping_poller(void *data)
12337 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12338 if (bd->kill_timer)
12340 ecore_timer_del(bd->kill_timer);
12341 bd->kill_timer = NULL;
12347 /* if time between last ping and now is greater
12348 * than half the ping interval... */
12349 if ((ecore_loop_time_get() - bd->ping) >
12350 ((e_config->ping_clients_interval *
12351 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12356 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12357 /* FIXME: if below dialog is up - hide it now */
12359 if (bd->delete_requested)
12361 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12362 e_border_act_kill_begin(bd);
12366 bd->ping_poller = NULL;
12368 return ECORE_CALLBACK_CANCEL;
12372 _e_border_cb_kill_timer(void *data)
12377 // dont wait until it's hung -
12380 if (bd->client.netwm.pid > 1)
12381 kill(bd->client.netwm.pid, SIGKILL);
12383 bd->kill_timer = NULL;
12384 return ECORE_CALLBACK_CANCEL;
12388 _e_border_pointer_resize_begin(E_Border *bd)
12390 switch (bd->resize_mode)
12393 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12397 e_pointer_type_push(bd->pointer, bd, "resize_t");
12401 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12405 e_pointer_type_push(bd->pointer, bd, "resize_r");
12409 e_pointer_type_push(bd->pointer, bd, "resize_br");
12413 e_pointer_type_push(bd->pointer, bd, "resize_b");
12417 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12421 e_pointer_type_push(bd->pointer, bd, "resize_l");
12427 _e_border_pointer_resize_end(E_Border *bd)
12429 switch (bd->resize_mode)
12432 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12436 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12440 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12444 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12448 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12452 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12456 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12460 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12466 _e_border_pointer_move_begin(E_Border *bd)
12468 e_pointer_type_push(bd->pointer, bd, "move");
12472 _e_border_pointer_move_end(E_Border *bd)
12474 e_pointer_type_pop(bd->pointer, bd, "move");
12477 static Eina_List *_e_border_hooks = NULL;
12478 static int _e_border_hooks_delete = 0;
12479 static int _e_border_hooks_walking = 0;
12482 _e_border_hooks_clean(void)
12487 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12491 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12498 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12504 _e_border_hooks_walking++;
12505 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12507 if (bh->delete_me) continue;
12508 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12510 _e_border_hooks_walking--;
12511 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12512 _e_border_hooks_clean();
12515 EAPI E_Border_Hook *
12516 e_border_hook_add(E_Border_Hook_Point hookpoint,
12517 void (*func)(void *data,
12523 bh = E_NEW(E_Border_Hook, 1);
12524 if (!bh) return NULL;
12525 bh->hookpoint = hookpoint;
12528 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12533 e_border_hook_del(E_Border_Hook *bh)
12536 if (_e_border_hooks_walking == 0)
12538 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12542 _e_border_hooks_delete++;
12546 e_border_focus_track_freeze(void)
12548 focus_track_frozen++;
12552 e_border_focus_track_thaw(void)
12554 focus_track_frozen--;
12558 e_border_under_pointer_get(E_Desk *desk,
12561 E_Border *bd = NULL, *cbd;
12565 /* We need to ensure that we can get the container window for the
12566 * zone of either the given desk or the desk of the excluded
12567 * window, so return if neither is given */
12569 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12571 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12575 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12577 if (!cbd) continue;
12578 /* If a border was specified which should be excluded from the list
12579 * (because it will be closed shortly for example), skip */
12580 if ((exclude) && (cbd == exclude)) continue;
12581 if ((desk) && (cbd->desk != desk)) continue;
12582 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12584 /* If the layer is higher, the position of the window is higher
12585 * (always on top vs always below) */
12586 if (!bd || (cbd->layer > bd->layer))
12596 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12603 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12604 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12605 (y - warp_y) > 5 || (y - warp_y) < -5)
12607 /* User moved the mouse, so stop warping */
12612 /* We just use the same warp speed as configured
12613 * for the windowlist */
12614 spd = e_config->winlist_warp_speed;
12617 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12618 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12619 if (warp_x == x && warp_y == y)
12621 warp_x = warp_to_x;
12622 warp_y = warp_to_y;
12626 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12627 return ECORE_CALLBACK_RENEW;
12630 ecore_timer_del(warp_timer);
12632 return ECORE_CALLBACK_CANCEL;
12636 e_border_pointer_warp_to_center(E_Border *bd)
12640 /* Do not slide pointer when disabled (probably breaks focus
12641 * on sloppy/mouse focus but requested by users). */
12642 if (!e_config->pointer_slide) return 0;
12643 /* Only warp the pointer if it is not already in the area of
12644 * the given border */
12645 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12646 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12647 (y >= bd->y) && (y <= (bd->y + bd->h)))
12650 warp_to_x = bd->x + (bd->w / 2);
12651 if (warp_to_x < (bd->zone->x + 1))
12652 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12653 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12654 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12656 warp_to_y = bd->y + (bd->h / 2);
12657 if (warp_to_y < (bd->zone->y + 1))
12658 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12659 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12660 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12663 warp_to_win = bd->zone->container->win;
12664 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12666 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12671 e_border_comp_hidden_set(E_Border *bd,
12677 E_OBJECT_CHECK(bd);
12678 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12680 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12683 ecore_x_window_hide(tmp->win);
12685 ecore_x_window_show(tmp->win);
12688 if (bd->comp_hidden == hidden) return;
12690 bd->comp_hidden = hidden;
12692 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12694 ecore_x_composite_window_events_disable(bd->win);
12695 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12699 _e_border_shape_input_rectangle_set(bd);
12700 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12705 e_border_tmp_input_hidden_push(E_Border *bd)
12710 E_OBJECT_CHECK(bd);
12711 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12713 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12714 e_border_tmp_input_hidden_push(tmp);
12716 bd->tmp_input_hidden++;
12717 if (bd->tmp_input_hidden != 1) return;
12719 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12721 ecore_x_composite_window_events_disable(bd->win);
12722 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12726 _e_border_shape_input_rectangle_set(bd);
12727 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12732 e_border_tmp_input_hidden_pop(E_Border *bd)
12737 E_OBJECT_CHECK(bd);
12738 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12740 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12741 e_border_tmp_input_hidden_pop(tmp);
12743 bd->tmp_input_hidden--;
12744 if (bd->tmp_input_hidden != 0) return;
12746 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12748 ecore_x_composite_window_events_disable(bd->win);
12749 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12753 _e_border_shape_input_rectangle_set(bd);
12754 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12759 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12761 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12763 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12764 ((bd->parent->focused) &&
12765 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12770 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12771 e_desk_show(bd->desk);
12773 if (!bd->lock_user_iconify)
12774 e_border_uniconify(bd);
12776 if ((!bd->iconic) && (!bd->sticky))
12777 e_desk_show(bd->desk);
12778 if (!bd->lock_user_stacking) e_border_raise(bd);
12779 if (!bd->lock_focus_out)
12781 /* XXX ooffice does send this request for
12782 config dialogs when the main window gets focus.
12783 causing the pointer to jump back and forth. */
12784 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12785 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12786 ecore_x_pointer_warp(bd->zone->container->win,
12787 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12788 e_border_focus_set(bd, 1, 1);
12792 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/