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);
184 static void _e_border_move_resize_internal(E_Border *bd,
189 Eina_Bool without_border,
192 static void _e_border_eval(E_Border *bd);
193 static void _e_border_eval0(E_Border *bd);
194 static void _e_border_container_layout_hook(E_Container *con);
196 static void _e_border_moveinfo_gather(E_Border *bd,
198 static void _e_border_resize_handle(E_Border *bd);
200 static Eina_Bool _e_border_shade_animator(void *data);
202 static void _e_border_event_border_add_free(void *data,
204 static void _e_border_event_border_remove_free(void *data,
206 static void _e_border_event_border_zone_set_free(void *data,
208 static void _e_border_event_border_desk_set_free(void *data,
210 static void _e_border_event_border_stack_free(void *data,
212 static void _e_border_event_border_icon_change_free(void *data,
214 static void _e_border_event_border_urgent_change_free(void *data,
216 static void _e_border_event_border_focus_in_free(void *data,
218 static void _e_border_event_border_focus_out_free(void *data,
220 static void _e_border_event_border_resize_free(void *data,
222 static void _e_border_event_border_move_free(void *data,
224 static void _e_border_event_border_show_free(void *data,
226 static void _e_border_event_border_hide_free(void *data,
228 static void _e_border_event_border_iconify_free(void *data,
230 static void _e_border_event_border_uniconify_free(void *data,
232 static void _e_border_event_border_stick_free(void *data,
234 static void _e_border_event_border_unstick_free(void *data,
236 static void _e_border_event_border_property_free(void *data,
238 static void _e_border_event_border_fullscreen_free(void *data,
240 static void _e_border_event_border_unfullscreen_free(void *data,
242 #ifdef _F_ZONE_WINDOW_ROTATION_
243 static void _e_border_event_border_rotation_change_begin_free(void *data,
245 static void _e_border_event_border_rotation_change_cancel_free(void *data,
247 static void _e_border_event_border_rotation_change_end_free(void *data,
249 static void _e_border_event_border_rotation_change_begin_send(E_Border *bd);
252 static void _e_border_zone_update(E_Border *bd);
254 static int _e_border_resize_begin(E_Border *bd);
255 static int _e_border_resize_end(E_Border *bd);
256 static void _e_border_resize_update(E_Border *bd);
258 static int _e_border_move_begin(E_Border *bd);
259 static int _e_border_move_end(E_Border *bd);
260 static void _e_border_move_update(E_Border *bd);
262 static Eina_Bool _e_border_cb_ping_poller(void *data);
263 static Eina_Bool _e_border_cb_kill_timer(void *data);
265 static void _e_border_pointer_resize_begin(E_Border *bd);
266 static void _e_border_pointer_resize_end(E_Border *bd);
267 static void _e_border_pointer_move_begin(E_Border *bd);
268 static void _e_border_pointer_move_end(E_Border *bd);
270 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
273 static void _e_border_client_move_resize_send(E_Border *bd);
275 static void _e_border_frame_replace(E_Border *bd,
278 static void _e_border_shape_input_rectangle_set(E_Border* bd);
279 static void _e_border_show(E_Border *bd);
280 static void _e_border_hide(E_Border *bd);
283 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
284 static void _e_border_latest_stacked_focus (E_Border* bd);
285 static void _e_border_check_stack (E_Border *bd);
286 static void _e_border_focus_top_stack_set (E_Border* bd);
288 #if _F_BORDER_CLIP_TO_ZONE_
289 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
290 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
291 /* local subsystem globals */
292 static Eina_List *handlers = NULL;
293 static Eina_List *borders = NULL;
294 static Eina_Hash *borders_hash = NULL;
295 static E_Border *focused = NULL;
296 static E_Border *focusing = NULL;
297 static Eina_List *focus_next = NULL;
298 static Ecore_X_Time focus_time = 0;
300 static E_Border *bdresize = NULL;
301 static E_Border *bdmove = NULL;
302 static E_Drag *drag_border = NULL;
304 static int grabbed = 0;
306 static Eina_List *focus_stack = NULL;
307 static Eina_List *raise_stack = NULL;
309 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
310 static int screen_size_index = -1;
312 static int focus_track_frozen = 0;
314 static int warp_to = 0;
315 static int warp_to_x = 0;
316 static int warp_to_y = 0;
317 static int warp_x = 0;
318 static int warp_y = 0;
319 static Ecore_X_Window warp_to_win;
320 static Ecore_Timer *warp_timer = NULL;
322 #ifdef _F_ZONE_WINDOW_ROTATION_
323 typedef struct _E_Border_Rotation E_Border_Rotation;
324 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
326 struct _E_Border_Rotation
329 Eina_List *async_list;
331 Eina_Bool wait_prepare_done;
332 Ecore_Timer *prepare_timer;
333 Ecore_Timer *done_timer;
335 Ecore_Job *async_job;
337 Ecore_X_Window vkbd_ctrl_win;
339 E_Border *vkbd_prediction;
341 /* vkbd show/hide preprare */
342 Eina_Bool vkbd_show_prepare_done;
343 Ecore_Timer *vkbd_show_prepare_timer;
344 Ecore_Timer *vkbd_show_timer;
346 Eina_Bool vkbd_hide_prepare_done;
347 Ecore_Timer *vkbd_hide_prepare_timer;
348 Ecore_Timer *vkbd_hide_timer;
354 struct _E_Border_Rotation_Info
359 Eina_Bool win_resize;
362 static E_Border_Rotation rot =
385 EAPI int E_EVENT_BORDER_ADD = 0;
386 EAPI int E_EVENT_BORDER_REMOVE = 0;
387 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
388 EAPI int E_EVENT_BORDER_DESK_SET = 0;
389 EAPI int E_EVENT_BORDER_RESIZE = 0;
390 EAPI int E_EVENT_BORDER_MOVE = 0;
391 EAPI int E_EVENT_BORDER_SHOW = 0;
392 EAPI int E_EVENT_BORDER_HIDE = 0;
393 EAPI int E_EVENT_BORDER_ICONIFY = 0;
394 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
395 EAPI int E_EVENT_BORDER_STICK = 0;
396 EAPI int E_EVENT_BORDER_UNSTICK = 0;
397 EAPI int E_EVENT_BORDER_STACK = 0;
398 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
399 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
400 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
401 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
402 EAPI int E_EVENT_BORDER_PROPERTY = 0;
403 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
404 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
405 #ifdef _F_ZONE_WINDOW_ROTATION_
406 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
407 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
408 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
409 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
412 #define GRAV_SET(bd, grav) \
413 ecore_x_window_gravity_set(bd->bg_win, grav); \
414 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
415 ecore_x_window_gravity_set(bd->client.win, grav);
418 _e_border_sub_borders_new(E_Border *bd)
420 Eina_List *list = NULL, *l;
424 EINA_LIST_FOREACH(bd->transients, l, child)
426 if (!eina_list_data_find(list, child))
427 list = eina_list_append(list, child);
429 bl = e_container_border_list_first(bd->zone->container);
430 while ((child = e_container_border_list_next(bl)))
432 if (e_object_is_del(E_OBJECT(child))) continue;
433 if (child == bd) continue;
435 if ((bd->client.icccm.client_leader) &&
436 (child->client.icccm.client_leader ==
437 bd->client.icccm.client_leader))
439 printf("bd %s in group with %s\n",
440 e_border_name_get(child),
441 e_border_name_get(bd));
442 if (!eina_list_data_find(list, child))
443 list = eina_list_append(list, child);
447 e_container_border_list_free(bl);
451 /* externally accessible functions */
455 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
461 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
468 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
469 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
470 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
471 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
472 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
473 #ifdef _F_ZONE_WINDOW_ROTATION_
474 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
477 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
479 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
480 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
481 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
482 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
483 #ifdef _F_USE_DESK_WINDOW_PROFILE_
484 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
486 #ifdef _F_ZONE_WINDOW_ROTATION_
487 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
490 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
492 E_EVENT_BORDER_ADD = ecore_event_type_new();
493 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
494 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
495 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
496 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
497 E_EVENT_BORDER_MOVE = ecore_event_type_new();
498 E_EVENT_BORDER_SHOW = ecore_event_type_new();
499 E_EVENT_BORDER_HIDE = ecore_event_type_new();
500 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
501 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
502 E_EVENT_BORDER_STICK = ecore_event_type_new();
503 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
504 E_EVENT_BORDER_STACK = ecore_event_type_new();
505 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
506 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
507 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
508 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
509 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
510 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
511 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
512 #ifdef _F_ZONE_WINDOW_ROTATION_
513 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
514 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
515 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
516 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
525 e_border_shutdown(void)
527 E_FREE_LIST(handlers, ecore_event_handler_del);
529 if (borders_hash) eina_hash_free(borders_hash);
531 e_int_border_menu_hooks_clear();
537 e_border_new(E_Container *con,
543 Ecore_X_Window_Attributes *att;
544 unsigned int managed, desk[2];
547 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
548 if (!bd) return NULL;
549 ecore_x_window_shadow_tree_flush();
550 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
554 /* FIXME: ewww - round trip */
555 bd->client.argb = ecore_x_window_argb_get(win);
557 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
560 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
561 ecore_x_window_shape_events_select(bd->win, 1);
563 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
564 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
566 bd->bg_ecore_evas = e_canvas_new(bd->win,
567 0, 0, bd->w, bd->h, 1, 0,
569 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
570 e_canvas_add(bd->bg_ecore_evas);
571 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
572 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
573 ecore_x_window_shape_events_select(bd->bg_win, 1);
574 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
575 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
577 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
579 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
580 ecore_x_window_container_manage(bd->client.shell_win);
581 if (!internal) ecore_x_window_client_manage(win);
582 /* FIXME: Round trip. XCB */
583 /* fetch needed to avoid grabbing the server as window may vanish */
584 att = &bd->client.initial_attributes;
585 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
587 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
588 e_canvas_del(bd->bg_ecore_evas);
589 ecore_evas_free(bd->bg_ecore_evas);
590 ecore_x_window_free(bd->client.shell_win);
591 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
592 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
593 ecore_x_window_free(bd->win);
598 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
599 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
601 /* FIXME: if first_map is 1 then we should ignore the first hide event
602 * or ensure the window is already hidden and events flushed before we
603 * create a border for it */
606 // printf("##- FIRST MAP\n");
611 // needed to be 1 for internal windw and on restart.
612 // bd->ignore_first_unmap = 2;
615 bd->client.win = win;
616 bd->zone = e_zone_current_get(con);
618 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
620 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
621 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
622 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
623 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
624 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
625 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
627 bd->client.icccm.title = NULL;
628 bd->client.icccm.name = NULL;
629 bd->client.icccm.class = NULL;
630 bd->client.icccm.icon_name = NULL;
631 bd->client.icccm.machine = NULL;
632 bd->client.icccm.min_w = 1;
633 bd->client.icccm.min_h = 1;
634 bd->client.icccm.max_w = 32767;
635 bd->client.icccm.max_h = 32767;
636 bd->client.icccm.base_w = 0;
637 bd->client.icccm.base_h = 0;
638 bd->client.icccm.step_w = -1;
639 bd->client.icccm.step_h = -1;
640 bd->client.icccm.min_aspect = 0.0;
641 bd->client.icccm.max_aspect = 0.0;
642 bd->client.icccm.accepts_focus = 1;
644 bd->client.netwm.pid = 0;
645 bd->client.netwm.name = NULL;
646 bd->client.netwm.icon_name = NULL;
647 bd->client.netwm.desktop = 0;
648 bd->client.netwm.state.modal = 0;
649 bd->client.netwm.state.sticky = 0;
650 bd->client.netwm.state.shaded = 0;
651 bd->client.netwm.state.hidden = 0;
652 bd->client.netwm.state.maximized_v = 0;
653 bd->client.netwm.state.maximized_h = 0;
654 bd->client.netwm.state.skip_taskbar = 0;
655 bd->client.netwm.state.skip_pager = 0;
656 bd->client.netwm.state.fullscreen = 0;
657 bd->client.netwm.state.stacking = E_STACKING_NONE;
658 bd->client.netwm.action.move = 0;
659 bd->client.netwm.action.resize = 0;
660 bd->client.netwm.action.minimize = 0;
661 bd->client.netwm.action.shade = 0;
662 bd->client.netwm.action.stick = 0;
663 bd->client.netwm.action.maximized_h = 0;
664 bd->client.netwm.action.maximized_v = 0;
665 bd->client.netwm.action.fullscreen = 0;
666 bd->client.netwm.action.change_desktop = 0;
667 bd->client.netwm.action.close = 0;
668 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
674 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
675 bd->client.icccm.fetch.command = 1;
678 Eina_Bool video_parent = EINA_FALSE;
679 Eina_Bool video_position = EINA_FALSE;
682 for (i = 0; i < at_num; i++)
684 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
685 bd->client.icccm.fetch.title = 1;
686 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
687 bd->client.icccm.fetch.name_class = 1;
688 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
689 bd->client.icccm.fetch.icon_name = 1;
690 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
691 bd->client.icccm.fetch.machine = 1;
692 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
693 bd->client.icccm.fetch.hints = 1;
694 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
695 bd->client.icccm.fetch.size_pos_hints = 1;
696 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
697 bd->client.icccm.fetch.protocol = 1;
698 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
699 bd->client.mwm.fetch.hints = 1;
700 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
702 bd->client.icccm.fetch.transient_for = 1;
703 bd->client.netwm.fetch.type = 1;
705 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
706 bd->client.icccm.fetch.client_leader = 1;
707 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
708 bd->client.icccm.fetch.window_role = 1;
709 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
710 bd->client.icccm.fetch.state = 1;
712 /* netwm, loop again, netwm will ignore some icccm, so we
713 * have to be sure that netwm is checked after */
714 for (i = 0; i < at_num; i++)
716 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
719 bd->client.icccm.fetch.title = 0;
720 bd->client.netwm.fetch.name = 1;
722 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
725 bd->client.icccm.fetch.icon_name = 0;
726 bd->client.netwm.fetch.icon_name = 1;
728 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
730 bd->client.netwm.fetch.icon = 1;
732 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
734 bd->client.netwm.fetch.user_time = 1;
736 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
738 DBG("ECORE_X_ATOM_NET_WM_STRUT");
739 bd->client.netwm.fetch.strut = 1;
741 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
743 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
744 bd->client.netwm.fetch.strut = 1;
746 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
749 bd->client.mwm.fetch.hints = 0;
751 bd->client.netwm.fetch.type = 1;
753 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
755 bd->client.netwm.fetch.state = 1;
758 /* other misc atoms */
759 for (i = 0; i < at_num; i++)
761 /* loop to check for own atoms */
762 if (atoms[i] == E_ATOM_WINDOW_STATE)
764 bd->client.e.fetch.state = 1;
766 /* loop to check for qtopia atoms */
767 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
768 bd->client.qtopia.fetch.soft_menu = 1;
769 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
770 bd->client.qtopia.fetch.soft_menus = 1;
771 /* loop to check for vkbd atoms */
772 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
773 bd->client.vkbd.fetch.state = 1;
774 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
775 bd->client.vkbd.fetch.vkbd = 1;
776 /* loop to check for illume atoms */
777 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
778 bd->client.illume.conformant.fetch.conformant = 1;
779 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
780 bd->client.illume.quickpanel.fetch.state = 1;
781 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
782 bd->client.illume.quickpanel.fetch.quickpanel = 1;
783 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
784 bd->client.illume.quickpanel.fetch.priority.major = 1;
785 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
786 bd->client.illume.quickpanel.fetch.priority.minor = 1;
787 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
788 bd->client.illume.quickpanel.fetch.zone = 1;
789 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
790 bd->client.illume.drag.fetch.locked = 1;
791 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
792 bd->client.illume.drag.fetch.drag = 1;
793 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
794 bd->client.illume.win_state.fetch.state = 1;
795 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
796 video_parent = EINA_TRUE;
797 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
798 video_position = EINA_TRUE;
799 #ifdef _F_USE_DESK_WINDOW_PROFILE_
800 /* loop to check for window profile list atom */
801 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
802 bd->client.e.fetch.profile_list = 1;
804 #ifdef _F_ZONE_WINDOW_ROTATION_
805 /* loop to check for wm rotation */
806 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
808 if (e_config->wm_win_rotation)
809 bd->client.e.fetch.rot.support = 1;
811 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
812 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
813 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
814 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
816 if (e_config->wm_win_rotation)
817 bd->client.e.fetch.rot.geom_hint = 1;
819 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
821 if (e_config->wm_win_rotation)
822 bd->client.e.fetch.rot.app_set = 1;
824 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
826 if (e_config->wm_win_rotation)
827 bd->client.e.fetch.rot.preferred_rot = 1;
829 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
831 if (e_config->wm_win_rotation)
832 bd->client.e.fetch.rot.available_rots = 1;
835 #ifdef _F_DEICONIFY_APPROVE_
836 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
838 bd->client.e.state.deiconify_approve.support = 1;
842 if (video_position && video_parent)
844 bd->client.e.state.video = 1;
845 bd->client.e.fetch.video_parent = 1;
846 bd->client.e.fetch.video_position = 1;
847 ecore_x_window_lower(bd->win);
848 ecore_x_composite_window_events_disable(bd->win);
849 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
850 fprintf(stderr, "We found a video window \\o/ %x\n", win);
855 bd->client.border.changed = 1;
857 bd->client.w = att->w;
858 bd->client.h = att->h;
860 bd->w = bd->client.w;
861 bd->h = bd->client.h;
863 bd->resize_mode = RESIZE_NONE;
865 bd->saved.layer = bd->layer;
866 bd->changes.icon = 1;
867 bd->changes.size = 1;
868 bd->changes.shape = 1;
869 bd->changes.shape_input = 1;
871 bd->offer_resistance = 1;
873 /* just to friggin make java happy - we're DELAYING the reparent until
876 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
877 bd->need_reparent = 1;
879 ecore_x_window_border_width_set(win, 0);
880 ecore_x_window_show(bd->event_win);
881 ecore_x_window_show(bd->client.shell_win);
882 bd->shape = e_container_shape_add(con);
887 #ifdef _F_ZONE_WINDOW_ROTATION_
888 bd->client.e.state.rot.preferred_rot = -1;
889 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
890 bd->client.e.state.rot.changes = -1;
891 bd->client.e.state.rot.pending_show = 0;
892 bd->client.e.state.rot.curr = 0;
893 bd->client.e.state.rot.prev = 0;
896 // bd->zone = e_zone_current_get(con);
897 bd->desk = e_desk_current_get(bd->zone);
898 e_container_border_add(bd);
899 borders = eina_list_append(borders, bd);
900 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
904 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
905 "optimisations failing due to bizarre client behavior. will\n"
907 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
908 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
911 ELBF(ELBT_BD, 0, bd->client.win,
912 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
913 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
915 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
916 printf("optimisations failing due to bizarre client behavior. will\n");
917 printf("work around.\n");
918 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
919 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
922 ELBF(ELBT_BD, 0, bd->client.win,
923 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
924 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
927 #ifdef _F_ZONE_WINDOW_ROTATION_
928 if ((rot.vkbd) && (rot.vkbd == bd2))
930 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
931 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
932 rot.vkbd_hide_prepare_done);
934 if (rot.vkbd_hide_prepare_timer)
936 ecore_timer_del(rot.vkbd_hide_prepare_timer);
937 rot.vkbd_hide_prepare_timer = NULL;
939 e_object_unref(E_OBJECT(bd2));
942 _e_border_vkbd_hide(rot.vkbd);
944 if (rot.vkbd_ctrl_win)
946 ELB(ELBT_BD, "SET KBD_OFF", 0);
947 ecore_x_e_virtual_keyboard_state_set
948 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
950 rot.vkbd_hide_prepare_done = EINA_FALSE;
952 if (rot.vkbd_hide_timer)
953 ecore_timer_del(rot.vkbd_hide_timer);
954 rot.vkbd_hide_timer = NULL;
956 rot.vkbd_show_prepare_done = EINA_FALSE;
957 if (rot.vkbd_show_prepare_timer)
958 ecore_timer_del(rot.vkbd_show_prepare_timer);
959 rot.vkbd_show_prepare_timer = NULL;
960 if (rot.vkbd_show_timer)
961 ecore_timer_del(rot.vkbd_show_timer);
962 rot.vkbd_show_timer = NULL;
967 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
968 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
969 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
971 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
972 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
973 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
975 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
976 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
977 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
979 unsigned int zgeom[4];
981 zgeom[0] = bd->zone->x;
982 zgeom[1] = bd->zone->y;
983 zgeom[2] = bd->zone->w;
984 zgeom[3] = bd->zone->h;
985 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
987 e_desk_xy_get(bd->desk, &deskx, &desky);
990 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
991 #ifdef _F_USE_DESK_WINDOW_PROFILE_
992 if (strcmp(bd->desk->window_profile,
993 e_config->desktop_default_window_profile) != 0)
995 ecore_x_e_window_profile_set(bd->client.win,
996 bd->desk->window_profile);
1000 focus_stack = eina_list_append(focus_stack, bd);
1002 bd->pointer = e_pointer_window_new(bd->win, 0);
1007 e_border_res_change_geometry_save(E_Border *bd)
1010 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1012 if (bd->pre_res_change.valid) return;
1013 bd->pre_res_change.valid = 1;
1014 bd->pre_res_change.x = bd->x;
1015 bd->pre_res_change.y = bd->y;
1016 bd->pre_res_change.w = bd->w;
1017 bd->pre_res_change.h = bd->h;
1018 bd->pre_res_change.saved.x = bd->saved.x;
1019 bd->pre_res_change.saved.y = bd->saved.y;
1020 bd->pre_res_change.saved.w = bd->saved.w;
1021 bd->pre_res_change.saved.h = bd->saved.h;
1025 e_border_res_change_geometry_restore(E_Border *bd)
1029 unsigned char valid : 1;
1038 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1039 if (!bd->pre_res_change.valid) return;
1040 if (bd->new_client) return;
1042 ecore_x_window_shadow_tree_flush();
1043 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1047 e_border_unfullscreen(bd);
1048 e_border_fullscreen(bd, e_config->fullscreen_policy);
1050 else if (bd->maximized != E_MAXIMIZE_NONE)
1054 max = bd->maximized;
1055 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1056 e_border_maximize(bd, max);
1060 int x, y, w, h, zx, zy, zw, zh;
1062 bd->saved.x = bd->pre_res_change.saved.x;
1063 bd->saved.y = bd->pre_res_change.saved.y;
1064 bd->saved.w = bd->pre_res_change.saved.w;
1065 bd->saved.h = bd->pre_res_change.saved.h;
1067 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1069 if (bd->saved.w > zw)
1071 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1072 bd->saved.x = zx + zw - bd->saved.w;
1074 if (bd->saved.h > zh)
1076 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1077 bd->saved.y = zy + zh - bd->saved.h;
1079 x = bd->pre_res_change.x;
1080 y = bd->pre_res_change.y;
1081 w = bd->pre_res_change.w;
1082 h = bd->pre_res_change.h;
1087 if ((x + w) > (zx + zw))
1089 if ((y + h) > (zy + zh))
1091 e_border_move_resize(bd, x, y, w, h);
1093 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1097 e_border_zone_set(E_Border *bd,
1100 E_Event_Border_Zone_Set *ev;
1103 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1104 E_OBJECT_CHECK(zone);
1105 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1107 if (bd->zone == zone) return;
1109 /* if the window does not lie in the new zone, move it so that it does */
1110 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1113 /* first guess -- get offset from old zone, and apply to new zone */
1114 x = zone->x + (bd->x - bd->zone->x);
1115 y = zone->y + (bd->y - bd->zone->y);
1117 /* keep window from hanging off bottom and left */
1118 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1119 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1121 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1122 if (x < zone->x) x = zone->x;
1123 if (y < zone->y) y = zone->y;
1125 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1127 /* still not in zone at all, so just move it to closest edge */
1128 if (x < zone->x) x = zone->x;
1129 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1130 if (y < zone->y) y = zone->y;
1131 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1133 e_border_move(bd, x, y);
1138 if (bd->desk->zone != bd->zone)
1139 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1141 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1143 e_object_ref(E_OBJECT(bd));
1144 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1146 e_object_ref(E_OBJECT(zone));
1148 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1150 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1151 // XXXXXXXXXXXXXXXXXXXXXXXXX
1152 // XXX ZZZZZZZZZZZZZZZZZZZzz
1153 // need to adjust this if zone pos/size changes
1155 unsigned int zgeom[4];
1157 zgeom[0] = bd->zone->x;
1158 zgeom[1] = bd->zone->y;
1159 zgeom[2] = bd->zone->w;
1160 zgeom[3] = bd->zone->h;
1161 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1163 e_remember_update(bd);
1167 e_border_desk_set(E_Border *bd,
1170 E_Event_Border_Desk_Set *ev;
1174 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1175 E_OBJECT_CHECK(desk);
1176 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1177 if (bd->desk == desk) return;
1178 ecore_x_window_shadow_tree_flush();
1181 bd->desk->fullscreen_borders--;
1182 desk->fullscreen_borders++;
1184 old_desk = bd->desk;
1186 e_border_zone_set(bd, desk->zone);
1188 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1189 e_hints_window_desktop_set(bd);
1191 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1193 e_object_ref(E_OBJECT(bd));
1194 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1195 ev->desk = old_desk;
1196 e_object_ref(E_OBJECT(old_desk));
1197 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1199 if (bd->ignore_first_unmap != 1)
1201 if ((bd->desk->visible) || (bd->sticky))
1204 e_border_hide(bd, 1);
1207 if (e_config->transient.desktop)
1211 Eina_List *list = _e_border_sub_borders_new(bd);
1213 EINA_LIST_FOREACH(list, l, child)
1215 e_border_desk_set(child, bd->desk);
1217 eina_list_free(list);
1219 e_remember_update(bd);
1222 #ifdef _F_ZONE_WINDOW_ROTATION_
1224 _e_border_vkbd_state_check(E_Border *bd,
1227 Eina_Bool res = EINA_TRUE;
1228 if (!e_config->wm_win_rotation) return EINA_FALSE;
1229 if ((rot.vkbd) && (rot.vkbd == bd))
1233 if ((rot.vkbd_hide_prepare_done) ||
1234 (rot.vkbd_hide_prepare_timer))
1239 if ((rot.vkbd_show_prepare_done) ||
1240 (rot.vkbd_show_prepare_timer))
1248 _e_border_vkbd_show_timeout(void *data)
1250 E_Border *bd = data;
1251 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1252 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1254 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1256 if (rot.vkbd_ctrl_win)
1258 ELB(ELBT_BD, "SET KBD_ON", 0);
1259 ecore_x_e_virtual_keyboard_state_set
1260 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1265 rot.vkbd_show_prepare_done = EINA_FALSE;
1267 if (rot.vkbd_show_prepare_timer)
1268 ecore_timer_del(rot.vkbd_show_prepare_timer);
1269 rot.vkbd_show_prepare_timer = NULL;
1271 if (rot.vkbd_show_timer)
1272 ecore_timer_del(rot.vkbd_show_timer);
1273 rot.vkbd_show_timer = NULL;
1275 return ECORE_CALLBACK_CANCEL;
1279 _e_border_vkbd_hide_timeout(void *data)
1281 E_Border *bd = data;
1282 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1283 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1285 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1287 if (rot.vkbd_ctrl_win)
1289 ELB(ELBT_BD, "SET KBD_OFF", 0);
1290 ecore_x_e_virtual_keyboard_state_set
1291 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1294 e_object_unref(E_OBJECT(bd));
1297 rot.vkbd_hide_prepare_done = EINA_FALSE;
1299 if (rot.vkbd_hide_prepare_timer)
1300 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1301 rot.vkbd_hide_prepare_timer = NULL;
1303 if (rot.vkbd_hide_timer)
1304 ecore_timer_del(rot.vkbd_hide_timer);
1305 rot.vkbd_hide_timer = NULL;
1307 return ECORE_CALLBACK_CANCEL;
1311 _e_border_vkbd_show(E_Border *bd)
1313 if (!e_config->wm_win_rotation) return;
1314 rot.vkbd_show_prepare_done = EINA_TRUE;
1315 if (rot.vkbd_show_prepare_timer)
1316 ecore_timer_del(rot.vkbd_show_prepare_timer);
1317 rot.vkbd_show_prepare_timer = NULL;
1318 if (rot.vkbd_show_timer)
1319 ecore_timer_del(rot.vkbd_show_timer);
1320 rot.vkbd_show_timer = NULL;
1321 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1324 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1329 _e_border_vkbd_hide(E_Border *bd)
1331 if (!e_config->wm_win_rotation) return;
1332 rot.vkbd_hide_prepare_done = EINA_TRUE;
1333 if (rot.vkbd_hide_prepare_timer)
1334 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1335 rot.vkbd_hide_prepare_timer = NULL;
1336 if (rot.vkbd_hide_timer)
1337 ecore_timer_del(rot.vkbd_hide_timer);
1338 rot.vkbd_hide_timer = NULL;
1339 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1341 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1342 e_border_hide(bd, 0);
1343 if (!e_object_is_del(E_OBJECT(bd)))
1345 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1346 e_object_del(E_OBJECT(bd));
1348 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1353 _e_border_vkbd_show_prepare_timeout(void *data)
1355 E_Border *bd = data;
1356 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1357 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1359 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1360 _e_border_vkbd_show(bd);
1362 return ECORE_CALLBACK_CANCEL;
1366 _e_border_vkbd_hide_prepare_timeout(void *data)
1368 E_Border *bd = data;
1369 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1370 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1372 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1373 _e_border_vkbd_hide(bd);
1375 return ECORE_CALLBACK_CANCEL;
1380 e_border_show(E_Border *bd)
1382 E_Event_Border_Show *ev;
1383 unsigned int visible;
1386 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1387 if (bd->visible) return;
1388 #ifdef _F_ZONE_WINDOW_ROTATION_
1389 // newly created window that has to be rotated will be show after rotation done.
1390 // so, skip at this time. it will be called again after GETTING ROT_DONE.
1392 if ((bd->new_client) &&
1393 (bd->client.e.state.rot.changes != -1))
1395 // if this window is in withdrawn state, show this window right now.
1396 // that's because the window in withdrawn state can't render its canvas.
1397 // eventually, this window will not send the message of rotation done,
1398 // even if e17 request to rotation this window.
1399 if (bd->client.icccm.state != ECORE_X_WINDOW_STATE_HINT_NORMAL)
1400 e_hints_window_visible_set(bd);
1402 bd->client.e.state.rot.pending_show = 1;
1406 if ((e_config->wm_win_rotation) &&
1407 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1409 (!rot.vkbd_show_prepare_done))
1411 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1412 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1413 if (rot.vkbd_show_prepare_timer)
1414 ecore_timer_del(rot.vkbd_show_prepare_timer);
1415 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1416 _e_border_vkbd_show_prepare_timeout,
1420 ELB(ELBT_BD, "SHOW", bd->client.win);
1422 ecore_x_window_shadow_tree_flush();
1423 e_container_shape_show(bd->shape);
1424 if (!bd->need_reparent)
1425 ecore_x_window_show(bd->client.win);
1426 e_hints_window_visible_set(bd);
1429 bd->changes.visible = 1;
1432 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1433 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1435 ev = E_NEW(E_Event_Border_Show, 1);
1437 e_object_ref(E_OBJECT(bd));
1438 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1439 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1441 #ifdef _F_ZONE_WINDOW_ROTATION_
1442 if ((e_config->wm_win_rotation) &&
1443 ((bd->client.e.state.rot.support) ||
1444 (bd->client.e.state.rot.app_set)))
1446 ELB(ELBT_ROT, "CHECK", bd->client.win);
1447 int rotation = _e_border_rotation_angle_get(bd);
1448 if (rotation != -1) e_border_rotation_set(bd, rotation);
1454 e_border_hide(E_Border *bd,
1457 unsigned int visible;
1460 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1462 #ifdef _F_ZONE_WINDOW_ROTATION_
1463 if ((e_config->wm_win_rotation) &&
1464 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1466 (!rot.vkbd_hide_prepare_done) &&
1469 Eina_Bool need_prepare = EINA_TRUE;
1470 E_Border *child = NULL;
1473 if (e_object_is_del(E_OBJECT(bd->parent)))
1474 need_prepare = EINA_FALSE;
1477 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1478 if (bd->parent->modal == bd)
1480 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1481 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1482 bd->parent->lock_close = 0;
1483 bd->parent->saved.event_mask = 0;
1484 bd->parent->modal = NULL;
1490 need_prepare = EINA_FALSE;
1492 EINA_LIST_FREE(bd->transients, child)
1494 child->parent = NULL;
1497 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1501 e_object_ref(E_OBJECT(bd));
1502 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1503 if (rot.vkbd_hide_prepare_timer)
1504 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1505 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1506 _e_border_vkbd_hide_prepare_timeout,
1512 e_object_ref(E_OBJECT(bd));
1514 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1515 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1517 /* cleanup code from _e_border_vkbd_hide() */
1518 rot.vkbd_hide_prepare_done = EINA_TRUE;
1519 if (rot.vkbd_hide_prepare_timer)
1520 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1521 rot.vkbd_hide_prepare_timer = NULL;
1522 if (rot.vkbd_hide_timer)
1523 ecore_timer_del(rot.vkbd_hide_timer);
1524 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1527 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1529 if (!bd->visible) goto send_event;
1530 ecore_x_window_shadow_tree_flush();
1532 _e_border_move_end(bd);
1533 if (bd->resize_mode != RESIZE_NONE)
1535 _e_border_pointer_resize_end(bd);
1536 bd->resize_mode = RESIZE_NONE;
1537 _e_border_resize_end(bd);
1540 e_container_shape_hide(bd->shape);
1541 if (!bd->iconic) e_hints_window_hidden_set(bd);
1544 bd->changes.visible = 1;
1546 if (!bd->need_reparent)
1548 if ((bd->focused) ||
1549 (e_grabinput_last_focus_win_get() == bd->client.win))
1551 e_border_focus_set(bd, 0, 1);
1559 con = e_container_current_get(e_manager_current_get());
1560 zone = e_zone_current_get(con);
1561 desk = e_desk_current_get(zone);
1564 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1565 e_border_focus_set(bd->parent, 1, 1);
1566 else if (e_config->focus_revert_on_hide_or_close)
1568 /* When using pointer focus, the border under the
1569 * pointer (if any) gets focused, in sloppy/click
1570 * focus the last focused window on the current
1571 * desk gets focus */
1572 if (e_config->focus_policy == E_FOCUS_MOUSE)
1574 pbd = e_border_under_pointer_get(desk, bd);
1576 e_border_focus_set(pbd, 1, 1);
1578 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1579 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1580 (e_config->focus_policy == E_FOCUS_CLICK))
1581 _e_border_latest_stacked_focus(bd);
1585 e_desk_last_focused_focus(desk);
1595 /* Make sure that this border isn't deleted */
1596 bd->await_hide_event++;
1598 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1599 ecore_x_window_hide(bd->client.win);
1604 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1606 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1613 #ifdef _F_ZONE_WINDOW_ROTATION_
1614 _e_border_rotation_list_remove(bd);
1617 E_Event_Border_Hide *ev;
1619 ev = E_NEW(E_Event_Border_Hide, 1);
1621 e_object_ref(E_OBJECT(bd));
1622 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1623 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1628 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1632 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1633 setpriority(PRIO_PROCESS, pid, newpri);
1634 // shouldnt need to do this as default ionice class is "none" (0), and
1635 // this inherits io priority FROM nice level
1636 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1637 // IOPRIO_PRIO_VALUE(2, 5));
1641 char *file, buf[PATH_MAX];
1645 // yes - this is /proc specific... so this may not work on some
1646 // os's - works on linux. too bad for others.
1647 files = ecore_file_ls("/proc");
1648 EINA_LIST_FREE(files, file)
1650 if (isdigit(file[0]))
1652 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1653 f = fopen(buf, "r");
1658 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1664 _pri_adj(pid2, set, adj, EINA_TRUE,
1665 adj_children, do_children);
1667 _pri_adj(pid2, set, adj, use_adj,
1668 adj_children, do_children);
1680 _e_border_pri_raise(E_Border *bd)
1682 if (bd->client.netwm.pid <= 0) return;
1683 if (bd->client.netwm.pid == getpid()) return;
1684 _pri_adj(bd->client.netwm.pid,
1685 e_config->priority - 1, -1, EINA_FALSE,
1686 // EINA_TRUE, EINA_TRUE);
1687 EINA_TRUE, EINA_FALSE);
1688 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1689 // bd->client.netwm.pid, e_border_name_get(bd));
1693 _e_border_pri_norm(E_Border *bd)
1695 if (bd->client.netwm.pid <= 0) return;
1696 if (bd->client.netwm.pid == getpid()) return;
1697 _pri_adj(bd->client.netwm.pid,
1698 e_config->priority, 1, EINA_FALSE,
1699 // EINA_TRUE, EINA_TRUE);
1700 EINA_TRUE, EINA_FALSE);
1701 // printf("WIN: pid %i, title %s (NORMAL)\n",
1702 // bd->client.netwm.pid, e_border_name_get(bd));
1706 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1709 Ecore_Evas *bg_ecore_evas;
1715 bg_ecore_evas = bd->bg_ecore_evas;
1717 /* unregister old frame window */
1718 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1719 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1721 e_focus_setdown(bd);
1722 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1723 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1725 if (bd->icon_object)
1726 evas_object_del(bd->icon_object);
1728 evas_object_del(bd->bg_object);
1729 e_canvas_del(bg_ecore_evas);
1730 ecore_evas_free(bg_ecore_evas);
1733 e_object_del(E_OBJECT(bd->pointer));
1735 /* create new frame */
1737 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1738 bd->x, bd->y, bd->w, bd->h);
1741 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1742 bd->x, bd->y, bd->w, bd->h);
1743 ecore_x_window_shape_events_select(bd->win, 1);
1746 ecore_x_window_configure(bd->win,
1747 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1748 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1750 win, ECORE_X_WINDOW_STACK_BELOW);
1752 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1753 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1756 bd->bg_ecore_evas = e_canvas_new(bd->win,
1757 0, 0, bd->w, bd->h, 1, 0,
1760 e_canvas_add(bd->bg_ecore_evas);
1761 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1763 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1764 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1765 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1767 ecore_x_window_shape_events_select(bd->bg_win, 1);
1769 /* move client with shell win over to new frame */
1770 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1771 bd->client_inset.l, bd->client_inset.t);
1773 bd->pointer = e_pointer_window_new(bd->win, 0);
1775 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1776 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1783 ecore_evas_show(bd->bg_ecore_evas);
1784 ecore_x_window_show(bd->win);
1786 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1787 ecore_x_window_show(tmp->win);
1790 bd->bg_object = edje_object_add(bd->bg_evas);
1791 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1792 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1794 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1796 /* cleanup old frame */
1797 ecore_x_window_free(win);
1801 _e_border_client_move_resize_send(E_Border *bd)
1803 if (bd->internal_ecore_evas)
1804 ecore_evas_managed_move(bd->internal_ecore_evas,
1805 bd->x + bd->fx.x + bd->client_inset.l,
1806 bd->y + bd->fx.y + bd->client_inset.t);
1808 ecore_x_icccm_move_resize_send(bd->client.win,
1809 bd->x + bd->fx.x + bd->client_inset.l,
1810 bd->y + bd->fx.y + bd->client_inset.t,
1816 _e_border_pending_move_resize_add(E_Border *bd,
1823 Eina_Bool without_border,
1824 unsigned int serial)
1826 E_Border_Pending_Move_Resize *pnd;
1828 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1830 pnd->resize = resize;
1832 pnd->without_border = without_border;
1837 pnd->serial = serial;
1838 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1842 _e_border_move_internal(E_Border *bd,
1845 Eina_Bool without_border)
1847 E_Event_Border_Move *ev;
1850 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1852 ecore_x_window_shadow_tree_flush();
1855 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1861 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1863 if (e_config->allow_manip)
1866 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1871 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1876 else if (e_config->allow_manip)
1884 x -= bd->client_inset.l;
1885 y -= bd->client_inset.t;
1887 if (bd->move_intercept_cb)
1890 px = bd->x, py = bd->y;
1891 bd->move_intercept_cb(bd, x, y);
1892 if ((bd->x == px) && (bd->y == py)) return;
1894 else if ((x == bd->x) && (y == bd->y)) return;
1895 bd->pre_res_change.valid = 0;
1899 bd->changes.pos = 1;
1901 if (bd->client.netwm.sync.request)
1903 bd->client.netwm.sync.wait++;
1904 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1907 _e_border_client_move_resize_send(bd);
1908 _e_border_move_update(bd);
1909 ev = E_NEW(E_Event_Border_Move, 1);
1911 e_object_ref(E_OBJECT(bd));
1912 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1913 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1914 _e_border_zone_update(bd);
1918 * Move window to coordinates that already account border decorations.
1920 * This call will consider given position already accounts border
1921 * decorations, so it will not be considered later. This will just
1922 * work properly with borders that have being evaluated and border
1923 * decorations are known (border->client_inset).
1925 * @parm x horizontal position to place window.
1926 * @parm y vertical position to place window.
1928 * @see e_border_move_without_border()
1931 e_border_move(E_Border *bd,
1938 _e_border_move_internal(bd, x, y, 0);
1943 * Set a callback which will be called just prior to updating the
1944 * move coordinates for a border
1947 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1949 bd->move_intercept_cb = cb;
1953 * Move window to coordinates that do not account border decorations yet.
1955 * This call will consider given position does not account border
1956 * decoration, so these values (border->client_inset) will be
1957 * accounted automatically. This is specially useful when it is a new
1958 * client and has not be evaluated yet, in this case
1959 * border->client_inset will be zeroed and no information is known. It
1960 * will mark pending requests so border will be accounted on
1961 * evalutation phase.
1963 * @parm x horizontal position to place window.
1964 * @parm y vertical position to place window.
1966 * @see e_border_move()
1969 e_border_move_without_border(E_Border *bd,
1976 _e_border_move_internal(bd, x, y, 1);
1980 e_border_center(E_Border *bd)
1984 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1986 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1987 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1991 e_border_center_pos_get(E_Border *bd,
1997 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1999 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
2000 if (x) *x = zx + (zw - bd->w) / 2;
2001 if (y) *y = zy + (zh - bd->h) / 2;
2005 e_border_fx_offset(E_Border *bd,
2010 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2012 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2016 bd->changes.pos = 1;
2019 if (bd->moving) _e_border_move_update(bd);
2023 _e_border_move_resize_internal(E_Border *bd,
2028 Eina_Bool without_border,
2031 E_Event_Border_Move *mev;
2032 E_Event_Border_Resize *rev;
2035 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2037 ecore_x_window_shadow_tree_flush();
2041 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2047 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2049 if (e_config->allow_manip)
2052 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2058 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2065 if (e_config->allow_manip)
2073 x -= bd->client_inset.l;
2074 y -= bd->client_inset.t;
2075 w += (bd->client_inset.l + bd->client_inset.r);
2076 h += (bd->client_inset.t + bd->client_inset.b);
2079 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2080 (w == bd->w) && (h == bd->h))
2083 bd->pre_res_change.valid = 0;
2086 bd->changes.pos = 1;
2092 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2093 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2095 if ((bd->shaped) || (bd->client.shaped))
2097 bd->need_shape_merge = 1;
2098 bd->need_shape_export = 1;
2100 if (bd->shaped_input)
2102 bd->need_shape_merge = 1;
2105 if (bd->internal_ecore_evas)
2108 bd->changes.size = 1;
2112 if (bdresize && bd->client.netwm.sync.request)
2114 bd->client.netwm.sync.wait++;
2115 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2116 * when no move is intended. The border geometry is set above anyways.
2118 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2119 bd->client.netwm.sync.serial);
2120 ecore_x_netwm_sync_request_send(bd->client.win,
2121 bd->client.netwm.sync.serial++);
2126 bd->changes.size = 1;
2130 _e_border_client_move_resize_send(bd);
2132 _e_border_resize_update(bd);
2135 mev = E_NEW(E_Event_Border_Move, 1);
2137 e_object_ref(E_OBJECT(bd));
2138 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2139 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2142 rev = E_NEW(E_Event_Border_Resize, 1);
2144 e_object_ref(E_OBJECT(bd));
2145 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2146 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2147 _e_border_zone_update(bd);
2151 * Move and resize window to values that already account border decorations.
2153 * This call will consider given values already accounts border
2154 * decorations, so it will not be considered later. This will just
2155 * work properly with borders that have being evaluated and border
2156 * decorations are known (border->client_inset).
2158 * @parm x horizontal position to place window.
2159 * @parm y vertical position to place window.
2160 * @parm w horizontal window size.
2161 * @parm h vertical window size.
2163 * @see e_border_move_resize_without_border()
2166 e_border_move_resize(E_Border *bd,
2175 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2179 * Move and resize window to values that do not account border decorations yet.
2181 * This call will consider given values already accounts border
2182 * decorations, so it will not be considered later. This will just
2183 * work properly with borders that have being evaluated and border
2184 * decorations are known (border->client_inset).
2186 * @parm x horizontal position to place window.
2187 * @parm y vertical position to place window.
2188 * @parm w horizontal window size.
2189 * @parm h vertical window size.
2191 * @see e_border_move_resize()
2194 e_border_move_resize_without_border(E_Border *bd,
2203 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2207 * Resize window to values that already account border decorations.
2209 * This call will consider given size already accounts border
2210 * decorations, so it will not be considered later. This will just
2211 * work properly with borders that have being evaluated and border
2212 * decorations are known (border->client_inset).
2214 * @parm w horizontal window size.
2215 * @parm h vertical window size.
2217 * @see e_border_resize_without_border()
2220 e_border_resize(E_Border *bd,
2227 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2231 * Resize window to values that do not account border decorations yet.
2233 * This call will consider given size does not account border
2234 * decoration, so these values (border->client_inset) will be
2235 * accounted automatically. This is specially useful when it is a new
2236 * client and has not be evaluated yet, in this case
2237 * border->client_inset will be zeroed and no information is known. It
2238 * will mark pending requests so border will be accounted on
2239 * evalutation phase.
2241 * @parm w horizontal window size.
2242 * @parm h vertical window size.
2244 * @see e_border_resize()
2247 e_border_resize_without_border(E_Border *bd,
2254 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2258 e_border_layer_set(E_Border *bd,
2264 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2266 ecore_x_window_shadow_tree_flush();
2268 oldraise = e_config->transient.raise;
2272 bd->saved.layer = layer;
2276 if (e_config->transient.layer)
2280 Eina_List *list = _e_border_sub_borders_new(bd);
2282 /* We need to set raise to one, else the child wont
2283 * follow to the new layer. It should be like this,
2284 * even if the user usually doesn't want to raise
2287 e_config->transient.raise = 1;
2288 EINA_LIST_FOREACH(list, l, child)
2290 e_border_layer_set(child, layer);
2294 e_config->transient.raise = oldraise;
2298 e_border_raise(E_Border *bd)
2300 E_Event_Border_Stack *ev;
2301 E_Border *last = NULL, *child;
2305 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2307 ecore_x_window_shadow_tree_flush();
2309 if (e_config->transient.raise)
2311 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2312 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2315 Eina_List *list = _e_border_sub_borders_new(bd);
2317 EINA_LIST_REVERSE_FOREACH(list, l, child)
2319 /* Don't stack iconic transients. If the user wants these shown,
2320 * thats another option.
2325 e_border_stack_below(child, last);
2330 /* First raise the border to find out which border we will end up above */
2331 above = e_container_border_raise(child);
2335 /* We ended up above a border, now we must stack this border to
2336 * generate the stacking event, and to check if this transient
2337 * has other transients etc.
2339 e_border_stack_above(child, above);
2343 /* If we didn't end up above any border, we are on the bottom! */
2344 e_border_lower(child);
2350 eina_list_free(list);
2351 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2355 EINA_LIST_FOREACH(bd->transients, l, child)
2357 /* Don't stack iconic transients. If the user wants these shown,
2358 * thats another option.
2362 child->layer = bd->layer;
2363 if (!last) last = child;
2364 e_border_raise (child);
2371 ev = E_NEW(E_Event_Border_Stack, 1);
2373 e_object_ref(E_OBJECT(bd));
2377 e_container_border_stack_below(bd, last);
2379 e_object_ref(E_OBJECT(last));
2380 ev->type = E_STACKING_BELOW;
2386 /* If we don't have any children, raise this border */
2387 above = e_container_border_raise(bd);
2388 e_border_raise_latest_set(bd);
2391 /* We ended up above a border */
2393 e_object_ref(E_OBJECT(above));
2394 ev->type = E_STACKING_ABOVE;
2398 /* No border to raise above, same as a lower! */
2400 ev->type = E_STACKING_ABOVE;
2404 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2405 e_remember_update(bd);
2409 e_border_lower(E_Border *bd)
2411 E_Event_Border_Stack *ev;
2412 E_Border *last = NULL, *child;
2416 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2418 ecore_x_window_shadow_tree_flush();
2420 if (e_config->transient.lower)
2422 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2423 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2426 Eina_List *list = _e_border_sub_borders_new(bd);
2428 EINA_LIST_REVERSE_FOREACH(list, l, child)
2430 /* Don't stack iconic transients. If the user wants these shown,
2431 * thats another option.
2436 e_border_stack_below(child, last);
2441 /* First lower the border to find out which border we will end up below */
2442 below = e_container_border_lower(child);
2446 /* We ended up below a border, now we must stack this border to
2447 * generate the stacking event, and to check if this transient
2448 * has other transients etc.
2450 e_border_stack_below(child, below);
2454 /* If we didn't end up below any border, we are on top! */
2455 e_border_raise(child);
2461 eina_list_free(list);
2463 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2467 EINA_LIST_FOREACH(bd->transients, l, child)
2469 /* Don't stack iconic transients. If the user wants these shown,
2470 * thats another option.
2474 child->layer = bd->layer;
2475 e_border_lower (child);
2483 ev = E_NEW(E_Event_Border_Stack, 1);
2485 e_object_ref(E_OBJECT(bd));
2489 e_container_border_stack_below(bd, last);
2491 e_object_ref(E_OBJECT(last));
2492 ev->type = E_STACKING_BELOW;
2498 /* If we don't have any children, lower this border */
2499 below = e_container_border_lower(bd);
2502 /* We ended up below a border */
2504 e_object_ref(E_OBJECT(below));
2505 ev->type = E_STACKING_BELOW;
2509 /* No border to hide under, same as a raise! */
2511 ev->type = E_STACKING_BELOW;
2515 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2516 e_remember_update(bd);
2520 e_border_stack_above(E_Border *bd,
2523 /* TODO: Should stack above allow the border to change level */
2524 E_Event_Border_Stack *ev;
2525 E_Border *last = NULL, *child;
2529 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2531 ecore_x_window_shadow_tree_flush();
2533 if (e_config->transient.raise)
2535 Eina_List *list = _e_border_sub_borders_new(bd);
2537 EINA_LIST_REVERSE_FOREACH(list, l, child)
2539 /* Don't stack iconic transients. If the user wants these shown,
2540 * thats another option.
2545 e_border_stack_below(child, last);
2547 e_border_stack_above(child, above);
2551 eina_list_free(list);
2554 ev = E_NEW(E_Event_Border_Stack, 1);
2556 e_object_ref(E_OBJECT(bd));
2560 e_container_border_stack_below(bd, last);
2562 e_object_ref(E_OBJECT(last));
2563 ev->type = E_STACKING_BELOW;
2567 e_container_border_stack_above(bd, above);
2569 e_object_ref(E_OBJECT(above));
2570 ev->type = E_STACKING_ABOVE;
2573 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2574 e_remember_update(bd);
2578 e_border_stack_below(E_Border *bd,
2581 /* TODO: Should stack below allow the border to change level */
2582 E_Event_Border_Stack *ev;
2583 E_Border *last = NULL, *child;
2587 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2589 ecore_x_window_shadow_tree_flush();
2591 if (e_config->transient.lower)
2593 Eina_List *list = _e_border_sub_borders_new(bd);
2595 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2597 /* Don't stack iconic transients. If the user wants these shown,
2598 * thats another option.
2603 e_border_stack_below(child, last);
2605 e_border_stack_below(child, below);
2609 eina_list_free(list);
2612 ev = E_NEW(E_Event_Border_Stack, 1);
2614 e_object_ref(E_OBJECT(bd));
2618 e_container_border_stack_below(bd, last);
2620 e_object_ref(E_OBJECT(last));
2621 ev->type = E_STACKING_BELOW;
2625 e_container_border_stack_below(bd, below);
2627 e_object_ref(E_OBJECT(below));
2628 ev->type = E_STACKING_BELOW;
2631 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2632 e_remember_update(bd);
2636 e_border_focus_latest_set(E_Border *bd)
2638 focus_stack = eina_list_remove(focus_stack, bd);
2639 focus_stack = eina_list_prepend(focus_stack, bd);
2643 e_border_raise_latest_set(E_Border *bd)
2645 raise_stack = eina_list_remove(raise_stack, bd);
2646 raise_stack = eina_list_prepend(raise_stack, bd);
2650 * Sets the focus to the given border if necessary
2651 * There are 3 cases of different focus_policy-configurations:
2653 * - E_FOCUS_CLICK: just set the focus, the most simple one
2655 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2656 * warp the pointer to the window. If this fails (because
2657 * the pointer is already in the window), just set the focus.
2659 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2660 * last window which was focused, if the mouse is on the
2661 * desktop. So, we need to look if there is another window
2662 * under the pointer and warp to pointer to the right
2663 * one if so (also, we set the focus afterwards). In case
2664 * there is no window under pointer, the pointer is on the
2665 * desktop and so we just set the focus.
2668 * This function is to be called when setting the focus was not
2669 * explicitly triggered by the user (by moving the mouse or
2670 * clicking for example), but implicitly (by closing a window,
2671 * the last focused window should get focus).
2675 e_border_focus_set_with_pointer(E_Border *bd)
2677 #ifdef PRINT_LOTS_OF_DEBUG
2678 E_PRINT_BORDER_INFO(bd);
2680 /* note: this is here as it seems there are enough apps that do not even
2681 * expect us to emulate a look of focus but not actually set x input
2682 * focus as we do - so simply abort any focuse set on such windows */
2683 /* be strict about accepting focus hint */
2684 if ((!bd->client.icccm.accepts_focus) &&
2685 (!bd->client.icccm.take_focus)) return;
2686 if (bd->lock_focus_out) return;
2688 e_border_focus_set(bd, 1, 1);
2690 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2691 if (!bd->visible) return;
2693 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2695 if (!e_border_under_pointer_get(bd->desk, bd))
2697 e_border_pointer_warp_to_center(bd);
2702 e_border_pointer_warp_to_center(bd);
2707 e_border_focus_set(E_Border *bd,
2711 E_Border *bd_unfocus = NULL;
2712 Eina_Bool focus_changed = EINA_FALSE;
2715 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2716 /* note: this is here as it seems there are enough apps that do not even
2717 * expect us to emulate a look of focus but not actually set x input
2718 * focus as we do - so simply abort any focuse set on such windows */
2719 /* be strict about accepting focus hint */
2720 if ((!bd->client.icccm.accepts_focus) &&
2721 (!bd->client.icccm.take_focus))
2723 if ((set) && (focus) && (bd->lock_focus_out)) return;
2725 /* dont focus an iconified window. that's silly! */
2730 e_border_uniconify(bd);
2731 if (!focus_track_frozen)
2732 e_border_focus_latest_set(bd);
2735 else if (!bd->visible)
2739 /* FIXME: hack for deskflip animation:
2740 * dont update focus when sliding previous desk */
2741 else if ((!bd->sticky) &&
2742 (bd->desk != e_desk_current_get(bd->desk->zone)))
2748 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2750 e_border_focus_set(bd->modal, focus, set);
2753 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2755 e_border_focus_set(bd->leader->modal, focus, set);
2763 if (bd->visible && bd->changes.visible)
2768 else if ((!bd->focused) ||
2769 (focus_next && (bd != eina_list_data_get(focus_next))))
2773 if ((l = eina_list_data_find_list(focus_next, bd)))
2774 focus_next = eina_list_promote_list(focus_next, l);
2776 focus_next = eina_list_prepend(focus_next, bd);
2778 if ((bd->client.icccm.take_focus) &&
2779 (bd->client.icccm.accepts_focus))
2781 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2782 /* TODO what if the client didn't take focus ? */
2784 else if (!bd->client.icccm.accepts_focus)
2786 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2788 else if (!bd->client.icccm.take_focus)
2790 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2791 /* e_border_focus_set(bd, 1, 0); */
2801 if (focused) bd_unfocus = focused;
2802 if (focusing == bd) focusing = NULL;
2807 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2809 if ((bd2->fullscreen) &&
2811 (bd2->zone == bd->zone) &&
2812 ((bd2->desk == bd->desk) ||
2813 (bd2->sticky) || (bd->sticky)))
2815 Eina_Bool unfocus_is_parent = EINA_FALSE;
2816 E_Border *bd_parent;
2818 bd_parent = bd->parent;
2821 if (bd_parent == bd2)
2823 unfocus_is_parent = EINA_TRUE;
2826 bd_parent = bd->parent;
2828 if ((!unfocus_is_parent) &&
2829 (!e_config->allow_above_fullscreen))
2831 e_border_iconify(bd2);
2836 focus_changed = EINA_TRUE;
2842 focus_next = eina_list_remove(focus_next, bd);
2843 if (bd == focusing) focusing = NULL;
2845 if ((bd->focused) &&
2846 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2848 Eina_Bool wasfocused = EINA_FALSE;
2851 /* should always be the case. anyway */
2855 wasfocused = EINA_TRUE;
2858 if ((set) && (!focus_next) && (!focusing))
2860 e_grabinput_focus(bd->zone->container->bg_win,
2861 E_FOCUS_METHOD_PASSIVE);
2863 if ((bd->fullscreen) && (wasfocused))
2865 Eina_Bool have_vis_child = EINA_FALSE;
2869 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2872 (bd2->zone == bd->zone) &&
2873 ((bd2->desk == bd->desk) ||
2874 (bd2->sticky) || (bd->sticky)))
2876 if (bd2->parent == bd)
2878 have_vis_child = EINA_TRUE;
2883 if ((!have_vis_child) &&
2884 (!e_config->allow_above_fullscreen))
2885 e_border_iconify(bd);
2891 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2892 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2894 E_Event_Border_Focus_Out *ev;
2896 bd_unfocus->focused = 0;
2897 e_focus_event_focus_out(bd_unfocus);
2899 if (bd_unfocus->raise_timer)
2900 ecore_timer_del(bd_unfocus->raise_timer);
2901 bd_unfocus->raise_timer = NULL;
2903 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2904 if (bd_unfocus->icon_object)
2905 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2907 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2908 ev->border = bd_unfocus;
2909 e_object_ref(E_OBJECT(bd_unfocus));
2911 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2912 _e_border_event_border_focus_out_free, NULL);
2913 if ((bd_unfocus->fullscreen) &&
2914 (bd != bd_unfocus) &&
2915 (bd->zone == bd_unfocus->zone) &&
2916 ((bd->desk == bd_unfocus->desk) ||
2917 (bd->sticky) || (bd_unfocus->sticky)))
2919 Eina_Bool unfocus_is_parent = EINA_FALSE;
2920 E_Border *bd_parent;
2922 bd_parent = bd->parent;
2925 if (bd_parent == bd_unfocus)
2927 unfocus_is_parent = EINA_TRUE;
2930 bd_parent = bd->parent;
2932 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2934 e_border_iconify(bd_unfocus);
2941 E_Event_Border_Focus_In *ev;
2943 e_focus_event_focus_in(bd);
2945 if (!focus_track_frozen)
2946 e_border_focus_latest_set(bd);
2948 e_hints_active_window_set(bd->zone->container->manager, bd);
2950 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2951 if (bd->icon_object)
2952 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2954 ev = E_NEW(E_Event_Border_Focus_In, 1);
2956 e_object_ref(E_OBJECT(bd));
2958 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2959 _e_border_event_border_focus_in_free, NULL);
2964 e_border_shade(E_Border *bd,
2967 E_Event_Border_Resize *ev;
2972 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2973 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2974 ((bd->maximized) && (!e_config->allow_manip))) return;
2975 if ((bd->client.border.name) &&
2976 (!strcmp("borderless", bd->client.border.name))) return;
2978 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2979 ecore_x_window_hide(tmp->win);
2981 ecore_x_window_shadow_tree_flush();
2983 bd->shade.x = bd->x;
2984 bd->shade.y = bd->y;
2985 bd->shade.dir = dir;
2987 e_hints_window_shaded_set(bd, 1);
2988 e_hints_window_shade_direction_set(bd, dir);
2990 if (e_config->border_shade_animate)
2992 bd->shade.start = ecore_loop_time_get();
2994 bd->changes.shading = 1;
2997 if (bd->shade.dir == E_DIRECTION_UP ||
2998 bd->shade.dir == E_DIRECTION_LEFT)
2999 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3001 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3003 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3004 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
3008 if (bd->shade.dir == E_DIRECTION_UP)
3010 bd->h = bd->client_inset.t + bd->client_inset.b;
3012 else if (bd->shade.dir == E_DIRECTION_DOWN)
3014 bd->h = bd->client_inset.t + bd->client_inset.b;
3015 bd->y = bd->y + bd->client.h;
3016 bd->changes.pos = 1;
3018 else if (bd->shade.dir == E_DIRECTION_LEFT)
3020 bd->w = bd->client_inset.l + bd->client_inset.r;
3022 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3024 bd->w = bd->client_inset.l + bd->client_inset.r;
3025 bd->x = bd->x + bd->client.w;
3026 bd->changes.pos = 1;
3029 if ((bd->shaped) || (bd->client.shaped))
3031 bd->need_shape_merge = 1;
3032 bd->need_shape_export = 1;
3034 if (bd->shaped_input)
3036 bd->need_shape_merge = 1;
3039 bd->changes.size = 1;
3041 bd->changes.shaded = 1;
3043 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3044 e_border_frame_recalc(bd);
3045 ev = E_NEW(E_Event_Border_Resize, 1);
3047 /* The resize is added in the animator when animation complete */
3048 /* For non-animated, we add it immediately with the new size */
3049 e_object_ref(E_OBJECT(bd));
3050 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3051 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3054 e_remember_update(bd);
3058 e_border_unshade(E_Border *bd,
3061 E_Event_Border_Resize *ev;
3066 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3067 if ((!bd->shaded) || (bd->shading))
3070 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3071 ecore_x_window_show(tmp->win);
3073 ecore_x_window_shadow_tree_flush();
3075 bd->shade.dir = dir;
3077 e_hints_window_shaded_set(bd, 0);
3078 e_hints_window_shade_direction_set(bd, dir);
3080 if (bd->shade.dir == E_DIRECTION_UP ||
3081 bd->shade.dir == E_DIRECTION_LEFT)
3083 bd->shade.x = bd->x;
3084 bd->shade.y = bd->y;
3088 bd->shade.x = bd->x - bd->client.w;
3089 bd->shade.y = bd->y - bd->client.h;
3091 if (e_config->border_shade_animate)
3093 bd->shade.start = ecore_loop_time_get();
3095 bd->changes.shading = 1;
3098 if (bd->shade.dir == E_DIRECTION_UP)
3100 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3101 ecore_x_window_move_resize(bd->client.win, 0,
3102 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3104 bd->client.w, bd->client.h);
3106 else if (bd->shade.dir == E_DIRECTION_LEFT)
3108 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3109 ecore_x_window_move_resize(bd->client.win,
3110 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3112 0, bd->client.w, bd->client.h);
3115 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3117 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3118 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3122 if (bd->shade.dir == E_DIRECTION_UP)
3124 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3126 else if (bd->shade.dir == E_DIRECTION_DOWN)
3128 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3129 bd->y = bd->y - bd->client.h;
3130 bd->changes.pos = 1;
3132 else if (bd->shade.dir == E_DIRECTION_LEFT)
3134 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3136 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3138 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3139 bd->x = bd->x - bd->client.w;
3140 bd->changes.pos = 1;
3142 if ((bd->shaped) || (bd->client.shaped))
3144 bd->need_shape_merge = 1;
3145 bd->need_shape_export = 1;
3147 if (bd->shaped_input)
3149 bd->need_shape_merge = 1;
3152 bd->changes.size = 1;
3154 bd->changes.shaded = 1;
3156 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3157 e_border_frame_recalc(bd);
3158 ev = E_NEW(E_Event_Border_Resize, 1);
3160 /* The resize is added in the animator when animation complete */
3161 /* For non-animated, we add it immediately with the new size */
3162 e_object_ref(E_OBJECT(bd));
3163 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3164 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3167 e_remember_update(bd);
3171 _e_border_client_inset_calc(E_Border *bd)
3174 Evas_Coord cx, cy, cw, ch;
3178 evas_object_resize(bd->bg_object, 1000, 1000);
3179 edje_object_message_signal_process(bd->bg_object);
3180 edje_object_calc_force(bd->bg_object);
3181 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3182 bd->client_inset.l = cx;
3183 bd->client_inset.r = 1000 - (cx + cw);
3184 bd->client_inset.t = cy;
3185 bd->client_inset.b = 1000 - (cy + ch);
3189 bd->client_inset.l = 0;
3190 bd->client_inset.r = 0;
3191 bd->client_inset.t = 0;
3192 bd->client_inset.b = 0;
3195 ecore_x_netwm_frame_size_set(bd->client.win,
3196 bd->client_inset.l, bd->client_inset.r,
3197 bd->client_inset.t, bd->client_inset.b);
3198 ecore_x_e_frame_size_set(bd->client.win,
3199 bd->client_inset.l, bd->client_inset.r,
3200 bd->client_inset.t, bd->client_inset.b);
3204 _e_border_maximize(E_Border *bd, E_Maximize max)
3206 int x1, yy1, x2, y2;
3209 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3213 zx = zy = zw = zh = 0;
3215 switch (max & E_MAXIMIZE_TYPE)
3217 case E_MAXIMIZE_NONE:
3221 case E_MAXIMIZE_FULLSCREEN:
3227 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3228 _e_border_client_inset_calc(bd);
3230 e_border_resize_limit(bd, &w, &h);
3231 /* center x-direction */
3232 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3233 /* center y-direction */
3234 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3236 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3237 cy = bd->zone->y + (bd->zone->h / 2);
3240 switch (max & E_MAXIMIZE_DIRECTION)
3242 case E_MAXIMIZE_BOTH:
3243 e_border_move_resize(bd, x1, yy1, w, h);
3246 case E_MAXIMIZE_VERTICAL:
3247 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3250 case E_MAXIMIZE_HORIZONTAL:
3251 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3254 case E_MAXIMIZE_LEFT:
3255 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3258 case E_MAXIMIZE_RIGHT:
3259 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3261 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3262 case E_MAXIMIZE_TOP:
3263 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3265 case E_MAXIMIZE_BOTTOM:
3266 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3272 case E_MAXIMIZE_SMART:
3273 case E_MAXIMIZE_EXPAND:
3275 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3287 if (bd->x < zx) // window left not useful coordinates
3289 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3290 x1 = zx + zw - bd->w;
3291 else // window normal position
3294 if (bd->y < zy) // window top not useful coordinates
3296 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3297 yy1 = zy + zh - bd->h;
3298 else // window normal position
3301 switch (max & E_MAXIMIZE_DIRECTION)
3303 case E_MAXIMIZE_BOTH:
3304 e_border_move_resize(bd, zx, zy, zw, zh);
3307 case E_MAXIMIZE_VERTICAL:
3308 e_border_move_resize(bd, x1, zy, w, zh);
3311 case E_MAXIMIZE_HORIZONTAL:
3312 e_border_move_resize(bd, zx, yy1, zw, h);
3315 case E_MAXIMIZE_LEFT:
3316 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3319 case E_MAXIMIZE_RIGHT:
3320 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3324 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3327 case E_MAXIMIZE_FILL:
3330 x2 = bd->zone->x + bd->zone->w;
3331 y2 = bd->zone->y + bd->zone->h;
3333 /* walk through all shelves */
3334 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3336 /* walk through all windows */
3337 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3343 e_border_resize_limit(bd, &w, &h);
3344 /* center x-direction */
3345 x1 = x1 + (pw - w) / 2;
3346 /* center y-direction */
3347 yy1 = yy1 + (ph - h) / 2;
3349 switch (max & E_MAXIMIZE_DIRECTION)
3351 case E_MAXIMIZE_BOTH:
3352 e_border_move_resize(bd, x1, yy1, w, h);
3355 case E_MAXIMIZE_VERTICAL:
3356 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3359 case E_MAXIMIZE_HORIZONTAL:
3360 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3363 case E_MAXIMIZE_LEFT:
3364 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3367 case E_MAXIMIZE_RIGHT:
3368 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3376 e_border_maximize(E_Border *bd,
3380 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3382 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3384 if ((bd->shaded) || (bd->shading)) return;
3385 ecore_x_window_shadow_tree_flush();
3387 e_border_unfullscreen(bd);
3388 /* Only allow changes in vertical/ horizontal maximization */
3389 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3390 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3393 bd->need_maximize = 1;
3394 bd->maximized &= ~E_MAXIMIZE_TYPE;
3395 bd->maximized |= max;
3399 bd->pre_res_change.valid = 0;
3400 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3402 /* Horizontal hasn't been set */
3403 bd->saved.x = bd->x - bd->zone->x;
3404 bd->saved.w = bd->w;
3406 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3408 /* Vertical hasn't been set */
3409 bd->saved.y = bd->y - bd->zone->y;
3410 bd->saved.h = bd->h;
3413 bd->saved.zone = bd->zone->num;
3414 e_hints_window_size_set(bd);
3418 _e_border_maximize(bd, max);
3421 /* Remove previous type */
3422 bd->maximized &= ~E_MAXIMIZE_TYPE;
3423 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3424 bd->maximized |= max;
3426 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3427 bd->maximized & E_MAXIMIZE_VERTICAL);
3428 e_remember_update(bd);
3432 e_border_unmaximize(E_Border *bd,
3436 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3437 if (!(max & E_MAXIMIZE_DIRECTION))
3439 CRI("BUG: Unmaximize call without direction!");
3443 if ((bd->shaded) || (bd->shading)) return;
3444 ecore_x_window_shadow_tree_flush();
3445 /* Remove directions not used */
3446 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3447 /* Can only remove existing maximization directions */
3449 if (bd->maximized & E_MAXIMIZE_TYPE)
3451 bd->pre_res_change.valid = 0;
3452 bd->need_maximize = 0;
3454 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3458 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3459 _e_border_client_inset_calc(bd);
3462 bd->maximized = E_MAXIMIZE_NONE;
3463 _e_border_move_resize_internal(bd,
3464 bd->zone->x + bd->saved.x,
3465 bd->zone->y + bd->saved.y,
3466 bd->saved.w, bd->saved.h, 0, 1);
3467 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3468 e_hints_window_size_unset(bd);
3479 if (max & E_MAXIMIZE_VERTICAL)
3481 /* Remove vertical */
3483 y = bd->saved.y + bd->zone->y;
3484 bd->saved.h = bd->saved.y = 0;
3485 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3486 bd->maximized &= ~E_MAXIMIZE_LEFT;
3487 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3489 if (max & E_MAXIMIZE_HORIZONTAL)
3491 /* Remove horizontal */
3493 x = bd->saved.x + bd->zone->x;
3494 bd->saved.w = bd->saved.x = 0;
3495 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3498 e_border_resize_limit(bd, &w, &h);
3500 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3502 bd->maximized = E_MAXIMIZE_NONE;
3503 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3504 e_hints_window_size_unset(bd);
3505 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3509 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3510 e_hints_window_size_set(bd);
3513 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3514 bd->maximized & E_MAXIMIZE_VERTICAL);
3516 e_remember_update(bd);
3520 e_border_fullscreen(E_Border *bd,
3521 E_Fullscreen policy)
3523 E_Event_Border_Fullscreen *ev;
3526 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3528 if ((bd->shaded) || (bd->shading)) return;
3529 ecore_x_window_shadow_tree_flush();
3532 bd->need_fullscreen = 1;
3535 if (!bd->fullscreen)
3537 bd->pre_res_change.valid = 0;
3539 bd->saved.x = bd->x - bd->zone->x;
3540 bd->saved.y = bd->y - bd->zone->y;
3541 bd->saved.w = bd->client.w;
3542 bd->saved.h = bd->client.h;
3543 bd->saved.maximized = bd->maximized;
3544 bd->saved.zone = bd->zone->num;
3547 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3548 e_hints_window_size_set(bd);
3550 bd->client_inset.l = 0;
3551 bd->client_inset.r = 0;
3552 bd->client_inset.t = 0;
3553 bd->client_inset.b = 0;
3555 bd->desk->fullscreen_borders++;
3557 /* e_zone_fullscreen_set(bd->zone, 1); */
3558 bd->saved.layer = bd->layer;
3559 if (!e_config->allow_above_fullscreen)
3560 e_border_layer_set(bd, 250);
3562 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3563 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3565 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3567 else if (policy == E_FULLSCREEN_ZOOM)
3569 Ecore_X_Randr_Screen_Size_MM *sizes;
3570 int num_sizes, i, best_size_index = 0;
3572 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3574 &screen_size.height,
3576 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3580 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3581 int best_dist = INT_MAX, dist;
3583 for (i = 0; i < num_sizes; i++)
3585 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3587 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3588 if (dist < best_dist)
3590 best_size.width = sizes[i].width;
3591 best_size.height = sizes[i].height;
3593 best_size_index = i;
3597 if (((best_size.width != -1) && (best_size.height != -1)) &&
3598 ((best_size.width != screen_size.width) ||
3599 (best_size.height != screen_size.height)))
3601 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3603 screen_size_index = best_size_index;
3604 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3608 screen_size.width = -1;
3609 screen_size.height = -1;
3610 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3615 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3619 e_hints_window_fullscreen_set(bd, 1);
3620 e_hints_window_size_unset(bd);
3621 bd->client.border.changed = 1;
3624 bd->fullscreen_policy = policy;
3626 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3628 e_object_ref(E_OBJECT(bd));
3629 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3630 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3632 e_remember_update(bd);
3636 e_border_unfullscreen(E_Border *bd)
3638 E_Event_Border_Unfullscreen *ev;
3641 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3642 if ((bd->shaded) || (bd->shading)) return;
3643 ecore_x_window_shadow_tree_flush();
3646 bd->pre_res_change.valid = 0;
3648 bd->need_fullscreen = 0;
3649 bd->desk->fullscreen_borders--;
3651 if ((screen_size.width != -1) && (screen_size.height != -1))
3653 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3655 screen_size.width = -1;
3656 screen_size.height = -1;
3658 e_border_move_resize(bd,
3659 bd->saved.x + bd->zone->x,
3660 bd->saved.y + bd->zone->y,
3661 bd->saved.w, bd->saved.h);
3663 if (bd->saved.maximized)
3664 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3665 bd->saved.maximized);
3667 e_border_layer_set(bd, bd->saved.layer);
3669 e_hints_window_fullscreen_set(bd, 0);
3670 bd->client.border.changed = 1;
3673 bd->fullscreen_policy = 0;
3675 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3677 e_object_ref(E_OBJECT(bd));
3678 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3679 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3681 e_remember_update(bd);
3685 e_border_iconify(E_Border *bd)
3687 E_Event_Border_Iconify *ev;
3688 unsigned int iconic;
3691 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3692 if (bd->shading) return;
3693 ecore_x_window_shadow_tree_flush();
3697 e_border_hide(bd, 1);
3698 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3699 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3702 e_hints_window_iconic_set(bd);
3703 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3705 ev = E_NEW(E_Event_Border_Iconify, 1);
3707 e_object_ref(E_OBJECT(bd));
3708 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3709 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3711 if (e_config->transient.iconify)
3715 Eina_List *list = _e_border_sub_borders_new(bd);
3717 EINA_LIST_FOREACH(list, l, child)
3719 e_border_iconify(child);
3721 eina_list_free(list);
3723 e_remember_update(bd);
3726 #ifdef _F_DEICONIFY_APPROVE_
3728 _e_border_uniconify_timeout(void *data)
3735 if (!e_object_is_del(E_OBJECT(bd)))
3737 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3738 bd->client.e.state.deiconify_approve.render_done = 1;
3739 if (bd->client.e.state.deiconify_approve.req_list)
3741 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3743 child_bd->client.e.state.deiconify_approve.render_done = 1;
3744 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3747 bd->client.e.state.deiconify_approve.req_list = NULL;
3748 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3749 e_border_uniconify(bd);
3752 return ECORE_CALLBACK_CANCEL;
3756 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
3758 if (!bd || !bd_ancestor) return;
3760 if (e_config->deiconify_approve)
3762 if (e_config->transient.iconify)
3766 Eina_List *list = _e_border_sub_borders_new(bd);
3767 EINA_LIST_FOREACH(list, l, child)
3769 #ifdef _F_ZONE_WINDOW_ROTATION_
3770 if ((e_config->wm_win_rotation) &&
3771 ((child->client.e.state.rot.support) ||
3772 (child->client.e.state.rot.app_set)))
3774 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3775 int rotation = _e_border_rotation_angle_get(bd);
3776 if (rotation != -1) e_border_rotation_set(bd, rotation);
3779 _e_border_deiconify_approve_send(child, bd_ancestor);
3780 if (child->client.e.state.deiconify_approve.support)
3782 ELBF(ELBT_BD, 0, child->client.win,
3783 "SEND DEICONIFY_APPROVE. ancestor:%x", bd_ancestor->client.win);
3785 ecore_x_client_message32_send(child->client.win,
3786 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3787 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3788 child->client.win, 0, 0, 0, 0);
3789 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3790 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3793 eina_list_free(list);
3799 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3801 E_Border *bd_ancestor;
3804 if (e_config->deiconify_approve)
3806 #ifdef _F_ZONE_WINDOW_ROTATION_
3807 if ((e_config->wm_win_rotation) &&
3808 ((bd->client.e.state.rot.support) ||
3809 (bd->client.e.state.rot.app_set)))
3811 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3812 int rotation = _e_border_rotation_angle_get(bd);
3813 if (rotation != -1) e_border_rotation_set(bd, rotation);
3817 if (e_config->transient.iconify)
3819 _e_border_deiconify_approve_send(bd, bd_ancestor);
3822 if (bd->client.e.state.deiconify_approve.support)
3824 ELBF(ELBT_BD, 0, bd->client.win,
3825 "SEND DEICONIFY_APPROVE.. ancestor:%x", bd_ancestor->client.win);
3827 ecore_x_client_message32_send(bd->client.win,
3828 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3829 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3830 bd->client.win, 0, 0, 0, 0);
3831 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3838 e_border_uniconify(E_Border *bd)
3841 E_Event_Border_Uniconify *ev;
3842 unsigned int iconic;
3845 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3847 #ifdef _F_DEICONIFY_APPROVE_
3848 if (e_config->deiconify_approve)
3850 if (bd->client.e.state.deiconify_approve.support)
3852 if (bd->client.e.state.deiconify_approve.wait_timer)
3854 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3857 if (bd->client.e.state.deiconify_approve.render_done == 0)
3859 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3860 _e_border_deiconify_approve_send_all_transient(bd);
3864 bd->client.e.state.deiconify_approve.render_done = 0;
3868 #if _F_ZONE_WINDOW_ROTATION_
3869 if (!bd->client.win)
3871 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3876 if (bd->shading) return;
3877 ecore_x_window_shadow_tree_flush();
3882 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3883 desk = e_desk_current_get(bd->desk->zone);
3884 #ifdef _F_USE_EXTENDED_ICONIFY_
3885 if (e_manager_comp_evas_get(bd->zone->container->manager))
3887 if (bd->await_hide_event > 0)
3888 bd->await_hide_event--;
3891 e_border_desk_set(bd, desk);
3893 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3896 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3898 ev = E_NEW(E_Event_Border_Uniconify, 1);
3900 e_object_ref(E_OBJECT(bd));
3901 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3902 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3904 if (e_config->transient.iconify)
3908 Eina_List *list = _e_border_sub_borders_new(bd);
3910 EINA_LIST_FOREACH(list, l, child)
3912 e_border_uniconify(child);
3914 eina_list_free(list);
3916 e_remember_update(bd);
3920 e_border_stick(E_Border *bd)
3922 E_Event_Border_Stick *ev;
3925 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3926 if (bd->sticky) return;
3928 e_hints_window_sticky_set(bd, 1);
3931 if (e_config->transient.desktop)
3935 Eina_List *list = _e_border_sub_borders_new(bd);
3937 EINA_LIST_FOREACH(list, l, child)
3940 e_hints_window_sticky_set(child, 1);
3941 e_border_show(child);
3943 eina_list_free(list);
3946 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
3947 ev = E_NEW(E_Event_Border_Stick, 1);
3949 e_object_ref(E_OBJECT(bd));
3950 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
3951 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
3952 e_remember_update(bd);
3956 e_border_unstick(E_Border *bd)
3958 E_Event_Border_Unstick *ev;
3961 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3962 /* Set the desk before we unstick the border */
3963 if (!bd->sticky) return;
3965 e_hints_window_sticky_set(bd, 0);
3967 if (e_config->transient.desktop)
3971 Eina_List *list = _e_border_sub_borders_new(bd);
3973 EINA_LIST_FOREACH(list, l, child)
3976 e_hints_window_sticky_set(child, 0);
3978 eina_list_free(list);
3981 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
3982 ev = E_NEW(E_Event_Border_Unstick, 1);
3984 e_object_ref(E_OBJECT(bd));
3985 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
3986 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
3988 e_border_desk_set(bd, e_desk_current_get(bd->zone));
3989 e_remember_update(bd);
3993 e_border_pinned_set(E_Border *bd,
4001 bd->borderless = set;
4002 bd->user_skip_winlist = set;
4006 stacking = E_STACKING_BELOW;
4011 stacking = E_STACKING_NONE;
4014 e_border_layer_set(bd, layer);
4015 e_hints_window_stacking_set(bd, stacking);
4017 bd->client.border.changed = 1;
4023 e_border_find_by_client_window(Ecore_X_Window win)
4027 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4028 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4029 (bd->client.win == win))
4035 e_border_find_all_by_client_window(Ecore_X_Window win)
4039 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4040 if ((bd) && (bd->client.win == win))
4046 e_border_find_by_frame_window(Ecore_X_Window win)
4050 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4051 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4052 (bd->bg_win == win))
4058 e_border_find_by_window(Ecore_X_Window win)
4062 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4063 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4070 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4075 EINA_LIST_FOREACH(borders, l, bd)
4077 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4078 (bd->client.netwm.sync.alarm == al))
4085 e_border_focused_get(void)
4091 _e_border_shape_input_rectangle_set(E_Border* bd)
4095 if ((bd->visible) && (bd->shaped_input))
4097 Ecore_X_Rectangle rects[4];
4098 Ecore_X_Window twin, twin2;
4101 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4102 0, 0, bd->w, bd->h);
4105 rects[0].width = bd->w;
4106 rects[0].height = bd->client_inset.t;
4108 rects[1].y = bd->client_inset.t;
4109 rects[1].width = bd->client_inset.l;
4110 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4111 rects[2].x = bd->w - bd->client_inset.r;
4112 rects[2].y = bd->client_inset.t;
4113 rects[2].width = bd->client_inset.r;
4114 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4116 rects[3].y = bd->h - bd->client_inset.b;
4117 rects[3].width = bd->w;
4118 rects[3].height = bd->client_inset.b;
4119 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4121 twin2 = ecore_x_window_override_new
4122 (bd->zone->container->scratch_win, 0, 0,
4123 bd->w - bd->client_inset.l - bd->client_inset.r,
4124 bd->h - bd->client_inset.t - bd->client_inset.b);
4127 if ((bd->shading) || (bd->shaded))
4129 if (bd->shade.dir == E_DIRECTION_UP)
4130 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4132 else if (bd->shade.dir == E_DIRECTION_LEFT)
4133 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4136 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4138 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4139 bd->w - bd->client_inset.l - bd->client_inset.r,
4140 bd->h - bd->client_inset.t - bd->client_inset.b);
4141 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4143 bd->client_inset.t);
4144 ecore_x_window_shape_input_window_set(bd->win, twin);
4145 ecore_x_window_free(twin2);
4146 ecore_x_window_free(twin);
4150 if (bd->visible) // not shaped input
4152 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4153 ecore_x_composite_window_events_enable(bd->win);
4155 ecore_x_composite_window_events_disable(bd->win);
4159 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4160 ecore_x_composite_window_events_enable(bd->win);
4162 ecore_x_composite_window_events_disable(bd->win);
4168 e_border_idler_before(void)
4177 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4179 EINA_LIST_FOREACH(man->containers, cl, con)
4184 // pass 1 - eval0. fetch properties on new or on change and
4185 // call hooks to decide what to do - maybe move/resize
4186 bl = e_container_border_list_last(con);
4187 while ((bd = e_container_border_list_prev(bl)))
4189 if (bd->changed) _e_border_eval0(bd);
4191 e_container_border_list_free(bl);
4193 // layout hook - this is where a hook gets to figure out what to
4195 _e_border_container_layout_hook(con);
4197 // pass 2 - show windows needing show
4198 bl = e_container_border_list_last(con);
4199 while ((bd = e_container_border_list_prev(bl)))
4201 if ((bd->changes.visible) && (bd->visible) &&
4202 (!bd->new_client) && (!bd->changes.pos) &&
4203 (!bd->changes.size))
4206 bd->changes.visible = 0;
4209 e_container_border_list_free(bl);
4211 // pass 3 - hide windows needing hide and eval (main eval)
4212 bl = e_container_border_list_first(con);
4213 while ((bd = e_container_border_list_next(bl)))
4215 if (e_object_is_del(E_OBJECT(bd))) continue;
4217 if ((bd->changes.visible) && (!bd->visible))
4220 bd->changes.visible = 0;
4223 if (bd->changed) _e_border_eval(bd);
4225 if ((bd->changes.visible) && (bd->visible))
4228 bd->changes.visible = 0;
4231 e_container_border_list_free(bl);
4237 E_Border *bd = NULL, *bd2;
4239 EINA_LIST_FREE(focus_next, bd2)
4240 if ((!bd) && (bd2->visible)) bd = bd2;
4244 /* TODO revert focus when lost here ? */
4250 /* already focused. but anyway dont be so strict, this
4251 fcks up illume setting focus on internal windows */
4256 focus_time = ecore_x_current_time_get();
4260 if ((bd->client.icccm.take_focus) &&
4261 (bd->client.icccm.accepts_focus))
4263 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4264 /* TODO what if the client didn't take focus ? */
4266 else if (!bd->client.icccm.accepts_focus)
4268 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4270 else if (!bd->client.icccm.take_focus)
4272 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4273 /* e_border_focus_set(bd, 1, 0); */
4277 #ifdef _F_ZONE_WINDOW_ROTATION_
4278 if ((e_config->wm_win_rotation) &&
4281 Ecore_X_Event_Client_Message *msg = NULL;
4283 EINA_LIST_FREE(rot.msgs, msg)
4285 t = msg->message_type;
4286 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4288 if ((rot.vkbd_ctrl_win) &&
4289 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4292 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4293 if (rot.vkbd_show_prepare_timer)
4294 _e_border_vkbd_show(rot.vkbd);
4296 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4299 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4301 if ((rot.vkbd_ctrl_win) &&
4302 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4305 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4306 if (rot.vkbd_hide_prepare_timer)
4308 _e_border_vkbd_hide(rot.vkbd);
4309 rot.vkbd_hide_prepare_timer = NULL;
4310 e_object_unref(E_OBJECT(rot.vkbd));
4313 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4316 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4318 rot.vkbd_ctrl_win = msg->data.l[0];
4319 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4321 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4323 if ((rot.vkbd_ctrl_win) &&
4324 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4326 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4327 E_Manager *m = e_manager_current_get();
4328 E_Zone *zone = NULL;
4329 if (m) zone = e_util_zone_current_get(m);
4330 if ((zone) && (rot.wait_prepare_done))
4334 _e_border_rotation_change_request(zone);
4335 if (rot.prepare_timer)
4336 ecore_timer_del(rot.prepare_timer);
4337 rot.prepare_timer = NULL;
4338 rot.wait_prepare_done = EINA_FALSE;
4347 rot.fetch = EINA_FALSE;
4353 e_border_client_list(void)
4355 /* FIXME: This should be a somewhat ordered list */
4359 static Ecore_X_Window action_input_win = 0;
4360 static E_Border *action_border = NULL;
4361 static Ecore_Event_Handler *action_handler_key = NULL;
4362 static Ecore_Event_Handler *action_handler_mouse = NULL;
4363 static Ecore_Timer *action_timer = NULL;
4364 static Ecore_X_Rectangle action_orig;
4367 _e_border_show(E_Border *bd)
4372 ecore_evas_show(bd->bg_ecore_evas);
4380 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4382 _e_border_shape_input_rectangle_set(bd);
4384 // ecore_x_composite_window_events_enable(bd->win);
4385 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4388 ecore_x_window_show(bd->win);
4390 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4391 ecore_x_window_show(tmp->win);
4395 _e_border_hide(E_Border *bd)
4400 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4402 ecore_x_window_hide(bd->win);
4403 ecore_evas_hide(bd->bg_ecore_evas);
4405 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4406 ecore_x_window_hide(tmp->win);
4410 ecore_x_composite_window_events_disable(bd->win);
4411 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4416 _e_border_action_input_win_del(void)
4418 if (!action_input_win)
4421 e_grabinput_release(action_input_win, action_input_win);
4422 ecore_x_window_free(action_input_win);
4423 action_input_win = 0;
4428 _e_border_action_input_win_new(E_Border *bd)
4430 if (!action_input_win)
4432 Ecore_X_Window parent = bd->zone->container->win;
4433 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4434 if (!action_input_win)
4438 ecore_x_window_show(action_input_win);
4439 if (e_grabinput_get(action_input_win, 0, action_input_win))
4442 _e_border_action_input_win_del();
4447 _e_border_action_finish(void)
4449 _e_border_action_input_win_del();
4453 ecore_timer_del(action_timer);
4454 action_timer = NULL;
4457 if (action_handler_key)
4459 ecore_event_handler_del(action_handler_key);
4460 action_handler_key = NULL;
4463 if (action_handler_mouse)
4465 ecore_event_handler_del(action_handler_mouse);
4466 action_handler_mouse = NULL;
4469 action_border = NULL;
4473 _e_border_action_init(E_Border *bd)
4475 action_orig.x = bd->x;
4476 action_orig.y = bd->y;
4477 action_orig.width = bd->w;
4478 action_orig.height = bd->h;
4484 _e_border_action_restore_orig(E_Border *bd)
4486 if (action_border != bd)
4489 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4493 _e_border_key_down_modifier_apply(int modifier,
4496 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4498 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4511 _e_border_action_move_timeout(void *data __UNUSED__)
4513 _e_border_move_end(action_border);
4514 _e_border_action_finish();
4515 return ECORE_CALLBACK_CANCEL;
4519 _e_border_action_move_timeout_add(void)
4522 ecore_timer_del(action_timer);
4523 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4527 _e_border_move_key_down(void *data __UNUSED__,
4528 int type __UNUSED__,
4531 Ecore_Event_Key *ev = event;
4534 if (ev->event_window != action_input_win)
4535 return ECORE_CALLBACK_PASS_ON;
4538 fputs("ERROR: no action_border!\n", stderr);
4542 x = action_border->x;
4543 y = action_border->y;
4545 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4546 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4547 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4548 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4549 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4550 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4551 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4552 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4553 else if (strcmp(ev->key, "Return") == 0)
4555 else if (strcmp(ev->key, "Escape") == 0)
4557 _e_border_action_restore_orig(action_border);
4560 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4561 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4564 e_border_move(action_border, x, y);
4565 _e_border_action_move_timeout_add();
4567 return ECORE_CALLBACK_PASS_ON;
4570 _e_border_move_end(action_border);
4571 _e_border_action_finish();
4572 return ECORE_CALLBACK_DONE;
4576 _e_border_move_mouse_down(void *data __UNUSED__,
4577 int type __UNUSED__,
4580 Ecore_Event_Mouse_Button *ev = event;
4582 if (ev->event_window != action_input_win)
4583 return ECORE_CALLBACK_PASS_ON;
4586 fputs("ERROR: no action_border!\n", stderr);
4588 _e_border_move_end(action_border);
4589 _e_border_action_finish();
4590 return ECORE_CALLBACK_DONE;
4594 e_border_act_move_keyboard(E_Border *bd)
4599 if (!_e_border_move_begin(bd))
4602 if (!_e_border_action_input_win_new(bd))
4604 _e_border_move_end(bd);
4608 _e_border_action_init(bd);
4609 _e_border_action_move_timeout_add();
4610 _e_border_move_update(bd);
4612 if (action_handler_key)
4613 ecore_event_handler_del(action_handler_key);
4614 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4616 if (action_handler_mouse)
4617 ecore_event_handler_del(action_handler_mouse);
4618 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4622 _e_border_action_resize_timeout(void *data __UNUSED__)
4624 _e_border_resize_end(action_border);
4625 _e_border_action_finish();
4626 return ECORE_CALLBACK_CANCEL;
4630 _e_border_action_resize_timeout_add(void)
4633 ecore_timer_del(action_timer);
4634 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4638 _e_border_resize_key_down(void *data __UNUSED__,
4639 int type __UNUSED__,
4642 Ecore_Event_Key *ev = event;
4645 if (ev->event_window != action_input_win)
4646 return ECORE_CALLBACK_PASS_ON;
4649 fputs("ERROR: no action_border!\n", stderr);
4653 w = action_border->w;
4654 h = action_border->h;
4656 dx = e_config->border_keyboard.resize.dx;
4657 if (dx < action_border->client.icccm.step_w)
4658 dx = action_border->client.icccm.step_w;
4659 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4660 if (dx < action_border->client.icccm.step_w)
4661 dx = action_border->client.icccm.step_w;
4663 dy = e_config->border_keyboard.resize.dy;
4664 if (dy < action_border->client.icccm.step_h)
4665 dy = action_border->client.icccm.step_h;
4666 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4667 if (dy < action_border->client.icccm.step_h)
4668 dy = action_border->client.icccm.step_h;
4670 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4672 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4674 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4676 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4678 else if (strcmp(ev->key, "Return") == 0)
4680 else if (strcmp(ev->key, "Escape") == 0)
4682 _e_border_action_restore_orig(action_border);
4685 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4686 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4689 e_border_resize_limit(action_border, &w, &h);
4690 e_border_resize(action_border, w, h);
4691 _e_border_action_resize_timeout_add();
4693 return ECORE_CALLBACK_PASS_ON;
4696 _e_border_resize_end(action_border);
4697 _e_border_action_finish();
4698 return ECORE_CALLBACK_DONE;
4702 _e_border_resize_mouse_down(void *data __UNUSED__,
4703 int type __UNUSED__,
4706 Ecore_Event_Mouse_Button *ev = event;
4708 if (ev->event_window != action_input_win)
4709 return ECORE_CALLBACK_PASS_ON;
4712 fputs("ERROR: no action_border!\n", stderr);
4714 _e_border_resize_end(action_border);
4715 _e_border_action_finish();
4716 return ECORE_CALLBACK_DONE;
4720 e_border_act_resize_keyboard(E_Border *bd)
4725 if (!_e_border_resize_begin(bd))
4728 if (!_e_border_action_input_win_new(bd))
4730 _e_border_resize_end(bd);
4734 _e_border_action_init(bd);
4735 _e_border_action_resize_timeout_add();
4736 _e_border_resize_update(bd);
4738 if (action_handler_key)
4739 ecore_event_handler_del(action_handler_key);
4740 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4742 if (action_handler_mouse)
4743 ecore_event_handler_del(action_handler_mouse);
4744 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4748 e_border_act_move_begin(E_Border *bd,
4749 Ecore_Event_Mouse_Button *ev)
4752 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4753 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4754 if (!_e_border_move_begin(bd))
4757 e_zone_edge_disable();
4759 _e_border_pointer_move_begin(bd);
4764 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4765 _e_border_moveinfo_gather(bd, source);
4770 e_border_act_move_end(E_Border *bd,
4771 Ecore_Event_Mouse_Button *ev __UNUSED__)
4774 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4775 if (!bd->moving) return;
4777 _e_border_pointer_move_end(bd);
4778 e_zone_edge_enable();
4779 _e_border_move_end(bd);
4780 e_zone_flip_coords_handle(bd->zone, -1, -1);
4784 e_border_act_resize_begin(E_Border *bd,
4785 Ecore_Event_Mouse_Button *ev)
4788 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4789 if (bd->lock_user_size) return;
4790 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4791 if (!_e_border_resize_begin(bd))
4793 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4795 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4797 bd->resize_mode = RESIZE_TL;
4798 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4802 bd->resize_mode = RESIZE_BL;
4803 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4808 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4810 bd->resize_mode = RESIZE_TR;
4811 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4815 bd->resize_mode = RESIZE_BR;
4816 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4819 _e_border_pointer_resize_begin(bd);
4824 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4825 _e_border_moveinfo_gather(bd, source);
4830 e_border_act_resize_end(E_Border *bd,
4831 Ecore_Event_Mouse_Button *ev __UNUSED__)
4834 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4835 if (bd->resize_mode != RESIZE_NONE)
4837 _e_border_pointer_resize_end(bd);
4838 bd->resize_mode = RESIZE_NONE;
4839 _e_border_resize_end(bd);
4840 bd->changes.reset_gravity = 1;
4846 e_border_act_menu_begin(E_Border *bd,
4847 Ecore_Event_Mouse_Button *ev,
4851 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4854 e_int_border_menu_show(bd,
4855 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4856 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4863 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4864 e_int_border_menu_show(bd, x, y, key, 0);
4869 e_border_act_close_begin(E_Border *bd)
4872 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4873 if (bd->lock_close) return;
4874 if (bd->client.icccm.delete_request)
4876 bd->delete_requested = 1;
4877 ecore_x_window_delete_request_send(bd->client.win);
4878 if (bd->client.netwm.ping)
4881 else if (e_config->kill_if_close_not_possible)
4883 e_border_act_kill_begin(bd);
4888 e_border_act_kill_begin(E_Border *bd)
4891 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4892 if (bd->internal) return;
4893 if (bd->lock_close) return;
4894 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4896 kill(bd->client.netwm.pid, SIGINT);
4897 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4898 _e_border_cb_kill_timer, bd);
4902 if (!bd->internal) ecore_x_kill(bd->client.win);
4907 e_border_icon_add(E_Border *bd,
4912 E_OBJECT_CHECK_RETURN(bd, NULL);
4913 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4918 if (!bd->internal_icon)
4920 o = e_icon_add(evas);
4921 e_util_icon_theme_set(o, "enlightenment");
4925 if (!bd->internal_icon_key)
4929 ext = strrchr(bd->internal_icon, '.');
4930 if ((ext) && ((!strcmp(ext, ".edj"))))
4932 o = edje_object_add(evas);
4933 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4934 e_util_icon_theme_set(o, "enlightenment");
4938 o = e_icon_add(evas);
4939 e_icon_file_set(o, bd->internal_icon);
4943 o = e_icon_add(evas);
4944 if (!e_util_icon_theme_set(o, bd->internal_icon))
4945 e_util_icon_theme_set(o, "enlightenment");
4950 o = edje_object_add(evas);
4951 edje_object_file_set(o, bd->internal_icon,
4952 bd->internal_icon_key);
4957 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
4959 if (bd->client.netwm.icons)
4961 o = e_icon_add(evas);
4962 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4963 bd->client.netwm.icons[0].width,
4964 bd->client.netwm.icons[0].height);
4965 e_icon_alpha_set(o, 1);
4971 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
4973 o = e_icon_add(evas);
4976 e_icon_fdo_icon_set(o, bd->desktop->icon);
4980 else if (bd->client.netwm.icons)
4982 o = e_icon_add(evas);
4983 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4984 bd->client.netwm.icons[0].width,
4985 bd->client.netwm.icons[0].height);
4986 e_icon_alpha_set(o, 1);
4991 o = e_icon_add(evas);
4992 e_util_icon_theme_set(o, "unknown");
4997 e_border_button_bindings_ungrab_all(void)
5002 EINA_LIST_FOREACH(borders, l, bd)
5004 e_focus_setdown(bd);
5005 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5006 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5011 e_border_button_bindings_grab_all(void)
5016 EINA_LIST_FOREACH(borders, l, bd)
5018 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5019 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5025 e_border_focus_stack_get(void)
5031 e_border_raise_stack_get(void)
5037 e_border_lost_windows_get(E_Zone *zone)
5039 Eina_List *list = NULL, *l;
5041 int loss_overlap = 5;
5043 E_OBJECT_CHECK_RETURN(zone, NULL);
5044 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5045 EINA_LIST_FOREACH(borders, l, bd)
5050 if ((bd->zone != zone) ||
5051 (bd->zone->container != zone->container))
5054 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5055 bd->zone->y + loss_overlap,
5056 bd->zone->w - (2 * loss_overlap),
5057 bd->zone->h - (2 * loss_overlap),
5058 bd->x, bd->y, bd->w, bd->h))
5060 list = eina_list_append(list, bd);
5062 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5063 bd->zone->w, bd->zone->h,
5064 bd->x, bd->y, bd->w, bd->h)) &&
5067 Ecore_X_Rectangle *rect;
5070 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5076 for (i = 0; i < num; i++)
5078 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5079 bd->zone->y + loss_overlap,
5080 bd->zone->w - (2 * loss_overlap),
5081 bd->zone->h - (2 * loss_overlap),
5082 rect[i].x, rect[i].y,
5083 (int)rect[i].width, (int)rect[i].height))
5091 list = eina_list_append(list, bd);
5099 e_border_ping(E_Border *bd)
5102 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5103 if (!e_config->ping_clients) return;
5105 ecore_x_netwm_ping_send(bd->client.win);
5106 bd->ping = ecore_loop_time_get();
5107 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5108 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5109 e_config->ping_clients_interval,
5110 _e_border_cb_ping_poller, bd);
5114 e_border_move_cancel(void)
5118 if (bdmove->cur_mouse_action)
5123 e_object_ref(E_OBJECT(bd));
5124 if (bd->cur_mouse_action->func.end_mouse)
5125 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5126 else if (bd->cur_mouse_action->func.end)
5127 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5128 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5129 bd->cur_mouse_action = NULL;
5130 e_object_unref(E_OBJECT(bd));
5133 _e_border_move_end(bdmove);
5138 e_border_resize_cancel(void)
5142 if (bdresize->cur_mouse_action)
5147 e_object_ref(E_OBJECT(bd));
5148 if (bd->cur_mouse_action->func.end_mouse)
5149 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5150 else if (bd->cur_mouse_action->func.end)
5151 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5152 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5153 bd->cur_mouse_action = NULL;
5154 e_object_unref(E_OBJECT(bd));
5158 bdresize->resize_mode = RESIZE_NONE;
5159 _e_border_resize_end(bdresize);
5165 e_border_frame_recalc(E_Border *bd)
5167 if (!bd->bg_object) return;
5169 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5170 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5172 _e_border_client_inset_calc(bd);
5174 bd->w += (bd->client_inset.l + bd->client_inset.r);
5175 bd->h += (bd->client_inset.t + bd->client_inset.b);
5178 bd->changes.size = 1;
5179 if ((bd->shaped) || (bd->client.shaped))
5181 bd->need_shape_merge = 1;
5182 bd->need_shape_export = 1;
5184 if (bd->shaped_input)
5186 bd->need_shape_merge = 1;
5188 _e_border_client_move_resize_send(bd);
5192 e_border_immortal_windows_get(void)
5194 Eina_List *list = NULL, *l;
5197 EINA_LIST_FOREACH(borders, l, bd)
5200 list = eina_list_append(list, bd);
5206 e_border_name_get(const E_Border *bd)
5208 E_OBJECT_CHECK_RETURN(bd, "");
5209 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5210 if (bd->client.netwm.name)
5211 return bd->client.netwm.name;
5212 else if (bd->client.icccm.title)
5213 return bd->client.icccm.title;
5218 e_border_signal_move_begin(E_Border *bd,
5220 const char *src __UNUSED__)
5223 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5225 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5226 if (!_e_border_move_begin(bd)) return;
5228 _e_border_pointer_move_begin(bd);
5229 e_zone_edge_disable();
5230 _e_border_moveinfo_gather(bd, sig);
5231 if (bd->cur_mouse_action)
5233 if ((!bd->cur_mouse_action->func.end_mouse) &&
5234 (!bd->cur_mouse_action->func.end))
5235 bd->cur_mouse_action = NULL;
5237 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5239 bd->cur_mouse_action = e_action_find("window_move");
5240 if (bd->cur_mouse_action)
5241 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5245 e_border_signal_move_end(E_Border *bd,
5246 const char *sig __UNUSED__,
5247 const char *src __UNUSED__)
5250 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5251 if (!bd->moving) return;
5253 _e_border_pointer_move_end(bd);
5254 e_zone_edge_enable();
5255 _e_border_move_end(bd);
5256 e_zone_flip_coords_handle(bd->zone, -1, -1);
5260 e_border_resizing_get(E_Border *bd)
5262 E_OBJECT_CHECK_RETURN(bd, 0);
5263 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5264 if (bd->resize_mode == RESIZE_NONE) return 0;
5269 e_border_signal_resize_begin(E_Border *bd,
5272 const char *src __UNUSED__)
5274 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5275 int resize_mode = RESIZE_BR;
5278 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5280 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5281 if (!_e_border_resize_begin(bd))
5283 if (!strcmp(dir, "tl"))
5285 resize_mode = RESIZE_TL;
5286 grav = ECORE_X_GRAVITY_SE;
5288 else if (!strcmp(dir, "t"))
5290 resize_mode = RESIZE_T;
5291 grav = ECORE_X_GRAVITY_S;
5293 else if (!strcmp(dir, "tr"))
5295 resize_mode = RESIZE_TR;
5296 grav = ECORE_X_GRAVITY_SW;
5298 else if (!strcmp(dir, "r"))
5300 resize_mode = RESIZE_R;
5301 grav = ECORE_X_GRAVITY_W;
5303 else if (!strcmp(dir, "br"))
5305 resize_mode = RESIZE_BR;
5306 grav = ECORE_X_GRAVITY_NW;
5308 else if (!strcmp(dir, "b"))
5310 resize_mode = RESIZE_B;
5311 grav = ECORE_X_GRAVITY_N;
5313 else if (!strcmp(dir, "bl"))
5315 resize_mode = RESIZE_BL;
5316 grav = ECORE_X_GRAVITY_NE;
5318 else if (!strcmp(dir, "l"))
5320 resize_mode = RESIZE_L;
5321 grav = ECORE_X_GRAVITY_E;
5323 bd->resize_mode = resize_mode;
5324 _e_border_pointer_resize_begin(bd);
5325 _e_border_moveinfo_gather(bd, sig);
5327 if (bd->cur_mouse_action)
5329 if ((!bd->cur_mouse_action->func.end_mouse) &&
5330 (!bd->cur_mouse_action->func.end))
5331 bd->cur_mouse_action = NULL;
5333 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5335 bd->cur_mouse_action = e_action_find("window_resize");
5336 if (bd->cur_mouse_action)
5337 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5341 e_border_signal_resize_end(E_Border *bd,
5342 const char *dir __UNUSED__,
5343 const char *sig __UNUSED__,
5344 const char *src __UNUSED__)
5347 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5348 if (bd->resize_mode == RESIZE_NONE) return;
5349 _e_border_resize_handle(bd);
5350 _e_border_pointer_resize_end(bd);
5351 bd->resize_mode = RESIZE_NONE;
5352 _e_border_resize_end(bd);
5353 bd->changes.reset_gravity = 1;
5358 e_border_resize_limit(E_Border *bd,
5365 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5366 *w -= bd->client_inset.l + bd->client_inset.r;
5367 *h -= bd->client_inset.t + bd->client_inset.b;
5370 if ((bd->client.icccm.base_w >= 0) &&
5371 (bd->client.icccm.base_h >= 0))
5375 tw = *w - bd->client.icccm.base_w;
5376 th = *h - bd->client.icccm.base_h;
5379 a = (double)(tw) / (double)(th);
5380 if ((bd->client.icccm.min_aspect != 0.0) &&
5381 (a < bd->client.icccm.min_aspect))
5383 th = tw / bd->client.icccm.max_aspect;
5384 *h = th + bd->client.icccm.base_h;
5386 else if ((bd->client.icccm.max_aspect != 0.0) &&
5387 (a > bd->client.icccm.max_aspect))
5389 tw = th * bd->client.icccm.max_aspect;
5390 *w = tw + bd->client.icccm.base_w;
5395 a = (double)*w / (double)*h;
5396 if ((bd->client.icccm.min_aspect != 0.0) &&
5397 (a < bd->client.icccm.min_aspect))
5398 *h = *w / bd->client.icccm.min_aspect;
5399 else if ((bd->client.icccm.max_aspect != 0.0) &&
5400 (a > bd->client.icccm.max_aspect))
5401 *w = *h * bd->client.icccm.max_aspect;
5403 if (bd->client.icccm.step_w > 0)
5405 if (bd->client.icccm.base_w >= 0)
5406 *w = bd->client.icccm.base_w +
5407 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5408 bd->client.icccm.step_w);
5410 *w = bd->client.icccm.min_w +
5411 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5412 bd->client.icccm.step_w);
5414 if (bd->client.icccm.step_h > 0)
5416 if (bd->client.icccm.base_h >= 0)
5417 *h = bd->client.icccm.base_h +
5418 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5419 bd->client.icccm.step_h);
5421 *h = bd->client.icccm.min_h +
5422 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5423 bd->client.icccm.step_h);
5429 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5430 else if (*w < bd->client.icccm.min_w)
5431 *w = bd->client.icccm.min_w;
5432 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5433 else if (*h < bd->client.icccm.min_h)
5434 *h = bd->client.icccm.min_h;
5436 *w += bd->client_inset.l + bd->client_inset.r;
5437 *h += bd->client_inset.t + bd->client_inset.b;
5440 /* local subsystem functions */
5442 _e_border_free(E_Border *bd)
5444 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5447 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5449 bd->client.e.state.video_parent_border->client.e.state.video_child =
5451 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5454 if (bd->client.e.state.video_child)
5458 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5460 tmp->client.e.state.video_parent_border = NULL;
5465 efreet_desktop_free(bd->desktop);
5470 ecore_idle_enterer_del(bd->post_job);
5471 bd->post_job = NULL;
5475 e_object_del(E_OBJECT(bd->pointer));
5479 _e_border_resize_end(bd);
5481 _e_border_move_end(bd);
5482 /* TODO: Other states to end before dying? */
5484 if (bd->cur_mouse_action)
5486 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5487 bd->cur_mouse_action = NULL;
5490 E_FREE(bd->shape_rects);
5491 bd->shape_rects_num = 0;
5493 if (bd->dangling_ref_check)
5495 ecore_timer_del(bd->dangling_ref_check);
5496 bd->dangling_ref_check = NULL;
5501 ecore_timer_del(bd->kill_timer);
5502 bd->kill_timer = NULL;
5504 if (bd->ping_poller)
5506 ecore_poller_del(bd->ping_poller);
5507 bd->ping_poller = NULL;
5509 E_FREE_LIST(bd->pending_move_resize, free);
5511 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5512 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5514 if (bd->border_locks_dialog)
5516 e_object_del(E_OBJECT(bd->border_locks_dialog));
5517 bd->border_locks_dialog = NULL;
5519 if (bd->border_remember_dialog)
5521 e_object_del(E_OBJECT(bd->border_remember_dialog));
5522 bd->border_remember_dialog = NULL;
5524 if (bd->border_border_dialog)
5526 e_object_del(E_OBJECT(bd->border_border_dialog));
5527 bd->border_border_dialog = NULL;
5529 if (bd->border_prop_dialog)
5531 e_object_del(E_OBJECT(bd->border_prop_dialog));
5532 bd->border_prop_dialog = NULL;
5535 e_int_border_menu_del(bd);
5540 focus_next = eina_list_remove(focus_next, bd);
5542 if ((focused == bd) ||
5543 (e_grabinput_last_focus_win_get() == bd->client.win))
5545 if ((!focus_next) && (!focusing))
5547 e_grabinput_focus(bd->zone->container->bg_win,
5548 E_FOCUS_METHOD_PASSIVE);
5549 e_hints_active_window_set(bd->zone->container->manager, NULL);
5554 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5560 bd->remember = NULL;
5561 e_remember_unuse(rem);
5563 if (!bd->already_unparented)
5565 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5566 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5567 ecore_x_window_save_set_del(bd->client.win);
5568 bd->already_unparented = 1;
5570 if (bd->group) eina_list_free(bd->group);
5571 if (bd->transients) eina_list_free(bd->transients);
5572 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5573 if (bd->client.netwm.icons)
5576 for (i = 0; i < bd->client.netwm.num_icons; i++)
5577 free(bd->client.netwm.icons[i].data);
5578 free(bd->client.netwm.icons);
5580 if (bd->client.netwm.extra_types)
5581 free(bd->client.netwm.extra_types);
5582 if (bd->client.border.name)
5583 eina_stringshare_del(bd->client.border.name);
5585 eina_stringshare_del(bd->bordername);
5586 if (bd->client.icccm.name)
5587 eina_stringshare_del(bd->client.icccm.name);
5588 if (bd->client.icccm.class)
5590 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5591 e_bindings_mapping_change_enable(EINA_TRUE);
5592 eina_stringshare_del(bd->client.icccm.class);
5594 if (bd->client.icccm.title)
5595 eina_stringshare_del(bd->client.icccm.title);
5596 if (bd->client.icccm.icon_name)
5597 eina_stringshare_del(bd->client.icccm.icon_name);
5598 if (bd->client.icccm.machine)
5599 eina_stringshare_del(bd->client.icccm.machine);
5600 if (bd->client.icccm.window_role)
5601 eina_stringshare_del(bd->client.icccm.window_role);
5603 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5607 for (i = 0; i < bd->client.icccm.command.argc; i++)
5608 free(bd->client.icccm.command.argv[i]);
5609 free(bd->client.icccm.command.argv);
5611 if (bd->client.netwm.name)
5612 eina_stringshare_del(bd->client.netwm.name);
5613 if (bd->client.netwm.icon_name)
5614 eina_stringshare_del(bd->client.netwm.icon_name);
5615 e_object_del(E_OBJECT(bd->shape));
5616 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5617 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5618 if (bd->icon_object) evas_object_del(bd->icon_object);
5619 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5620 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5622 if (str) eina_stringshare_del(str);
5624 bd->client.e.state.profiles = NULL;
5625 if (bd->client.e.state.profile)
5626 eina_stringshare_del(bd->client.e.state.profile);
5627 bd->client.e.state.profile = NULL;
5629 #ifdef _F_ZONE_WINDOW_ROTATION_
5630 if (e_config->wm_win_rotation)
5632 bd->client.e.fetch.rot.app_set = 0;
5633 bd->client.e.state.rot.preferred_rot = -1;
5635 if (bd->client.e.state.rot.available_rots)
5636 E_FREE(bd->client.e.state.rot.available_rots);
5638 _e_border_rotation_list_remove(bd);
5639 if ((rot.vkbd) && (rot.vkbd == bd))
5641 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5643 if (rot.vkbd_ctrl_win)
5645 ELB(ELBT_BD, "SET KBD_OFF", 0);
5646 ecore_x_e_virtual_keyboard_state_set
5647 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5650 rot.vkbd_hide_prepare_done = EINA_FALSE;
5651 if (rot.vkbd_hide_prepare_timer)
5652 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5653 rot.vkbd_hide_prepare_timer = NULL;
5654 if (rot.vkbd_hide_timer)
5655 ecore_timer_del(rot.vkbd_hide_timer);
5656 rot.vkbd_hide_timer = NULL;
5658 rot.vkbd_show_prepare_done = EINA_FALSE;
5659 if (rot.vkbd_show_prepare_timer)
5660 ecore_timer_del(rot.vkbd_show_prepare_timer);
5661 rot.vkbd_show_prepare_timer = NULL;
5662 if (rot.vkbd_show_timer)
5663 ecore_timer_del(rot.vkbd_show_timer);
5664 rot.vkbd_show_timer = NULL;
5666 else if ((rot.vkbd_prediction) &&
5667 (rot.vkbd_prediction == bd))
5668 rot.vkbd_prediction = NULL;
5671 evas_object_del(bd->bg_object);
5672 e_canvas_del(bd->bg_ecore_evas);
5673 ecore_evas_free(bd->bg_ecore_evas);
5674 ecore_x_window_free(bd->client.shell_win);
5675 e_focus_setdown(bd);
5676 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5677 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5678 ecore_x_window_free(bd->win);
5680 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5681 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5682 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5683 borders = eina_list_remove(borders, bd);
5684 focus_stack = eina_list_remove(focus_stack, bd);
5685 raise_stack = eina_list_remove(raise_stack, bd);
5687 e_container_border_remove(bd);
5693 _e_border_del_dangling_ref_check(void *data)
5699 printf("EEK EEK border still around 1 second after being deleted!\n");
5700 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5701 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5702 bd->client.icccm.name, bd->client.icccm.class);
5703 // e_object_breadcrumb_debug(E_OBJECT(bd));
5710 _e_border_del(E_Border *bd)
5712 E_Event_Border_Remove *ev;
5715 #ifdef _F_BORDER_HOOK_PATCH_
5716 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5727 focus_next = eina_list_remove(focus_next, bd);
5729 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5731 if ((drag_border) && (drag_border->data == bd))
5733 e_object_del(E_OBJECT(drag_border));
5736 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5738 if (bd->border_locks_dialog)
5740 e_object_del(E_OBJECT(bd->border_locks_dialog));
5741 bd->border_locks_dialog = NULL;
5743 if (bd->border_remember_dialog)
5745 e_object_del(E_OBJECT(bd->border_remember_dialog));
5746 bd->border_remember_dialog = NULL;
5748 if (bd->border_border_dialog)
5750 e_object_del(E_OBJECT(bd->border_border_dialog));
5751 bd->border_border_dialog = NULL;
5753 if (bd->border_prop_dialog)
5755 e_object_del(E_OBJECT(bd->border_prop_dialog));
5756 bd->border_prop_dialog = NULL;
5759 e_int_border_menu_del(bd);
5761 if (bd->raise_timer)
5763 ecore_timer_del(bd->raise_timer);
5764 bd->raise_timer = NULL;
5766 if (!bd->already_unparented)
5768 ecore_x_window_reparent(bd->client.win,
5769 bd->zone->container->manager->root,
5770 bd->x + bd->client_inset.l,
5771 bd->y + bd->client_inset.t);
5772 ecore_x_window_save_set_del(bd->client.win);
5773 bd->already_unparented = 1;
5774 // bd->client.win = 0;
5776 bd->already_unparented = 1;
5778 if ((!bd->new_client) && (!stopping))
5780 ev = E_NEW(E_Event_Border_Remove, 1);
5782 e_object_ref(E_OBJECT(bd));
5783 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5784 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5789 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5790 if (bd->parent->modal == bd)
5792 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5793 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5794 bd->parent->lock_close = 0;
5795 bd->parent->saved.event_mask = 0;
5796 bd->parent->modal = NULL;
5800 EINA_LIST_FREE(bd->transients, child)
5802 child->parent = NULL;
5805 #ifdef _F_DEICONIFY_APPROVE_
5806 bd->client.e.state.deiconify_approve.render_done = 0;
5808 E_Border *ancestor_bd;
5809 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5810 if ((ancestor_bd) &&
5811 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5813 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5814 bd->client.e.state.deiconify_approve.ancestor = NULL;
5816 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5817 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5819 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5821 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5822 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5823 e_border_uniconify(ancestor_bd);
5828 if (bd->client.e.state.deiconify_approve.wait_timer)
5830 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5831 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5834 if (bd->client.e.state.deiconify_approve.req_list)
5836 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5838 child->client.e.state.deiconify_approve.render_done = 0;
5839 child->client.e.state.deiconify_approve.ancestor = NULL;
5844 #ifdef _F_ZONE_WINDOW_ROTATION_
5845 if (rot.list) _e_border_rotation_list_remove(bd);
5849 E_Border_Rotation_Info *info = NULL;
5851 EINA_LIST_FOREACH(rot.async_list, l, info)
5854 rot.async_list = eina_list_remove(rot.async_list, info);
5862 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5863 if (bd->leader->modal == bd)
5864 bd->leader->modal = NULL;
5867 EINA_LIST_FREE(bd->group, child)
5869 child->leader = NULL;
5873 #ifdef PRINT_LOTS_OF_DEBUG
5875 _e_border_print(E_Border *bd,
5884 "\tBorderless: %s\n",
5885 bd, bd->client.icccm.name, bd->client.icccm.title,
5886 bd->borderless ? "TRUE" : "FALSE");
5892 _e_border_cb_window_show_request(void *data __UNUSED__,
5893 int ev_type __UNUSED__,
5898 Ecore_X_Event_Window_Show_Request *e;
5901 bd = e_border_find_by_client_window(e->win);
5902 if (!bd) return ECORE_CALLBACK_PASS_ON;
5904 if ((e_config->wm_win_rotation) &&
5905 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
5907 (rot.vkbd_hide_prepare_timer))
5909 con = bd->zone->container;
5910 bd = e_border_new(con, e->win, 0, 0);
5915 if (!bd->lock_client_iconify)
5916 e_border_uniconify(bd);
5920 /* FIXME: make border "urgent" for a bit - it wants attention */
5921 /* e_border_show(bd); */
5922 if (!bd->lock_client_stacking)
5925 return ECORE_CALLBACK_PASS_ON;
5929 _e_border_cb_window_destroy(void *data __UNUSED__,
5930 int ev_type __UNUSED__,
5934 Ecore_X_Event_Window_Destroy *e;
5937 bd = e_border_find_by_client_window(e->win);
5938 if (!bd) return ECORE_CALLBACK_PASS_ON;
5939 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
5940 #ifdef _F_ZONE_WINDOW_ROTATION_
5941 if (e_config->wm_win_rotation)
5943 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
5945 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
5946 if (!rot.vkbd_hide_prepare_timer)
5948 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
5949 e_border_hide(bd, 0);
5950 if (!rot.vkbd_hide_prepare_timer)
5952 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
5953 e_object_del(E_OBJECT(bd));
5956 return ECORE_CALLBACK_PASS_ON;
5960 e_border_hide(bd, 0);
5961 e_object_del(E_OBJECT(bd));
5962 return ECORE_CALLBACK_PASS_ON;
5966 _e_border_cb_window_hide(void *data __UNUSED__,
5967 int ev_type __UNUSED__,
5970 E_Border *bd = NULL;
5971 Ecore_X_Event_Window_Hide *e;
5974 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
5975 // not interested in hide events from windows other than the window in question
5976 if (e->win != e->event_win)
5978 bd = e_border_find_by_client_window(e->win);
5979 if (!bd) return ECORE_CALLBACK_PASS_ON;
5980 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
5984 (bd->zone->container->manager->root == e->event_win)))
5985 return ECORE_CALLBACK_PASS_ON;
5988 if (!bd) bd = e_border_find_by_client_window(e->win);
5989 // printf(" bd = %p\n", bd);
5992 if (ecore_x_window_visible_get(e->win))
5994 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
5995 ecore_x_window_hide(e->win);
5997 return ECORE_CALLBACK_PASS_ON;
6000 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
6001 if (bd->ignore_first_unmap > 0)
6003 bd->ignore_first_unmap--;
6004 return ECORE_CALLBACK_PASS_ON;
6006 /* Don't delete hidden or iconified windows */
6007 #ifdef _F_USE_EXTENDED_ICONIFY_
6008 if (bd->await_hide_event > 0)
6010 if ((bd->iconic) || (bd->await_hide_event > 0))
6013 // printf(" Don't delete hidden or iconified windows\n");
6014 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6015 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6016 if (bd->await_hide_event > 0)
6018 bd->await_hide_event--;
6022 // printf(" hide really\n");
6023 /* Only hide the border if it is visible */
6024 if (bd->visible) e_border_hide(bd, 1);
6029 // printf(" hide2\n");
6030 #ifdef _F_USE_EXTENDED_ICONIFY_
6038 #ifdef _F_ZONE_WINDOW_ROTATION_
6039 if (e_config->wm_win_rotation)
6041 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6043 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6044 if (!rot.vkbd_hide_prepare_timer)
6046 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6047 e_border_hide(bd, 0);
6048 if (!rot.vkbd_hide_prepare_timer)
6050 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6051 e_object_del(E_OBJECT(bd));
6054 return ECORE_CALLBACK_PASS_ON;
6058 e_border_hide(bd, 0);
6059 e_object_del(E_OBJECT(bd));
6061 return ECORE_CALLBACK_PASS_ON;
6065 _e_border_cb_window_reparent(void *data __UNUSED__,
6066 int ev_type __UNUSED__,
6067 void *ev __UNUSED__)
6071 Ecore_X_Event_Window_Reparent *e;
6074 bd = e_border_find_by_client_window(e->win);
6076 if (e->parent == bd->client.shell_win) return 1;
6077 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6081 e_border_hide(bd, 0);
6082 e_object_del(E_OBJECT(bd));
6084 return ECORE_CALLBACK_PASS_ON;
6088 _e_border_cb_window_configure_request(void *data __UNUSED__,
6089 int ev_type __UNUSED__,
6093 Ecore_X_Event_Window_Configure_Request *e;
6096 bd = e_border_find_by_client_window(e->win);
6099 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6100 if (!e_util_container_window_find(e->win))
6101 ecore_x_window_configure(e->win, e->value_mask,
6102 e->x, e->y, e->w, e->h, e->border,
6103 e->abovewin, e->detail);
6104 return ECORE_CALLBACK_PASS_ON;
6107 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6108 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6114 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6116 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6118 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6119 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6125 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6126 w = e->w + bd->client_inset.l + bd->client_inset.r;
6127 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6128 h = e->h + bd->client_inset.t + bd->client_inset.b;
6129 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6131 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6133 bd->saved.x = x - bd->zone->x;
6134 bd->saved.y = y - bd->zone->y;
6139 e_border_move_resize(bd, x, y, w, h);
6141 else if (!bd->lock_client_location)
6143 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6145 bd->saved.x = x - bd->zone->x;
6146 bd->saved.y = y - bd->zone->y;
6149 e_border_move(bd, x, y);
6151 else if (!bd->lock_client_size)
6153 if ((bd->shaded) || (bd->shading))
6159 if ((bd->shade.dir == E_DIRECTION_UP) ||
6160 (bd->shade.dir == E_DIRECTION_DOWN))
6162 e_border_resize(bd, w, bd->h);
6167 e_border_resize(bd, bd->w, h);
6173 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6179 e_border_resize(bd, w, h);
6185 if (!bd->lock_client_location)
6187 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6189 bd->saved.x = x - bd->zone->x;
6190 bd->saved.y = y - bd->zone->y;
6193 e_border_move(bd, x, y);
6197 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6198 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6204 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6205 w = e->w + bd->client_inset.l + bd->client_inset.r;
6206 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6207 h = e->h + bd->client_inset.t + bd->client_inset.b;
6208 #ifdef _F_ZONE_WINDOW_ROTATION_
6209 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6211 if (!bd->lock_client_size)
6213 if ((bd->shaded) || (bd->shading))
6219 if ((bd->shade.dir == E_DIRECTION_UP) ||
6220 (bd->shade.dir == E_DIRECTION_DOWN))
6222 e_border_resize(bd, w, bd->h);
6227 e_border_resize(bd, bd->w, h);
6233 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6238 zx = zy = zw = zh = 0;
6241 * This code does resize and move a window on a
6242 * X configure request into an useful geometry.
6243 * This is really useful for size jumping file dialogs.
6248 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6250 if (e_config->geometry_auto_resize_limit == 1)
6259 e_border_resize(bd, w, h);
6261 if (e_config->geometry_auto_move == 1)
6263 /* z{x,y,w,h} are only set here; FIXME! */
6266 // move window horizontal if resize to not useful geometry
6267 if (bd->x + bd->w > zx + zw)
6268 rx = zx + zw - bd->w;
6269 else if (bd->x < zx)
6272 // move window vertical if resize to not useful geometry
6273 if (bd->y + bd->h > zy + zh)
6274 ry = zy + zh - bd->h;
6275 else if (bd->y < zy)
6278 e_border_move(bd, rx, ry);
6284 if (!bd->lock_client_stacking)
6286 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6287 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6291 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6293 obd = e_border_find_by_client_window(e->abovewin);
6296 e_border_stack_above(bd, obd);
6300 ecore_x_window_configure(bd->win,
6301 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6302 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6304 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6305 /* FIXME: need to rebuiuld border list from current stacking */
6308 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6310 obd = e_border_find_by_client_window(e->abovewin);
6313 e_border_stack_below(bd, obd);
6317 ecore_x_window_configure(bd->win,
6318 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6319 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6321 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6322 /* FIXME: need to rebuiuld border list from current stacking */
6325 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6329 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6333 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6338 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6340 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6344 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6348 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6352 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6356 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6363 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6364 _e_border_client_move_resize_send(bd);
6365 return ECORE_CALLBACK_PASS_ON;
6369 _e_border_cb_window_resize_request(void *data __UNUSED__,
6370 int ev_type __UNUSED__,
6374 Ecore_X_Event_Window_Resize_Request *e;
6377 bd = e_border_find_by_client_window(e->win);
6380 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6381 ecore_x_window_resize(e->win, e->w, e->h);
6382 return ECORE_CALLBACK_PASS_ON;
6387 w = e->w + bd->client_inset.l + bd->client_inset.r;
6388 h = e->h + bd->client_inset.t + bd->client_inset.b;
6389 if ((bd->shaded) || (bd->shading))
6395 if ((bd->shade.dir == E_DIRECTION_UP) ||
6396 (bd->shade.dir == E_DIRECTION_DOWN))
6398 e_border_resize(bd, w, bd->h);
6403 e_border_resize(bd, bd->w, h);
6408 e_border_resize(bd, w, h);
6411 _e_border_client_move_resize_send(bd);
6412 return ECORE_CALLBACK_PASS_ON;
6416 _e_border_cb_window_gravity(void *data __UNUSED__,
6417 int ev_type __UNUSED__,
6418 void *ev __UNUSED__)
6421 // Ecore_X_Event_Window_Gravity *e;
6424 // bd = e_border_find_by_client_window(e->win);
6425 // if (!bd) return 1;
6430 _e_border_cb_window_stack_request(void *data __UNUSED__,
6431 int ev_type __UNUSED__,
6435 Ecore_X_Event_Window_Stack_Request *e;
6438 bd = e_border_find_by_client_window(e->win);
6441 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6442 if (!e_util_container_window_find(e->win))
6444 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6445 ecore_x_window_raise(e->win);
6446 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6447 ecore_x_window_lower(e->win);
6449 return ECORE_CALLBACK_PASS_ON;
6451 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6453 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6455 return ECORE_CALLBACK_PASS_ON;
6459 _e_border_cb_window_property(void *data __UNUSED__,
6460 int ev_type __UNUSED__,
6464 Ecore_X_Event_Window_Property *e;
6467 bd = e_border_find_by_client_window(e->win);
6468 if (!bd) return ECORE_CALLBACK_PASS_ON;
6469 if (e->atom == ECORE_X_ATOM_WM_NAME)
6471 if ((!bd->client.netwm.name) &&
6472 (!bd->client.netwm.fetch.name))
6474 bd->client.icccm.fetch.title = 1;
6478 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6480 bd->client.netwm.fetch.name = 1;
6483 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6485 bd->client.icccm.fetch.name_class = 1;
6488 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6490 if ((!bd->client.netwm.icon_name) &&
6491 (!bd->client.netwm.fetch.icon_name))
6493 bd->client.icccm.fetch.icon_name = 1;
6497 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6499 bd->client.netwm.fetch.icon_name = 1;
6502 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6504 bd->client.icccm.fetch.machine = 1;
6507 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6509 bd->client.icccm.fetch.protocol = 1;
6512 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6514 bd->client.icccm.fetch.hints = 1;
6517 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6519 bd->client.icccm.fetch.size_pos_hints = 1;
6522 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6525 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6526 (!bd->client.netwm.fetch.type))
6529 bd->client.mwm.fetch.hints = 1;
6535 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6537 bd->client.icccm.fetch.transient_for = 1;
6540 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6542 bd->client.icccm.fetch.client_leader = 1;
6545 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6547 bd->client.icccm.fetch.window_role = 1;
6550 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6552 bd->client.netwm.fetch.icon = 1;
6555 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6557 bd->client.qtopia.fetch.soft_menu = 1;
6560 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6562 bd->client.qtopia.fetch.soft_menus = 1;
6565 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6567 bd->client.vkbd.fetch.state = 1;
6570 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6572 bd->client.vkbd.fetch.vkbd = 1;
6575 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6577 bd->client.illume.conformant.fetch.conformant = 1;
6580 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6582 bd->client.illume.quickpanel.fetch.state = 1;
6585 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6587 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6590 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6592 bd->client.illume.quickpanel.fetch.priority.major = 1;
6595 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6597 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6600 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6602 bd->client.illume.quickpanel.fetch.zone = 1;
6605 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6607 bd->client.illume.drag.fetch.locked = 1;
6610 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6612 bd->client.illume.drag.fetch.drag = 1;
6615 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6617 bd->client.illume.win_state.fetch.state = 1;
6621 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6623 bd->client.netwm.fetch.user_time = 1;
6626 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6628 bd->client.netwm.fetch.strut = 1;
6631 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6633 bd->client.netwm.fetch.strut = 1;
6637 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6639 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6641 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6643 bd->client.e.fetch.video_position = 1;
6646 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6648 bd->client.e.fetch.video_parent = 1;
6651 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6653 bd->client.netwm.fetch.state = 1;
6656 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6657 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6659 bd->client.e.fetch.profile_list = 1;
6663 #ifdef _F_ZONE_WINDOW_ROTATION_
6664 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6666 if (e_config->wm_win_rotation)
6668 bd->client.e.fetch.rot.support = 1;
6672 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6673 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6674 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6675 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6677 if (e_config->wm_win_rotation)
6679 bd->client.e.fetch.rot.geom_hint = 1;
6683 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6685 if (e_config->wm_win_rotation)
6687 bd->client.e.fetch.rot.app_set = 1;
6691 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6693 if (e_config->wm_win_rotation)
6695 bd->client.e.fetch.rot.preferred_rot = 1;
6699 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6701 if (e_config->wm_win_rotation)
6703 bd->client.e.fetch.rot.available_rots = 1;
6709 return ECORE_CALLBACK_PASS_ON;
6713 _e_border_cb_window_colormap(void *data __UNUSED__,
6714 int ev_type __UNUSED__,
6718 Ecore_X_Event_Window_Colormap *e;
6721 bd = e_border_find_by_client_window(e->win);
6722 if (!bd) return ECORE_CALLBACK_PASS_ON;
6723 return ECORE_CALLBACK_PASS_ON;
6727 _e_border_cb_window_shape(void *data __UNUSED__,
6728 int ev_type __UNUSED__,
6732 Ecore_X_Event_Window_Shape *e;
6735 bd = e_border_find_by_client_window(e->win);
6737 if (e->type == ECORE_X_SHAPE_INPUT)
6741 bd->need_shape_merge = 1;
6742 // YYY bd->shaped_input = 1;
6743 bd->changes.shape_input = 1;
6747 return ECORE_CALLBACK_PASS_ON;
6752 bd->changes.shape = 1;
6754 return ECORE_CALLBACK_PASS_ON;
6756 bd = e_border_find_by_window(e->win);
6759 bd->need_shape_export = 1;
6761 return ECORE_CALLBACK_PASS_ON;
6763 bd = e_border_find_by_frame_window(e->win);
6766 bd->need_shape_merge = 1;
6768 return ECORE_CALLBACK_PASS_ON;
6770 return ECORE_CALLBACK_PASS_ON;
6774 _e_border_cb_window_focus_in(void *data __UNUSED__,
6775 int ev_type __UNUSED__,
6779 Ecore_X_Event_Window_Focus_In *e;
6782 bd = e_border_find_by_client_window(e->win);
6783 if (!bd) return ECORE_CALLBACK_PASS_ON;
6784 #ifdef INOUTDEBUG_FOCUS
6789 const char *modes[] = {
6791 "MODE_WHILE_GRABBED",
6795 const char *details[] = {
6799 "DETAIL_NON_LINEAR",
6800 "DETAIL_NON_LINEAR_VIRTUAL",
6802 "DETAIL_POINTER_ROOT",
6803 "DETAIL_DETAIL_NONE"
6807 ct[strlen(ct) - 1] = 0;
6808 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6813 details[e->detail]);
6815 DBG("%s cb focus in %d %d\n",
6816 e_border_name_get(bd),
6817 bd->client.icccm.accepts_focus,
6818 bd->client.icccm.take_focus);
6821 _e_border_pri_raise(bd);
6822 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6824 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6826 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6828 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6831 /* ignore focus in from !take_focus windows, we just gave it em */
6832 /* if (!bd->client.icccm.take_focus)
6833 * return ECORE_CALLBACK_PASS_ON; */
6835 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6836 if (e->time >= focus_time)
6837 e_border_focus_set(bd, 1, 0);
6838 return ECORE_CALLBACK_PASS_ON;
6842 _e_border_cb_window_focus_out(void *data __UNUSED__,
6843 int ev_type __UNUSED__,
6847 Ecore_X_Event_Window_Focus_Out *e;
6850 bd = e_border_find_by_client_window(e->win);
6851 if (!bd) return ECORE_CALLBACK_PASS_ON;
6852 #ifdef INOUTDEBUG_FOCUS
6857 const char *modes[] = {
6859 "MODE_WHILE_GRABBED",
6863 const char *details[] = {
6867 "DETAIL_NON_LINEAR",
6868 "DETAIL_NON_LINEAR_VIRTUAL",
6870 "DETAIL_POINTER_ROOT",
6871 "DETAIL_DETAIL_NONE"
6875 ct[strlen(ct) - 1] = 0;
6876 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6881 details[e->detail]);
6883 DBG("%s cb focus out %d %d",
6884 e_border_name_get(bd),
6885 bd->client.icccm.accepts_focus,
6886 bd->client.icccm.take_focus);
6889 _e_border_pri_norm(bd);
6890 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6892 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6893 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6894 return ECORE_CALLBACK_PASS_ON;
6895 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6896 return ECORE_CALLBACK_PASS_ON;
6898 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6900 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6901 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6902 return ECORE_CALLBACK_PASS_ON;
6903 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6904 return ECORE_CALLBACK_PASS_ON;
6905 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6906 return ECORE_CALLBACK_PASS_ON;
6907 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6908 return ECORE_CALLBACK_PASS_ON;
6910 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6912 /* for firefox/thunderbird (xul) menu walking */
6913 /* NB: why did i disable this before? */
6914 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6915 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6916 return ECORE_CALLBACK_PASS_ON;
6918 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6920 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6921 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6922 return ECORE_CALLBACK_PASS_ON;
6924 e_border_focus_set(bd, 0, 0);
6925 return ECORE_CALLBACK_PASS_ON;
6928 #if _F_BORDER_CLIP_TO_ZONE_
6930 _e_border_shape_input_clip_to_zone(E_Border *bd)
6932 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
6936 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
6937 bd->zone->w, bd->zone->h,
6938 bd->x, bd->y, bd->w, bd->h)))
6941 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
6942 E_RECTS_CLIP_TO_RECT(x, y, w, h,
6943 bd->zone->x, bd->zone->y,
6944 bd->zone->w, bd->zone->h);
6947 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
6948 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
6952 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
6953 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
6956 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
6959 _e_border_cb_client_message(void *data __UNUSED__,
6960 int ev_type __UNUSED__,
6963 Ecore_X_Event_Client_Message *e;
6967 #ifdef _F_DEICONIFY_APPROVE_
6968 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
6970 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
6972 bd = e_border_find_by_client_window(e->win);
6975 if (bd->client.e.state.deiconify_approve.support)
6977 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
6978 bd->client.e.state.deiconify_approve.render_done = 1;
6980 E_Border *ancestor_bd;
6981 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
6984 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
6985 bd->client.e.state.deiconify_approve.ancestor = NULL;
6992 ELBF(ELBT_BD, 0, bd->client.win,
6993 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
6995 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
6996 (ancestor_bd->client.e.state.deiconify_approve.render_done))
6998 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
7000 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
7001 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
7002 e_border_uniconify(ancestor_bd);
7006 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
7007 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7012 return ECORE_CALLBACK_PASS_ON;
7016 #ifdef _F_ZONE_WINDOW_ROTATION_
7017 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7019 bd = e_border_find_by_client_window(e->win);
7022 if (e_config->wm_win_rotation)
7024 Ecore_X_Event_Client_Message *msg = NULL;
7025 Ecore_X_Atom t = e->message_type;
7026 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7027 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7028 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7029 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7031 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7032 if (!msg) return ECORE_CALLBACK_PASS_ON;
7035 msg->message_type = e->message_type;
7036 msg->data.l[0] = e->data.l[0];
7037 msg->data.l[1] = e->data.l[1];
7038 msg->data.l[2] = e->data.l[2];
7039 msg->data.l[3] = e->data.l[3];
7040 msg->data.l[4] = e->data.l[4];
7041 rot.msgs = eina_list_append(rot.msgs, msg);
7043 rot.fetch = EINA_TRUE;
7046 return ECORE_CALLBACK_PASS_ON;
7049 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7051 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7052 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7054 if (e_config->wm_win_rotation)
7056 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7058 _e_border_rotation_list_remove(bd);
7060 if (bd->client.e.state.rot.pending_show)
7062 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7064 bd->client.e.state.rot.pending_show = 0;
7071 return ECORE_CALLBACK_PASS_ON;
7075 _e_border_cb_window_state_request(void *data __UNUSED__,
7076 int ev_type __UNUSED__,
7080 Ecore_X_Event_Window_State_Request *e;
7084 bd = e_border_find_by_client_window(e->win);
7085 if (!bd) return ECORE_CALLBACK_PASS_ON;
7087 for (i = 0; i < 2; i++)
7088 e_hints_window_state_update(bd, e->state[i], e->action);
7090 return ECORE_CALLBACK_PASS_ON;
7094 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7095 int ev_type __UNUSED__,
7099 Ecore_X_Event_Window_Move_Resize_Request *e;
7102 bd = e_border_find_by_client_window(e->win);
7103 if (!bd) return ECORE_CALLBACK_PASS_ON;
7105 if ((bd->shaded) || (bd->shading) ||
7106 (bd->fullscreen) || (bd->moving) ||
7107 (bd->resize_mode != RESIZE_NONE))
7108 return ECORE_CALLBACK_PASS_ON;
7110 if ((e->button >= 1) && (e->button <= 3))
7112 bd->mouse.last_down[e->button - 1].mx = e->x;
7113 bd->mouse.last_down[e->button - 1].my = e->y;
7114 bd->mouse.last_down[e->button - 1].x = bd->x;
7115 bd->mouse.last_down[e->button - 1].y = bd->y;
7116 bd->mouse.last_down[e->button - 1].w = bd->w;
7117 bd->mouse.last_down[e->button - 1].h = bd->h;
7121 bd->moveinfo.down.x = bd->x;
7122 bd->moveinfo.down.y = bd->y;
7123 bd->moveinfo.down.w = bd->w;
7124 bd->moveinfo.down.h = bd->h;
7126 bd->mouse.current.mx = e->x;
7127 bd->mouse.current.my = e->y;
7128 bd->moveinfo.down.button = e->button;
7129 bd->moveinfo.down.mx = e->x;
7130 bd->moveinfo.down.my = e->y;
7133 if (!bd->lock_user_stacking)
7136 if (e->direction == MOVE)
7138 bd->cur_mouse_action = e_action_find("window_move");
7139 if (bd->cur_mouse_action)
7141 if ((!bd->cur_mouse_action->func.end_mouse) &&
7142 (!bd->cur_mouse_action->func.end))
7143 bd->cur_mouse_action = NULL;
7144 if (bd->cur_mouse_action)
7146 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7147 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7150 return ECORE_CALLBACK_PASS_ON;
7153 if (!_e_border_resize_begin(bd))
7154 return ECORE_CALLBACK_PASS_ON;
7156 switch (e->direction)
7159 bd->resize_mode = RESIZE_TL;
7160 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7164 bd->resize_mode = RESIZE_T;
7165 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7169 bd->resize_mode = RESIZE_TR;
7170 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7174 bd->resize_mode = RESIZE_R;
7175 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7179 bd->resize_mode = RESIZE_BR;
7180 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7184 bd->resize_mode = RESIZE_B;
7185 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7189 bd->resize_mode = RESIZE_BL;
7190 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7194 bd->resize_mode = RESIZE_L;
7195 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7199 return ECORE_CALLBACK_PASS_ON;
7202 bd->cur_mouse_action = e_action_find("window_resize");
7203 if (bd->cur_mouse_action)
7205 if ((!bd->cur_mouse_action->func.end_mouse) &&
7206 (!bd->cur_mouse_action->func.end))
7207 bd->cur_mouse_action = NULL;
7209 if (bd->cur_mouse_action)
7210 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7212 return ECORE_CALLBACK_PASS_ON;
7216 _e_border_cb_desktop_change(void *data __UNUSED__,
7217 int ev_type __UNUSED__,
7221 Ecore_X_Event_Desktop_Change *e;
7224 bd = e_border_find_by_client_window(e->win);
7227 if (e->desk == 0xffffffff)
7229 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7233 desk = e_desk_at_pos_get(bd->zone, e->desk);
7235 e_border_desk_set(bd, desk);
7240 ecore_x_netwm_desktop_set(e->win, e->desk);
7242 return ECORE_CALLBACK_PASS_ON;
7246 _e_border_cb_sync_alarm(void *data __UNUSED__,
7247 int ev_type __UNUSED__,
7251 Ecore_X_Event_Sync_Alarm *e;
7252 unsigned int serial;
7255 bd = e_border_find_by_alarm(e->alarm);
7256 if (!bd) return ECORE_CALLBACK_PASS_ON;
7258 if (bd->client.netwm.sync.wait)
7259 bd->client.netwm.sync.wait--;
7261 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7263 E_Border_Pending_Move_Resize *pnd = NULL;
7265 /* skip pending for which we didn't get a reply */
7266 while (bd->pending_move_resize)
7268 pnd = bd->pending_move_resize->data;
7269 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7271 if (serial == pnd->serial)
7283 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7284 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7289 bd->changes.size = 1;
7290 bd->changes.pos = 1;
7293 evas_render(bd->bg_evas);
7295 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7296 &bd->mouse.current.mx,
7297 &bd->mouse.current.my);
7299 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7300 _e_border_resize_handle(bd);
7302 return ECORE_CALLBACK_PASS_ON;
7306 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7307 int ev_type __UNUSED__,
7308 void *ev __UNUSED__)
7313 /* mark all borders for desktop/icon updates */
7314 EINA_LIST_FOREACH(borders, l, bd)
7318 efreet_desktop_free(bd->desktop);
7321 bd->changes.icon = 1;
7325 e_init_status_set(_("Desktop files scan done"));
7328 return ECORE_CALLBACK_PASS_ON;
7332 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7333 int ev_type __UNUSED__,
7334 void *ev __UNUSED__)
7339 /* mark all borders for desktop/icon updates */
7340 EINA_LIST_FOREACH(borders, l, bd)
7342 bd->changes.icon = 1;
7345 return ECORE_CALLBACK_PASS_ON;
7349 _e_border_cb_pointer_warp(void *data __UNUSED__,
7350 int ev_type __UNUSED__,
7353 E_Event_Pointer_Warp *e;
7356 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7357 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7358 return ECORE_CALLBACK_PASS_ON;
7362 _e_border_cb_signal_bind(void *data,
7363 Evas_Object *obj __UNUSED__,
7364 const char *emission,
7370 if (e_dnd_active()) return;
7371 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7376 _e_border_cb_mouse_in(void *data,
7377 int type __UNUSED__,
7380 Ecore_X_Event_Mouse_In *ev;
7385 #ifdef INOUTDEBUG_MOUSE
7390 const char *modes[] = {
7392 "MODE_WHILE_GRABBED",
7396 const char *details[] = {
7400 "DETAIL_NON_LINEAR",
7401 "DETAIL_NON_LINEAR_VIRTUAL",
7403 "DETAIL_POINTER_ROOT",
7404 "DETAIL_DETAIL_NONE"
7408 ct[strlen(ct) - 1] = 0;
7409 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7410 ev->win, ev->event_win,
7413 details[ev->detail]);
7416 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7417 if (ev->event_win == bd->win)
7419 e_focus_event_mouse_in(bd);
7422 if ((ev->win != bd->win) &&
7423 (ev->win != bd->event_win) &&
7424 (ev->event_win != bd->win) &&
7425 (ev->event_win != bd->event_win))
7426 return ECORE_CALLBACK_PASS_ON;
7428 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7430 bd->mouse.current.mx = ev->root.x;
7431 bd->mouse.current.my = ev->root.y;
7432 if (!bd->bg_evas_in)
7434 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7435 bd->bg_evas_in = EINA_TRUE;
7437 return ECORE_CALLBACK_PASS_ON;
7441 _e_border_cb_mouse_out(void *data,
7442 int type __UNUSED__,
7445 Ecore_X_Event_Mouse_Out *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("@@ <-OUT 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)
7485 return ECORE_CALLBACK_PASS_ON;
7486 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7487 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7488 return ECORE_CALLBACK_PASS_ON;
7489 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7490 return ECORE_CALLBACK_PASS_ON;
7491 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7492 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7493 return ECORE_CALLBACK_PASS_ON;
7494 e_focus_event_mouse_out(bd);
7497 if ((ev->win != bd->win) &&
7498 (ev->win != bd->event_win) &&
7499 (ev->event_win != bd->win) &&
7500 (ev->event_win != bd->event_win))
7501 return ECORE_CALLBACK_PASS_ON;
7503 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7505 bd->mouse.current.mx = ev->root.x;
7506 bd->mouse.current.my = ev->root.y;
7509 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7510 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7511 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7513 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7514 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7515 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7516 bd->bg_evas_in = EINA_FALSE;
7519 return ECORE_CALLBACK_PASS_ON;
7523 _e_border_cb_mouse_wheel(void *data,
7524 int type __UNUSED__,
7527 Ecore_Event_Mouse_Wheel *ev;
7532 if ((ev->event_window == bd->win) ||
7533 (ev->event_window == bd->event_win))
7535 bd->mouse.current.mx = ev->root.x;
7536 bd->mouse.current.my = ev->root.y;
7537 if (!bd->cur_mouse_action)
7538 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7541 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7542 return ECORE_CALLBACK_PASS_ON;
7546 _e_border_cb_mouse_down(void *data,
7547 int type __UNUSED__,
7550 Ecore_Event_Mouse_Button *ev;
7555 if ((ev->event_window == bd->win) ||
7556 (ev->event_window == bd->event_win))
7558 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7560 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7561 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7562 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7563 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7564 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7565 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7569 bd->moveinfo.down.x = bd->x + bd->fx.x;
7570 bd->moveinfo.down.y = bd->y + bd->fx.y;
7571 bd->moveinfo.down.w = bd->w;
7572 bd->moveinfo.down.h = bd->h;
7574 bd->mouse.current.mx = ev->root.x;
7575 bd->mouse.current.my = ev->root.y;
7576 if (!bd->cur_mouse_action)
7578 bd->cur_mouse_action =
7579 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7581 if (bd->cur_mouse_action)
7583 if ((!bd->cur_mouse_action->func.end_mouse) &&
7584 (!bd->cur_mouse_action->func.end))
7585 bd->cur_mouse_action = NULL;
7586 if (bd->cur_mouse_action)
7587 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7590 e_focus_event_mouse_down(bd);
7592 if (ev->window != ev->event_window)
7596 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7600 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7602 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7603 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7604 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7605 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7606 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7607 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7611 bd->moveinfo.down.x = bd->x + bd->fx.x;
7612 bd->moveinfo.down.y = bd->y + bd->fx.y;
7613 bd->moveinfo.down.w = bd->w;
7614 bd->moveinfo.down.h = bd->h;
7616 bd->mouse.current.mx = ev->root.x;
7617 bd->mouse.current.my = ev->root.y;
7622 else if (bd->resize_mode != RESIZE_NONE)
7628 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7630 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7631 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7632 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7634 return ECORE_CALLBACK_PASS_ON;
7638 _e_border_cb_mouse_up(void *data,
7639 int type __UNUSED__,
7642 Ecore_Event_Mouse_Button *ev;
7647 if ((ev->event_window == bd->win) ||
7648 (ev->event_window == bd->event_win))
7650 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7652 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7653 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7654 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7655 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7657 bd->mouse.current.mx = ev->root.x;
7658 bd->mouse.current.my = ev->root.y;
7659 /* also we dont pass the same params that went in - then again that */
7660 /* should be ok as we are just ending the action if it has an end */
7661 if (bd->cur_mouse_action)
7663 if (bd->cur_mouse_action->func.end_mouse)
7664 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7665 else if (bd->cur_mouse_action->func.end)
7666 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7667 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7668 bd->cur_mouse_action = NULL;
7672 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7673 e_focus_event_mouse_up(bd);
7676 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7677 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7679 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7680 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7681 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7682 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7684 bd->mouse.current.mx = ev->root.x;
7685 bd->mouse.current.my = ev->root.y;
7689 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7690 return ECORE_CALLBACK_PASS_ON;
7694 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7696 #ifdef _F_BORDER_CLIP_TO_ZONE_
7697 int new_x_max, new_y_max;
7698 int new_x_min, new_y_min;
7699 int margin_x, margin_y;
7701 margin_x = bd->w - 100;
7702 margin_y = bd->h - 100;
7704 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7705 new_x_min = bd->zone->x - margin_x;
7706 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7707 new_y_min = bd->zone->y - margin_y;
7709 if (x >= new_x_max) *new_x = new_x_max;
7710 else if (x <= new_x_min) *new_x = new_x_min;
7712 if (y >= new_y_max) *new_y = new_y_max;
7713 else if (y <= new_y_min) *new_y = new_y_min;
7718 _e_border_cb_mouse_move(void *data,
7719 int type __UNUSED__,
7722 Ecore_Event_Mouse_Move *ev;
7727 if ((ev->window != bd->event_win) &&
7728 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7729 bd->mouse.current.mx = ev->root.x;
7730 bd->mouse.current.my = ev->root.y;
7733 int x, y, new_x, new_y;
7735 Eina_List *skiplist = NULL;
7737 // FIXME: remove? sync what for when only moving?
7738 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7739 bd->client.netwm.sync.wait = 0;
7740 if ((bd->client.netwm.sync.request) &&
7741 (bd->client.netwm.sync.alarm) &&
7742 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7744 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7746 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7747 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7748 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7749 (bd->mouse.current.my - bd->moveinfo.down.my);
7753 x = bd->moveinfo.down.x +
7754 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7755 y = bd->moveinfo.down.y +
7756 (bd->mouse.current.my - bd->moveinfo.down.my);
7761 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7762 skiplist = eina_list_append(skiplist, bd);
7763 e_resist_container_border_position(bd->zone->container, skiplist,
7764 bd->x, bd->y, bd->w, bd->h,
7766 &new_x, &new_y, &new_w, &new_h);
7767 eina_list_free(skiplist);
7769 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7771 /* if (e_config->window_out_of_vscreen_limits_partly) */
7773 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7776 skiplist = eina_list_append(skiplist, bd);
7777 e_resist_container_border_position(bd->zone->container, skiplist,
7778 bd->x, bd->y, bd->w, bd->h,
7780 &new_x, &new_y, &new_w, &new_h);
7781 eina_list_free(skiplist);
7784 bd->shelf_fix.x = 0;
7785 bd->shelf_fix.y = 0;
7786 bd->shelf_fix.modified = 0;
7787 e_border_move(bd, new_x, new_y);
7788 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7790 else if (bd->resize_mode != RESIZE_NONE)
7792 if ((bd->client.netwm.sync.request) &&
7793 (bd->client.netwm.sync.alarm))
7795 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7797 E_Border_Pending_Move_Resize *pnd;
7799 if (bd->pending_move_resize)
7801 bd->changes.pos = 1;
7802 bd->changes.size = 1;
7804 _e_border_client_move_resize_send(bd);
7806 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7809 bd->client.netwm.sync.wait = 0;
7811 /* sync.wait is incremented when resize_handle sends
7812 * sync-request and decremented by sync-alarm cb. so
7813 * we resize here either on initial resize, timeout or
7814 * when no new resize-request was added by sync-alarm cb.
7816 if (!bd->client.netwm.sync.wait)
7817 _e_border_resize_handle(bd);
7820 _e_border_resize_handle(bd);
7826 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7828 bd->drag.x = ev->root.x;
7829 bd->drag.y = ev->root.y;
7835 dx = bd->drag.x - ev->root.x;
7836 dy = bd->drag.y - ev->root.y;
7837 if (((dx * dx) + (dy * dy)) >
7838 (e_config->drag_resist * e_config->drag_resist))
7841 if (bd->icon_object)
7843 Evas_Object *o = NULL;
7844 Evas_Coord x, y, w, h;
7845 const char *drag_types[] = { "enlightenment/border" };
7847 e_object_ref(E_OBJECT(bd));
7848 evas_object_geometry_get(bd->icon_object,
7850 drag_border = e_drag_new(bd->zone->container,
7851 bd->x + bd->fx.x + x,
7852 bd->y + bd->fx.y + y,
7853 drag_types, 1, bd, -1,
7855 _e_border_cb_drag_finished);
7856 o = e_border_icon_add(bd, drag_border->evas);
7859 /* FIXME: fallback icon for drag */
7860 o = evas_object_rectangle_add(drag_border->evas);
7861 evas_object_color_set(o, 255, 255, 255, 255);
7863 e_drag_object_set(drag_border, o);
7865 e_drag_resize(drag_border, w, h);
7866 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7872 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7874 return ECORE_CALLBACK_PASS_ON;
7878 _e_border_cb_grab_replay(void *data __UNUSED__,
7882 Ecore_Event_Mouse_Button *ev;
7884 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7886 if ((e_config->pass_click_on)
7887 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7888 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7893 bd = e_border_find_by_window(ev->event_window);
7896 if (bd->cur_mouse_action)
7897 return ECORE_CALLBACK_DONE;
7898 if (ev->event_window == bd->win)
7900 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7901 E_OBJECT(bd), ev, NULL))
7902 return ECORE_CALLBACK_PASS_ON;
7906 return ECORE_CALLBACK_DONE;
7910 _e_border_cb_drag_finished(E_Drag *drag,
7911 int dropped __UNUSED__)
7916 e_object_unref(E_OBJECT(bd));
7920 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7922 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7923 int ev_type __UNUSED__,
7926 E_Event_Desk_Window_Profile_Change *e;
7931 EINA_LIST_FOREACH(borders, l, bd)
7933 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
7935 bd->client.e.fetch.profile_list = 1;
7939 return ECORE_CALLBACK_PASS_ON;
7943 #ifdef _F_ZONE_WINDOW_ROTATION_
7945 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
7946 int ev_type __UNUSED__,
7949 E_Event_Zone_Rotation_Change_Begin *e = ev;
7951 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7952 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
7954 if (!_e_border_rotation_zone_set(e->zone))
7956 /* there is no border which supports window manager rotation */
7957 e_zone_rotation_update_cancel(e->zone);
7959 return ECORE_CALLBACK_PASS_ON;
7963 _e_border_cb_rotation_sync_job(void *data)
7965 E_Zone *zone = data;
7967 E_Border_Rotation_Info *info = NULL;
7969 ELB(ELBT_ROT, "DO ROTATION SYNC_JOB", zone->id);
7973 EINA_LIST_FOREACH(rot.list, l, info)
7974 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
7975 if (!rot.wait_prepare_done)
7977 _e_border_rotation_change_request(zone);
7984 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
7985 ecore_job_del(rot.sync_job);
7986 rot.sync_job = NULL;
7991 _e_border_cb_rotation_async_job(void *data)
7993 E_Zone *zone = data;
7995 if (rot.list) goto end;
7997 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
7999 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8000 rot.async_list = NULL;
8006 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
8007 ecore_job_del(rot.async_job);
8008 rot.async_job = NULL;
8013 _e_border_rotation_change_prepare_timeout(void *data)
8015 E_Zone *zone = data;
8016 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8018 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8020 if ((zone) && (rot.wait_prepare_done))
8024 _e_border_rotation_change_request(zone);
8025 if (rot.prepare_timer)
8026 ecore_timer_del(rot.prepare_timer);
8027 rot.prepare_timer = NULL;
8028 rot.wait_prepare_done = EINA_FALSE;
8031 return ECORE_CALLBACK_CANCEL;
8035 _e_border_rotation_change_request(E_Zone *zone)
8037 if (!e_config->wm_win_rotation) return;
8038 if (!rot.list) return;
8039 if (eina_list_count(rot.list) <= 0) return;
8040 if (zone->rot.block_count) return;
8042 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8043 rot.prepare_timer = NULL;
8044 rot.wait_prepare_done = EINA_FALSE;
8046 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8049 ecore_timer_del(rot.done_timer);
8050 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8051 rot.done_timer = ecore_timer_add(5.0f,
8052 _e_border_rotation_change_done_timeout,
8057 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8060 E_Border_Rotation_Info *info =NULL;
8063 EINA_LIST_FOREACH (list, l, info)
8065 if (!info->bd) continue;
8066 if ((info->bd->client.e.state.rot.wait_for_done) &&
8067 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8069 _e_border_event_border_rotation_change_begin_send(info->bd);
8072 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8073 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8075 info->x = x; info->y = y;
8076 info->w = w; info->h = h;
8078 ELBF(ELBT_ROT, 1, info->bd->client.win,
8079 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8080 info->ang, info->win_resize, info->w, info->h);
8082 ecore_x_e_window_rotation_change_prepare_send
8083 (info->bd->client.win, info->ang,
8084 info->win_resize, info->w, info->h);
8086 if (!info->bd->client.e.state.rot.pending_change_request)
8088 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8089 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8091 info->bd->client.e.state.rot.wait_for_done = 1;
8092 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8098 EINA_LIST_FREE(list, info)
8104 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8106 E_Border_Rotation_Info *info = NULL;
8108 if (send_request) _e_border_rotation_change_request(zone);
8111 EINA_LIST_FREE(rot.list, info)
8118 _e_border_rotation_list_remove(E_Border *bd)
8120 Eina_List *l = NULL;
8121 E_Border_Rotation_Info *info = NULL;
8122 E_Event_Border_Rotation_Change_End *ev = NULL;
8123 Eina_Bool found = EINA_FALSE;
8125 if (!e_config->wm_win_rotation) return;
8127 EINA_LIST_FOREACH(rot.list, l, info)
8131 rot.list = eina_list_remove(rot.list, info);
8137 if (bd->client.e.state.rot.wait_for_done)
8139 bd->client.e.state.rot.wait_for_done = 0;
8141 /* if we make the border event in the _e_border_free function,
8142 * then we may meet a crash problem, only work this at least e_border_hide.
8144 if (!e_object_is_del(E_OBJECT(bd)))
8146 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8150 e_object_ref(E_OBJECT(bd));
8151 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8153 _e_border_event_border_rotation_change_end_free,
8159 (eina_list_count(rot.list) == 0))
8161 _e_border_rotation_change_done();
8167 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8169 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8170 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8171 _e_border_rotation_change_done();
8172 return ECORE_CALLBACK_CANCEL;
8176 _e_border_rotation_change_done(void)
8178 E_Manager *m = NULL;
8179 E_Border_Rotation_Info *info = NULL;
8181 if (!e_config->wm_win_rotation) return;
8183 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8184 rot.prepare_timer = NULL;
8186 rot.wait_prepare_done = EINA_FALSE;
8188 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8189 rot.done_timer = NULL;
8191 EINA_LIST_FREE(rot.list, info)
8195 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8196 if (info->bd->client.e.state.rot.pending_show)
8198 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8199 e_border_show(info->bd);
8200 info->bd->client.e.state.rot.pending_show = 0;
8202 info->bd->client.e.state.rot.wait_for_done = 0;
8207 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8210 rot.async_list = NULL;
8212 m = e_manager_current_get();
8213 e_manager_comp_screen_unlock(m);
8214 e_zone_rotation_update_done(e_util_zone_current_get(m));
8218 _prev_angle_get(Ecore_X_Window win)
8220 int ret, count = 0, ang = -1;
8221 unsigned char* data = NULL;
8223 ret = ecore_x_window_prop_property_get
8224 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8225 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8227 if ((ret) && (data) && (count))
8228 ang = ((int *)data)[0];
8229 if (data) free(data);
8233 /* get proper rotation value using preferred rotation and list of available rotations */
8235 _e_border_rotation_get(E_Border *bd,
8239 int current_ang = bd->client.e.state.rot.curr;
8241 Eina_Bool found = EINA_FALSE;
8242 Eina_Bool found_curr_ang = EINA_FALSE;
8244 if (!e_config->wm_win_rotation) return ang;
8245 if (!bd->client.e.state.rot.app_set) return ang;
8247 if (bd->client.e.state.rot.preferred_rot != -1)
8249 ang = bd->client.e.state.rot.preferred_rot;
8250 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8252 else if ((bd->client.e.state.rot.available_rots) &&
8253 (bd->client.e.state.rot.count))
8255 for (i = 0; i < bd->client.e.state.rot.count; i++)
8257 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8263 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8264 found_curr_ang = EINA_TRUE;
8267 /* do nothing. this window wants to maintain current state.
8268 * for example, window's available_rots: 0, 90, 270,
8269 * current zone rotation request: 180. the WM does nothing
8274 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8275 ang = bd->client.e.state.rot.curr;
8277 ang = bd->client.e.state.rot.available_rots[0];
8282 /* In this case, border doesn't have a list of
8283 * available rotations, thus WM should request
8284 * rotation with '0' degree to the application.
8293 _e_border_rotation_angle_get(E_Border *bd)
8295 E_Zone *zone = bd->zone;
8300 if (!e_config->wm_win_rotation) return ret;
8301 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8303 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8305 // the window with "ECORE_X_WINDOW_TYPE_NORMAL" type
8306 // should follow the state of rotation of zone.
8308 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL))
8309 will_ang = bd->parent->client.e.state.rot.curr;
8310 else will_ang = zone->rot.curr;
8312 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8314 ELBF(ELBT_ROT, 1, bd->client.win,
8315 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8316 (rot.vkbd == bd) ? "vkbd" : "prediction",
8317 bd->parent ? bd->parent->client.win : 0,
8318 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8319 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8320 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8324 will_ang = bd->parent->client.e.state.rot.curr;
8325 if ((!bd->parent->client.e.state.rot.support) &&
8326 (!bd->parent->client.e.state.rot.app_set))
8333 if ((!bd->client.e.state.rot.app_set) &&
8334 (!bd->client.e.state.rot.support))
8336 /* hack for magnifier and keyboard popup */
8337 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8338 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8340 ELB(ELBT_BD, "MAG", bd->client.win);
8342 if ((rot.vkbd) && (rot.vkbd->visible))
8343 will_ang = rot.vkbd->client.e.state.rot.curr;
8347 if (bd->client.e.state.rot.app_set)
8349 /* utility type window should be rotated according to
8350 * rotation of the transient_for window.
8353 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8355 will_ang = bd->parent->client.e.state.rot.curr;
8356 if ((!bd->parent->client.e.state.rot.support) &&
8357 (!bd->parent->client.e.state.rot.app_set))
8359 /* if transient_for window doesn't support rotation feature,
8360 * then this window should't be rotated.
8361 * TODO: need to check whether window supports '0' degree or not.
8364 ELBF(ELBT_ROT, 0, bd->client.win,
8365 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8366 will_ang, bd->parent->client.win);
8370 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8371 ELBF(ELBT_ROT, 0, bd->client.win,
8372 "GET ROT ang:%d Transient_For:0x%08x",
8373 will_ang, bd->parent->client.win);
8378 will_ang = _e_border_rotation_get(bd, will_ang);
8379 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8380 will_ang, bd->parent ? bd->parent->client.win : 0,
8381 bd->client.netwm.type);
8387 _ang = _prev_angle_get(bd->client.win);
8389 bd->client.e.state.rot.curr = _ang;
8390 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8393 if (bd->client.e.state.rot.curr != will_ang)
8401 _e_border_rotation_zone_set(E_Zone *zone)
8403 E_Border_List *l = NULL;
8404 E_Border *bd = NULL;
8405 Eina_Bool ret = EINA_FALSE;
8407 if (!e_config->wm_win_rotation) return EINA_FALSE;
8409 l = e_container_border_list_last(zone->container);
8412 /* step 1. make the list needs to be rotated. */
8413 while ((bd = e_container_border_list_prev(l)))
8417 // if this window has parent and window type isn't "ECORE_X_WINDOW_TYPE_NORMAL",
8418 // it will be rotated when parent do rotate itself.
8421 (bd->client.netwm.type != ECORE_X_WINDOW_TYPE_NORMAL)) continue;
8423 // default type is "E_BORDER_ROTATION_TYPE_NORMAL",
8424 // but it can be changed to "E_BORDER_ROTATION_TYPE_DEPENDENT" by illume according to its policy.
8425 // if it's not normal type window, will be rotated by illume.
8427 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8429 if ((!bd->visible) ||
8430 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8431 bd->x, bd->y, bd->w, bd->h))) continue;
8433 if (_e_border_rotatable_check(bd, zone->rot.curr))
8435 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8436 bd->client.e.state.rot.curr, zone->rot.curr);
8438 ret = e_border_rotation_set(bd, zone->rot.curr);
8441 if (l) e_container_border_list_free(l);
8447 e_border_rotation_set(E_Border *bd, int rotation)
8449 E_Zone *zone = bd->zone;
8450 E_Border_Rotation_Info *info = NULL;
8451 Eina_List *list, *l;
8454 if (rotation < 0) return EINA_FALSE;
8456 /* step 1. check if rotation */
8457 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8459 /* step 2. add to async/sync list */
8460 if ((!zone->rot.block_count) &&
8462 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8464 // send rotation change request later.
8465 // and no need to wait message of rotation done.
8468 info = E_NEW(E_Border_Rotation_Info, 1);
8469 if (!info) return EINA_FALSE;
8470 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8472 info->ang = rotation;
8473 rot.async_list = eina_list_append(rot.async_list, info);
8475 // add job for sending event.
8478 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8479 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8485 info = E_NEW(E_Border_Rotation_Info, 1);
8486 if (!info) return EINA_FALSE;
8487 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8489 info->ang = rotation;
8490 rot.list = eina_list_append(rot.list, info);
8492 // add job for sending event.
8495 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8496 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8499 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8501 // but, DO NOT lock the screen when rotation block state.
8502 if ((!zone->rot.block_count) &&
8503 ((eina_list_count(rot.list) == 2)))
8504 e_manager_comp_screen_lock(e_manager_current_get());
8507 /* step 3. search rotatable window in this window's child */
8508 list = _e_border_sub_borders_new(bd);
8509 EINA_LIST_FOREACH(list, l, child)
8511 // the window which type is "ECORE_X_WINDOW_TYPE_NORMAL" will be rotated itself.
8512 // it shouldn't be rotated by rotation state of parent window.
8513 if (child->client.netwm.type == ECORE_X_WINDOW_TYPE_NORMAL) continue;
8514 if (_e_border_rotatable_check(child, rotation))
8516 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8517 bd->client.e.state.rot.curr, rotation);
8518 e_border_rotation_set(child, rotation);
8522 /* step 4. if there is vkbd window, send message to prepare rotation */
8523 if (_e_border_is_vkbd(bd))
8525 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8526 if (rot.prepare_timer)
8527 ecore_timer_del(rot.prepare_timer);
8528 rot.prepare_timer = NULL;
8531 ecore_timer_del(rot.done_timer);
8532 rot.done_timer = NULL;
8534 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8535 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8538 rot.prepare_timer = ecore_timer_add(4.0f,
8539 _e_border_rotation_change_prepare_timeout,
8542 rot.wait_prepare_done = EINA_TRUE;
8545 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8546 bd->client.e.state.rot.curr = rotation;
8551 // check if border is rotatable in ang.
8553 _e_border_rotatable_check(E_Border *bd, int ang)
8555 Eina_Bool ret = EINA_FALSE;
8557 if (!bd) return ret;
8558 if (ang < 0) return ret;
8559 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8560 if (e_object_is_del(E_OBJECT(bd))) return ret;
8562 // same with current angle of window, then false return.
8563 if (ang == bd->client.e.state.rot.curr) return ret;
8565 /* basically WM allows only fullscreen window to rotate */
8566 if (bd->client.e.state.rot.preferred_rot == -1)
8570 if (bd->client.e.state.rot.app_set)
8572 if (bd->client.e.state.rot.available_rots &&
8573 bd->client.e.state.rot.count)
8575 Eina_Bool found = EINA_FALSE;
8576 for (i = 0; i < bd->client.e.state.rot.count; i++)
8578 if (bd->client.e.state.rot.available_rots[i] == ang)
8583 if (found) ret = EINA_TRUE;
8588 ELB(ELBT_ROT, "DO ROT", 0);
8592 // if it has preferred rotation angle,
8593 // it will be rotated at border's evaluation time.
8595 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8600 /* check whether virtual keyboard is visible on the zone */
8602 _e_border_is_vkbd(E_Border *bd)
8604 if (!e_config->wm_win_rotation) return EINA_FALSE;
8606 if ((rot.vkbd_ctrl_win) &&
8608 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8609 (rot.vkbd->visible) &&
8610 (rot.vkbd->zone == bd->zone) &&
8611 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8612 bd->zone->w, bd->zone->h,
8613 rot.vkbd->x, rot.vkbd->y,
8614 rot.vkbd->w, rot.vkbd->h)))
8622 _e_border_rotation_change_floating_pos(E_Border *bd, int *x, int *y)
8625 int min_title_width=96;
8627 if (!bd) return EINA_FALSE;
8628 if (!x || !y) return EINA_FALSE;
8633 // Portrait -> Landscape, x= pre_x*2, y=pre_y/2
8634 // Landscape -> Portrait, x= pre_x/2, y=pre_y*2
8635 // guaranteeing the minimum size of titlebar shown, min_title_width
8636 // so user can initiate drag&drop action after rotation changed.
8637 if (bd->client.e.state.rot.curr == 0)
8639 if (bd->client.e.state.rot.prev == 90)
8641 new_x = (bd->zone->h - bd->h - bd->y) / 2;
8644 else if (bd->client.e.state.rot.prev == 270)
8647 new_y = (bd->zone->w - bd->w - bd->x) * 2;
8649 else if (bd->client.e.state.rot.prev == 180)
8651 new_x = bd->zone->w - bd->x - bd->w;
8652 new_y = bd->zone->h - bd->y - bd->h;
8655 if(new_x + bd->w < min_title_width)
8657 new_x = min_title_width - bd->w;
8659 else if(new_x > bd->zone->w - min_title_width)
8661 new_x = bd->zone->w - min_title_width;
8664 else if (bd->client.e.state.rot.curr == 90)
8666 if (bd->client.e.state.rot.prev == 0)
8669 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8671 else if (bd->client.e.state.rot.prev == 270)
8673 new_x = bd->zone->w - bd->x - bd->w;
8674 new_y = bd->zone->h - bd->y - bd->h;
8676 else if (bd->client.e.state.rot.prev == 180)
8678 new_x = (bd->zone->h - bd->y - bd->h) / 2;
8679 new_y = bd->zone->h - (2 * (bd->zone->w - bd->x - bd->w)) - bd->w;
8682 if(new_y > bd->zone->h - min_title_width)
8684 new_y = bd->zone->h - min_title_width;
8686 else if(new_y < min_title_width - bd->w)
8688 new_y = min_title_width - bd->w;
8691 else if (bd->client.e.state.rot.curr == 270)
8693 if (bd->client.e.state.rot.prev == 0)
8695 new_x = bd->zone->w - bd->h - (bd->y / 2);
8698 else if (bd->client.e.state.rot.prev == 90)
8700 new_x = bd->zone->w - bd->x - bd->w;
8701 new_y = bd->zone->h - bd->y - bd->h;
8703 else if (bd->client.e.state.rot.prev == 180)
8705 new_x = bd->zone->w - bd->x - bd->w;
8706 new_y = bd->zone->h - bd->y - bd->h;
8708 new_x = bd->zone->w - bd->h - ((bd->zone->h - bd->y - bd->h) / 2);
8709 new_y = (bd->zone->w - bd->x - bd->w) * 2;
8712 if(new_y > bd->zone->h - min_title_width)
8714 new_y = bd->zone->h - min_title_width;
8716 else if( new_y + bd->w < min_title_width)
8718 new_y = min_title_width - bd->w ;
8721 else if (bd->client.e.state.rot.curr == 180)
8723 if (bd->client.e.state.rot.prev == 0)
8725 new_x = bd->zone->w - bd->x - bd->w;
8726 new_y = bd->zone->h - bd->y - bd->h;
8728 else if (bd->client.e.state.rot.prev == 90)
8730 new_x = bd->zone->w - ((bd->zone->h - bd->h - bd->y) / 2) - bd->h;
8731 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8733 else if (bd->client.e.state.rot.prev == 270)
8735 new_x = bd->zone->w - (bd->y / 2) - bd->h;
8736 new_y = bd->zone->h - ((bd->zone->w - bd->w - bd->x) * 2) - bd->w;
8739 if(new_x + bd->w < min_title_width)
8741 new_x = min_title_width - bd->w;
8743 else if(new_x > bd->zone->w - min_title_width)
8745 new_x = bd->zone->w - min_title_width;
8749 ELBF(ELBT_ROT, 0, bd->client.win,
8750 "Floating Mode. ANGLE (%d->%d), POS (%d,%d) -> (%d,%d)",
8751 bd->client.e.state.rot.prev, bd->client.e.state.rot.curr,
8752 bd->x, bd->y, new_x, new_y);
8754 if ((new_x == *x) &&
8766 #define SIZE_EQUAL_TO_ZONE(a, z) \
8767 ((((a)->w) == ((z)->w)) && \
8768 (((a)->h) == ((z)->h)))
8770 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
8772 E_Zone *zone = bd->zone;
8775 Eina_Bool move = EINA_FALSE;
8776 Eina_Bool hint = EINA_FALSE;
8777 Eina_Bool resize = EINA_FALSE;
8784 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
8786 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
8787 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
8788 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
8790 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
8791 &_x, &_y, &_w, &_h, &move);
8794 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
8796 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8797 bd->client.icccm.name, _x, _y, _w, _h);
8801 _x = bd->x; _y = bd->y;
8802 _w = bd->w; _h = bd->h;
8804 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)
8805 move = _e_border_rotation_change_floating_pos(bd, &_x, &_y);
8809 rot_dif = bd->client.e.state.rot.prev - rotation;
8810 if (rot_dif < 0) rot_dif = -rot_dif;
8819 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
8820 EINA_TRUE, EINA_TRUE);
8821 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
8822 bd->client.icccm.name, _x, _y, _w, _h);
8827 if (!resize && move)
8828 _e_border_move_internal(bd, _x, _y, EINA_TRUE);
8843 _e_border_cb_window_configure(void *data __UNUSED__,
8844 int ev_type __UNUSED__,
8847 Ecore_X_Event_Window_Configure *e = ev;
8848 E_Border_Rotation_Info *info = NULL;
8850 Eina_Bool found = EINA_FALSE;
8852 if (!e) return ECORE_CALLBACK_PASS_ON;
8853 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8855 E_Border *bd = e_border_find_by_client_window(e->win);
8856 if (!bd) return ECORE_CALLBACK_PASS_ON;
8858 if (bd->client.e.state.rot.pending_change_request)
8860 if ((e->w == bd->w) && (e->h == bd->h))
8862 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
8863 bd->client.e.state.rot.pending_change_request = 0;
8865 if ((bd->client.e.state.rot.wait_for_done) &&
8866 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
8868 // if this window is rotation dependent window and zone is blocked to rotate,
8869 // then skip here, request will be sent after cancel block.
8870 if ((bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT) &&
8871 (bd->zone->rot.block_count)) goto end;
8873 EINA_LIST_FOREACH(rot.list, l, info)
8874 if (info->bd == bd) found = EINA_TRUE;
8875 // send request message if it's async rotation window,
8876 // even if wait prepare done.
8877 if ((found) && (rot.wait_prepare_done)) goto end;
8879 ELBF(ELBT_ROT, 0, bd->client.win,
8880 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8881 bd->client.e.state.rot.curr,
8883 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8884 bd->client.e.state.rot.curr);
8885 bd->client.e.state.rot.wait_for_done = 1;
8886 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
8891 return ECORE_CALLBACK_PASS_ON;
8895 _e_border_rotation_geom_get(E_Border *bd,
8904 if (!e_config->wm_win_rotation) return EINA_FALSE;
8906 Eina_Bool res = EINA_FALSE;
8907 Eina_Bool _move = EINA_TRUE;
8917 if (move) *move = EINA_TRUE;
8919 if (bd->client.e.state.rot.geom_hint)
8924 _w = bd->client.e.state.rot.geom[0].w;
8925 _h = bd->client.e.state.rot.geom[0].h;
8926 if (_w == 0) _w = bd->w;
8927 if (_h == 0) _h = bd->h;
8928 _x = 0; _y = zone->h - _h;
8931 _w = bd->client.e.state.rot.geom[1].w;
8932 _h = bd->client.e.state.rot.geom[1].h;
8933 if (_w == 0) _w = bd->w;
8934 if (_h == 0) _h = bd->h;
8935 _x = zone->w - _w; _y = 0;
8938 _w = bd->client.e.state.rot.geom[2].w;
8939 _h = bd->client.e.state.rot.geom[2].h;
8940 if (_w == 0) _w = bd->w;
8941 if (_h == 0) _h = bd->h;
8945 _w = bd->client.e.state.rot.geom[3].w;
8946 _h = bd->client.e.state.rot.geom[3].h;
8947 if (_w == 0) _w = bd->w;
8948 if (_h == 0) _h = bd->h;
8958 if (!((rot.vkbd) && (rot.vkbd == bd)))
8962 if (move) *move = EINA_FALSE;
8970 _x = 0; _y = 0; _w = 0; _h = 0;
8975 if (move) _move = *move;
8977 ELBF(ELBT_ROT, 1, bd->client.win,
8978 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
8979 ang, _x, _y, _w, _h, _move);
8987 _e_border_post_move_resize_job(void *data)
8991 bd = (E_Border *)data;
8997 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
8998 ecore_x_window_move(tmp->win,
9000 bd->client_inset.l +
9002 tmp->client.e.state.video_position.x,
9004 bd->client_inset.t +
9006 tmp->client.e.state.video_position.y);
9008 if (bd->client.e.state.video)
9012 parent = bd->client.e.state.video_parent_border;
9013 ecore_x_window_move(bd->win,
9015 parent->client_inset.l +
9017 bd->client.e.state.video_position.x,
9019 parent->client_inset.t +
9021 bd->client.e.state.video_position.y);
9023 else if ((bd->post_move) && (bd->post_resize))
9025 ecore_x_window_move_resize(bd->win,
9030 else if (bd->post_move)
9032 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
9034 else if (bd->post_resize)
9036 ecore_x_window_resize(bd->win, bd->w, bd->h);
9039 if (bd->client.e.state.video)
9041 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
9043 bd->client.e.state.video_parent_border->x +
9044 bd->client.e.state.video_parent_border->client_inset.l +
9045 bd->client.e.state.video_parent_border->fx.x +
9046 bd->client.e.state.video_position.x,
9047 bd->client.e.state.video_parent_border->y +
9048 bd->client.e.state.video_parent_border->client_inset.t +
9049 bd->client.e.state.video_parent_border->fx.y +
9050 bd->client.e.state.video_position.y,
9058 bd->post_job = NULL;
9064 bd->post_resize = 0;
9065 bd->post_job = NULL;
9066 return ECORE_CALLBACK_CANCEL;
9070 _e_border_container_layout_hook(E_Container *con)
9072 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
9076 _e_border_eval0(E_Border *bd)
9078 int change_urgent = 0;
9080 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9081 Eina_Bool need_desk_set = EINA_FALSE;
9083 #ifdef _F_ZONE_WINDOW_ROTATION_
9084 Eina_Bool need_rotation_set = EINA_FALSE;
9086 if ((e_config->wm_win_rotation) &&
9087 (bd->client.icccm.fetch.transient_for))
9089 if (((rot.vkbd) && (rot.vkbd == bd)) ||
9090 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
9092 need_rotation_set = EINA_TRUE;
9093 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
9098 if (e_object_is_del(E_OBJECT(bd)))
9100 CRI("_e_border_eval(%p) with deleted border!\n", bd);
9105 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
9107 bd->changes.border = 0;
9109 /* fetch any info queued to be fetched */
9110 if (bd->client.netwm.fetch.state)
9112 e_hints_window_state_get(bd);
9113 bd->client.netwm.fetch.state = 0;
9116 if (bd->client.icccm.fetch.client_leader)
9118 /* TODO: What do to if the client leader isn't mapped yet? */
9119 E_Border *bd_leader = NULL;
9121 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
9122 if (bd->client.icccm.client_leader)
9123 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
9126 if (bd->leader != bd_leader)
9128 bd->leader->group = eina_list_remove(bd->leader->group, bd);
9129 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9135 /* If this border is the leader of the group, don't register itself */
9136 if ((bd_leader) && (bd_leader != bd))
9138 bd_leader->group = eina_list_append(bd_leader->group, bd);
9139 bd->leader = bd_leader;
9140 /* Only set the window modal to the leader it there is no parent */
9141 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9142 ((!bd->parent) || (bd->parent->modal != bd)))
9144 bd->leader->modal = bd;
9145 if (bd->leader->focused)
9146 e_border_focus_set(bd, 1, 1);
9152 EINA_LIST_FOREACH(bd->leader->group, l, child)
9154 if ((child != bd) && (child->focused))
9155 e_border_focus_set(bd, 1, 1);
9160 bd->client.icccm.fetch.client_leader = 0;
9163 if (bd->client.icccm.fetch.title)
9165 char *title = ecore_x_icccm_title_get(bd->client.win);
9166 eina_stringshare_replace(&bd->client.icccm.title, title);
9167 if (title) free(title);
9170 edje_object_part_text_set(bd->bg_object, "e.text.title",
9171 bd->client.icccm.title);
9172 bd->client.icccm.fetch.title = 0;
9175 if (bd->client.netwm.fetch.name)
9178 ecore_x_netwm_name_get(bd->client.win, &name);
9179 eina_stringshare_replace(&bd->client.netwm.name, name);
9180 if (name) free(name);
9183 edje_object_part_text_set(bd->bg_object, "e.text.title",
9184 bd->client.netwm.name);
9185 bd->client.netwm.fetch.name = 0;
9188 if (bd->client.icccm.fetch.name_class)
9190 const char *pname, *pclass;
9191 char *nname, *nclass;
9193 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9194 pname = bd->client.icccm.name;
9195 pclass = bd->client.icccm.class;
9196 bd->client.icccm.name = eina_stringshare_add(nname);
9197 bd->client.icccm.class = eina_stringshare_add(nclass);
9198 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9199 e_bindings_mapping_change_enable(EINA_FALSE);
9200 #ifdef _F_ZONE_WINDOW_ROTATION_
9201 if (e_config->wm_win_rotation)
9203 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9205 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9206 (!strcmp(bd->client.icccm.class, "ISF")))
9208 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9209 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9212 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9213 (!strcmp(bd->client.icccm.class, "ISF")))
9215 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9216 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9217 rot.vkbd_prediction = bd;
9219 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9220 (!strcmp(bd->client.icccm.class, "ISF")))
9222 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9223 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9225 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9226 (!strcmp(bd->client.icccm.class, "ISF")))
9228 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9229 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9234 if (nname) free(nname);
9235 if (nclass) free(nclass);
9237 if (!((bd->client.icccm.name == pname) &&
9238 (bd->client.icccm.class == pclass)))
9239 bd->changes.icon = 1;
9241 if (pname) eina_stringshare_del(pname);
9242 if (pclass) eina_stringshare_del(pclass);
9243 bd->client.icccm.fetch.name_class = 0;
9244 bd->changes.icon = 1;
9247 if (bd->client.icccm.fetch.state)
9249 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9250 bd->client.icccm.fetch.state = 0;
9253 if (bd->client.e.fetch.state)
9255 e_hints_window_e_state_get(bd);
9256 bd->client.e.fetch.state = 0;
9259 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9260 if (bd->client.e.fetch.profile_list)
9262 const char **profiles = NULL;
9266 if (bd->client.e.state.profile)
9267 eina_stringshare_del(bd->client.e.state.profile);
9268 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9270 if (str) eina_stringshare_del(str);
9272 bd->client.e.state.profile = NULL;
9273 bd->client.e.state.profiles = NULL;
9274 bd->client.e.state.profile_list = 0;
9276 if (ecore_x_e_window_profile_list_get(bd->client.win,
9279 bd->client.e.state.profile_list = 1;
9280 for (i = 0; i < num; i++)
9282 str = eina_stringshare_add(profiles[i]);
9283 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9286 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9287 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9289 need_desk_set = EINA_TRUE;
9293 if (strcmp(bd->desk->window_profile,
9294 e_config->desktop_default_window_profile) != 0)
9296 ecore_x_e_window_profile_set(bd->client.win,
9297 bd->desk->window_profile);
9303 for (i = 0; i < num; i++)
9304 if (profiles[i]) free(profiles[i]);
9308 bd->client.e.fetch.profile_list = 0;
9311 #ifdef _F_ZONE_WINDOW_ROTATION_
9312 if ((e_config->wm_win_rotation) &&
9313 (bd->client.e.fetch.rot.support))
9316 unsigned int support = 0;
9318 ret = ecore_x_window_prop_card32_get
9320 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9323 bd->client.e.state.rot.support = 0;
9324 if ((ret == 1) && (support == 1))
9325 bd->client.e.state.rot.support = 1;
9327 if (bd->client.e.state.rot.support)
9328 need_rotation_set = EINA_TRUE;
9330 bd->client.e.fetch.rot.support = 0;
9332 if ((e_config->wm_win_rotation) &&
9333 (bd->client.e.fetch.rot.geom_hint))
9335 Eina_Rectangle r[4];
9337 bd->client.e.state.rot.geom_hint = 0;
9338 for (i = 0; i < 4; i++)
9340 r[i].x = bd->client.e.state.rot.geom[i].x;
9341 r[i].y = bd->client.e.state.rot.geom[i].y;
9342 r[i].w = bd->client.e.state.rot.geom[i].w;
9343 r[i].h = bd->client.e.state.rot.geom[i].h;
9345 bd->client.e.state.rot.geom[i].x = 0;
9346 bd->client.e.state.rot.geom[i].y = 0;
9347 bd->client.e.state.rot.geom[i].w = 0;
9348 bd->client.e.state.rot.geom[i].h = 0;
9351 for (i = 0; i < 4; i++)
9353 x = 0; y = 0; w = 0; h = 0;
9354 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9356 bd->client.e.state.rot.geom_hint = 1;
9357 bd->client.e.state.rot.geom[i].x = x;
9358 bd->client.e.state.rot.geom[i].y = y;
9359 bd->client.e.state.rot.geom[i].w = w;
9360 bd->client.e.state.rot.geom[i].h = h;
9362 if (!((r[i].x == x) && (r[i].y == y) &&
9363 (r[i].w == w) && (r[i].h == h)))
9365 need_rotation_set = EINA_TRUE;
9369 bd->client.e.fetch.rot.geom_hint = 0;
9371 if ((e_config->wm_win_rotation) &&
9372 (bd->client.e.fetch.rot.app_set))
9374 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9375 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9376 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9378 if (_prev_app_set != bd->client.e.state.rot.app_set)
9379 need_rotation_set = EINA_TRUE;
9381 bd->client.e.fetch.rot.app_set = 0;
9383 if ((e_config->wm_win_rotation) &&
9384 (bd->client.e.fetch.rot.preferred_rot))
9386 int r = 0, _prev_preferred_rot;
9387 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9388 bd->client.e.state.rot.preferred_rot = -1;
9389 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9391 bd->client.e.state.rot.preferred_rot = r;
9392 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9396 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9399 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9400 need_rotation_set = EINA_TRUE;
9402 bd->client.e.fetch.rot.preferred_rot = 0;
9404 if ((e_config->wm_win_rotation) &&
9405 (bd->client.e.fetch.rot.available_rots))
9407 Eina_Bool res, diff = EINA_FALSE;
9409 unsigned int count = 0, i = 0;
9410 int _prev_rots[4] = { -1, };
9412 if (bd->client.e.state.rot.available_rots)
9415 bd->client.e.state.rot.available_rots,
9416 (sizeof(int) * bd->client.e.state.rot.count));
9418 E_FREE(bd->client.e.state.rot.available_rots);
9421 bd->client.e.state.rot.count = 0;
9423 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9425 if ((res) && (count > 0) && (rots))
9427 bd->client.e.state.rot.available_rots = rots;
9428 bd->client.e.state.rot.count = count;
9430 for (i = 0; i < count; i++)
9432 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9433 if ((!diff) && (_prev_rots[i] != rots[i]))
9435 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9436 count, i, _prev_rots[i], rots[i]);
9443 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9447 if (diff) need_rotation_set = EINA_TRUE;
9448 bd->client.e.fetch.rot.available_rots = 0;
9451 if (bd->client.netwm.fetch.type)
9453 e_hints_window_type_get(bd);
9454 if ((!bd->lock_border) || (!bd->client.border.name))
9455 bd->client.border.changed = 1;
9457 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9459 if (!bd->client.netwm.state.skip_pager)
9461 bd->client.netwm.state.skip_pager = 1;
9462 bd->client.netwm.update.state = 1;
9464 if (!bd->client.netwm.state.skip_taskbar)
9466 bd->client.netwm.state.skip_taskbar = 1;
9467 bd->client.netwm.update.state = 1;
9470 bd->client.netwm.fetch.type = 0;
9472 if (bd->client.icccm.fetch.machine)
9474 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9476 if ((!machine) && (bd->client.icccm.client_leader))
9477 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9479 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9480 if (machine) free(machine);
9482 bd->client.icccm.fetch.machine = 0;
9485 if (bd->client.icccm.fetch.command)
9487 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9491 for (i = 0; i < bd->client.icccm.command.argc; i++)
9492 free(bd->client.icccm.command.argv[i]);
9493 free(bd->client.icccm.command.argv);
9495 bd->client.icccm.command.argc = 0;
9496 bd->client.icccm.command.argv = NULL;
9497 ecore_x_icccm_command_get(bd->client.win,
9498 &(bd->client.icccm.command.argc),
9499 &(bd->client.icccm.command.argv));
9500 if ((bd->client.icccm.client_leader) &&
9501 (!bd->client.icccm.command.argv))
9502 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9503 &(bd->client.icccm.command.argc),
9504 &(bd->client.icccm.command.argv));
9505 bd->client.icccm.fetch.command = 0;
9508 if (bd->client.icccm.fetch.hints)
9510 Eina_Bool accepts_focus, is_urgent;
9512 accepts_focus = EINA_TRUE;
9513 is_urgent = EINA_FALSE;
9514 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9515 if (ecore_x_icccm_hints_get(bd->client.win,
9517 &bd->client.icccm.initial_state,
9518 &bd->client.icccm.icon_pixmap,
9519 &bd->client.icccm.icon_mask,
9520 &bd->client.icccm.icon_window,
9521 &bd->client.icccm.window_group,
9524 bd->client.icccm.accepts_focus = accepts_focus;
9525 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9527 bd->client.icccm.urgent = is_urgent;
9529 /* If this is a new window, set the state as requested. */
9530 if ((bd->new_client) &&
9531 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9533 e_border_iconify(bd);
9534 e_border_hide(bd, 1);
9537 bd->client.icccm.fetch.hints = 0;
9540 if (bd->client.icccm.fetch.size_pos_hints)
9542 Eina_Bool request_pos;
9544 request_pos = EINA_FALSE;
9545 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9547 &bd->client.icccm.gravity,
9548 &bd->client.icccm.min_w,
9549 &bd->client.icccm.min_h,
9550 &bd->client.icccm.max_w,
9551 &bd->client.icccm.max_h,
9552 &bd->client.icccm.base_w,
9553 &bd->client.icccm.base_h,
9554 &bd->client.icccm.step_w,
9555 &bd->client.icccm.step_h,
9556 &bd->client.icccm.min_aspect,
9557 &bd->client.icccm.max_aspect))
9559 bd->client.icccm.request_pos = request_pos;
9564 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9565 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9566 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9567 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9568 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9569 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9570 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9571 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9572 // if doing a resize, fix it up
9573 if (bd->resize_mode != RESIZE_NONE)
9575 int x, y, w, h, new_w, new_h;
9583 e_border_resize_limit(bd, &new_w, &new_h);
9584 if ((bd->resize_mode == RESIZE_TL) ||
9585 (bd->resize_mode == RESIZE_L) ||
9586 (bd->resize_mode == RESIZE_BL))
9588 if ((bd->resize_mode == RESIZE_TL) ||
9589 (bd->resize_mode == RESIZE_T) ||
9590 (bd->resize_mode == RESIZE_TR))
9592 e_border_move_resize(bd, x, y, new_w, new_h);
9594 bd->client.icccm.fetch.size_pos_hints = 0;
9597 if (bd->client.icccm.fetch.protocol)
9600 Ecore_X_WM_Protocol *proto;
9602 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9605 for (i = 0; i < num; i++)
9607 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9608 bd->client.icccm.delete_request = 1;
9609 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9610 bd->client.icccm.take_focus = 1;
9611 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9612 bd->client.netwm.ping = 1;
9613 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9615 bd->client.netwm.sync.request = 1;
9616 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9617 &bd->client.netwm.sync.counter))
9618 bd->client.netwm.sync.request = 0;
9623 if (bd->client.netwm.ping)
9627 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9628 bd->ping_poller = NULL;
9630 bd->client.icccm.fetch.protocol = 0;
9632 if (bd->client.icccm.fetch.transient_for)
9634 /* TODO: What do to if the transient for isn't mapped yet? */
9635 E_Border *bd_parent = NULL;
9636 #ifdef _F_DEICONIFY_APPROVE_
9637 Eina_Bool change_parent = EINA_FALSE;
9640 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9641 if (bd->client.icccm.transient_for)
9642 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9643 /* If we already have a parent, remove it */
9646 if (bd_parent != bd->parent)
9648 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9649 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9655 if ((bd_parent) && (bd_parent != bd) &&
9656 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9658 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9659 bd->parent = bd_parent;
9660 #ifdef _F_DEICONIFY_APPROVE_
9661 change_parent = EINA_TRUE;
9666 e_border_layer_set(bd, bd->parent->layer);
9667 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9669 Ecore_X_Window_Attributes attr;
9670 bd->parent->modal = bd;
9671 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9672 bd->parent->saved.event_mask = attr.event_mask.mine;
9673 bd->parent->lock_close = 1;
9674 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9675 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9678 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9679 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9683 #ifdef _F_DEICONIFY_APPROVE_
9686 bd->client.e.state.deiconify_approve.render_done = 0;
9688 E_Border *ancestor_bd;
9689 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9690 if ((ancestor_bd) &&
9691 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9693 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9694 bd->client.e.state.deiconify_approve.ancestor = NULL;
9696 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9697 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9699 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9701 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9702 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9703 e_border_uniconify(ancestor_bd);
9709 bd->client.icccm.fetch.transient_for = 0;
9712 if (bd->client.icccm.fetch.window_role)
9714 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9715 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9716 if (role) free(role);
9718 bd->client.icccm.fetch.window_role = 0;
9721 if (bd->client.icccm.fetch.icon_name)
9723 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9724 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9725 if (icon_name) free(icon_name);
9727 bd->client.icccm.fetch.icon_name = 0;
9730 if (bd->client.netwm.fetch.icon_name)
9733 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9734 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9735 if (icon_name) free(icon_name);
9737 bd->client.netwm.fetch.icon_name = 0;
9740 if (bd->client.netwm.fetch.icon)
9743 if (bd->client.netwm.icons)
9745 for (i = 0; i < bd->client.netwm.num_icons; i++)
9747 free(bd->client.netwm.icons[i].data);
9748 bd->client.netwm.icons[i].data = NULL;
9750 free(bd->client.netwm.icons);
9752 bd->client.netwm.icons = NULL;
9753 bd->client.netwm.num_icons = 0;
9754 if (ecore_x_netwm_icons_get(bd->client.win,
9755 &bd->client.netwm.icons,
9756 &bd->client.netwm.num_icons))
9758 // unless the rest of e17 uses border icons OTHER than icon #0
9759 // then free the rest that we don't need anymore.
9760 for (i = 1; i < bd->client.netwm.num_icons; i++)
9762 free(bd->client.netwm.icons[i].data);
9763 bd->client.netwm.icons[i].data = NULL;
9765 bd->client.netwm.num_icons = 1;
9766 bd->changes.icon = 1;
9768 bd->client.netwm.fetch.icon = 0;
9770 if (bd->client.netwm.fetch.user_time)
9772 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9773 bd->client.netwm.fetch.user_time = 0;
9775 if (bd->client.netwm.fetch.strut)
9777 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9778 &bd->client.netwm.strut.left,
9779 &bd->client.netwm.strut.right,
9780 &bd->client.netwm.strut.top,
9781 &bd->client.netwm.strut.bottom,
9782 &bd->client.netwm.strut.left_start_y,
9783 &bd->client.netwm.strut.left_end_y,
9784 &bd->client.netwm.strut.right_start_y,
9785 &bd->client.netwm.strut.right_end_y,
9786 &bd->client.netwm.strut.top_start_x,
9787 &bd->client.netwm.strut.top_end_x,
9788 &bd->client.netwm.strut.bottom_start_x,
9789 &bd->client.netwm.strut.bottom_end_x))
9791 ecore_x_netwm_strut_get(bd->client.win,
9792 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9793 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9795 bd->client.netwm.strut.left_start_y = 0;
9796 bd->client.netwm.strut.left_end_y = 0;
9797 bd->client.netwm.strut.right_start_y = 0;
9798 bd->client.netwm.strut.right_end_y = 0;
9799 bd->client.netwm.strut.top_start_x = 0;
9800 bd->client.netwm.strut.top_end_x = 0;
9801 bd->client.netwm.strut.bottom_start_x = 0;
9802 bd->client.netwm.strut.bottom_end_x = 0;
9804 bd->client.netwm.fetch.strut = 0;
9806 if (bd->client.qtopia.fetch.soft_menu)
9808 e_hints_window_qtopia_soft_menu_get(bd);
9809 bd->client.qtopia.fetch.soft_menu = 0;
9812 if (bd->client.qtopia.fetch.soft_menus)
9814 e_hints_window_qtopia_soft_menus_get(bd);
9815 bd->client.qtopia.fetch.soft_menus = 0;
9818 if (bd->client.vkbd.fetch.state)
9820 e_hints_window_virtual_keyboard_state_get(bd);
9821 bd->client.vkbd.fetch.state = 0;
9824 if (bd->client.vkbd.fetch.vkbd)
9826 e_hints_window_virtual_keyboard_get(bd);
9827 bd->client.vkbd.fetch.vkbd = 0;
9830 if (bd->client.illume.conformant.fetch.conformant)
9832 bd->client.illume.conformant.conformant =
9833 ecore_x_e_illume_conformant_get(bd->client.win);
9834 bd->client.illume.conformant.fetch.conformant = 0;
9836 if (bd->client.illume.quickpanel.fetch.state)
9838 bd->client.illume.quickpanel.state =
9839 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9840 bd->client.illume.quickpanel.fetch.state = 0;
9842 if (bd->client.illume.quickpanel.fetch.quickpanel)
9844 bd->client.illume.quickpanel.quickpanel =
9845 ecore_x_e_illume_quickpanel_get(bd->client.win);
9846 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9848 if (bd->client.illume.quickpanel.fetch.priority.major)
9850 bd->client.illume.quickpanel.priority.major =
9851 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9852 bd->client.illume.quickpanel.fetch.priority.major = 0;
9854 if (bd->client.illume.quickpanel.fetch.priority.minor)
9856 bd->client.illume.quickpanel.priority.minor =
9857 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9858 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9860 if (bd->client.illume.quickpanel.fetch.zone)
9862 bd->client.illume.quickpanel.zone =
9863 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9864 bd->client.illume.quickpanel.fetch.zone = 0;
9866 if (bd->client.illume.drag.fetch.drag)
9868 bd->client.illume.drag.drag =
9869 ecore_x_e_illume_drag_get(bd->client.win);
9870 bd->client.illume.drag.fetch.drag = 0;
9872 if (bd->client.illume.drag.fetch.locked)
9874 bd->client.illume.drag.locked =
9875 ecore_x_e_illume_drag_locked_get(bd->client.win);
9876 bd->client.illume.drag.fetch.locked = 0;
9878 if (bd->client.illume.win_state.fetch.state)
9880 bd->client.illume.win_state.state =
9881 ecore_x_e_illume_window_state_get(bd->client.win);
9882 bd->client.illume.win_state.fetch.state = 0;
9884 if (bd->changes.shape)
9886 Ecore_X_Rectangle *rects;
9889 bd->changes.shape = 0;
9890 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9895 /* This doesn't fix the race, but makes it smaller. we detect
9896 * this and if cw and ch != client w/h then mark this as needing
9897 * a shape change again to fixup next event loop.
9899 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9900 if ((cw != bd->client.w) || (ch != bd->client.h))
9901 bd->changes.shape = 1;
9903 (rects[0].x == 0) &&
9904 (rects[0].y == 0) &&
9905 ((int)rects[0].width == cw) &&
9906 ((int)rects[0].height == ch))
9908 if (bd->client.shaped)
9910 bd->client.shaped = 0;
9911 if (!bd->bordername)
9912 bd->client.border.changed = 1;
9917 if (!bd->client.shaped)
9919 bd->client.shaped = 1;
9920 if (!bd->bordername)
9921 bd->client.border.changed = 1;
9928 // FIXME: no rects i think can mean... totally empty window
9929 bd->client.shaped = 0;
9930 if (!bd->bordername)
9931 bd->client.border.changed = 1;
9933 bd->need_shape_merge = 1;
9935 if (bd->changes.shape_input)
9937 Ecore_X_Rectangle *rects;
9940 bd->changes.shape_input = 0;
9941 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
9946 /* This doesn't fix the race, but makes it smaller. we detect
9947 * this and if cw and ch != client w/h then mark this as needing
9948 * a shape change again to fixup next event loop.
9950 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9951 if ((cw != bd->client.w) || (ch != bd->client.h))
9952 bd->changes.shape_input = 1;
9954 (rects[0].x == 0) &&
9955 (rects[0].y == 0) &&
9956 ((int)rects[0].width == cw) &&
9957 ((int)rects[0].height == ch))
9959 if (bd->shaped_input)
9961 bd->shaped_input = 0;
9962 if (!bd->bordername)
9963 bd->client.border.changed = 1;
9968 if (!bd->shaped_input)
9970 bd->shaped_input = 1;
9971 if (!bd->bordername)
9972 bd->client.border.changed = 1;
9979 bd->shaped_input = 1;
9980 if (!bd->bordername)
9981 bd->client.border.changed = 1;
9983 bd->need_shape_merge = 1;
9985 if (bd->client.mwm.fetch.hints)
9989 bd->client.mwm.exists =
9990 ecore_x_mwm_hints_get(bd->client.win,
9991 &bd->client.mwm.func,
9992 &bd->client.mwm.decor,
9993 &bd->client.mwm.input);
9994 pb = bd->client.mwm.borderless;
9995 bd->client.mwm.borderless = 0;
9996 if (bd->client.mwm.exists)
9998 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
9999 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
10000 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
10001 bd->client.mwm.borderless = 1;
10003 if (bd->client.mwm.borderless != pb)
10005 if ((!bd->lock_border) || (!bd->client.border.name))
10006 bd->client.border.changed = 1;
10008 bd->client.mwm.fetch.hints = 0;
10011 if (bd->client.e.fetch.video_parent)
10013 /* unlinking child/parent */
10014 if (bd->client.e.state.video_parent_border != NULL)
10016 bd->client.e.state.video_parent_border->client.e.state.video_child =
10018 (bd->client.e.state.video_parent_border->client.e.state.video_child,
10022 ecore_x_window_prop_card32_get(bd->client.win,
10023 ECORE_X_ATOM_E_VIDEO_PARENT,
10024 &bd->client.e.state.video_parent,
10027 /* linking child/parent */
10028 if (bd->client.e.state.video_parent != 0)
10033 EINA_LIST_FOREACH(borders, l, tmp)
10034 if (tmp->client.win == bd->client.e.state.video_parent)
10036 /* fprintf(stderr, "child added to parent \\o/\n"); */
10037 bd->client.e.state.video_parent_border = tmp;
10038 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
10040 if (bd->desk != tmp->desk)
10041 e_border_desk_set(bd, tmp->desk);
10046 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
10048 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
10051 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
10053 unsigned int xy[2];
10055 ecore_x_window_prop_card32_get(bd->client.win,
10056 ECORE_X_ATOM_E_VIDEO_POSITION,
10059 bd->client.e.state.video_position.x = xy[0];
10060 bd->client.e.state.video_position.y = xy[1];
10061 bd->client.e.state.video_position.updated = 1;
10062 bd->client.e.fetch.video_position = 0;
10063 bd->x = bd->client.e.state.video_position.x;
10064 bd->y = bd->client.e.state.video_position.y;
10066 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
10068 if (bd->client.netwm.update.state)
10070 e_hints_window_state_set(bd);
10071 /* Some stats might change the border, like modal */
10072 if (((!bd->lock_border) || (!bd->client.border.name)) &&
10073 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10075 bd->client.border.changed = 1;
10079 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10081 bd->parent->modal = bd;
10082 if (bd->parent->focused)
10083 e_border_focus_set(bd, 1, 1);
10086 else if (bd->leader)
10088 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10090 bd->leader->modal = bd;
10091 if (bd->leader->focused)
10092 e_border_focus_set(bd, 1, 1);
10098 EINA_LIST_FOREACH(bd->leader->group, l, child)
10100 if ((child != bd) && (child->focused))
10101 e_border_focus_set(bd, 1, 1);
10106 bd->client.netwm.update.state = 0;
10109 if (bd->new_client)
10111 E_Event_Border_Add *ev;
10112 E_Exec_Instance *inst;
10114 ev = E_NEW(E_Event_Border_Add, 1);
10116 e_object_ref(E_OBJECT(bd));
10117 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
10118 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
10120 if ((!bd->lock_border) || (!bd->client.border.name))
10121 bd->client.border.changed = 1;
10126 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
10127 ((bd->client.icccm.client_leader > 0) &&
10128 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10131 if (!strncmp(str, "E_START|", 8))
10135 id = atoi(str + 8);
10136 if (id > 0) bd->client.netwm.startup_id = id;
10141 /* It's ok not to have fetch flag, should only be set on startup
10142 * * and not changed. */
10143 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10145 if (bd->client.icccm.client_leader)
10147 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10148 bd->client.netwm.pid = -1;
10151 bd->client.netwm.pid = -1;
10154 if (!bd->re_manage)
10156 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10157 bd->client.netwm.pid);
10158 if ((inst) && (inst->used == 0))
10164 zone = e_container_zone_number_get(bd->zone->container,
10166 if (zone) e_border_zone_set(bd, zone);
10167 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10169 if (desk) e_border_desk_set(bd, desk);
10170 e_exec_instance_found(inst);
10173 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10175 E_Border *bdl = NULL;
10180 if (bd->leader) bdl = bd->leader;
10187 bl = e_container_border_list_first(bd->zone->container);
10188 while ((child = e_container_border_list_next(bl)))
10190 if (child == bd) continue;
10191 if (e_object_is_del(E_OBJECT(child))) continue;
10192 if ((bd->client.icccm.client_leader) &&
10193 (child->client.icccm.client_leader ==
10194 bd->client.icccm.client_leader))
10200 e_container_border_list_free(bl);
10205 e_border_zone_set(bd, bdl->zone);
10207 e_border_desk_set(bd, bdl->desk);
10209 e_border_stick(bd);
10215 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10218 E_Container *con = bd->zone->container;
10219 E_Desk *desk = NULL;
10222 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10224 desk = e_container_desk_window_profile_get(con, str);
10227 if (bd->desk != desk)
10229 bd->client.e.state.profile = eina_stringshare_add(str);
10230 if (bd->zone != desk->zone)
10231 e_border_zone_set(bd, desk->zone);
10232 e_border_desk_set(bd, desk);
10240 /* PRE_POST_FETCH calls e_remember apply for new client */
10241 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10242 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10243 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10245 #ifdef _F_ZONE_WINDOW_ROTATION_
10246 if (e_config->wm_win_rotation)
10248 if (need_rotation_set)
10250 Eina_Bool hint = EINA_FALSE;
10252 int x, y, w, h, move;
10254 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10255 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10257 if (bd->client.e.state.rot.changes != -1)
10259 ang = bd->client.e.state.rot.changes;
10262 else ang = bd->client.e.state.rot.curr;
10264 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10267 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10268 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10269 bd->client.icccm.name, x, y, w, h);
10275 if (bd->need_reparent)
10278 ecore_x_window_save_set_add(bd->client.win);
10279 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10282 if ((bd->new_client) && (bd->internal) &&
10283 (bd->internal_ecore_evas))
10284 ecore_evas_show(bd->internal_ecore_evas);
10285 ecore_x_window_show(bd->client.win);
10287 bd->need_reparent = 0;
10290 if ((bd->client.border.changed) && (!bd->shaded) &&
10291 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10293 const char *bordername;
10295 if (bd->fullscreen)
10296 bordername = "borderless";
10297 else if (bd->bordername)
10298 bordername = bd->bordername;
10299 else if ((bd->client.mwm.borderless) || (bd->borderless))
10300 bordername = "borderless";
10301 else if (((bd->client.icccm.transient_for != 0) ||
10302 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10303 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10304 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10305 bordername = "noresize_dialog";
10306 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10307 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10308 bordername = "noresize";
10309 else if (bd->client.shaped)
10310 bordername = "shaped";
10311 else if ((!bd->client.icccm.accepts_focus) &&
10312 (!bd->client.icccm.take_focus))
10313 bordername = "nofocus";
10314 else if (bd->client.icccm.urgent)
10315 bordername = "urgent";
10316 else if ((bd->client.icccm.transient_for != 0) ||
10317 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10318 bordername = "dialog";
10319 else if (bd->client.netwm.state.modal)
10320 bordername = "modal";
10321 else if ((bd->client.netwm.state.skip_taskbar) ||
10322 (bd->client.netwm.state.skip_pager))
10323 bordername = "skipped";
10324 else if ((bd->internal) && (bd->client.icccm.class) &&
10325 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10326 bordername = "internal_fileman";
10328 bordername = e_config->theme_default_border_style;
10329 if (!bordername) bordername = "default";
10331 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10337 bd->changes.border = 1;
10338 eina_stringshare_replace(&bd->client.border.name, bordername);
10342 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10343 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10344 bd->changes.size = 1;
10345 evas_object_del(bd->bg_object);
10347 o = edje_object_add(bd->bg_evas);
10348 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10349 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10350 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10352 if (bd->client.border.name != e_config->theme_default_border_style)
10354 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10355 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10359 ok = e_theme_edje_object_set(o, "base/theme/borders",
10360 "e/widgets/border/default/border");
10363 /* Reset default border style to default */
10364 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10365 e_config_save_queue();
10373 const char *shape_option, *argb_option;
10378 if ((e_config->use_composite) && (!bd->client.argb))
10380 argb_option = edje_object_data_get(o, "argb");
10381 if ((argb_option) && (!strcmp(argb_option, "1")))
10384 if (use_argb != bd->argb)
10385 _e_border_frame_replace(bd, use_argb);
10392 shape_option = edje_object_data_get(o, "shaped");
10393 if ((shape_option) && (!strcmp(shape_option, "1")))
10397 if (bd->client.netwm.name)
10398 edje_object_part_text_set(o, "e.text.title",
10399 bd->client.netwm.name);
10400 else if (bd->client.icccm.title)
10401 edje_object_part_text_set(o, "e.text.title",
10402 bd->client.icccm.title);
10406 evas_object_del(o);
10407 bd->bg_object = NULL;
10410 _e_border_client_inset_calc(bd);
10412 bd->w += (bd->client_inset.l + bd->client_inset.r);
10413 bd->h += (bd->client_inset.t + bd->client_inset.b);
10414 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10415 bd->changes.size = 1;
10416 /* really needed ? */
10417 ecore_x_window_move(bd->client.shell_win,
10418 bd->client_inset.l,
10419 bd->client_inset.t);
10421 if (bd->maximized != E_MAXIMIZE_NONE)
10423 E_Maximize maximized = bd->maximized;
10425 /* to force possible resizes */
10426 bd->maximized = E_MAXIMIZE_NONE;
10428 _e_border_maximize(bd, maximized);
10430 /* restore maximized state */
10431 bd->maximized = maximized;
10433 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10434 bd->maximized & E_MAXIMIZE_VERTICAL);
10438 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10439 _e_border_cb_signal_bind, bd);
10442 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10443 if (bd->icon_object)
10444 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10447 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10449 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10451 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10452 // FIXME: in eval -do differently
10453 // edje_object_message_signal_process(bd->bg_object);
10454 // e_border_frame_recalc(bd);
10456 evas_object_move(bd->bg_object, 0, 0);
10457 evas_object_resize(bd->bg_object, bd->w, bd->h);
10458 evas_object_show(bd->bg_object);
10461 bd->client.border.changed = 0;
10463 if (bd->icon_object)
10467 evas_object_show(bd->icon_object);
10468 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10471 evas_object_hide(bd->icon_object);
10475 if (rem_change) e_remember_update(bd);
10479 E_Event_Border_Urgent_Change *ev;
10481 if (bd->client.icccm.urgent)
10482 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10484 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10486 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10488 e_object_ref(E_OBJECT(bd));
10489 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10490 _e_border_event_border_urgent_change_free, NULL);
10493 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10496 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10498 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10500 E_Border* temp_bd = NULL;
10501 E_Border* top_focusable_bd = NULL;
10502 Eina_Bool is_fully_obscured = EINA_FALSE;
10503 Ecore_X_XRegion *visible_region = NULL;
10504 Ecore_X_XRegion *win_region = NULL;
10505 Ecore_X_Rectangle visible_rect, win_rect;
10508 // set the entire visible region as a root geometry
10509 visible_rect.x = bd->zone->x;
10510 visible_rect.y = bd->zone->y;
10511 visible_rect.width = bd->zone->w;
10512 visible_rect.height = bd->zone->h;
10514 visible_region = ecore_x_xregion_new();
10515 if (!visible_region) return;
10517 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10519 bl = e_container_border_list_last(bd->zone->container);
10520 while ((temp_bd = e_container_border_list_prev(bl)))
10522 if (temp_bd == bd) break;
10524 if (temp_bd == focused) continue;
10525 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10526 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10527 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10528 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10529 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10530 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10531 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10532 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10533 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10535 if (!top_focusable_bd)
10537 top_focusable_bd = temp_bd;
10540 win_rect.x = temp_bd->x;
10541 win_rect.y = temp_bd->y;
10542 win_rect.width = temp_bd->w;
10543 win_rect.height = temp_bd->h;
10545 // if it stick out or is bigger than the entire visible region,
10546 // clip it by the entire visible's geometry.
10547 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10548 win_rect.width, win_rect.height,
10549 visible_rect.x, visible_rect.y,
10550 (int)(visible_rect.width), (int)(visible_rect.height));
10552 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10554 win_region = ecore_x_xregion_new();
10557 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10558 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10559 ecore_x_xregion_free(win_region);
10562 if (ecore_x_xregion_is_empty(visible_region))
10564 is_fully_obscured = EINA_TRUE;
10572 if (is_fully_obscured == EINA_TRUE)
10574 e_border_focus_set(top_focusable_bd, 1, 1);
10578 e_border_focus_set(bd, 1, 1);
10581 if (visible_region) ecore_x_xregion_free(visible_region);
10582 e_container_border_list_free(bl);
10586 _e_border_latest_stacked_focus(E_Border *bd)
10589 int root_w, root_h;
10591 root_w = bd->zone->w;
10592 root_h = bd->zone->h;
10595 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10597 if (bd == temp_bd) continue;
10598 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10599 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10601 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10602 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10603 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10604 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10605 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10606 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10607 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10609 _e_border_latest_stacked_focus_check_set(temp_bd);
10616 _e_border_check_stack (E_Border *bd)
10618 E_Border* temp_bd = NULL;
10619 E_Border* top_bd = NULL;
10620 int passed_focus = 0;
10622 int root_w = bd->zone->w;
10623 int root_h = bd->zone->h;
10626 bl = e_container_border_list_last(bd->zone->container);
10627 while ((temp_bd = e_container_border_list_prev(bl)))
10629 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10630 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10631 if ((temp_bd != bd) &&
10632 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10634 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10635 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10636 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10637 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10638 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10639 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10640 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10646 e_border_focus_set_with_pointer(bd);
10653 e_border_focus_set_with_pointer(top_bd);
10662 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10664 if (!bd->lock_focus_out)
10666 e_border_focus_latest_set(bd);
10678 if (temp_bd == focused)
10684 e_container_border_list_free(bl);
10688 _e_border_focus_top_stack_set(E_Border* bd)
10691 int root_w, root_h;
10693 root_w = bd->zone->w;
10694 root_h = bd->zone->h;
10697 bl = e_container_border_list_last(bd->zone->container);
10698 while ((temp_bd = e_container_border_list_prev(bl)))
10700 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10701 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10702 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10704 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10705 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10706 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10707 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10708 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10709 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10710 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10712 if (!temp_bd->focused)
10714 /* this border is the top of the latest stack */
10715 e_border_focus_set (temp_bd, 1, 1);
10720 e_container_border_list_free(bl);
10725 _e_border_eval(E_Border *bd)
10727 E_Event_Border_Property *event;
10728 E_Border_Pending_Move_Resize *pnd;
10729 int rem_change = 0;
10730 int send_event = 1;
10732 if (e_object_is_del(E_OBJECT(bd)))
10734 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10739 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10741 if (bd->new_client)
10743 int zx = 0, zy = 0, zw = 0, zh = 0;
10746 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10749 * Limit maximum size of windows to useful geometry
10751 // TODO: temoporary limited maximize algorithm
10763 if ((rw != bd->w) || (rh != bd->h))
10767 e_border_resize (bd, bd->w, bd->h);
10773 bd->x -= bd->client_inset.l;
10774 bd->y -= bd->client_inset.t;
10775 bd->changes.pos = 1;
10778 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10781 Ecore_X_Window_Attributes *att;
10784 att = &bd->client.initial_attributes;
10785 bw = att->border * 2;
10786 switch (bd->client.icccm.gravity)
10788 case ECORE_X_GRAVITY_N:
10789 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10793 case ECORE_X_GRAVITY_NE:
10794 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10798 case ECORE_X_GRAVITY_E:
10799 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10800 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10803 case ECORE_X_GRAVITY_SE:
10804 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10805 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10808 case ECORE_X_GRAVITY_S:
10809 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10810 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10813 case ECORE_X_GRAVITY_SW:
10815 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10818 case ECORE_X_GRAVITY_W:
10820 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10823 case ECORE_X_GRAVITY_CENTER:
10824 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10825 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10828 case ECORE_X_GRAVITY_NW:
10835 * This ensures that windows that like to open with a x/y
10836 * position smaller than returned by e_zone_useful_geometry_get()
10837 * are moved to useful positions.
10840 if (e_config->geometry_auto_move)
10848 if (bd->x + bd->w > zx + zw)
10849 bd->x = zx + zw - bd->w;
10851 if (bd->y + bd->h > zy + zh)
10852 bd->y = zy + zh - bd->h;
10855 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10857 bd->changes.pos = 1;
10863 bd->changes.pos = 1;
10869 /* FIXME: special placement for dialogs etc. etc. etc goes
10871 /* FIXME: what if parent is not on this desktop - or zone? */
10872 if ((bd->parent) && (bd->parent->visible))
10874 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10875 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10876 bd->changes.pos = 1;
10880 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10882 /* TODO: Place in center of group */
10885 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10887 bd->x = zx + ((zw - bd->w) / 2);
10888 bd->y = zy + ((zh - bd->h) / 2);
10889 bd->changes.pos = 1;
10895 Eina_List *skiplist = NULL;
10899 new_x = zx + (rand() % (zw - bd->w));
10903 new_y = zy + (rand() % (zh - bd->h));
10907 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10909 skiplist = eina_list_append(skiplist, bd);
10911 e_place_desk_region_smart(bd->desk, skiplist,
10912 bd->x, bd->y, bd->w, bd->h,
10915 e_place_zone_region_smart(bd->zone, skiplist,
10916 bd->x, bd->y, bd->w, bd->h,
10918 eina_list_free(skiplist);
10920 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10922 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10927 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10928 bd->client_inset.t, &new_x, &new_y);
10932 bd->changes.pos = 1;
10935 EINA_LIST_FREE(bd->pending_move_resize, pnd)
10937 if ((!bd->lock_client_location) && (pnd->move))
10941 bd->changes.pos = 1;
10943 if (pnd->without_border)
10945 bd->x -= bd->client_inset.l;
10946 bd->y -= bd->client_inset.t;
10949 if ((!bd->lock_client_size) && (pnd->resize))
10951 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
10952 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
10953 bd->client.w = pnd->w;
10954 bd->client.h = pnd->h;
10955 bd->changes.size = 1;
10961 /* Recreate state */
10962 e_hints_window_init(bd);
10963 if ((bd->client.e.state.centered) &&
10964 ((!bd->remember) ||
10965 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
10967 bd->x = zx + (zw - bd->w) / 2;
10968 bd->y = zy + (zh - bd->h) / 2;
10969 bd->changes.pos = 1;
10973 _e_border_client_move_resize_send(bd);
10975 /* if the explicit geometry request asks for the app to be
10976 * in another zone - well move it there */
10980 zone = e_container_zone_at_point_get(bd->zone->container,
10981 bd->x + (bd->w / 2),
10982 bd->y + (bd->h / 2));
10984 zone = e_container_zone_at_point_get(bd->zone->container,
10988 zone = e_container_zone_at_point_get(bd->zone->container,
10992 zone = e_container_zone_at_point_get(bd->zone->container,
10994 bd->y + bd->h - 1);
10996 zone = e_container_zone_at_point_get(bd->zone->container,
10998 bd->y + bd->h - 1);
10999 if ((zone) && (zone != bd->zone))
11000 e_border_zone_set(bd, zone);
11004 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
11006 /* effect changes to the window border itself */
11007 if ((bd->changes.shading))
11009 /* show at start of unshade (but don't hide until end of shade) */
11011 ecore_x_window_raise(bd->client.shell_win);
11012 bd->changes.shading = 0;
11015 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
11018 ecore_x_window_lower(bd->client.shell_win);
11020 ecore_x_window_raise(bd->client.shell_win);
11021 bd->changes.shaded = 0;
11024 else if ((bd->changes.shaded) && (bd->changes.pos))
11027 ecore_x_window_lower(bd->client.shell_win);
11029 ecore_x_window_raise(bd->client.shell_win);
11030 bd->changes.size = 1;
11031 bd->changes.shaded = 0;
11034 else if ((bd->changes.shaded) && (bd->changes.size))
11037 ecore_x_window_lower(bd->client.shell_win);
11039 ecore_x_window_raise(bd->client.shell_win);
11040 bd->changes.shaded = 0;
11043 else if (bd->changes.shaded)
11046 ecore_x_window_lower(bd->client.shell_win);
11048 ecore_x_window_raise(bd->client.shell_win);
11049 bd->changes.size = 1;
11050 bd->changes.shaded = 0;
11054 if (bd->changes.size)
11056 int x = 0, y = 0, xx = 0, yy = 0;
11058 if ((bd->shaded) && (!bd->shading))
11060 evas_obscured_clear(bd->bg_evas);
11064 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
11065 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
11067 evas_obscured_clear(bd->bg_evas);
11068 evas_obscured_rectangle_add(bd->bg_evas,
11069 bd->client_inset.l, bd->client_inset.t, xx, yy);
11073 if (bd->shade.dir == E_DIRECTION_UP)
11075 y = yy - bd->client.h;
11077 else if (bd->shade.dir == E_DIRECTION_LEFT)
11079 x = xx - bd->client.w;
11084 if (bd->client.e.state.video)
11086 if (bd->client.e.state.video_position.updated)
11088 ecore_x_window_move(bd->win,
11089 bd->client.e.state.video_parent_border->x +
11090 bd->client.e.state.video_parent_border->client_inset.l +
11091 bd->client.e.state.video_parent_border->fx.x +
11092 bd->client.e.state.video_position.x,
11093 bd->client.e.state.video_parent_border->y +
11094 bd->client.e.state.video_parent_border->client_inset.t +
11095 bd->client.e.state.video_parent_border->fx.y +
11096 bd->client.e.state.video_position.y);
11097 bd->client.e.state.video_position.updated = 0;
11100 else if (!bd->changes.pos)
11102 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11103 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11104 bd->post_resize = 1;
11111 ecore_x_window_move_resize(bd->win,
11116 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
11117 ecore_x_window_move(tmp->win,
11118 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
11119 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
11122 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
11124 if ((!bd->shaded) || (bd->shading))
11125 ecore_x_window_move_resize(bd->client.shell_win,
11126 bd->client_inset.l, bd->client_inset.t, xx, yy);
11128 if (bd->internal_ecore_evas)
11129 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
11130 else if (!bd->client.e.state.video)
11131 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11133 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11134 evas_object_resize(bd->bg_object, bd->w, bd->h);
11135 e_container_shape_resize(bd->shape, bd->w, bd->h);
11136 if (bd->changes.pos)
11137 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11139 _e_border_client_move_resize_send(bd);
11141 bd->changes.pos = 0;
11142 bd->changes.size = 0;
11145 else if (bd->changes.pos)
11147 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11148 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11151 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11153 _e_border_client_move_resize_send(bd);
11155 bd->changes.pos = 0;
11159 if (bd->changes.reset_gravity)
11161 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11162 bd->changes.reset_gravity = 0;
11166 if (bd->need_shape_merge)
11168 _e_border_shape_input_rectangle_set(bd);
11169 if ((bd->shaped) || (bd->client.shaped))
11171 Ecore_X_Window twin, twin2;
11174 twin = ecore_x_window_override_new
11175 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11177 ecore_x_window_shape_window_set(twin, bd->bg_win);
11180 Ecore_X_Rectangle rects[4];
11184 rects[0].width = bd->w;
11185 rects[0].height = bd->client_inset.t;
11187 rects[1].y = bd->client_inset.t;
11188 rects[1].width = bd->client_inset.l;
11189 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11190 rects[2].x = bd->w - bd->client_inset.r;
11191 rects[2].y = bd->client_inset.t;
11192 rects[2].width = bd->client_inset.r;
11193 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11195 rects[3].y = bd->h - bd->client_inset.b;
11196 rects[3].width = bd->w;
11197 rects[3].height = bd->client_inset.b;
11198 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11200 twin2 = ecore_x_window_override_new
11201 (bd->zone->container->scratch_win, 0, 0,
11202 bd->w - bd->client_inset.l - bd->client_inset.r,
11203 bd->h - bd->client_inset.t - bd->client_inset.b);
11206 if ((bd->shading) || (bd->shaded))
11208 if (bd->shade.dir == E_DIRECTION_UP)
11209 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11210 else if (bd->shade.dir == E_DIRECTION_LEFT)
11211 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11213 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11215 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11216 bd->w - bd->client_inset.l - bd->client_inset.r,
11217 bd->h - bd->client_inset.t - bd->client_inset.b);
11218 ecore_x_window_shape_window_add_xy(twin, twin2,
11219 bd->client_inset.l,
11220 bd->client_inset.t);
11221 ecore_x_window_free(twin2);
11222 ecore_x_window_shape_window_set(bd->win, twin);
11223 ecore_x_window_free(twin);
11226 ecore_x_window_shape_mask_set(bd->win, 0);
11227 // bd->need_shape_export = 1;
11228 bd->need_shape_merge = 0;
11231 if (bd->need_shape_export)
11233 Ecore_X_Rectangle *rects, *orects;
11236 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11242 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11246 orects = bd->shape_rects;
11248 for (i = 0; i < num; i++)
11250 if (rects[i].x < 0)
11252 rects[i].width -= rects[i].x;
11255 if ((rects[i].x + (int)rects[i].width) > bd->w)
11256 rects[i].width = rects[i].width - rects[i].x;
11257 if (rects[i].y < 0)
11259 rects[i].height -= rects[i].y;
11262 if ((rects[i].y + (int)rects[i].height) > bd->h)
11263 rects[i].height = rects[i].height - rects[i].y;
11265 if ((orects[i].x != rects[i].x) ||
11266 (orects[i].y != rects[i].y) ||
11267 (orects[i].width != rects[i].width) ||
11268 (orects[i].height != rects[i].height))
11277 if (bd->client.shaped)
11278 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11280 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11281 E_FREE(bd->shape_rects);
11282 bd->shape_rects = rects;
11283 bd->shape_rects_num = num;
11284 e_container_shape_rects_set(bd->shape, rects, num);
11291 E_FREE(bd->shape_rects);
11292 bd->shape_rects = NULL;
11293 bd->shape_rects_num = 0;
11294 e_container_shape_rects_set(bd->shape, NULL, 0);
11296 bd->need_shape_export = 0;
11299 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11303 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11304 if ((!bd->placed) && (!bd->re_manage) &&
11305 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11306 (!((bd->client.icccm.transient_for != 0) ||
11307 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11308 (!bdmove) && (!bdresize))
11310 /* Set this window into moving state */
11312 bd->cur_mouse_action = e_action_find("window_move");
11313 if (bd->cur_mouse_action)
11315 if ((!bd->cur_mouse_action->func.end_mouse) &&
11316 (!bd->cur_mouse_action->func.end))
11317 bd->cur_mouse_action = NULL;
11318 if (bd->cur_mouse_action)
11320 bd->x = x - (bd->w >> 1);
11321 bd->y = y - (bd->client_inset.t >> 1);
11323 bd->changes.pos = 1;
11325 _e_border_client_move_resize_send(bd);
11330 _e_border_show(bd);
11332 if (bd->cur_mouse_action)
11334 bd->moveinfo.down.x = bd->x + bd->fx.x;
11335 bd->moveinfo.down.y = bd->y + bd->fx.y;
11336 bd->moveinfo.down.w = bd->w;
11337 bd->moveinfo.down.h = bd->h;
11338 bd->mouse.current.mx = x;
11339 bd->mouse.current.my = y;
11340 bd->moveinfo.down.button = 0;
11341 bd->moveinfo.down.mx = x;
11342 bd->moveinfo.down.my = y;
11345 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11346 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11347 if (e_config->border_raise_on_mouse_action)
11348 e_border_raise(bd);
11349 e_border_focus_set(bd, 1, 1);
11351 bd->changes.visible = 0;
11355 if (bd->changes.icon)
11359 efreet_desktop_free(bd->desktop);
11360 bd->desktop = NULL;
11362 if (bd->icon_object)
11364 evas_object_del(bd->icon_object);
11365 bd->icon_object = NULL;
11367 if (bd->remember && bd->remember->prop.desktop_file)
11369 const char *desktop = bd->remember->prop.desktop_file;
11371 bd->desktop = efreet_desktop_get(desktop);
11373 bd->desktop = efreet_util_desktop_name_find(desktop);
11377 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11378 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11379 bd->client.icccm.class);
11383 /* libreoffice and maybe others match window class
11384 with .desktop file name */
11385 if (bd->client.icccm.class)
11388 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11389 bd->desktop = efreet_util_desktop_file_id_find(buf);
11394 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11395 bd->client.netwm.pid);
11396 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11398 if (!bd->desktop && bd->client.icccm.name)
11400 /* this works for most cases as fallback. useful when app is
11401 run from a shell */
11402 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11404 if (!bd->desktop && bd->client.icccm.transient_for)
11406 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11407 if (bd2 && bd2->desktop)
11409 efreet_desktop_ref(bd2->desktop);
11410 bd->desktop = bd2->desktop;
11415 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11416 bd->desktop->orig_path);
11419 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11420 if ((bd->focused) && (bd->icon_object))
11421 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11424 evas_object_show(bd->icon_object);
11425 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11428 evas_object_hide(bd->icon_object);
11431 E_Event_Border_Icon_Change *ev;
11433 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11435 e_object_ref(E_OBJECT(bd));
11436 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11437 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11438 _e_border_event_border_icon_change_free, NULL);
11440 bd->changes.icon = 0;
11443 bd->new_client = 0;
11445 bd->changes.stack = 0;
11446 bd->changes.prop = 0;
11448 if (bd->client.e.state.rot.changes != -1)
11450 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11451 bd->client.e.state.rot.changes = -1;
11454 if ((bd->take_focus) || (bd->want_focus))
11456 bd->take_focus = 0;
11457 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11458 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11459 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11462 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11465 bd->want_focus = 0;
11466 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11467 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11468 _e_border_check_stack(bd);
11471 e_border_focus_set_with_pointer(bd);
11473 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11475 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11476 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11477 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11478 e_border_focused_get())))
11480 e_border_focus_set_with_pointer(bd);
11485 /* focus window by default when it is the only one on desk */
11486 E_Border *bd2 = NULL;
11488 EINA_LIST_FOREACH(focus_stack, l, bd2)
11490 if (bd == bd2) continue;
11491 if ((!bd2->iconic) && (bd2->visible) &&
11492 ((bd->desk == bd2->desk) || bd2->sticky))
11498 e_border_focus_set_with_pointer(bd);
11503 if (bd->need_maximize)
11506 max = bd->maximized;
11507 bd->maximized = E_MAXIMIZE_NONE;
11508 e_border_maximize(bd, max);
11509 bd->need_maximize = 0;
11512 if (bd->need_fullscreen)
11514 e_border_fullscreen(bd, e_config->fullscreen_policy);
11515 bd->need_fullscreen = 0;
11519 e_remember_update(bd);
11521 if (send_event) // FIXME: send only if a property changed - above need to
11522 { // check on that. for now - always send.
11523 event = E_NEW(E_Event_Border_Property, 1);
11524 event->border = bd;
11525 e_object_ref(E_OBJECT(bd));
11526 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11528 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11532 _e_border_moveinfo_gather(E_Border *bd,
11533 const char *source)
11535 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11536 else if (e_util_glob_match(source, "mouse,*,2"))
11537 bd->moveinfo.down.button = 2;
11538 else if (e_util_glob_match(source, "mouse,*,3"))
11539 bd->moveinfo.down.button = 3;
11540 else bd->moveinfo.down.button = 0;
11541 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11543 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11544 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11548 bd->moveinfo.down.mx = bd->mouse.current.mx;
11549 bd->moveinfo.down.my = bd->mouse.current.my;
11554 _e_border_resize_handle(E_Border *bd)
11557 int new_x, new_y, new_w, new_h;
11559 Eina_List *skiplist = NULL;
11566 if ((bd->resize_mode == RESIZE_TR) ||
11567 (bd->resize_mode == RESIZE_R) ||
11568 (bd->resize_mode == RESIZE_BR))
11570 if ((bd->moveinfo.down.button >= 1) &&
11571 (bd->moveinfo.down.button <= 3))
11572 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11573 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11575 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11577 else if ((bd->resize_mode == RESIZE_TL) ||
11578 (bd->resize_mode == RESIZE_L) ||
11579 (bd->resize_mode == RESIZE_BL))
11581 if ((bd->moveinfo.down.button >= 1) &&
11582 (bd->moveinfo.down.button <= 3))
11583 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11584 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11586 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11589 if ((bd->resize_mode == RESIZE_TL) ||
11590 (bd->resize_mode == RESIZE_T) ||
11591 (bd->resize_mode == RESIZE_TR))
11593 if ((bd->moveinfo.down.button >= 1) &&
11594 (bd->moveinfo.down.button <= 3))
11595 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11596 (bd->mouse.current.my - bd->moveinfo.down.my);
11598 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11600 else if ((bd->resize_mode == RESIZE_BL) ||
11601 (bd->resize_mode == RESIZE_B) ||
11602 (bd->resize_mode == RESIZE_BR))
11604 if ((bd->moveinfo.down.button >= 1) &&
11605 (bd->moveinfo.down.button <= 3))
11606 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11607 (bd->mouse.current.my - bd->moveinfo.down.my);
11609 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11615 if ((bd->resize_mode == RESIZE_TL) ||
11616 (bd->resize_mode == RESIZE_L) ||
11617 (bd->resize_mode == RESIZE_BL))
11619 if ((bd->resize_mode == RESIZE_TL) ||
11620 (bd->resize_mode == RESIZE_T) ||
11621 (bd->resize_mode == RESIZE_TR))
11624 skiplist = eina_list_append(skiplist, bd);
11625 e_resist_container_border_position(bd->zone->container, skiplist,
11626 bd->x, bd->y, bd->w, bd->h,
11628 &new_x, &new_y, &new_w, &new_h);
11629 eina_list_free(skiplist);
11633 e_border_resize_limit(bd, &new_w, &new_h);
11634 if ((bd->resize_mode == RESIZE_TL) ||
11635 (bd->resize_mode == RESIZE_L) ||
11636 (bd->resize_mode == RESIZE_BL))
11637 new_x += (w - new_w);
11638 if ((bd->resize_mode == RESIZE_TL) ||
11639 (bd->resize_mode == RESIZE_T) ||
11640 (bd->resize_mode == RESIZE_TR))
11641 new_y += (h - new_h);
11643 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11647 _e_border_shade_animator(void *data)
11649 E_Border *bd = data;
11651 double dur = bd->client.h / e_config->border_shade_speed;
11653 dt = ecore_loop_time_get() - bd->shade.start;
11656 if (val < 0.0) val = 0.0;
11657 else if (val > 1.0) val = 1.0;
11659 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11662 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11663 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11665 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11668 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11669 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11671 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11674 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11675 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11677 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11680 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11681 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11683 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11686 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11687 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11689 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11692 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11693 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11695 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11698 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11699 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11701 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11704 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11705 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11707 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11710 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11711 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11716 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11717 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11720 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11721 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11722 else if (bd->shade.val > .999)
11723 bd->shade.val = 1.0;
11725 if (bd->shade.dir == E_DIRECTION_UP)
11726 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11727 else if (bd->shade.dir == E_DIRECTION_DOWN)
11729 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11730 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11731 bd->changes.pos = 1;
11733 else if (bd->shade.dir == E_DIRECTION_LEFT)
11734 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11735 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11737 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11738 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11739 bd->changes.pos = 1;
11742 if ((bd->shaped) || (bd->client.shaped))
11744 bd->need_shape_merge = 1;
11745 bd->need_shape_export = 1;
11747 if (bd->shaped_input)
11749 bd->need_shape_merge = 1;
11751 bd->changes.size = 1;
11757 E_Event_Border_Resize *ev;
11760 bd->shaded = !(bd->shaded);
11761 bd->changes.size = 1;
11762 bd->changes.shaded = 1;
11763 bd->changes.shading = 1;
11765 bd->shade.anim = NULL;
11768 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11770 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11771 edje_object_message_signal_process(bd->bg_object);
11772 e_border_frame_recalc(bd);
11774 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11775 ev = E_NEW(E_Event_Border_Resize, 1);
11777 e_object_ref(E_OBJECT(bd));
11778 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11779 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11780 return ECORE_CALLBACK_CANCEL;
11782 return ECORE_CALLBACK_RENEW;
11786 _e_border_event_border_resize_free(void *data __UNUSED__,
11789 E_Event_Border_Resize *e;
11792 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11793 e_object_unref(E_OBJECT(e->border));
11798 _e_border_event_border_move_free(void *data __UNUSED__,
11801 E_Event_Border_Move *e;
11804 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11805 e_object_unref(E_OBJECT(e->border));
11810 _e_border_event_border_add_free(void *data __UNUSED__,
11813 E_Event_Border_Add *e;
11816 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11817 e_object_unref(E_OBJECT(e->border));
11822 _e_border_event_border_remove_free(void *data __UNUSED__,
11825 E_Event_Border_Remove *e;
11828 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11829 e_object_unref(E_OBJECT(e->border));
11834 _e_border_event_border_show_free(void *data __UNUSED__,
11837 E_Event_Border_Show *e;
11840 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11841 e_object_unref(E_OBJECT(e->border));
11846 _e_border_event_border_hide_free(void *data __UNUSED__,
11849 E_Event_Border_Hide *e;
11852 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11853 e_object_unref(E_OBJECT(e->border));
11858 _e_border_event_border_iconify_free(void *data __UNUSED__,
11861 E_Event_Border_Iconify *e;
11864 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11865 e_object_unref(E_OBJECT(e->border));
11870 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11873 E_Event_Border_Uniconify *e;
11876 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11877 e_object_unref(E_OBJECT(e->border));
11882 _e_border_event_border_stick_free(void *data __UNUSED__,
11885 E_Event_Border_Stick *e;
11888 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11889 e_object_unref(E_OBJECT(e->border));
11894 _e_border_event_border_unstick_free(void *data __UNUSED__,
11897 E_Event_Border_Unstick *e;
11900 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11901 e_object_unref(E_OBJECT(e->border));
11906 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11909 E_Event_Border_Zone_Set *e;
11912 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11913 e_object_unref(E_OBJECT(e->border));
11914 e_object_unref(E_OBJECT(e->zone));
11919 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11922 E_Event_Border_Desk_Set *e;
11925 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11926 e_object_unref(E_OBJECT(e->border));
11927 e_object_unref(E_OBJECT(e->desk));
11932 _e_border_event_border_stack_free(void *data __UNUSED__,
11935 E_Event_Border_Stack *e;
11938 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
11939 e_object_unref(E_OBJECT(e->border));
11942 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
11943 e_object_unref(E_OBJECT(e->stack));
11949 _e_border_event_border_icon_change_free(void *data __UNUSED__,
11952 E_Event_Border_Icon_Change *e;
11955 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
11956 e_object_unref(E_OBJECT(e->border));
11961 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
11964 E_Event_Border_Urgent_Change *e;
11967 e_object_unref(E_OBJECT(e->border));
11972 _e_border_event_border_focus_in_free(void *data __UNUSED__,
11975 E_Event_Border_Focus_In *e;
11978 e_object_unref(E_OBJECT(e->border));
11983 _e_border_event_border_focus_out_free(void *data __UNUSED__,
11986 E_Event_Border_Focus_Out *e;
11989 e_object_unref(E_OBJECT(e->border));
11994 _e_border_event_border_property_free(void *data __UNUSED__,
11997 E_Event_Border_Property *e;
12000 e_object_unref(E_OBJECT(e->border));
12005 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
12008 E_Event_Border_Fullscreen *e;
12011 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
12012 e_object_unref(E_OBJECT(e->border));
12017 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
12020 E_Event_Border_Unfullscreen *e;
12023 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
12024 e_object_unref(E_OBJECT(e->border));
12028 #ifdef _F_ZONE_WINDOW_ROTATION_
12030 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
12033 E_Event_Border_Rotation_Change_Begin *e;
12035 e_object_unref(E_OBJECT(e->border));
12040 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
12043 E_Event_Border_Rotation_Change_Cancel *e;
12045 e_object_unref(E_OBJECT(e->border));
12050 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
12053 E_Event_Border_Rotation_Change_End *e;
12055 e_object_unref(E_OBJECT(e->border));
12060 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
12062 E_Event_Border_Rotation_Change_Begin *ev = NULL;
12063 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
12067 e_object_ref(E_OBJECT(bd));
12068 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
12070 _e_border_event_border_rotation_change_begin_free,
12077 _e_border_zone_update(E_Border *bd)
12083 /* still within old zone - leave it there */
12084 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12085 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
12086 #if _F_BORDER_CLIP_TO_ZONE_
12088 _e_border_shape_input_clip_to_zone(bd);
12093 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12094 /* find a new zone */
12095 con = bd->zone->container;
12096 EINA_LIST_FOREACH(con->zones, l, zone)
12098 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12099 zone->x, zone->y, zone->w, zone->h))
12101 e_border_zone_set(bd, zone);
12102 #if _F_BORDER_CLIP_TO_ZONE_
12103 _e_border_shape_input_clip_to_zone(bd);
12104 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12111 _e_border_resize_begin(E_Border *bd)
12115 if (!bd->lock_user_stacking)
12117 if (e_config->border_raise_on_mouse_action)
12118 e_border_raise(bd);
12120 if ((bd->shaded) || (bd->shading) ||
12121 (bd->fullscreen) || (bd->lock_user_size))
12124 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12125 ret = e_grabinput_get(bd->win, 0, bd->win);
12127 ret = e_grabinput_get(bd->win, 0, 0);
12129 if (grabbed && !ret)
12135 if (bd->client.netwm.sync.request)
12137 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12138 bd->client.netwm.sync.serial = 1;
12139 bd->client.netwm.sync.wait = 0;
12140 bd->client.netwm.sync.send_time = ecore_loop_time_get();
12143 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12150 _e_border_resize_end(E_Border *bd)
12154 e_grabinput_release(bd->win, bd->win);
12157 if (bd->client.netwm.sync.alarm)
12159 E_Border_Pending_Move_Resize *pnd;
12161 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12162 bd->client.netwm.sync.alarm = 0;
12163 /* resize to last geometry if sync alarm for it was not yet handled */
12164 if (bd->pending_move_resize)
12167 bd->changes.pos = 1;
12168 bd->changes.size = 1;
12169 _e_border_client_move_resize_send(bd);
12172 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12176 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12180 /* If this border was maximized, we need to unset Maximized state or
12181 * on restart, E still thinks it's maximized */
12182 if (bd->maximized != E_MAXIMIZE_NONE)
12183 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12184 bd->maximized & E_MAXIMIZE_NONE);
12189 _e_border_resize_update(E_Border *bd)
12191 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12195 _e_border_move_begin(E_Border *bd)
12198 if (!bd->lock_user_stacking)
12200 if (e_config->border_raise_on_mouse_action)
12201 e_border_raise(bd);
12203 if ((bd->fullscreen) || (bd->lock_user_location))
12206 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12207 ret = e_grabinput_get(bd->win, 0, bd->win);
12209 ret = e_grabinput_get(bd->win, 0, 0);
12211 if (grabbed && !ret)
12217 if (bd->client.netwm.sync.request)
12219 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12220 bd->client.netwm.sync.serial = 0;
12221 bd->client.netwm.sync.wait = 0;
12222 bd->client.netwm.sync.time = ecore_loop_time_get();
12225 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12232 _e_border_move_end(E_Border *bd)
12236 e_grabinput_release(bd->win, bd->win);
12240 if (bd->client.netwm.sync.alarm)
12242 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12243 bd->client.netwm.sync.alarm = 0;
12246 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12253 _e_border_move_update(E_Border *bd)
12255 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12259 _e_border_cb_ping_poller(void *data)
12269 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12270 if (bd->kill_timer)
12272 ecore_timer_del(bd->kill_timer);
12273 bd->kill_timer = NULL;
12279 /* if time between last ping and now is greater
12280 * than half the ping interval... */
12281 if ((ecore_loop_time_get() - bd->ping) >
12282 ((e_config->ping_clients_interval *
12283 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12288 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12289 /* FIXME: if below dialog is up - hide it now */
12291 if (bd->delete_requested)
12293 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12294 e_border_act_kill_begin(bd);
12298 bd->ping_poller = NULL;
12300 return ECORE_CALLBACK_CANCEL;
12304 _e_border_cb_kill_timer(void *data)
12309 // dont wait until it's hung -
12312 if (bd->client.netwm.pid > 1)
12313 kill(bd->client.netwm.pid, SIGKILL);
12315 bd->kill_timer = NULL;
12316 return ECORE_CALLBACK_CANCEL;
12320 _e_border_pointer_resize_begin(E_Border *bd)
12322 switch (bd->resize_mode)
12325 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12329 e_pointer_type_push(bd->pointer, bd, "resize_t");
12333 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12337 e_pointer_type_push(bd->pointer, bd, "resize_r");
12341 e_pointer_type_push(bd->pointer, bd, "resize_br");
12345 e_pointer_type_push(bd->pointer, bd, "resize_b");
12349 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12353 e_pointer_type_push(bd->pointer, bd, "resize_l");
12359 _e_border_pointer_resize_end(E_Border *bd)
12361 switch (bd->resize_mode)
12364 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12368 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12372 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12376 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12380 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12384 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12388 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12392 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12398 _e_border_pointer_move_begin(E_Border *bd)
12400 e_pointer_type_push(bd->pointer, bd, "move");
12404 _e_border_pointer_move_end(E_Border *bd)
12406 e_pointer_type_pop(bd->pointer, bd, "move");
12409 static Eina_List *_e_border_hooks = NULL;
12410 static int _e_border_hooks_delete = 0;
12411 static int _e_border_hooks_walking = 0;
12414 _e_border_hooks_clean(void)
12419 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12423 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12430 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12436 _e_border_hooks_walking++;
12437 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12439 if (bh->delete_me) continue;
12440 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12442 _e_border_hooks_walking--;
12443 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12444 _e_border_hooks_clean();
12447 EAPI E_Border_Hook *
12448 e_border_hook_add(E_Border_Hook_Point hookpoint,
12449 void (*func)(void *data,
12455 bh = E_NEW(E_Border_Hook, 1);
12456 if (!bh) return NULL;
12457 bh->hookpoint = hookpoint;
12460 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12465 e_border_hook_del(E_Border_Hook *bh)
12468 if (_e_border_hooks_walking == 0)
12470 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12474 _e_border_hooks_delete++;
12478 e_border_focus_track_freeze(void)
12480 focus_track_frozen++;
12484 e_border_focus_track_thaw(void)
12486 focus_track_frozen--;
12490 e_border_under_pointer_get(E_Desk *desk,
12493 E_Border *bd = NULL, *cbd;
12497 /* We need to ensure that we can get the container window for the
12498 * zone of either the given desk or the desk of the excluded
12499 * window, so return if neither is given */
12501 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12503 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12507 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12509 if (!cbd) continue;
12510 /* If a border was specified which should be excluded from the list
12511 * (because it will be closed shortly for example), skip */
12512 if ((exclude) && (cbd == exclude)) continue;
12513 if ((desk) && (cbd->desk != desk)) continue;
12514 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12516 /* If the layer is higher, the position of the window is higher
12517 * (always on top vs always below) */
12518 if (!bd || (cbd->layer > bd->layer))
12528 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12535 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12536 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12537 (y - warp_y) > 5 || (y - warp_y) < -5)
12539 /* User moved the mouse, so stop warping */
12544 /* We just use the same warp speed as configured
12545 * for the windowlist */
12546 spd = e_config->winlist_warp_speed;
12549 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12550 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12551 if (warp_x == x && warp_y == y)
12553 warp_x = warp_to_x;
12554 warp_y = warp_to_y;
12558 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12559 return ECORE_CALLBACK_RENEW;
12562 ecore_timer_del(warp_timer);
12564 return ECORE_CALLBACK_CANCEL;
12568 e_border_pointer_warp_to_center(E_Border *bd)
12572 /* Do not slide pointer when disabled (probably breaks focus
12573 * on sloppy/mouse focus but requested by users). */
12574 if (!e_config->pointer_slide) return 0;
12575 /* Only warp the pointer if it is not already in the area of
12576 * the given border */
12577 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12578 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12579 (y >= bd->y) && (y <= (bd->y + bd->h)))
12582 warp_to_x = bd->x + (bd->w / 2);
12583 if (warp_to_x < (bd->zone->x + 1))
12584 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12585 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12586 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12588 warp_to_y = bd->y + (bd->h / 2);
12589 if (warp_to_y < (bd->zone->y + 1))
12590 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12591 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12592 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12595 warp_to_win = bd->zone->container->win;
12596 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12598 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12603 e_border_comp_hidden_set(E_Border *bd,
12609 E_OBJECT_CHECK(bd);
12610 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12612 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12615 ecore_x_window_hide(tmp->win);
12617 ecore_x_window_show(tmp->win);
12620 if (bd->comp_hidden == hidden) return;
12622 bd->comp_hidden = hidden;
12624 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12626 ecore_x_composite_window_events_disable(bd->win);
12627 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12631 _e_border_shape_input_rectangle_set(bd);
12632 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12637 e_border_tmp_input_hidden_push(E_Border *bd)
12642 E_OBJECT_CHECK(bd);
12643 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12645 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12646 e_border_tmp_input_hidden_push(tmp);
12648 bd->tmp_input_hidden++;
12649 if (bd->tmp_input_hidden != 1) return;
12651 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12653 ecore_x_composite_window_events_disable(bd->win);
12654 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12658 _e_border_shape_input_rectangle_set(bd);
12659 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12664 e_border_tmp_input_hidden_pop(E_Border *bd)
12669 E_OBJECT_CHECK(bd);
12670 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12672 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12673 e_border_tmp_input_hidden_pop(tmp);
12675 bd->tmp_input_hidden--;
12676 if (bd->tmp_input_hidden != 0) return;
12678 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12680 ecore_x_composite_window_events_disable(bd->win);
12681 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12685 _e_border_shape_input_rectangle_set(bd);
12686 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12691 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12693 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12695 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12696 ((bd->parent->focused) &&
12697 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12702 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12703 e_desk_show(bd->desk);
12705 if (!bd->lock_user_iconify)
12706 e_border_uniconify(bd);
12708 if ((!bd->iconic) && (!bd->sticky))
12709 e_desk_show(bd->desk);
12710 if (!bd->lock_user_stacking) e_border_raise(bd);
12711 if (!bd->lock_focus_out)
12713 /* XXX ooffice does send this request for
12714 config dialogs when the main window gets focus.
12715 causing the pointer to jump back and forth. */
12716 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12717 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12718 ecore_x_pointer_warp(bd->zone->container->win,
12719 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12720 e_border_focus_set(bd, 1, 1);
12724 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/