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 Eina_Bool _e_border_rotation_change_prepare_timeout(void *data);
156 static void _e_border_rotation_change_request(E_Zone *zone);
157 static Eina_Bool _e_border_rotation_change_done_timeout(void *data);
158 static void _e_border_rotation_change_done(void);
159 static Eina_Bool _e_border_rotation_geom_get(E_Border *bd,
167 static Eina_Bool _e_border_rotation_start(E_Zone *zone, Eina_Bool without_vkbd);
168 static void _e_border_rotation_list_remove(E_Border *bd);
169 static Eina_Bool _e_border_rotation_pre_resize(E_Border *bd, int *x, int *y, int *w, int *h);
170 static Eina_Bool _e_border_rotation_check(E_Border *bd);
171 static Eina_Bool _e_border_rotation_zone_check(E_Zone *zone);
172 static Eina_Bool _e_border_rotation_border_check(E_Border *bd, int ang);
173 static Eina_Bool _e_border_rotation_zone_vkbd_check(E_Zone *zone);
174 static Eina_Bool _e_border_rotation_vkbd_transient_for_check(E_Border *bd);
175 static Eina_Bool _e_border_rotation_transient_for_check(E_Border *bd, int ang);
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
330 Eina_Bool wait_prepare_done;
331 Ecore_Timer *prepare_timer;
332 Ecore_Timer *done_timer;
334 Ecore_X_Window vkbd_ctrl_win;
336 E_Border *vkbd_prediction;
338 /* vkbd show/hide preprare */
339 Eina_Bool vkbd_show_prepare_done;
340 Ecore_Timer *vkbd_show_prepare_timer;
341 Ecore_Timer *vkbd_show_timer;
343 Eina_Bool vkbd_hide_prepare_done;
344 Ecore_Timer *vkbd_hide_prepare_timer;
345 Ecore_Timer *vkbd_hide_timer;
351 struct _E_Border_Rotation_Info
356 Eina_Bool win_resize;
359 static E_Border_Rotation rot =
379 EAPI int E_EVENT_BORDER_ADD = 0;
380 EAPI int E_EVENT_BORDER_REMOVE = 0;
381 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
382 EAPI int E_EVENT_BORDER_DESK_SET = 0;
383 EAPI int E_EVENT_BORDER_RESIZE = 0;
384 EAPI int E_EVENT_BORDER_MOVE = 0;
385 EAPI int E_EVENT_BORDER_SHOW = 0;
386 EAPI int E_EVENT_BORDER_HIDE = 0;
387 EAPI int E_EVENT_BORDER_ICONIFY = 0;
388 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
389 EAPI int E_EVENT_BORDER_STICK = 0;
390 EAPI int E_EVENT_BORDER_UNSTICK = 0;
391 EAPI int E_EVENT_BORDER_STACK = 0;
392 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
393 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
394 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
395 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
396 EAPI int E_EVENT_BORDER_PROPERTY = 0;
397 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
398 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
399 #ifdef _F_ZONE_WINDOW_ROTATION_
400 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
401 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
402 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
403 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
406 #define GRAV_SET(bd, grav) \
407 ecore_x_window_gravity_set(bd->bg_win, grav); \
408 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
409 ecore_x_window_gravity_set(bd->client.win, grav);
412 _e_border_sub_borders_new(E_Border *bd)
414 Eina_List *list = NULL, *l;
418 EINA_LIST_FOREACH(bd->transients, l, child)
420 if (!eina_list_data_find(list, child))
421 list = eina_list_append(list, child);
423 bl = e_container_border_list_first(bd->zone->container);
424 while ((child = e_container_border_list_next(bl)))
426 if (e_object_is_del(E_OBJECT(child))) continue;
427 if (child == bd) continue;
429 if ((bd->client.icccm.client_leader) &&
430 (child->client.icccm.client_leader ==
431 bd->client.icccm.client_leader))
433 printf("bd %s in group with %s\n",
434 e_border_name_get(child),
435 e_border_name_get(bd));
436 if (!eina_list_data_find(list, child))
437 list = eina_list_append(list, child);
441 e_container_border_list_free(bl);
445 /* externally accessible functions */
449 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
450 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
451 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
452 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
453 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
454 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
455 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
461 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
467 #ifdef _F_ZONE_WINDOW_ROTATION_
468 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
471 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
473 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
474 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
475 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
476 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
477 #ifdef _F_USE_DESK_WINDOW_PROFILE_
478 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
480 #ifdef _F_ZONE_WINDOW_ROTATION_
481 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
484 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
486 E_EVENT_BORDER_ADD = ecore_event_type_new();
487 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
488 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
489 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
490 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
491 E_EVENT_BORDER_MOVE = ecore_event_type_new();
492 E_EVENT_BORDER_SHOW = ecore_event_type_new();
493 E_EVENT_BORDER_HIDE = ecore_event_type_new();
494 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
495 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
496 E_EVENT_BORDER_STICK = ecore_event_type_new();
497 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
498 E_EVENT_BORDER_STACK = ecore_event_type_new();
499 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
500 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
501 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
502 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
503 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
504 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
505 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
506 #ifdef _F_ZONE_WINDOW_ROTATION_
507 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
508 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
509 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
510 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
519 e_border_shutdown(void)
521 E_FREE_LIST(handlers, ecore_event_handler_del);
523 if (borders_hash) eina_hash_free(borders_hash);
525 e_int_border_menu_hooks_clear();
531 e_border_new(E_Container *con,
537 Ecore_X_Window_Attributes *att;
538 unsigned int managed, desk[2];
541 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
542 if (!bd) return NULL;
543 ecore_x_window_shadow_tree_flush();
544 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
548 /* FIXME: ewww - round trip */
549 bd->client.argb = ecore_x_window_argb_get(win);
551 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
554 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
555 ecore_x_window_shape_events_select(bd->win, 1);
557 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
558 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
560 bd->bg_ecore_evas = e_canvas_new(bd->win,
561 0, 0, bd->w, bd->h, 1, 0,
563 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
564 e_canvas_add(bd->bg_ecore_evas);
565 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
566 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
567 ecore_x_window_shape_events_select(bd->bg_win, 1);
568 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
569 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
571 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
573 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
574 ecore_x_window_container_manage(bd->client.shell_win);
575 if (!internal) ecore_x_window_client_manage(win);
576 /* FIXME: Round trip. XCB */
577 /* fetch needed to avoid grabbing the server as window may vanish */
578 att = &bd->client.initial_attributes;
579 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
581 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
582 e_canvas_del(bd->bg_ecore_evas);
583 ecore_evas_free(bd->bg_ecore_evas);
584 ecore_x_window_free(bd->client.shell_win);
585 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
586 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
587 ecore_x_window_free(bd->win);
592 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
593 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
595 /* FIXME: if first_map is 1 then we should ignore the first hide event
596 * or ensure the window is already hidden and events flushed before we
597 * create a border for it */
600 // printf("##- FIRST MAP\n");
605 // needed to be 1 for internal windw and on restart.
606 // bd->ignore_first_unmap = 2;
609 bd->client.win = win;
610 bd->zone = e_zone_current_get(con);
612 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
614 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
615 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
616 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
617 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
618 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
619 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
621 bd->client.icccm.title = NULL;
622 bd->client.icccm.name = NULL;
623 bd->client.icccm.class = NULL;
624 bd->client.icccm.icon_name = NULL;
625 bd->client.icccm.machine = NULL;
626 bd->client.icccm.min_w = 1;
627 bd->client.icccm.min_h = 1;
628 bd->client.icccm.max_w = 32767;
629 bd->client.icccm.max_h = 32767;
630 bd->client.icccm.base_w = 0;
631 bd->client.icccm.base_h = 0;
632 bd->client.icccm.step_w = -1;
633 bd->client.icccm.step_h = -1;
634 bd->client.icccm.min_aspect = 0.0;
635 bd->client.icccm.max_aspect = 0.0;
636 bd->client.icccm.accepts_focus = 1;
638 bd->client.netwm.pid = 0;
639 bd->client.netwm.name = NULL;
640 bd->client.netwm.icon_name = NULL;
641 bd->client.netwm.desktop = 0;
642 bd->client.netwm.state.modal = 0;
643 bd->client.netwm.state.sticky = 0;
644 bd->client.netwm.state.shaded = 0;
645 bd->client.netwm.state.hidden = 0;
646 bd->client.netwm.state.maximized_v = 0;
647 bd->client.netwm.state.maximized_h = 0;
648 bd->client.netwm.state.skip_taskbar = 0;
649 bd->client.netwm.state.skip_pager = 0;
650 bd->client.netwm.state.fullscreen = 0;
651 bd->client.netwm.state.stacking = E_STACKING_NONE;
652 bd->client.netwm.action.move = 0;
653 bd->client.netwm.action.resize = 0;
654 bd->client.netwm.action.minimize = 0;
655 bd->client.netwm.action.shade = 0;
656 bd->client.netwm.action.stick = 0;
657 bd->client.netwm.action.maximized_h = 0;
658 bd->client.netwm.action.maximized_v = 0;
659 bd->client.netwm.action.fullscreen = 0;
660 bd->client.netwm.action.change_desktop = 0;
661 bd->client.netwm.action.close = 0;
662 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
668 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
669 bd->client.icccm.fetch.command = 1;
672 Eina_Bool video_parent = EINA_FALSE;
673 Eina_Bool video_position = EINA_FALSE;
676 for (i = 0; i < at_num; i++)
678 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
679 bd->client.icccm.fetch.title = 1;
680 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
681 bd->client.icccm.fetch.name_class = 1;
682 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
683 bd->client.icccm.fetch.icon_name = 1;
684 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
685 bd->client.icccm.fetch.machine = 1;
686 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
687 bd->client.icccm.fetch.hints = 1;
688 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
689 bd->client.icccm.fetch.size_pos_hints = 1;
690 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
691 bd->client.icccm.fetch.protocol = 1;
692 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
693 bd->client.mwm.fetch.hints = 1;
694 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
696 bd->client.icccm.fetch.transient_for = 1;
697 bd->client.netwm.fetch.type = 1;
699 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
700 bd->client.icccm.fetch.client_leader = 1;
701 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
702 bd->client.icccm.fetch.window_role = 1;
703 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
704 bd->client.icccm.fetch.state = 1;
706 /* netwm, loop again, netwm will ignore some icccm, so we
707 * have to be sure that netwm is checked after */
708 for (i = 0; i < at_num; i++)
710 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
713 bd->client.icccm.fetch.title = 0;
714 bd->client.netwm.fetch.name = 1;
716 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
719 bd->client.icccm.fetch.icon_name = 0;
720 bd->client.netwm.fetch.icon_name = 1;
722 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
724 bd->client.netwm.fetch.icon = 1;
726 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
728 bd->client.netwm.fetch.user_time = 1;
730 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
732 DBG("ECORE_X_ATOM_NET_WM_STRUT");
733 bd->client.netwm.fetch.strut = 1;
735 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
737 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
738 bd->client.netwm.fetch.strut = 1;
740 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
743 bd->client.mwm.fetch.hints = 0;
745 bd->client.netwm.fetch.type = 1;
747 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
749 bd->client.netwm.fetch.state = 1;
752 /* other misc atoms */
753 for (i = 0; i < at_num; i++)
755 /* loop to check for own atoms */
756 if (atoms[i] == E_ATOM_WINDOW_STATE)
758 bd->client.e.fetch.state = 1;
760 /* loop to check for qtopia atoms */
761 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
762 bd->client.qtopia.fetch.soft_menu = 1;
763 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
764 bd->client.qtopia.fetch.soft_menus = 1;
765 /* loop to check for vkbd atoms */
766 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
767 bd->client.vkbd.fetch.state = 1;
768 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
769 bd->client.vkbd.fetch.vkbd = 1;
770 /* loop to check for illume atoms */
771 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
772 bd->client.illume.conformant.fetch.conformant = 1;
773 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
774 bd->client.illume.quickpanel.fetch.state = 1;
775 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
776 bd->client.illume.quickpanel.fetch.quickpanel = 1;
777 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
778 bd->client.illume.quickpanel.fetch.priority.major = 1;
779 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
780 bd->client.illume.quickpanel.fetch.priority.minor = 1;
781 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
782 bd->client.illume.quickpanel.fetch.zone = 1;
783 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
784 bd->client.illume.drag.fetch.locked = 1;
785 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
786 bd->client.illume.drag.fetch.drag = 1;
787 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
788 bd->client.illume.win_state.fetch.state = 1;
789 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
790 video_parent = EINA_TRUE;
791 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
792 video_position = EINA_TRUE;
793 #ifdef _F_USE_DESK_WINDOW_PROFILE_
794 /* loop to check for window profile list atom */
795 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
796 bd->client.e.fetch.profile_list = 1;
798 #ifdef _F_ZONE_WINDOW_ROTATION_
799 /* loop to check for wm rotation */
800 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
802 if (e_config->wm_win_rotation)
803 bd->client.e.fetch.rot.support = 1;
805 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
806 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
807 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
808 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
810 if (e_config->wm_win_rotation)
811 bd->client.e.fetch.rot.geom_hint = 1;
813 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
815 if (e_config->wm_win_rotation)
816 bd->client.e.fetch.rot.app_set = 1;
818 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
820 if (e_config->wm_win_rotation)
821 bd->client.e.fetch.rot.preferred_rot = 1;
823 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
825 if (e_config->wm_win_rotation)
826 bd->client.e.fetch.rot.available_rots = 1;
829 #ifdef _F_DEICONIFY_APPROVE_
830 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
832 bd->client.e.state.deiconify_approve.support = 1;
836 if (video_position && video_parent)
838 bd->client.e.state.video = 1;
839 bd->client.e.fetch.video_parent = 1;
840 bd->client.e.fetch.video_position = 1;
841 ecore_x_window_lower(bd->win);
842 ecore_x_composite_window_events_disable(bd->win);
843 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
844 fprintf(stderr, "We found a video window \\o/ %x\n", win);
849 bd->client.border.changed = 1;
851 bd->client.w = att->w;
852 bd->client.h = att->h;
854 bd->w = bd->client.w;
855 bd->h = bd->client.h;
857 bd->resize_mode = RESIZE_NONE;
859 bd->saved.layer = bd->layer;
860 bd->changes.icon = 1;
861 bd->changes.size = 1;
862 bd->changes.shape = 1;
863 bd->changes.shape_input = 1;
865 bd->offer_resistance = 1;
867 /* just to friggin make java happy - we're DELAYING the reparent until
870 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
871 bd->need_reparent = 1;
873 ecore_x_window_border_width_set(win, 0);
874 ecore_x_window_show(bd->event_win);
875 ecore_x_window_show(bd->client.shell_win);
876 bd->shape = e_container_shape_add(con);
881 #ifdef _F_ZONE_WINDOW_ROTATION_
882 bd->client.e.state.rot.preferred_rot = -1;
883 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
886 // bd->zone = e_zone_current_get(con);
887 bd->desk = e_desk_current_get(bd->zone);
888 e_container_border_add(bd);
889 borders = eina_list_append(borders, bd);
890 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
894 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
895 "optimisations failing due to bizarre client behavior. will\n"
897 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
898 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
901 ELBF(ELBT_BD, 0, bd->client.win,
902 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
903 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
905 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
906 printf("optimisations failing due to bizarre client behavior. will\n");
907 printf("work around.\n");
908 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
909 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
912 ELBF(ELBT_BD, 0, bd->client.win,
913 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
914 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
917 #ifdef _F_ZONE_WINDOW_ROTATION_
918 if ((rot.vkbd) && (rot.vkbd == bd2))
920 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
921 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
922 rot.vkbd_hide_prepare_done);
924 if (rot.vkbd_hide_prepare_timer)
926 ecore_timer_del(rot.vkbd_hide_prepare_timer);
927 rot.vkbd_hide_prepare_timer = NULL;
929 e_object_unref(E_OBJECT(bd2));
932 _e_border_vkbd_hide(rot.vkbd);
934 if (rot.vkbd_ctrl_win)
936 ELB(ELBT_BD, "SET KBD_OFF", 0);
937 ecore_x_e_virtual_keyboard_state_set
938 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
940 rot.vkbd_hide_prepare_done = EINA_FALSE;
942 if (rot.vkbd_hide_timer)
943 ecore_timer_del(rot.vkbd_hide_timer);
944 rot.vkbd_hide_timer = NULL;
946 rot.vkbd_show_prepare_done = EINA_FALSE;
947 if (rot.vkbd_show_prepare_timer)
948 ecore_timer_del(rot.vkbd_show_prepare_timer);
949 rot.vkbd_show_prepare_timer = NULL;
950 if (rot.vkbd_show_timer)
951 ecore_timer_del(rot.vkbd_show_timer);
952 rot.vkbd_show_timer = NULL;
957 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
958 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
959 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
961 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
962 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
963 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
965 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
966 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
967 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
969 unsigned int zgeom[4];
971 zgeom[0] = bd->zone->x;
972 zgeom[1] = bd->zone->y;
973 zgeom[2] = bd->zone->w;
974 zgeom[3] = bd->zone->h;
975 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
977 e_desk_xy_get(bd->desk, &deskx, &desky);
980 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
981 #ifdef _F_USE_DESK_WINDOW_PROFILE_
982 if (strcmp(bd->desk->window_profile,
983 e_config->desktop_default_window_profile) != 0)
985 ecore_x_e_window_profile_set(bd->client.win,
986 bd->desk->window_profile);
990 focus_stack = eina_list_append(focus_stack, bd);
992 bd->pointer = e_pointer_window_new(bd->win, 0);
997 e_border_res_change_geometry_save(E_Border *bd)
1000 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1002 if (bd->pre_res_change.valid) return;
1003 bd->pre_res_change.valid = 1;
1004 bd->pre_res_change.x = bd->x;
1005 bd->pre_res_change.y = bd->y;
1006 bd->pre_res_change.w = bd->w;
1007 bd->pre_res_change.h = bd->h;
1008 bd->pre_res_change.saved.x = bd->saved.x;
1009 bd->pre_res_change.saved.y = bd->saved.y;
1010 bd->pre_res_change.saved.w = bd->saved.w;
1011 bd->pre_res_change.saved.h = bd->saved.h;
1015 e_border_res_change_geometry_restore(E_Border *bd)
1019 unsigned char valid : 1;
1028 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1029 if (!bd->pre_res_change.valid) return;
1030 if (bd->new_client) return;
1032 ecore_x_window_shadow_tree_flush();
1033 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1037 e_border_unfullscreen(bd);
1038 e_border_fullscreen(bd, e_config->fullscreen_policy);
1040 else if (bd->maximized != E_MAXIMIZE_NONE)
1044 max = bd->maximized;
1045 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1046 e_border_maximize(bd, max);
1050 int x, y, w, h, zx, zy, zw, zh;
1052 bd->saved.x = bd->pre_res_change.saved.x;
1053 bd->saved.y = bd->pre_res_change.saved.y;
1054 bd->saved.w = bd->pre_res_change.saved.w;
1055 bd->saved.h = bd->pre_res_change.saved.h;
1057 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1059 if (bd->saved.w > zw)
1061 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1062 bd->saved.x = zx + zw - bd->saved.w;
1064 if (bd->saved.h > zh)
1066 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1067 bd->saved.y = zy + zh - bd->saved.h;
1069 x = bd->pre_res_change.x;
1070 y = bd->pre_res_change.y;
1071 w = bd->pre_res_change.w;
1072 h = bd->pre_res_change.h;
1077 if ((x + w) > (zx + zw))
1079 if ((y + h) > (zy + zh))
1081 e_border_move_resize(bd, x, y, w, h);
1083 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1087 e_border_zone_set(E_Border *bd,
1090 E_Event_Border_Zone_Set *ev;
1093 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1094 E_OBJECT_CHECK(zone);
1095 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1097 if (bd->zone == zone) return;
1099 /* if the window does not lie in the new zone, move it so that it does */
1100 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1103 /* first guess -- get offset from old zone, and apply to new zone */
1104 x = zone->x + (bd->x - bd->zone->x);
1105 y = zone->y + (bd->y - bd->zone->y);
1107 /* keep window from hanging off bottom and left */
1108 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1109 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1111 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1112 if (x < zone->x) x = zone->x;
1113 if (y < zone->y) y = zone->y;
1115 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1117 /* still not in zone at all, so just move it to closest edge */
1118 if (x < zone->x) x = zone->x;
1119 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1120 if (y < zone->y) y = zone->y;
1121 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1123 e_border_move(bd, x, y);
1128 if (bd->desk->zone != bd->zone)
1129 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1131 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1133 e_object_ref(E_OBJECT(bd));
1134 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1136 e_object_ref(E_OBJECT(zone));
1138 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1140 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1141 // XXXXXXXXXXXXXXXXXXXXXXXXX
1142 // XXX ZZZZZZZZZZZZZZZZZZZzz
1143 // need to adjust this if zone pos/size changes
1145 unsigned int zgeom[4];
1147 zgeom[0] = bd->zone->x;
1148 zgeom[1] = bd->zone->y;
1149 zgeom[2] = bd->zone->w;
1150 zgeom[3] = bd->zone->h;
1151 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1153 e_remember_update(bd);
1157 e_border_desk_set(E_Border *bd,
1160 E_Event_Border_Desk_Set *ev;
1164 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1165 E_OBJECT_CHECK(desk);
1166 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1167 if (bd->desk == desk) return;
1168 ecore_x_window_shadow_tree_flush();
1171 bd->desk->fullscreen_borders--;
1172 desk->fullscreen_borders++;
1174 old_desk = bd->desk;
1176 e_border_zone_set(bd, desk->zone);
1178 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1179 e_hints_window_desktop_set(bd);
1181 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1183 e_object_ref(E_OBJECT(bd));
1184 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1185 ev->desk = old_desk;
1186 e_object_ref(E_OBJECT(old_desk));
1187 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1189 if (bd->ignore_first_unmap != 1)
1191 if ((bd->desk->visible) || (bd->sticky))
1194 e_border_hide(bd, 1);
1197 if (e_config->transient.desktop)
1201 Eina_List *list = _e_border_sub_borders_new(bd);
1203 EINA_LIST_FOREACH(list, l, child)
1205 e_border_desk_set(child, bd->desk);
1207 eina_list_free(list);
1209 e_remember_update(bd);
1212 #ifdef _F_ZONE_WINDOW_ROTATION_
1214 _e_border_vkbd_state_check(E_Border *bd,
1217 Eina_Bool res = EINA_TRUE;
1218 if (!e_config->wm_win_rotation) return EINA_FALSE;
1219 if ((rot.vkbd) && (rot.vkbd == bd))
1223 if ((rot.vkbd_hide_prepare_done) ||
1224 (rot.vkbd_hide_prepare_timer))
1229 if ((rot.vkbd_show_prepare_done) ||
1230 (rot.vkbd_show_prepare_timer))
1238 _e_border_vkbd_show_timeout(void *data)
1240 E_Border *bd = data;
1241 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1242 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1244 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1246 if (rot.vkbd_ctrl_win)
1248 ELB(ELBT_BD, "SET KBD_ON", 0);
1249 ecore_x_e_virtual_keyboard_state_set
1250 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1255 rot.vkbd_show_prepare_done = EINA_FALSE;
1257 if (rot.vkbd_show_prepare_timer)
1258 ecore_timer_del(rot.vkbd_show_prepare_timer);
1259 rot.vkbd_show_prepare_timer = NULL;
1261 if (rot.vkbd_show_timer)
1262 ecore_timer_del(rot.vkbd_show_timer);
1263 rot.vkbd_show_timer = NULL;
1265 return ECORE_CALLBACK_CANCEL;
1269 _e_border_vkbd_hide_timeout(void *data)
1271 E_Border *bd = data;
1272 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1273 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1275 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1277 if (rot.vkbd_ctrl_win)
1279 ELB(ELBT_BD, "SET KBD_OFF", 0);
1280 ecore_x_e_virtual_keyboard_state_set
1281 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1284 e_object_unref(E_OBJECT(bd));
1287 rot.vkbd_hide_prepare_done = EINA_FALSE;
1289 if (rot.vkbd_hide_prepare_timer)
1290 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1291 rot.vkbd_hide_prepare_timer = NULL;
1293 if (rot.vkbd_hide_timer)
1294 ecore_timer_del(rot.vkbd_hide_timer);
1295 rot.vkbd_hide_timer = NULL;
1297 return ECORE_CALLBACK_CANCEL;
1301 _e_border_vkbd_show(E_Border *bd)
1303 if (!e_config->wm_win_rotation) return;
1304 rot.vkbd_show_prepare_done = EINA_TRUE;
1305 if (rot.vkbd_show_prepare_timer)
1306 ecore_timer_del(rot.vkbd_show_prepare_timer);
1307 rot.vkbd_show_prepare_timer = NULL;
1308 if (rot.vkbd_show_timer)
1309 ecore_timer_del(rot.vkbd_show_timer);
1310 rot.vkbd_show_timer = NULL;
1311 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1314 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1319 _e_border_vkbd_hide(E_Border *bd)
1321 if (!e_config->wm_win_rotation) return;
1322 rot.vkbd_hide_prepare_done = EINA_TRUE;
1323 if (rot.vkbd_hide_prepare_timer)
1324 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1325 rot.vkbd_hide_prepare_timer = NULL;
1326 if (rot.vkbd_hide_timer)
1327 ecore_timer_del(rot.vkbd_hide_timer);
1328 rot.vkbd_hide_timer = NULL;
1329 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1331 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1332 e_border_hide(bd, 0);
1333 if (!e_object_is_del(E_OBJECT(bd)))
1335 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1336 e_object_del(E_OBJECT(bd));
1338 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1343 _e_border_vkbd_show_prepare_timeout(void *data)
1345 E_Border *bd = data;
1346 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1347 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1349 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1350 _e_border_vkbd_show(bd);
1352 return ECORE_CALLBACK_CANCEL;
1356 _e_border_vkbd_hide_prepare_timeout(void *data)
1358 E_Border *bd = data;
1359 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1360 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1362 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1363 _e_border_vkbd_hide(bd);
1365 return ECORE_CALLBACK_CANCEL;
1370 e_border_show(E_Border *bd)
1372 E_Event_Border_Show *ev;
1373 unsigned int visible;
1376 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1377 if (bd->visible) return;
1378 #ifdef _F_ZONE_WINDOW_ROTATION_
1379 if ((e_config->wm_win_rotation) &&
1380 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1382 (!rot.vkbd_show_prepare_done))
1384 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1385 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1386 if (rot.vkbd_show_prepare_timer)
1387 ecore_timer_del(rot.vkbd_show_prepare_timer);
1388 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1389 _e_border_vkbd_show_prepare_timeout,
1393 ELB(ELBT_BD, "SHOW", bd->client.win);
1395 ecore_x_window_shadow_tree_flush();
1396 e_container_shape_show(bd->shape);
1397 if (!bd->need_reparent)
1398 ecore_x_window_show(bd->client.win);
1399 e_hints_window_visible_set(bd);
1402 bd->changes.visible = 1;
1405 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1406 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1408 ev = E_NEW(E_Event_Border_Show, 1);
1410 e_object_ref(E_OBJECT(bd));
1411 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1412 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1414 #ifdef _F_ZONE_WINDOW_ROTATION_
1415 if ((e_config->wm_win_rotation) &&
1416 ((bd->client.e.state.rot.support) ||
1417 (bd->client.e.state.rot.app_set)))
1419 ELB(ELBT_ROT, "CHECK", bd->client.win);
1420 Eina_Bool _rot = _e_border_rotation_check(bd);
1421 /* check whether rotation is available for sub borders such as prediction and magnifier */
1426 Eina_List *_list = _e_border_sub_borders_new(bd);
1427 EINA_LIST_FOREACH(_list, ll, _child)
1429 if ((_child->client.e.state.rot.support) ||
1430 (_child->client.e.state.rot.app_set))
1431 _e_border_rotation_check(_child);
1433 eina_list_free(_list);
1440 e_border_hide(E_Border *bd,
1443 unsigned int visible;
1446 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1448 #ifdef _F_ZONE_WINDOW_ROTATION_
1449 if ((e_config->wm_win_rotation) &&
1450 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1452 (!rot.vkbd_hide_prepare_done) &&
1455 Eina_Bool need_prepare = EINA_TRUE;
1456 E_Border *child = NULL;
1459 if (e_object_is_del(E_OBJECT(bd->parent)))
1460 need_prepare = EINA_FALSE;
1463 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1464 if (bd->parent->modal == bd)
1466 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1467 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1468 bd->parent->lock_close = 0;
1469 bd->parent->saved.event_mask = 0;
1470 bd->parent->modal = NULL;
1476 need_prepare = EINA_FALSE;
1478 EINA_LIST_FREE(bd->transients, child)
1480 child->parent = NULL;
1483 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1487 e_object_ref(E_OBJECT(bd));
1488 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1489 if (rot.vkbd_hide_prepare_timer)
1490 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1491 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1492 _e_border_vkbd_hide_prepare_timeout,
1498 e_object_ref(E_OBJECT(bd));
1500 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1501 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1503 /* cleanup code from _e_border_vkbd_hide() */
1504 rot.vkbd_hide_prepare_done = EINA_TRUE;
1505 if (rot.vkbd_hide_prepare_timer)
1506 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1507 rot.vkbd_hide_prepare_timer = NULL;
1508 if (rot.vkbd_hide_timer)
1509 ecore_timer_del(rot.vkbd_hide_timer);
1510 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1513 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1515 if (!bd->visible) goto send_event;
1516 ecore_x_window_shadow_tree_flush();
1518 _e_border_move_end(bd);
1519 if (bd->resize_mode != RESIZE_NONE)
1521 _e_border_pointer_resize_end(bd);
1522 bd->resize_mode = RESIZE_NONE;
1523 _e_border_resize_end(bd);
1526 e_container_shape_hide(bd->shape);
1527 if (!bd->iconic) e_hints_window_hidden_set(bd);
1530 bd->changes.visible = 1;
1532 if (!bd->need_reparent)
1534 if ((bd->focused) ||
1535 (e_grabinput_last_focus_win_get() == bd->client.win))
1537 e_border_focus_set(bd, 0, 1);
1545 con = e_container_current_get(e_manager_current_get());
1546 zone = e_zone_current_get(con);
1547 desk = e_desk_current_get(zone);
1550 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1551 e_border_focus_set(bd->parent, 1, 1);
1552 else if (e_config->focus_revert_on_hide_or_close)
1554 /* When using pointer focus, the border under the
1555 * pointer (if any) gets focused, in sloppy/click
1556 * focus the last focused window on the current
1557 * desk gets focus */
1558 if (e_config->focus_policy == E_FOCUS_MOUSE)
1560 pbd = e_border_under_pointer_get(desk, bd);
1562 e_border_focus_set(pbd, 1, 1);
1564 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1565 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1566 (e_config->focus_policy == E_FOCUS_CLICK))
1567 _e_border_latest_stacked_focus(bd);
1571 e_desk_last_focused_focus(desk);
1581 /* Make sure that this border isn't deleted */
1582 bd->await_hide_event++;
1584 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1585 ecore_x_window_hide(bd->client.win);
1590 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1592 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1599 #ifdef _F_ZONE_WINDOW_ROTATION_
1600 _e_border_rotation_list_remove(bd);
1603 E_Event_Border_Hide *ev;
1605 ev = E_NEW(E_Event_Border_Hide, 1);
1607 e_object_ref(E_OBJECT(bd));
1608 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1609 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1614 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1618 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1619 setpriority(PRIO_PROCESS, pid, newpri);
1620 // shouldnt need to do this as default ionice class is "none" (0), and
1621 // this inherits io priority FROM nice level
1622 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1623 // IOPRIO_PRIO_VALUE(2, 5));
1627 char *file, buf[PATH_MAX];
1631 // yes - this is /proc specific... so this may not work on some
1632 // os's - works on linux. too bad for others.
1633 files = ecore_file_ls("/proc");
1634 EINA_LIST_FREE(files, file)
1636 if (isdigit(file[0]))
1638 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1639 f = fopen(buf, "r");
1644 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1650 _pri_adj(pid2, set, adj, EINA_TRUE,
1651 adj_children, do_children);
1653 _pri_adj(pid2, set, adj, use_adj,
1654 adj_children, do_children);
1666 _e_border_pri_raise(E_Border *bd)
1668 if (bd->client.netwm.pid <= 0) return;
1669 if (bd->client.netwm.pid == getpid()) return;
1670 _pri_adj(bd->client.netwm.pid,
1671 e_config->priority - 1, -1, EINA_FALSE,
1672 // EINA_TRUE, EINA_TRUE);
1673 EINA_TRUE, EINA_FALSE);
1674 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1675 // bd->client.netwm.pid, e_border_name_get(bd));
1679 _e_border_pri_norm(E_Border *bd)
1681 if (bd->client.netwm.pid <= 0) return;
1682 if (bd->client.netwm.pid == getpid()) return;
1683 _pri_adj(bd->client.netwm.pid,
1684 e_config->priority, 1, EINA_FALSE,
1685 // EINA_TRUE, EINA_TRUE);
1686 EINA_TRUE, EINA_FALSE);
1687 // printf("WIN: pid %i, title %s (NORMAL)\n",
1688 // bd->client.netwm.pid, e_border_name_get(bd));
1692 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1695 Ecore_Evas *bg_ecore_evas;
1701 bg_ecore_evas = bd->bg_ecore_evas;
1703 /* unregister old frame window */
1704 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1705 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1707 e_focus_setdown(bd);
1708 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1709 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1711 if (bd->icon_object)
1712 evas_object_del(bd->icon_object);
1714 evas_object_del(bd->bg_object);
1715 e_canvas_del(bg_ecore_evas);
1716 ecore_evas_free(bg_ecore_evas);
1719 e_object_del(E_OBJECT(bd->pointer));
1721 /* create new frame */
1723 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1724 bd->x, bd->y, bd->w, bd->h);
1727 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1728 bd->x, bd->y, bd->w, bd->h);
1729 ecore_x_window_shape_events_select(bd->win, 1);
1732 ecore_x_window_configure(bd->win,
1733 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1734 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1736 win, ECORE_X_WINDOW_STACK_BELOW);
1738 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1739 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1742 bd->bg_ecore_evas = e_canvas_new(bd->win,
1743 0, 0, bd->w, bd->h, 1, 0,
1746 e_canvas_add(bd->bg_ecore_evas);
1747 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1749 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1750 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1751 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1753 ecore_x_window_shape_events_select(bd->bg_win, 1);
1755 /* move client with shell win over to new frame */
1756 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1757 bd->client_inset.l, bd->client_inset.t);
1759 bd->pointer = e_pointer_window_new(bd->win, 0);
1761 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1762 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1769 ecore_evas_show(bd->bg_ecore_evas);
1770 ecore_x_window_show(bd->win);
1772 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1773 ecore_x_window_show(tmp->win);
1776 bd->bg_object = edje_object_add(bd->bg_evas);
1777 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1778 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1780 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1782 /* cleanup old frame */
1783 ecore_x_window_free(win);
1787 _e_border_client_move_resize_send(E_Border *bd)
1789 if (bd->internal_ecore_evas)
1790 ecore_evas_managed_move(bd->internal_ecore_evas,
1791 bd->x + bd->fx.x + bd->client_inset.l,
1792 bd->y + bd->fx.y + bd->client_inset.t);
1794 ecore_x_icccm_move_resize_send(bd->client.win,
1795 bd->x + bd->fx.x + bd->client_inset.l,
1796 bd->y + bd->fx.y + bd->client_inset.t,
1802 _e_border_pending_move_resize_add(E_Border *bd,
1809 Eina_Bool without_border,
1810 unsigned int serial)
1812 E_Border_Pending_Move_Resize *pnd;
1814 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1816 pnd->resize = resize;
1818 pnd->without_border = without_border;
1823 pnd->serial = serial;
1824 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1828 _e_border_move_internal(E_Border *bd,
1831 Eina_Bool without_border)
1833 E_Event_Border_Move *ev;
1836 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1838 ecore_x_window_shadow_tree_flush();
1841 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1847 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1849 if (e_config->allow_manip)
1852 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1857 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1862 else if (e_config->allow_manip)
1870 x -= bd->client_inset.l;
1871 y -= bd->client_inset.t;
1873 if (bd->move_intercept_cb)
1876 px = bd->x, py = bd->y;
1877 bd->move_intercept_cb(bd, x, y);
1878 if ((bd->x == px) && (bd->y == py)) return;
1880 else if ((x == bd->x) && (y == bd->y)) return;
1881 bd->pre_res_change.valid = 0;
1885 bd->changes.pos = 1;
1887 if (bd->client.netwm.sync.request)
1889 bd->client.netwm.sync.wait++;
1890 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1893 _e_border_client_move_resize_send(bd);
1894 _e_border_move_update(bd);
1895 ev = E_NEW(E_Event_Border_Move, 1);
1897 e_object_ref(E_OBJECT(bd));
1898 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1899 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1900 _e_border_zone_update(bd);
1904 * Move window to coordinates that already account border decorations.
1906 * This call will consider given position already accounts border
1907 * decorations, so it will not be considered later. This will just
1908 * work properly with borders that have being evaluated and border
1909 * decorations are known (border->client_inset).
1911 * @parm x horizontal position to place window.
1912 * @parm y vertical position to place window.
1914 * @see e_border_move_without_border()
1917 e_border_move(E_Border *bd,
1924 _e_border_move_internal(bd, x, y, 0);
1929 * Set a callback which will be called just prior to updating the
1930 * move coordinates for a border
1933 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1935 bd->move_intercept_cb = cb;
1939 * Move window to coordinates that do not account border decorations yet.
1941 * This call will consider given position does not account border
1942 * decoration, so these values (border->client_inset) will be
1943 * accounted automatically. This is specially useful when it is a new
1944 * client and has not be evaluated yet, in this case
1945 * border->client_inset will be zeroed and no information is known. It
1946 * will mark pending requests so border will be accounted on
1947 * evalutation phase.
1949 * @parm x horizontal position to place window.
1950 * @parm y vertical position to place window.
1952 * @see e_border_move()
1955 e_border_move_without_border(E_Border *bd,
1962 _e_border_move_internal(bd, x, y, 1);
1966 e_border_center(E_Border *bd)
1970 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1972 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1973 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1977 e_border_center_pos_get(E_Border *bd,
1983 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1985 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1986 if (x) *x = zx + (zw - bd->w) / 2;
1987 if (y) *y = zy + (zh - bd->h) / 2;
1991 e_border_fx_offset(E_Border *bd,
1996 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1998 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2002 bd->changes.pos = 1;
2005 if (bd->moving) _e_border_move_update(bd);
2009 _e_border_move_resize_internal(E_Border *bd,
2014 Eina_Bool without_border,
2017 E_Event_Border_Move *mev;
2018 E_Event_Border_Resize *rev;
2021 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2023 ecore_x_window_shadow_tree_flush();
2027 /* FIXME: hack for resizing vkbd like window.
2028 * IT SHOULD BE REMOVED after move the code which set the geometry of vkbd like window
2029 * to illume's layout hook handler.
2030 * the job of pending move/resize wouldn't be processed,
2031 * in case this function is called from "_e_border_rotation_check" via "e_hints_window_init".
2032 * thus we have to move/resize directry without pending in case geometry hint is existed. */
2033 if (!_e_border_rotation_geom_get(bd, bd->zone, bd->client.e.state.rot.curr,
2034 NULL, NULL, NULL, NULL, NULL))
2036 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2043 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2045 if (e_config->allow_manip)
2048 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2054 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2061 if (e_config->allow_manip)
2069 x -= bd->client_inset.l;
2070 y -= bd->client_inset.t;
2071 w += (bd->client_inset.l + bd->client_inset.r);
2072 h += (bd->client_inset.t + bd->client_inset.b);
2075 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2076 (w == bd->w) && (h == bd->h))
2079 bd->pre_res_change.valid = 0;
2082 bd->changes.pos = 1;
2088 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2089 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2091 if ((bd->shaped) || (bd->client.shaped))
2093 bd->need_shape_merge = 1;
2094 bd->need_shape_export = 1;
2096 if (bd->shaped_input)
2098 bd->need_shape_merge = 1;
2101 if (bd->internal_ecore_evas)
2104 bd->changes.size = 1;
2108 if (bdresize && bd->client.netwm.sync.request)
2110 bd->client.netwm.sync.wait++;
2111 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2112 * when no move is intended. The border geometry is set above anyways.
2114 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2115 bd->client.netwm.sync.serial);
2116 ecore_x_netwm_sync_request_send(bd->client.win,
2117 bd->client.netwm.sync.serial++);
2122 bd->changes.size = 1;
2126 _e_border_client_move_resize_send(bd);
2128 _e_border_resize_update(bd);
2131 mev = E_NEW(E_Event_Border_Move, 1);
2133 e_object_ref(E_OBJECT(bd));
2134 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2135 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2138 rev = E_NEW(E_Event_Border_Resize, 1);
2140 e_object_ref(E_OBJECT(bd));
2141 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2142 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2143 _e_border_zone_update(bd);
2147 * Move and resize window to values that already account border decorations.
2149 * This call will consider given values already accounts border
2150 * decorations, so it will not be considered later. This will just
2151 * work properly with borders that have being evaluated and border
2152 * decorations are known (border->client_inset).
2154 * @parm x horizontal position to place window.
2155 * @parm y vertical position to place window.
2156 * @parm w horizontal window size.
2157 * @parm h vertical window size.
2159 * @see e_border_move_resize_without_border()
2162 e_border_move_resize(E_Border *bd,
2171 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2175 * Move and resize window to values that do not account border decorations yet.
2177 * This call will consider given values already accounts border
2178 * decorations, so it will not be considered later. This will just
2179 * work properly with borders that have being evaluated and border
2180 * decorations are known (border->client_inset).
2182 * @parm x horizontal position to place window.
2183 * @parm y vertical position to place window.
2184 * @parm w horizontal window size.
2185 * @parm h vertical window size.
2187 * @see e_border_move_resize()
2190 e_border_move_resize_without_border(E_Border *bd,
2199 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2203 * Resize window to values that already account border decorations.
2205 * This call will consider given size already accounts border
2206 * decorations, so it will not be considered later. This will just
2207 * work properly with borders that have being evaluated and border
2208 * decorations are known (border->client_inset).
2210 * @parm w horizontal window size.
2211 * @parm h vertical window size.
2213 * @see e_border_resize_without_border()
2216 e_border_resize(E_Border *bd,
2223 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2227 * Resize window to values that do not account border decorations yet.
2229 * This call will consider given size does not account border
2230 * decoration, so these values (border->client_inset) will be
2231 * accounted automatically. This is specially useful when it is a new
2232 * client and has not be evaluated yet, in this case
2233 * border->client_inset will be zeroed and no information is known. It
2234 * will mark pending requests so border will be accounted on
2235 * evalutation phase.
2237 * @parm w horizontal window size.
2238 * @parm h vertical window size.
2240 * @see e_border_resize()
2243 e_border_resize_without_border(E_Border *bd,
2250 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2254 e_border_layer_set(E_Border *bd,
2260 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2262 ecore_x_window_shadow_tree_flush();
2264 oldraise = e_config->transient.raise;
2268 bd->saved.layer = layer;
2272 if (e_config->transient.layer)
2276 Eina_List *list = _e_border_sub_borders_new(bd);
2278 /* We need to set raise to one, else the child wont
2279 * follow to the new layer. It should be like this,
2280 * even if the user usually doesn't want to raise
2283 e_config->transient.raise = 1;
2284 EINA_LIST_FOREACH(list, l, child)
2286 e_border_layer_set(child, layer);
2290 e_config->transient.raise = oldraise;
2294 e_border_raise(E_Border *bd)
2296 E_Event_Border_Stack *ev;
2297 E_Border *last = NULL, *child;
2301 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2303 ecore_x_window_shadow_tree_flush();
2305 if (e_config->transient.raise)
2307 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2308 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2311 Eina_List *list = _e_border_sub_borders_new(bd);
2313 EINA_LIST_REVERSE_FOREACH(list, l, child)
2315 /* Don't stack iconic transients. If the user wants these shown,
2316 * thats another option.
2321 e_border_stack_below(child, last);
2326 /* First raise the border to find out which border we will end up above */
2327 above = e_container_border_raise(child);
2331 /* We ended up above a border, now we must stack this border to
2332 * generate the stacking event, and to check if this transient
2333 * has other transients etc.
2335 e_border_stack_above(child, above);
2339 /* If we didn't end up above any border, we are on the bottom! */
2340 e_border_lower(child);
2346 eina_list_free(list);
2347 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2351 EINA_LIST_FOREACH(bd->transients, l, child)
2353 /* Don't stack iconic transients. If the user wants these shown,
2354 * thats another option.
2358 child->layer = bd->layer;
2359 if (!last) last = child;
2360 e_border_raise (child);
2367 ev = E_NEW(E_Event_Border_Stack, 1);
2369 e_object_ref(E_OBJECT(bd));
2373 e_container_border_stack_below(bd, last);
2375 e_object_ref(E_OBJECT(last));
2376 ev->type = E_STACKING_BELOW;
2382 /* If we don't have any children, raise this border */
2383 above = e_container_border_raise(bd);
2384 e_border_raise_latest_set(bd);
2387 /* We ended up above a border */
2389 e_object_ref(E_OBJECT(above));
2390 ev->type = E_STACKING_ABOVE;
2394 /* No border to raise above, same as a lower! */
2396 ev->type = E_STACKING_ABOVE;
2400 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2401 e_remember_update(bd);
2405 e_border_lower(E_Border *bd)
2407 E_Event_Border_Stack *ev;
2408 E_Border *last = NULL, *child;
2412 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2414 ecore_x_window_shadow_tree_flush();
2416 if (e_config->transient.lower)
2418 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2419 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2422 Eina_List *list = _e_border_sub_borders_new(bd);
2424 EINA_LIST_REVERSE_FOREACH(list, l, child)
2426 /* Don't stack iconic transients. If the user wants these shown,
2427 * thats another option.
2432 e_border_stack_below(child, last);
2437 /* First lower the border to find out which border we will end up below */
2438 below = e_container_border_lower(child);
2442 /* We ended up below a border, now we must stack this border to
2443 * generate the stacking event, and to check if this transient
2444 * has other transients etc.
2446 e_border_stack_below(child, below);
2450 /* If we didn't end up below any border, we are on top! */
2451 e_border_raise(child);
2457 eina_list_free(list);
2459 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2463 EINA_LIST_FOREACH(bd->transients, l, child)
2465 /* Don't stack iconic transients. If the user wants these shown,
2466 * thats another option.
2470 child->layer = bd->layer;
2471 e_border_lower (child);
2479 ev = E_NEW(E_Event_Border_Stack, 1);
2481 e_object_ref(E_OBJECT(bd));
2485 e_container_border_stack_below(bd, last);
2487 e_object_ref(E_OBJECT(last));
2488 ev->type = E_STACKING_BELOW;
2494 /* If we don't have any children, lower this border */
2495 below = e_container_border_lower(bd);
2498 /* We ended up below a border */
2500 e_object_ref(E_OBJECT(below));
2501 ev->type = E_STACKING_BELOW;
2505 /* No border to hide under, same as a raise! */
2507 ev->type = E_STACKING_BELOW;
2511 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2512 e_remember_update(bd);
2516 e_border_stack_above(E_Border *bd,
2519 /* TODO: Should stack above allow the border to change level */
2520 E_Event_Border_Stack *ev;
2521 E_Border *last = NULL, *child;
2525 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2527 ecore_x_window_shadow_tree_flush();
2529 if (e_config->transient.raise)
2531 Eina_List *list = _e_border_sub_borders_new(bd);
2533 EINA_LIST_REVERSE_FOREACH(list, l, child)
2535 /* Don't stack iconic transients. If the user wants these shown,
2536 * thats another option.
2541 e_border_stack_below(child, last);
2543 e_border_stack_above(child, above);
2547 eina_list_free(list);
2550 ev = E_NEW(E_Event_Border_Stack, 1);
2552 e_object_ref(E_OBJECT(bd));
2556 e_container_border_stack_below(bd, last);
2558 e_object_ref(E_OBJECT(last));
2559 ev->type = E_STACKING_BELOW;
2563 e_container_border_stack_above(bd, above);
2565 e_object_ref(E_OBJECT(above));
2566 ev->type = E_STACKING_ABOVE;
2569 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2570 e_remember_update(bd);
2574 e_border_stack_below(E_Border *bd,
2577 /* TODO: Should stack below allow the border to change level */
2578 E_Event_Border_Stack *ev;
2579 E_Border *last = NULL, *child;
2583 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2585 ecore_x_window_shadow_tree_flush();
2587 if (e_config->transient.lower)
2589 Eina_List *list = _e_border_sub_borders_new(bd);
2591 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2593 /* Don't stack iconic transients. If the user wants these shown,
2594 * thats another option.
2599 e_border_stack_below(child, last);
2601 e_border_stack_below(child, below);
2605 eina_list_free(list);
2608 ev = E_NEW(E_Event_Border_Stack, 1);
2610 e_object_ref(E_OBJECT(bd));
2614 e_container_border_stack_below(bd, last);
2616 e_object_ref(E_OBJECT(last));
2617 ev->type = E_STACKING_BELOW;
2621 e_container_border_stack_below(bd, below);
2623 e_object_ref(E_OBJECT(below));
2624 ev->type = E_STACKING_BELOW;
2627 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2628 e_remember_update(bd);
2632 e_border_focus_latest_set(E_Border *bd)
2634 focus_stack = eina_list_remove(focus_stack, bd);
2635 focus_stack = eina_list_prepend(focus_stack, bd);
2639 e_border_raise_latest_set(E_Border *bd)
2641 raise_stack = eina_list_remove(raise_stack, bd);
2642 raise_stack = eina_list_prepend(raise_stack, bd);
2646 * Sets the focus to the given border if necessary
2647 * There are 3 cases of different focus_policy-configurations:
2649 * - E_FOCUS_CLICK: just set the focus, the most simple one
2651 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2652 * warp the pointer to the window. If this fails (because
2653 * the pointer is already in the window), just set the focus.
2655 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2656 * last window which was focused, if the mouse is on the
2657 * desktop. So, we need to look if there is another window
2658 * under the pointer and warp to pointer to the right
2659 * one if so (also, we set the focus afterwards). In case
2660 * there is no window under pointer, the pointer is on the
2661 * desktop and so we just set the focus.
2664 * This function is to be called when setting the focus was not
2665 * explicitly triggered by the user (by moving the mouse or
2666 * clicking for example), but implicitly (by closing a window,
2667 * the last focused window should get focus).
2671 e_border_focus_set_with_pointer(E_Border *bd)
2673 #ifdef PRINT_LOTS_OF_DEBUG
2674 E_PRINT_BORDER_INFO(bd);
2676 /* note: this is here as it seems there are enough apps that do not even
2677 * expect us to emulate a look of focus but not actually set x input
2678 * focus as we do - so simply abort any focuse set on such windows */
2679 /* be strict about accepting focus hint */
2680 if ((!bd->client.icccm.accepts_focus) &&
2681 (!bd->client.icccm.take_focus)) return;
2682 if (bd->lock_focus_out) return;
2684 e_border_focus_set(bd, 1, 1);
2686 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2687 if (!bd->visible) return;
2689 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2691 if (!e_border_under_pointer_get(bd->desk, bd))
2693 e_border_pointer_warp_to_center(bd);
2698 e_border_pointer_warp_to_center(bd);
2703 e_border_focus_set(E_Border *bd,
2707 E_Border *bd_unfocus = NULL;
2708 Eina_Bool focus_changed = EINA_FALSE;
2711 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2712 /* note: this is here as it seems there are enough apps that do not even
2713 * expect us to emulate a look of focus but not actually set x input
2714 * focus as we do - so simply abort any focuse set on such windows */
2715 /* be strict about accepting focus hint */
2716 if ((!bd->client.icccm.accepts_focus) &&
2717 (!bd->client.icccm.take_focus))
2719 if ((set) && (focus) && (bd->lock_focus_out)) return;
2721 /* dont focus an iconified window. that's silly! */
2726 e_border_uniconify(bd);
2727 if (!focus_track_frozen)
2728 e_border_focus_latest_set(bd);
2731 else if (!bd->visible)
2735 /* FIXME: hack for deskflip animation:
2736 * dont update focus when sliding previous desk */
2737 else if ((!bd->sticky) &&
2738 (bd->desk != e_desk_current_get(bd->desk->zone)))
2744 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2746 e_border_focus_set(bd->modal, focus, set);
2749 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2751 e_border_focus_set(bd->leader->modal, focus, set);
2759 if (bd->visible && bd->changes.visible)
2764 else if ((!bd->focused) ||
2765 (focus_next && (bd != eina_list_data_get(focus_next))))
2769 if ((l = eina_list_data_find_list(focus_next, bd)))
2770 focus_next = eina_list_promote_list(focus_next, l);
2772 focus_next = eina_list_prepend(focus_next, bd);
2774 if ((bd->client.icccm.take_focus) &&
2775 (bd->client.icccm.accepts_focus))
2777 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2778 /* TODO what if the client didn't take focus ? */
2780 else if (!bd->client.icccm.accepts_focus)
2782 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2784 else if (!bd->client.icccm.take_focus)
2786 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2787 /* e_border_focus_set(bd, 1, 0); */
2797 if (focused) bd_unfocus = focused;
2798 if (focusing == bd) focusing = NULL;
2803 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2805 if ((bd2->fullscreen) &&
2807 (bd2->zone == bd->zone) &&
2808 ((bd2->desk == bd->desk) ||
2809 (bd2->sticky) || (bd->sticky)))
2811 Eina_Bool unfocus_is_parent = EINA_FALSE;
2812 E_Border *bd_parent;
2814 bd_parent = bd->parent;
2817 if (bd_parent == bd2)
2819 unfocus_is_parent = EINA_TRUE;
2822 bd_parent = bd->parent;
2824 if ((!unfocus_is_parent) &&
2825 (!e_config->allow_above_fullscreen))
2827 e_border_iconify(bd2);
2832 focus_changed = EINA_TRUE;
2838 focus_next = eina_list_remove(focus_next, bd);
2839 if (bd == focusing) focusing = NULL;
2841 if ((bd->focused) &&
2842 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2844 Eina_Bool wasfocused = EINA_FALSE;
2847 /* should always be the case. anyway */
2851 wasfocused = EINA_TRUE;
2854 if ((set) && (!focus_next) && (!focusing))
2856 e_grabinput_focus(bd->zone->container->bg_win,
2857 E_FOCUS_METHOD_PASSIVE);
2859 if ((bd->fullscreen) && (wasfocused))
2861 Eina_Bool have_vis_child = EINA_FALSE;
2865 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2868 (bd2->zone == bd->zone) &&
2869 ((bd2->desk == bd->desk) ||
2870 (bd2->sticky) || (bd->sticky)))
2872 if (bd2->parent == bd)
2874 have_vis_child = EINA_TRUE;
2879 if ((!have_vis_child) &&
2880 (!e_config->allow_above_fullscreen))
2881 e_border_iconify(bd);
2887 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2888 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2890 E_Event_Border_Focus_Out *ev;
2892 bd_unfocus->focused = 0;
2893 e_focus_event_focus_out(bd_unfocus);
2895 if (bd_unfocus->raise_timer)
2896 ecore_timer_del(bd_unfocus->raise_timer);
2897 bd_unfocus->raise_timer = NULL;
2899 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2900 if (bd_unfocus->icon_object)
2901 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2903 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2904 ev->border = bd_unfocus;
2905 e_object_ref(E_OBJECT(bd_unfocus));
2907 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2908 _e_border_event_border_focus_out_free, NULL);
2909 if ((bd_unfocus->fullscreen) &&
2910 (bd != bd_unfocus) &&
2911 (bd->zone == bd_unfocus->zone) &&
2912 ((bd->desk == bd_unfocus->desk) ||
2913 (bd->sticky) || (bd_unfocus->sticky)))
2915 Eina_Bool unfocus_is_parent = EINA_FALSE;
2916 E_Border *bd_parent;
2918 bd_parent = bd->parent;
2921 if (bd_parent == bd_unfocus)
2923 unfocus_is_parent = EINA_TRUE;
2926 bd_parent = bd->parent;
2928 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2930 e_border_iconify(bd_unfocus);
2937 E_Event_Border_Focus_In *ev;
2939 e_focus_event_focus_in(bd);
2941 if (!focus_track_frozen)
2942 e_border_focus_latest_set(bd);
2944 e_hints_active_window_set(bd->zone->container->manager, bd);
2946 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2947 if (bd->icon_object)
2948 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2950 ev = E_NEW(E_Event_Border_Focus_In, 1);
2952 e_object_ref(E_OBJECT(bd));
2954 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2955 _e_border_event_border_focus_in_free, NULL);
2960 e_border_shade(E_Border *bd,
2963 E_Event_Border_Resize *ev;
2968 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2969 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2970 ((bd->maximized) && (!e_config->allow_manip))) return;
2971 if ((bd->client.border.name) &&
2972 (!strcmp("borderless", bd->client.border.name))) return;
2974 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2975 ecore_x_window_hide(tmp->win);
2977 ecore_x_window_shadow_tree_flush();
2979 bd->shade.x = bd->x;
2980 bd->shade.y = bd->y;
2981 bd->shade.dir = dir;
2983 e_hints_window_shaded_set(bd, 1);
2984 e_hints_window_shade_direction_set(bd, dir);
2986 if (e_config->border_shade_animate)
2988 bd->shade.start = ecore_loop_time_get();
2990 bd->changes.shading = 1;
2993 if (bd->shade.dir == E_DIRECTION_UP ||
2994 bd->shade.dir == E_DIRECTION_LEFT)
2995 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2997 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2999 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3000 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
3004 if (bd->shade.dir == E_DIRECTION_UP)
3006 bd->h = bd->client_inset.t + bd->client_inset.b;
3008 else if (bd->shade.dir == E_DIRECTION_DOWN)
3010 bd->h = bd->client_inset.t + bd->client_inset.b;
3011 bd->y = bd->y + bd->client.h;
3012 bd->changes.pos = 1;
3014 else if (bd->shade.dir == E_DIRECTION_LEFT)
3016 bd->w = bd->client_inset.l + bd->client_inset.r;
3018 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3020 bd->w = bd->client_inset.l + bd->client_inset.r;
3021 bd->x = bd->x + bd->client.w;
3022 bd->changes.pos = 1;
3025 if ((bd->shaped) || (bd->client.shaped))
3027 bd->need_shape_merge = 1;
3028 bd->need_shape_export = 1;
3030 if (bd->shaped_input)
3032 bd->need_shape_merge = 1;
3035 bd->changes.size = 1;
3037 bd->changes.shaded = 1;
3039 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3040 e_border_frame_recalc(bd);
3041 ev = E_NEW(E_Event_Border_Resize, 1);
3043 /* The resize is added in the animator when animation complete */
3044 /* For non-animated, we add it immediately with the new size */
3045 e_object_ref(E_OBJECT(bd));
3046 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3047 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3050 e_remember_update(bd);
3054 e_border_unshade(E_Border *bd,
3057 E_Event_Border_Resize *ev;
3062 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3063 if ((!bd->shaded) || (bd->shading))
3066 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3067 ecore_x_window_show(tmp->win);
3069 ecore_x_window_shadow_tree_flush();
3071 bd->shade.dir = dir;
3073 e_hints_window_shaded_set(bd, 0);
3074 e_hints_window_shade_direction_set(bd, dir);
3076 if (bd->shade.dir == E_DIRECTION_UP ||
3077 bd->shade.dir == E_DIRECTION_LEFT)
3079 bd->shade.x = bd->x;
3080 bd->shade.y = bd->y;
3084 bd->shade.x = bd->x - bd->client.w;
3085 bd->shade.y = bd->y - bd->client.h;
3087 if (e_config->border_shade_animate)
3089 bd->shade.start = ecore_loop_time_get();
3091 bd->changes.shading = 1;
3094 if (bd->shade.dir == E_DIRECTION_UP)
3096 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3097 ecore_x_window_move_resize(bd->client.win, 0,
3098 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3100 bd->client.w, bd->client.h);
3102 else if (bd->shade.dir == E_DIRECTION_LEFT)
3104 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3105 ecore_x_window_move_resize(bd->client.win,
3106 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3108 0, bd->client.w, bd->client.h);
3111 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3113 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3114 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3118 if (bd->shade.dir == E_DIRECTION_UP)
3120 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3122 else if (bd->shade.dir == E_DIRECTION_DOWN)
3124 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3125 bd->y = bd->y - bd->client.h;
3126 bd->changes.pos = 1;
3128 else if (bd->shade.dir == E_DIRECTION_LEFT)
3130 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3132 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3134 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3135 bd->x = bd->x - bd->client.w;
3136 bd->changes.pos = 1;
3138 if ((bd->shaped) || (bd->client.shaped))
3140 bd->need_shape_merge = 1;
3141 bd->need_shape_export = 1;
3143 if (bd->shaped_input)
3145 bd->need_shape_merge = 1;
3148 bd->changes.size = 1;
3150 bd->changes.shaded = 1;
3152 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3153 e_border_frame_recalc(bd);
3154 ev = E_NEW(E_Event_Border_Resize, 1);
3156 /* The resize is added in the animator when animation complete */
3157 /* For non-animated, we add it immediately with the new size */
3158 e_object_ref(E_OBJECT(bd));
3159 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3160 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3163 e_remember_update(bd);
3167 _e_border_client_inset_calc(E_Border *bd)
3170 Evas_Coord cx, cy, cw, ch;
3174 evas_object_resize(bd->bg_object, 1000, 1000);
3175 edje_object_message_signal_process(bd->bg_object);
3176 edje_object_calc_force(bd->bg_object);
3177 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3178 bd->client_inset.l = cx;
3179 bd->client_inset.r = 1000 - (cx + cw);
3180 bd->client_inset.t = cy;
3181 bd->client_inset.b = 1000 - (cy + ch);
3185 bd->client_inset.l = 0;
3186 bd->client_inset.r = 0;
3187 bd->client_inset.t = 0;
3188 bd->client_inset.b = 0;
3191 ecore_x_netwm_frame_size_set(bd->client.win,
3192 bd->client_inset.l, bd->client_inset.r,
3193 bd->client_inset.t, bd->client_inset.b);
3194 ecore_x_e_frame_size_set(bd->client.win,
3195 bd->client_inset.l, bd->client_inset.r,
3196 bd->client_inset.t, bd->client_inset.b);
3200 _e_border_maximize(E_Border *bd, E_Maximize max)
3202 int x1, yy1, x2, y2;
3205 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3209 zx = zy = zw = zh = 0;
3211 switch (max & E_MAXIMIZE_TYPE)
3213 case E_MAXIMIZE_NONE:
3217 case E_MAXIMIZE_FULLSCREEN:
3223 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3224 _e_border_client_inset_calc(bd);
3226 e_border_resize_limit(bd, &w, &h);
3227 /* center x-direction */
3228 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3229 /* center y-direction */
3230 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3232 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3233 cy = bd->zone->y + (bd->zone->h / 2);
3236 switch (max & E_MAXIMIZE_DIRECTION)
3238 case E_MAXIMIZE_BOTH:
3239 e_border_move_resize(bd, x1, yy1, w, h);
3242 case E_MAXIMIZE_VERTICAL:
3243 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3246 case E_MAXIMIZE_HORIZONTAL:
3247 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3250 case E_MAXIMIZE_LEFT:
3251 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3254 case E_MAXIMIZE_RIGHT:
3255 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3257 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3258 case E_MAXIMIZE_TOP:
3259 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3261 case E_MAXIMIZE_BOTTOM:
3262 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3268 case E_MAXIMIZE_SMART:
3269 case E_MAXIMIZE_EXPAND:
3271 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3283 if (bd->x < zx) // window left not useful coordinates
3285 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3286 x1 = zx + zw - bd->w;
3287 else // window normal position
3290 if (bd->y < zy) // window top not useful coordinates
3292 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3293 yy1 = zy + zh - bd->h;
3294 else // window normal position
3297 switch (max & E_MAXIMIZE_DIRECTION)
3299 case E_MAXIMIZE_BOTH:
3300 e_border_move_resize(bd, zx, zy, zw, zh);
3303 case E_MAXIMIZE_VERTICAL:
3304 e_border_move_resize(bd, x1, zy, w, zh);
3307 case E_MAXIMIZE_HORIZONTAL:
3308 e_border_move_resize(bd, zx, yy1, zw, h);
3311 case E_MAXIMIZE_LEFT:
3312 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3315 case E_MAXIMIZE_RIGHT:
3316 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3320 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3323 case E_MAXIMIZE_FILL:
3326 x2 = bd->zone->x + bd->zone->w;
3327 y2 = bd->zone->y + bd->zone->h;
3329 /* walk through all shelves */
3330 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3332 /* walk through all windows */
3333 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3339 e_border_resize_limit(bd, &w, &h);
3340 /* center x-direction */
3341 x1 = x1 + (pw - w) / 2;
3342 /* center y-direction */
3343 yy1 = yy1 + (ph - h) / 2;
3345 switch (max & E_MAXIMIZE_DIRECTION)
3347 case E_MAXIMIZE_BOTH:
3348 e_border_move_resize(bd, x1, yy1, w, h);
3351 case E_MAXIMIZE_VERTICAL:
3352 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3355 case E_MAXIMIZE_HORIZONTAL:
3356 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3359 case E_MAXIMIZE_LEFT:
3360 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3363 case E_MAXIMIZE_RIGHT:
3364 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3372 e_border_maximize(E_Border *bd,
3376 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3378 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3380 if ((bd->shaded) || (bd->shading)) return;
3381 ecore_x_window_shadow_tree_flush();
3383 e_border_unfullscreen(bd);
3384 /* Only allow changes in vertical/ horizontal maximization */
3385 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3386 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3389 bd->need_maximize = 1;
3390 bd->maximized &= ~E_MAXIMIZE_TYPE;
3391 bd->maximized |= max;
3395 bd->pre_res_change.valid = 0;
3396 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3398 /* Horizontal hasn't been set */
3399 bd->saved.x = bd->x - bd->zone->x;
3400 bd->saved.w = bd->w;
3402 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3404 /* Vertical hasn't been set */
3405 bd->saved.y = bd->y - bd->zone->y;
3406 bd->saved.h = bd->h;
3409 bd->saved.zone = bd->zone->num;
3410 e_hints_window_size_set(bd);
3414 _e_border_maximize(bd, max);
3417 /* Remove previous type */
3418 bd->maximized &= ~E_MAXIMIZE_TYPE;
3419 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3420 bd->maximized |= max;
3422 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3423 bd->maximized & E_MAXIMIZE_VERTICAL);
3424 e_remember_update(bd);
3428 e_border_unmaximize(E_Border *bd,
3432 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3433 if (!(max & E_MAXIMIZE_DIRECTION))
3435 CRI("BUG: Unmaximize call without direction!");
3439 if ((bd->shaded) || (bd->shading)) return;
3440 ecore_x_window_shadow_tree_flush();
3441 /* Remove directions not used */
3442 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3443 /* Can only remove existing maximization directions */
3445 if (bd->maximized & E_MAXIMIZE_TYPE)
3447 bd->pre_res_change.valid = 0;
3448 bd->need_maximize = 0;
3450 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3454 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3455 _e_border_client_inset_calc(bd);
3458 bd->maximized = E_MAXIMIZE_NONE;
3459 _e_border_move_resize_internal(bd,
3460 bd->zone->x + bd->saved.x,
3461 bd->zone->y + bd->saved.y,
3462 bd->saved.w, bd->saved.h, 0, 1);
3463 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3464 e_hints_window_size_unset(bd);
3475 if (max & E_MAXIMIZE_VERTICAL)
3477 /* Remove vertical */
3479 y = bd->saved.y + bd->zone->y;
3480 bd->saved.h = bd->saved.y = 0;
3481 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3482 bd->maximized &= ~E_MAXIMIZE_LEFT;
3483 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3485 if (max & E_MAXIMIZE_HORIZONTAL)
3487 /* Remove horizontal */
3489 x = bd->saved.x + bd->zone->x;
3490 bd->saved.w = bd->saved.x = 0;
3491 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3494 e_border_resize_limit(bd, &w, &h);
3496 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3498 bd->maximized = E_MAXIMIZE_NONE;
3499 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3500 e_hints_window_size_unset(bd);
3501 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3505 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3506 e_hints_window_size_set(bd);
3509 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3510 bd->maximized & E_MAXIMIZE_VERTICAL);
3512 e_remember_update(bd);
3516 e_border_fullscreen(E_Border *bd,
3517 E_Fullscreen policy)
3519 E_Event_Border_Fullscreen *ev;
3522 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3524 if ((bd->shaded) || (bd->shading)) return;
3525 ecore_x_window_shadow_tree_flush();
3528 bd->need_fullscreen = 1;
3531 if (!bd->fullscreen)
3533 bd->pre_res_change.valid = 0;
3535 bd->saved.x = bd->x - bd->zone->x;
3536 bd->saved.y = bd->y - bd->zone->y;
3537 bd->saved.w = bd->client.w;
3538 bd->saved.h = bd->client.h;
3539 bd->saved.maximized = bd->maximized;
3540 bd->saved.zone = bd->zone->num;
3543 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3544 e_hints_window_size_set(bd);
3546 bd->client_inset.l = 0;
3547 bd->client_inset.r = 0;
3548 bd->client_inset.t = 0;
3549 bd->client_inset.b = 0;
3551 bd->desk->fullscreen_borders++;
3553 /* e_zone_fullscreen_set(bd->zone, 1); */
3554 bd->saved.layer = bd->layer;
3555 if (!e_config->allow_above_fullscreen)
3556 e_border_layer_set(bd, 250);
3558 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3559 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3561 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3563 else if (policy == E_FULLSCREEN_ZOOM)
3565 Ecore_X_Randr_Screen_Size_MM *sizes;
3566 int num_sizes, i, best_size_index = 0;
3568 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3570 &screen_size.height,
3572 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3576 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3577 int best_dist = INT_MAX, dist;
3579 for (i = 0; i < num_sizes; i++)
3581 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3583 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3584 if (dist < best_dist)
3586 best_size.width = sizes[i].width;
3587 best_size.height = sizes[i].height;
3589 best_size_index = i;
3593 if (((best_size.width != -1) && (best_size.height != -1)) &&
3594 ((best_size.width != screen_size.width) ||
3595 (best_size.height != screen_size.height)))
3597 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3599 screen_size_index = best_size_index;
3600 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3604 screen_size.width = -1;
3605 screen_size.height = -1;
3606 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3611 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3615 e_hints_window_fullscreen_set(bd, 1);
3616 e_hints_window_size_unset(bd);
3617 bd->client.border.changed = 1;
3620 bd->fullscreen_policy = policy;
3622 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3624 e_object_ref(E_OBJECT(bd));
3625 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3626 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3628 e_remember_update(bd);
3632 e_border_unfullscreen(E_Border *bd)
3634 E_Event_Border_Unfullscreen *ev;
3637 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3638 if ((bd->shaded) || (bd->shading)) return;
3639 ecore_x_window_shadow_tree_flush();
3642 bd->pre_res_change.valid = 0;
3644 bd->need_fullscreen = 0;
3645 bd->desk->fullscreen_borders--;
3647 if ((screen_size.width != -1) && (screen_size.height != -1))
3649 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3651 screen_size.width = -1;
3652 screen_size.height = -1;
3654 e_border_move_resize(bd,
3655 bd->saved.x + bd->zone->x,
3656 bd->saved.y + bd->zone->y,
3657 bd->saved.w, bd->saved.h);
3659 if (bd->saved.maximized)
3660 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3661 bd->saved.maximized);
3663 e_border_layer_set(bd, bd->saved.layer);
3665 e_hints_window_fullscreen_set(bd, 0);
3666 bd->client.border.changed = 1;
3669 bd->fullscreen_policy = 0;
3671 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3673 e_object_ref(E_OBJECT(bd));
3674 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3675 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3677 e_remember_update(bd);
3681 e_border_iconify(E_Border *bd)
3683 E_Event_Border_Iconify *ev;
3684 unsigned int iconic;
3687 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3688 if (bd->shading) return;
3689 ecore_x_window_shadow_tree_flush();
3693 e_border_hide(bd, 1);
3694 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3695 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3698 e_hints_window_iconic_set(bd);
3699 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3701 ev = E_NEW(E_Event_Border_Iconify, 1);
3703 e_object_ref(E_OBJECT(bd));
3704 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3705 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3707 if (e_config->transient.iconify)
3711 Eina_List *list = _e_border_sub_borders_new(bd);
3713 EINA_LIST_FOREACH(list, l, child)
3715 e_border_iconify(child);
3717 eina_list_free(list);
3719 e_remember_update(bd);
3722 #ifdef _F_DEICONIFY_APPROVE_
3724 _e_border_uniconify_timeout(void *data)
3731 if (!e_object_is_del(E_OBJECT(bd)))
3733 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3734 bd->client.e.state.deiconify_approve.render_done = 1;
3735 if (bd->client.e.state.deiconify_approve.req_list)
3737 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3739 child_bd->client.e.state.deiconify_approve.render_done = 1;
3740 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3743 bd->client.e.state.deiconify_approve.req_list = NULL;
3744 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3745 e_border_uniconify(bd);
3748 return ECORE_CALLBACK_CANCEL;
3752 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
3754 if (!bd || !bd_ancestor) return;
3756 if (e_config->deiconify_approve)
3758 if (e_config->transient.iconify)
3762 Eina_List *list = _e_border_sub_borders_new(bd);
3763 EINA_LIST_FOREACH(list, l, child)
3765 #ifdef _F_ZONE_WINDOW_ROTATION_
3766 if ((e_config->wm_win_rotation) &&
3767 ((child->client.e.state.rot.support) ||
3768 (child->client.e.state.rot.app_set)))
3770 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3771 _e_border_rotation_check(child);
3774 _e_border_deiconify_approve_send(child, bd_ancestor);
3775 if (child->client.e.state.deiconify_approve.support)
3777 ELBF(ELBT_BD, 0, child->client.win,
3778 "SEND DEICONIFY_APPROVE. ancestor:%x", bd_ancestor->client.win);
3780 ecore_x_client_message32_send(child->client.win,
3781 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3782 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3783 child->client.win, 0, 0, 0, 0);
3784 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3785 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3788 eina_list_free(list);
3794 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3796 E_Border *bd_ancestor;
3799 if (e_config->deiconify_approve)
3801 #ifdef _F_ZONE_WINDOW_ROTATION_
3802 if ((e_config->wm_win_rotation) &&
3803 ((bd->client.e.state.rot.support) ||
3804 (bd->client.e.state.rot.app_set)))
3806 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3807 _e_border_rotation_check(bd);
3811 if (e_config->transient.iconify)
3813 _e_border_deiconify_approve_send(bd, bd_ancestor);
3816 if (bd->client.e.state.deiconify_approve.support)
3818 ELBF(ELBT_BD, 0, bd->client.win,
3819 "SEND DEICONIFY_APPROVE.. ancestor:%x", bd_ancestor->client.win);
3821 ecore_x_client_message32_send(bd->client.win,
3822 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3823 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3824 bd->client.win, 0, 0, 0, 0);
3825 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3832 e_border_uniconify(E_Border *bd)
3835 E_Event_Border_Uniconify *ev;
3836 unsigned int iconic;
3839 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3841 #ifdef _F_DEICONIFY_APPROVE_
3842 if (e_config->deiconify_approve)
3844 if (bd->client.e.state.deiconify_approve.support)
3846 if (bd->client.e.state.deiconify_approve.wait_timer)
3848 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3851 if (bd->client.e.state.deiconify_approve.render_done == 0)
3853 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3854 _e_border_deiconify_approve_send_all_transient(bd);
3858 bd->client.e.state.deiconify_approve.render_done = 0;
3862 #if _F_ZONE_WINDOW_ROTATION_
3863 if (!bd->client.win)
3865 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3870 if (bd->shading) return;
3871 ecore_x_window_shadow_tree_flush();
3876 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3877 desk = e_desk_current_get(bd->desk->zone);
3878 #ifdef _F_USE_EXTENDED_ICONIFY_
3879 if (e_manager_comp_evas_get(bd->zone->container->manager))
3881 if (bd->await_hide_event > 0)
3882 bd->await_hide_event--;
3885 e_border_desk_set(bd, desk);
3887 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3890 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3892 ev = E_NEW(E_Event_Border_Uniconify, 1);
3894 e_object_ref(E_OBJECT(bd));
3895 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3896 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3898 if (e_config->transient.iconify)
3902 Eina_List *list = _e_border_sub_borders_new(bd);
3904 EINA_LIST_FOREACH(list, l, child)
3906 e_border_uniconify(child);
3908 eina_list_free(list);
3910 e_remember_update(bd);
3914 e_border_stick(E_Border *bd)
3916 E_Event_Border_Stick *ev;
3919 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3920 if (bd->sticky) return;
3922 e_hints_window_sticky_set(bd, 1);
3925 if (e_config->transient.desktop)
3929 Eina_List *list = _e_border_sub_borders_new(bd);
3931 EINA_LIST_FOREACH(list, l, child)
3934 e_hints_window_sticky_set(child, 1);
3935 e_border_show(child);
3937 eina_list_free(list);
3940 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
3941 ev = E_NEW(E_Event_Border_Stick, 1);
3943 e_object_ref(E_OBJECT(bd));
3944 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
3945 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
3946 e_remember_update(bd);
3950 e_border_unstick(E_Border *bd)
3952 E_Event_Border_Unstick *ev;
3955 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3956 /* Set the desk before we unstick the border */
3957 if (!bd->sticky) return;
3959 e_hints_window_sticky_set(bd, 0);
3961 if (e_config->transient.desktop)
3965 Eina_List *list = _e_border_sub_borders_new(bd);
3967 EINA_LIST_FOREACH(list, l, child)
3970 e_hints_window_sticky_set(child, 0);
3972 eina_list_free(list);
3975 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
3976 ev = E_NEW(E_Event_Border_Unstick, 1);
3978 e_object_ref(E_OBJECT(bd));
3979 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
3980 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
3982 e_border_desk_set(bd, e_desk_current_get(bd->zone));
3983 e_remember_update(bd);
3987 e_border_pinned_set(E_Border *bd,
3995 bd->borderless = set;
3996 bd->user_skip_winlist = set;
4000 stacking = E_STACKING_BELOW;
4005 stacking = E_STACKING_NONE;
4008 e_border_layer_set(bd, layer);
4009 e_hints_window_stacking_set(bd, stacking);
4011 bd->client.border.changed = 1;
4017 e_border_find_by_client_window(Ecore_X_Window win)
4021 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4022 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4023 (bd->client.win == win))
4029 e_border_find_all_by_client_window(Ecore_X_Window win)
4033 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4034 if ((bd) && (bd->client.win == win))
4040 e_border_find_by_frame_window(Ecore_X_Window win)
4044 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4045 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4046 (bd->bg_win == win))
4052 e_border_find_by_window(Ecore_X_Window win)
4056 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4057 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4064 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4069 EINA_LIST_FOREACH(borders, l, bd)
4071 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4072 (bd->client.netwm.sync.alarm == al))
4079 e_border_focused_get(void)
4085 _e_border_shape_input_rectangle_set(E_Border* bd)
4089 if ((bd->visible) && (bd->shaped_input))
4091 Ecore_X_Rectangle rects[4];
4092 Ecore_X_Window twin, twin2;
4095 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4096 0, 0, bd->w, bd->h);
4099 rects[0].width = bd->w;
4100 rects[0].height = bd->client_inset.t;
4102 rects[1].y = bd->client_inset.t;
4103 rects[1].width = bd->client_inset.l;
4104 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4105 rects[2].x = bd->w - bd->client_inset.r;
4106 rects[2].y = bd->client_inset.t;
4107 rects[2].width = bd->client_inset.r;
4108 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4110 rects[3].y = bd->h - bd->client_inset.b;
4111 rects[3].width = bd->w;
4112 rects[3].height = bd->client_inset.b;
4113 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4115 twin2 = ecore_x_window_override_new
4116 (bd->zone->container->scratch_win, 0, 0,
4117 bd->w - bd->client_inset.l - bd->client_inset.r,
4118 bd->h - bd->client_inset.t - bd->client_inset.b);
4121 if ((bd->shading) || (bd->shaded))
4123 if (bd->shade.dir == E_DIRECTION_UP)
4124 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4126 else if (bd->shade.dir == E_DIRECTION_LEFT)
4127 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4130 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4132 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4133 bd->w - bd->client_inset.l - bd->client_inset.r,
4134 bd->h - bd->client_inset.t - bd->client_inset.b);
4135 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4137 bd->client_inset.t);
4138 ecore_x_window_shape_input_window_set(bd->win, twin);
4139 ecore_x_window_free(twin2);
4140 ecore_x_window_free(twin);
4144 if (bd->visible) // not shaped input
4146 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4147 ecore_x_composite_window_events_enable(bd->win);
4149 ecore_x_composite_window_events_disable(bd->win);
4153 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4154 ecore_x_composite_window_events_enable(bd->win);
4156 ecore_x_composite_window_events_disable(bd->win);
4162 e_border_idler_before(void)
4171 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4173 EINA_LIST_FOREACH(man->containers, cl, con)
4178 // pass 1 - eval0. fetch properties on new or on change and
4179 // call hooks to decide what to do - maybe move/resize
4180 bl = e_container_border_list_last(con);
4181 while ((bd = e_container_border_list_prev(bl)))
4183 if (bd->changed) _e_border_eval0(bd);
4185 e_container_border_list_free(bl);
4187 // layout hook - this is where a hook gets to figure out what to
4189 _e_border_container_layout_hook(con);
4191 // pass 2 - show windows needing show
4192 bl = e_container_border_list_last(con);
4193 while ((bd = e_container_border_list_prev(bl)))
4195 if ((bd->changes.visible) && (bd->visible) &&
4196 (!bd->new_client) && (!bd->changes.pos) &&
4197 (!bd->changes.size))
4200 bd->changes.visible = 0;
4203 e_container_border_list_free(bl);
4205 // pass 3 - hide windows needing hide and eval (main eval)
4206 bl = e_container_border_list_first(con);
4207 while ((bd = e_container_border_list_next(bl)))
4209 if (e_object_is_del(E_OBJECT(bd))) continue;
4211 if ((bd->changes.visible) && (!bd->visible))
4214 bd->changes.visible = 0;
4217 if (bd->changed) _e_border_eval(bd);
4219 if ((bd->changes.visible) && (bd->visible))
4222 bd->changes.visible = 0;
4225 e_container_border_list_free(bl);
4231 E_Border *bd = NULL, *bd2;
4233 EINA_LIST_FREE(focus_next, bd2)
4234 if ((!bd) && (bd2->visible)) bd = bd2;
4238 /* TODO revert focus when lost here ? */
4244 /* already focused. but anyway dont be so strict, this
4245 fcks up illume setting focus on internal windows */
4250 focus_time = ecore_x_current_time_get();
4254 if ((bd->client.icccm.take_focus) &&
4255 (bd->client.icccm.accepts_focus))
4257 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4258 /* TODO what if the client didn't take focus ? */
4260 else if (!bd->client.icccm.accepts_focus)
4262 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4264 else if (!bd->client.icccm.take_focus)
4266 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4267 /* e_border_focus_set(bd, 1, 0); */
4271 #ifdef _F_ZONE_WINDOW_ROTATION_
4272 if ((e_config->wm_win_rotation) &&
4275 Ecore_X_Event_Client_Message *msg = NULL;
4277 EINA_LIST_FREE(rot.msgs, msg)
4279 t = msg->message_type;
4280 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4282 if ((rot.vkbd_ctrl_win) &&
4283 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4286 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4287 if (rot.vkbd_show_prepare_timer)
4288 _e_border_vkbd_show(rot.vkbd);
4290 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4293 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4295 if ((rot.vkbd_ctrl_win) &&
4296 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4299 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4300 if (rot.vkbd_hide_prepare_timer)
4302 _e_border_vkbd_hide(rot.vkbd);
4303 rot.vkbd_hide_prepare_timer = NULL;
4304 e_object_unref(E_OBJECT(rot.vkbd));
4307 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4310 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4312 rot.vkbd_ctrl_win = msg->data.l[0];
4313 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4315 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4317 if ((rot.vkbd_ctrl_win) &&
4318 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4320 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4321 E_Manager *m = e_manager_current_get();
4322 E_Zone *zone = NULL;
4323 if (m) zone = e_util_zone_current_get(m);
4324 if ((zone) && (rot.wait_prepare_done))
4326 if (!_e_border_rotation_start(zone, EINA_FALSE))
4328 if (rot.prepare_timer)
4329 ecore_timer_del(rot.prepare_timer);
4330 rot.prepare_timer = NULL;
4331 rot.wait_prepare_done = EINA_FALSE;
4339 rot.fetch = EINA_FALSE;
4345 e_border_client_list(void)
4347 /* FIXME: This should be a somewhat ordered list */
4351 static Ecore_X_Window action_input_win = 0;
4352 static E_Border *action_border = NULL;
4353 static Ecore_Event_Handler *action_handler_key = NULL;
4354 static Ecore_Event_Handler *action_handler_mouse = NULL;
4355 static Ecore_Timer *action_timer = NULL;
4356 static Ecore_X_Rectangle action_orig;
4359 _e_border_show(E_Border *bd)
4364 ecore_evas_show(bd->bg_ecore_evas);
4372 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4374 _e_border_shape_input_rectangle_set(bd);
4376 // ecore_x_composite_window_events_enable(bd->win);
4377 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4380 ecore_x_window_show(bd->win);
4382 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4383 ecore_x_window_show(tmp->win);
4387 _e_border_hide(E_Border *bd)
4392 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4394 ecore_x_window_hide(bd->win);
4395 ecore_evas_hide(bd->bg_ecore_evas);
4397 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4398 ecore_x_window_hide(tmp->win);
4402 ecore_x_composite_window_events_disable(bd->win);
4403 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4408 _e_border_action_input_win_del(void)
4410 if (!action_input_win)
4413 e_grabinput_release(action_input_win, action_input_win);
4414 ecore_x_window_free(action_input_win);
4415 action_input_win = 0;
4420 _e_border_action_input_win_new(E_Border *bd)
4422 if (!action_input_win)
4424 Ecore_X_Window parent = bd->zone->container->win;
4425 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4426 if (!action_input_win)
4430 ecore_x_window_show(action_input_win);
4431 if (e_grabinput_get(action_input_win, 0, action_input_win))
4434 _e_border_action_input_win_del();
4439 _e_border_action_finish(void)
4441 _e_border_action_input_win_del();
4445 ecore_timer_del(action_timer);
4446 action_timer = NULL;
4449 if (action_handler_key)
4451 ecore_event_handler_del(action_handler_key);
4452 action_handler_key = NULL;
4455 if (action_handler_mouse)
4457 ecore_event_handler_del(action_handler_mouse);
4458 action_handler_mouse = NULL;
4461 action_border = NULL;
4465 _e_border_action_init(E_Border *bd)
4467 action_orig.x = bd->x;
4468 action_orig.y = bd->y;
4469 action_orig.width = bd->w;
4470 action_orig.height = bd->h;
4476 _e_border_action_restore_orig(E_Border *bd)
4478 if (action_border != bd)
4481 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4485 _e_border_key_down_modifier_apply(int modifier,
4488 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4490 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4503 _e_border_action_move_timeout(void *data __UNUSED__)
4505 _e_border_move_end(action_border);
4506 _e_border_action_finish();
4507 return ECORE_CALLBACK_CANCEL;
4511 _e_border_action_move_timeout_add(void)
4514 ecore_timer_del(action_timer);
4515 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4519 _e_border_move_key_down(void *data __UNUSED__,
4520 int type __UNUSED__,
4523 Ecore_Event_Key *ev = event;
4526 if (ev->event_window != action_input_win)
4527 return ECORE_CALLBACK_PASS_ON;
4530 fputs("ERROR: no action_border!\n", stderr);
4534 x = action_border->x;
4535 y = action_border->y;
4537 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4538 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4539 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4540 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4541 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4542 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4543 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4544 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4545 else if (strcmp(ev->key, "Return") == 0)
4547 else if (strcmp(ev->key, "Escape") == 0)
4549 _e_border_action_restore_orig(action_border);
4552 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4553 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4556 e_border_move(action_border, x, y);
4557 _e_border_action_move_timeout_add();
4559 return ECORE_CALLBACK_PASS_ON;
4562 _e_border_move_end(action_border);
4563 _e_border_action_finish();
4564 return ECORE_CALLBACK_DONE;
4568 _e_border_move_mouse_down(void *data __UNUSED__,
4569 int type __UNUSED__,
4572 Ecore_Event_Mouse_Button *ev = event;
4574 if (ev->event_window != action_input_win)
4575 return ECORE_CALLBACK_PASS_ON;
4578 fputs("ERROR: no action_border!\n", stderr);
4580 _e_border_move_end(action_border);
4581 _e_border_action_finish();
4582 return ECORE_CALLBACK_DONE;
4586 e_border_act_move_keyboard(E_Border *bd)
4591 if (!_e_border_move_begin(bd))
4594 if (!_e_border_action_input_win_new(bd))
4596 _e_border_move_end(bd);
4600 _e_border_action_init(bd);
4601 _e_border_action_move_timeout_add();
4602 _e_border_move_update(bd);
4604 if (action_handler_key)
4605 ecore_event_handler_del(action_handler_key);
4606 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4608 if (action_handler_mouse)
4609 ecore_event_handler_del(action_handler_mouse);
4610 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4614 _e_border_action_resize_timeout(void *data __UNUSED__)
4616 _e_border_resize_end(action_border);
4617 _e_border_action_finish();
4618 return ECORE_CALLBACK_CANCEL;
4622 _e_border_action_resize_timeout_add(void)
4625 ecore_timer_del(action_timer);
4626 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4630 _e_border_resize_key_down(void *data __UNUSED__,
4631 int type __UNUSED__,
4634 Ecore_Event_Key *ev = event;
4637 if (ev->event_window != action_input_win)
4638 return ECORE_CALLBACK_PASS_ON;
4641 fputs("ERROR: no action_border!\n", stderr);
4645 w = action_border->w;
4646 h = action_border->h;
4648 dx = e_config->border_keyboard.resize.dx;
4649 if (dx < action_border->client.icccm.step_w)
4650 dx = action_border->client.icccm.step_w;
4651 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4652 if (dx < action_border->client.icccm.step_w)
4653 dx = action_border->client.icccm.step_w;
4655 dy = e_config->border_keyboard.resize.dy;
4656 if (dy < action_border->client.icccm.step_h)
4657 dy = action_border->client.icccm.step_h;
4658 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4659 if (dy < action_border->client.icccm.step_h)
4660 dy = action_border->client.icccm.step_h;
4662 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4664 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4666 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4668 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4670 else if (strcmp(ev->key, "Return") == 0)
4672 else if (strcmp(ev->key, "Escape") == 0)
4674 _e_border_action_restore_orig(action_border);
4677 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4678 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4681 e_border_resize_limit(action_border, &w, &h);
4682 e_border_resize(action_border, w, h);
4683 _e_border_action_resize_timeout_add();
4685 return ECORE_CALLBACK_PASS_ON;
4688 _e_border_resize_end(action_border);
4689 _e_border_action_finish();
4690 return ECORE_CALLBACK_DONE;
4694 _e_border_resize_mouse_down(void *data __UNUSED__,
4695 int type __UNUSED__,
4698 Ecore_Event_Mouse_Button *ev = event;
4700 if (ev->event_window != action_input_win)
4701 return ECORE_CALLBACK_PASS_ON;
4704 fputs("ERROR: no action_border!\n", stderr);
4706 _e_border_resize_end(action_border);
4707 _e_border_action_finish();
4708 return ECORE_CALLBACK_DONE;
4712 e_border_act_resize_keyboard(E_Border *bd)
4717 if (!_e_border_resize_begin(bd))
4720 if (!_e_border_action_input_win_new(bd))
4722 _e_border_resize_end(bd);
4726 _e_border_action_init(bd);
4727 _e_border_action_resize_timeout_add();
4728 _e_border_resize_update(bd);
4730 if (action_handler_key)
4731 ecore_event_handler_del(action_handler_key);
4732 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4734 if (action_handler_mouse)
4735 ecore_event_handler_del(action_handler_mouse);
4736 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4740 e_border_act_move_begin(E_Border *bd,
4741 Ecore_Event_Mouse_Button *ev)
4744 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4745 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4746 if (!_e_border_move_begin(bd))
4749 e_zone_edge_disable();
4751 _e_border_pointer_move_begin(bd);
4756 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4757 _e_border_moveinfo_gather(bd, source);
4762 e_border_act_move_end(E_Border *bd,
4763 Ecore_Event_Mouse_Button *ev __UNUSED__)
4766 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4767 if (!bd->moving) return;
4769 _e_border_pointer_move_end(bd);
4770 e_zone_edge_enable();
4771 _e_border_move_end(bd);
4772 e_zone_flip_coords_handle(bd->zone, -1, -1);
4776 e_border_act_resize_begin(E_Border *bd,
4777 Ecore_Event_Mouse_Button *ev)
4780 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4781 if (bd->lock_user_size) return;
4782 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4783 if (!_e_border_resize_begin(bd))
4785 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4787 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4789 bd->resize_mode = RESIZE_TL;
4790 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4794 bd->resize_mode = RESIZE_BL;
4795 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4800 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4802 bd->resize_mode = RESIZE_TR;
4803 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4807 bd->resize_mode = RESIZE_BR;
4808 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4811 _e_border_pointer_resize_begin(bd);
4816 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4817 _e_border_moveinfo_gather(bd, source);
4822 e_border_act_resize_end(E_Border *bd,
4823 Ecore_Event_Mouse_Button *ev __UNUSED__)
4826 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4827 if (bd->resize_mode != RESIZE_NONE)
4829 _e_border_pointer_resize_end(bd);
4830 bd->resize_mode = RESIZE_NONE;
4831 _e_border_resize_end(bd);
4832 bd->changes.reset_gravity = 1;
4838 e_border_act_menu_begin(E_Border *bd,
4839 Ecore_Event_Mouse_Button *ev,
4843 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4846 e_int_border_menu_show(bd,
4847 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4848 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4855 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4856 e_int_border_menu_show(bd, x, y, key, 0);
4861 e_border_act_close_begin(E_Border *bd)
4864 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4865 if (bd->lock_close) return;
4866 if (bd->client.icccm.delete_request)
4868 bd->delete_requested = 1;
4869 ecore_x_window_delete_request_send(bd->client.win);
4870 if (bd->client.netwm.ping)
4873 else if (e_config->kill_if_close_not_possible)
4875 e_border_act_kill_begin(bd);
4880 e_border_act_kill_begin(E_Border *bd)
4883 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4884 if (bd->internal) return;
4885 if (bd->lock_close) return;
4886 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4888 kill(bd->client.netwm.pid, SIGINT);
4889 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4890 _e_border_cb_kill_timer, bd);
4894 if (!bd->internal) ecore_x_kill(bd->client.win);
4899 e_border_icon_add(E_Border *bd,
4904 E_OBJECT_CHECK_RETURN(bd, NULL);
4905 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4910 if (!bd->internal_icon)
4912 o = e_icon_add(evas);
4913 e_util_icon_theme_set(o, "enlightenment");
4917 if (!bd->internal_icon_key)
4921 ext = strrchr(bd->internal_icon, '.');
4922 if ((ext) && ((!strcmp(ext, ".edj"))))
4924 o = edje_object_add(evas);
4925 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4926 e_util_icon_theme_set(o, "enlightenment");
4930 o = e_icon_add(evas);
4931 e_icon_file_set(o, bd->internal_icon);
4935 o = e_icon_add(evas);
4936 if (!e_util_icon_theme_set(o, bd->internal_icon))
4937 e_util_icon_theme_set(o, "enlightenment");
4942 o = edje_object_add(evas);
4943 edje_object_file_set(o, bd->internal_icon,
4944 bd->internal_icon_key);
4949 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
4951 if (bd->client.netwm.icons)
4953 o = e_icon_add(evas);
4954 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4955 bd->client.netwm.icons[0].width,
4956 bd->client.netwm.icons[0].height);
4957 e_icon_alpha_set(o, 1);
4963 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
4965 o = e_icon_add(evas);
4968 e_icon_fdo_icon_set(o, bd->desktop->icon);
4972 else if (bd->client.netwm.icons)
4974 o = e_icon_add(evas);
4975 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4976 bd->client.netwm.icons[0].width,
4977 bd->client.netwm.icons[0].height);
4978 e_icon_alpha_set(o, 1);
4983 o = e_icon_add(evas);
4984 e_util_icon_theme_set(o, "unknown");
4989 e_border_button_bindings_ungrab_all(void)
4994 EINA_LIST_FOREACH(borders, l, bd)
4996 e_focus_setdown(bd);
4997 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4998 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5003 e_border_button_bindings_grab_all(void)
5008 EINA_LIST_FOREACH(borders, l, bd)
5010 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5011 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5017 e_border_focus_stack_get(void)
5023 e_border_raise_stack_get(void)
5029 e_border_lost_windows_get(E_Zone *zone)
5031 Eina_List *list = NULL, *l;
5033 int loss_overlap = 5;
5035 E_OBJECT_CHECK_RETURN(zone, NULL);
5036 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5037 EINA_LIST_FOREACH(borders, l, bd)
5042 if ((bd->zone != zone) ||
5043 (bd->zone->container != zone->container))
5046 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5047 bd->zone->y + loss_overlap,
5048 bd->zone->w - (2 * loss_overlap),
5049 bd->zone->h - (2 * loss_overlap),
5050 bd->x, bd->y, bd->w, bd->h))
5052 list = eina_list_append(list, bd);
5054 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5055 bd->zone->w, bd->zone->h,
5056 bd->x, bd->y, bd->w, bd->h)) &&
5059 Ecore_X_Rectangle *rect;
5062 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5068 for (i = 0; i < num; i++)
5070 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5071 bd->zone->y + loss_overlap,
5072 bd->zone->w - (2 * loss_overlap),
5073 bd->zone->h - (2 * loss_overlap),
5074 rect[i].x, rect[i].y,
5075 (int)rect[i].width, (int)rect[i].height))
5083 list = eina_list_append(list, bd);
5091 e_border_ping(E_Border *bd)
5094 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5095 if (!e_config->ping_clients) return;
5097 ecore_x_netwm_ping_send(bd->client.win);
5098 bd->ping = ecore_loop_time_get();
5099 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5100 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5101 e_config->ping_clients_interval,
5102 _e_border_cb_ping_poller, bd);
5106 e_border_move_cancel(void)
5110 if (bdmove->cur_mouse_action)
5115 e_object_ref(E_OBJECT(bd));
5116 if (bd->cur_mouse_action->func.end_mouse)
5117 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5118 else if (bd->cur_mouse_action->func.end)
5119 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5120 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5121 bd->cur_mouse_action = NULL;
5122 e_object_unref(E_OBJECT(bd));
5125 _e_border_move_end(bdmove);
5130 e_border_resize_cancel(void)
5134 if (bdresize->cur_mouse_action)
5139 e_object_ref(E_OBJECT(bd));
5140 if (bd->cur_mouse_action->func.end_mouse)
5141 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5142 else if (bd->cur_mouse_action->func.end)
5143 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5144 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5145 bd->cur_mouse_action = NULL;
5146 e_object_unref(E_OBJECT(bd));
5150 bdresize->resize_mode = RESIZE_NONE;
5151 _e_border_resize_end(bdresize);
5157 e_border_frame_recalc(E_Border *bd)
5159 if (!bd->bg_object) return;
5161 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5162 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5164 _e_border_client_inset_calc(bd);
5166 bd->w += (bd->client_inset.l + bd->client_inset.r);
5167 bd->h += (bd->client_inset.t + bd->client_inset.b);
5170 bd->changes.size = 1;
5171 if ((bd->shaped) || (bd->client.shaped))
5173 bd->need_shape_merge = 1;
5174 bd->need_shape_export = 1;
5176 if (bd->shaped_input)
5178 bd->need_shape_merge = 1;
5180 _e_border_client_move_resize_send(bd);
5184 e_border_immortal_windows_get(void)
5186 Eina_List *list = NULL, *l;
5189 EINA_LIST_FOREACH(borders, l, bd)
5192 list = eina_list_append(list, bd);
5198 e_border_name_get(const E_Border *bd)
5200 E_OBJECT_CHECK_RETURN(bd, "");
5201 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5202 if (bd->client.netwm.name)
5203 return bd->client.netwm.name;
5204 else if (bd->client.icccm.title)
5205 return bd->client.icccm.title;
5210 e_border_signal_move_begin(E_Border *bd,
5212 const char *src __UNUSED__)
5215 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5217 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5218 if (!_e_border_move_begin(bd)) return;
5220 _e_border_pointer_move_begin(bd);
5221 e_zone_edge_disable();
5222 _e_border_moveinfo_gather(bd, sig);
5223 if (bd->cur_mouse_action)
5225 if ((!bd->cur_mouse_action->func.end_mouse) &&
5226 (!bd->cur_mouse_action->func.end))
5227 bd->cur_mouse_action = NULL;
5229 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5231 bd->cur_mouse_action = e_action_find("window_move");
5232 if (bd->cur_mouse_action)
5233 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5237 e_border_signal_move_end(E_Border *bd,
5238 const char *sig __UNUSED__,
5239 const char *src __UNUSED__)
5242 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5243 if (!bd->moving) return;
5245 _e_border_pointer_move_end(bd);
5246 e_zone_edge_enable();
5247 _e_border_move_end(bd);
5248 e_zone_flip_coords_handle(bd->zone, -1, -1);
5252 e_border_resizing_get(E_Border *bd)
5254 E_OBJECT_CHECK_RETURN(bd, 0);
5255 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5256 if (bd->resize_mode == RESIZE_NONE) return 0;
5261 e_border_signal_resize_begin(E_Border *bd,
5264 const char *src __UNUSED__)
5266 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5267 int resize_mode = RESIZE_BR;
5270 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5272 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5273 if (!_e_border_resize_begin(bd))
5275 if (!strcmp(dir, "tl"))
5277 resize_mode = RESIZE_TL;
5278 grav = ECORE_X_GRAVITY_SE;
5280 else if (!strcmp(dir, "t"))
5282 resize_mode = RESIZE_T;
5283 grav = ECORE_X_GRAVITY_S;
5285 else if (!strcmp(dir, "tr"))
5287 resize_mode = RESIZE_TR;
5288 grav = ECORE_X_GRAVITY_SW;
5290 else if (!strcmp(dir, "r"))
5292 resize_mode = RESIZE_R;
5293 grav = ECORE_X_GRAVITY_W;
5295 else if (!strcmp(dir, "br"))
5297 resize_mode = RESIZE_BR;
5298 grav = ECORE_X_GRAVITY_NW;
5300 else if (!strcmp(dir, "b"))
5302 resize_mode = RESIZE_B;
5303 grav = ECORE_X_GRAVITY_N;
5305 else if (!strcmp(dir, "bl"))
5307 resize_mode = RESIZE_BL;
5308 grav = ECORE_X_GRAVITY_NE;
5310 else if (!strcmp(dir, "l"))
5312 resize_mode = RESIZE_L;
5313 grav = ECORE_X_GRAVITY_E;
5315 bd->resize_mode = resize_mode;
5316 _e_border_pointer_resize_begin(bd);
5317 _e_border_moveinfo_gather(bd, sig);
5319 if (bd->cur_mouse_action)
5321 if ((!bd->cur_mouse_action->func.end_mouse) &&
5322 (!bd->cur_mouse_action->func.end))
5323 bd->cur_mouse_action = NULL;
5325 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5327 bd->cur_mouse_action = e_action_find("window_resize");
5328 if (bd->cur_mouse_action)
5329 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5333 e_border_signal_resize_end(E_Border *bd,
5334 const char *dir __UNUSED__,
5335 const char *sig __UNUSED__,
5336 const char *src __UNUSED__)
5339 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5340 if (bd->resize_mode == RESIZE_NONE) return;
5341 _e_border_resize_handle(bd);
5342 _e_border_pointer_resize_end(bd);
5343 bd->resize_mode = RESIZE_NONE;
5344 _e_border_resize_end(bd);
5345 bd->changes.reset_gravity = 1;
5350 e_border_resize_limit(E_Border *bd,
5357 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5358 *w -= bd->client_inset.l + bd->client_inset.r;
5359 *h -= bd->client_inset.t + bd->client_inset.b;
5362 if ((bd->client.icccm.base_w >= 0) &&
5363 (bd->client.icccm.base_h >= 0))
5367 tw = *w - bd->client.icccm.base_w;
5368 th = *h - bd->client.icccm.base_h;
5371 a = (double)(tw) / (double)(th);
5372 if ((bd->client.icccm.min_aspect != 0.0) &&
5373 (a < bd->client.icccm.min_aspect))
5375 th = tw / bd->client.icccm.max_aspect;
5376 *h = th + bd->client.icccm.base_h;
5378 else if ((bd->client.icccm.max_aspect != 0.0) &&
5379 (a > bd->client.icccm.max_aspect))
5381 tw = th * bd->client.icccm.max_aspect;
5382 *w = tw + bd->client.icccm.base_w;
5387 a = (double)*w / (double)*h;
5388 if ((bd->client.icccm.min_aspect != 0.0) &&
5389 (a < bd->client.icccm.min_aspect))
5390 *h = *w / bd->client.icccm.min_aspect;
5391 else if ((bd->client.icccm.max_aspect != 0.0) &&
5392 (a > bd->client.icccm.max_aspect))
5393 *w = *h * bd->client.icccm.max_aspect;
5395 if (bd->client.icccm.step_w > 0)
5397 if (bd->client.icccm.base_w >= 0)
5398 *w = bd->client.icccm.base_w +
5399 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5400 bd->client.icccm.step_w);
5402 *w = bd->client.icccm.min_w +
5403 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5404 bd->client.icccm.step_w);
5406 if (bd->client.icccm.step_h > 0)
5408 if (bd->client.icccm.base_h >= 0)
5409 *h = bd->client.icccm.base_h +
5410 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5411 bd->client.icccm.step_h);
5413 *h = bd->client.icccm.min_h +
5414 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5415 bd->client.icccm.step_h);
5421 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5422 else if (*w < bd->client.icccm.min_w)
5423 *w = bd->client.icccm.min_w;
5424 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5425 else if (*h < bd->client.icccm.min_h)
5426 *h = bd->client.icccm.min_h;
5428 *w += bd->client_inset.l + bd->client_inset.r;
5429 *h += bd->client_inset.t + bd->client_inset.b;
5432 /* local subsystem functions */
5434 _e_border_free(E_Border *bd)
5436 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5439 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5441 bd->client.e.state.video_parent_border->client.e.state.video_child =
5443 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5446 if (bd->client.e.state.video_child)
5450 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5452 tmp->client.e.state.video_parent_border = NULL;
5457 efreet_desktop_free(bd->desktop);
5462 ecore_idle_enterer_del(bd->post_job);
5463 bd->post_job = NULL;
5467 e_object_del(E_OBJECT(bd->pointer));
5471 _e_border_resize_end(bd);
5473 _e_border_move_end(bd);
5474 /* TODO: Other states to end before dying? */
5476 if (bd->cur_mouse_action)
5478 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5479 bd->cur_mouse_action = NULL;
5482 E_FREE(bd->shape_rects);
5483 bd->shape_rects_num = 0;
5485 if (bd->dangling_ref_check)
5487 ecore_timer_del(bd->dangling_ref_check);
5488 bd->dangling_ref_check = NULL;
5493 ecore_timer_del(bd->kill_timer);
5494 bd->kill_timer = NULL;
5496 if (bd->ping_poller)
5498 ecore_poller_del(bd->ping_poller);
5499 bd->ping_poller = NULL;
5501 E_FREE_LIST(bd->pending_move_resize, free);
5503 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5504 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5506 if (bd->border_locks_dialog)
5508 e_object_del(E_OBJECT(bd->border_locks_dialog));
5509 bd->border_locks_dialog = NULL;
5511 if (bd->border_remember_dialog)
5513 e_object_del(E_OBJECT(bd->border_remember_dialog));
5514 bd->border_remember_dialog = NULL;
5516 if (bd->border_border_dialog)
5518 e_object_del(E_OBJECT(bd->border_border_dialog));
5519 bd->border_border_dialog = NULL;
5521 if (bd->border_prop_dialog)
5523 e_object_del(E_OBJECT(bd->border_prop_dialog));
5524 bd->border_prop_dialog = NULL;
5527 e_int_border_menu_del(bd);
5532 focus_next = eina_list_remove(focus_next, bd);
5534 if ((focused == bd) ||
5535 (e_grabinput_last_focus_win_get() == bd->client.win))
5537 if ((!focus_next) && (!focusing))
5539 e_grabinput_focus(bd->zone->container->bg_win,
5540 E_FOCUS_METHOD_PASSIVE);
5541 e_hints_active_window_set(bd->zone->container->manager, NULL);
5546 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5552 bd->remember = NULL;
5553 e_remember_unuse(rem);
5555 if (!bd->already_unparented)
5557 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5558 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5559 ecore_x_window_save_set_del(bd->client.win);
5560 bd->already_unparented = 1;
5562 if (bd->group) eina_list_free(bd->group);
5563 if (bd->transients) eina_list_free(bd->transients);
5564 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5565 if (bd->client.netwm.icons)
5568 for (i = 0; i < bd->client.netwm.num_icons; i++)
5569 free(bd->client.netwm.icons[i].data);
5570 free(bd->client.netwm.icons);
5572 if (bd->client.netwm.extra_types)
5573 free(bd->client.netwm.extra_types);
5574 if (bd->client.border.name)
5575 eina_stringshare_del(bd->client.border.name);
5577 eina_stringshare_del(bd->bordername);
5578 if (bd->client.icccm.name)
5579 eina_stringshare_del(bd->client.icccm.name);
5580 if (bd->client.icccm.class)
5582 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5583 e_bindings_mapping_change_enable(EINA_TRUE);
5584 eina_stringshare_del(bd->client.icccm.class);
5586 if (bd->client.icccm.title)
5587 eina_stringshare_del(bd->client.icccm.title);
5588 if (bd->client.icccm.icon_name)
5589 eina_stringshare_del(bd->client.icccm.icon_name);
5590 if (bd->client.icccm.machine)
5591 eina_stringshare_del(bd->client.icccm.machine);
5592 if (bd->client.icccm.window_role)
5593 eina_stringshare_del(bd->client.icccm.window_role);
5595 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5599 for (i = 0; i < bd->client.icccm.command.argc; i++)
5600 free(bd->client.icccm.command.argv[i]);
5601 free(bd->client.icccm.command.argv);
5603 if (bd->client.netwm.name)
5604 eina_stringshare_del(bd->client.netwm.name);
5605 if (bd->client.netwm.icon_name)
5606 eina_stringshare_del(bd->client.netwm.icon_name);
5607 e_object_del(E_OBJECT(bd->shape));
5608 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5609 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5610 if (bd->icon_object) evas_object_del(bd->icon_object);
5611 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5612 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5614 if (str) eina_stringshare_del(str);
5616 bd->client.e.state.profiles = NULL;
5617 if (bd->client.e.state.profile)
5618 eina_stringshare_del(bd->client.e.state.profile);
5619 bd->client.e.state.profile = NULL;
5621 #ifdef _F_ZONE_WINDOW_ROTATION_
5622 if (e_config->wm_win_rotation)
5624 bd->client.e.fetch.rot.app_set = 0;
5625 bd->client.e.state.rot.preferred_rot = -1;
5627 if (bd->client.e.state.rot.available_rots)
5628 E_FREE(bd->client.e.state.rot.available_rots);
5630 _e_border_rotation_list_remove(bd);
5631 if ((rot.vkbd) && (rot.vkbd == bd))
5633 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5635 if (rot.vkbd_ctrl_win)
5637 ELB(ELBT_BD, "SET KBD_OFF", 0);
5638 ecore_x_e_virtual_keyboard_state_set
5639 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5642 rot.vkbd_hide_prepare_done = EINA_FALSE;
5643 if (rot.vkbd_hide_prepare_timer)
5644 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5645 rot.vkbd_hide_prepare_timer = NULL;
5646 if (rot.vkbd_hide_timer)
5647 ecore_timer_del(rot.vkbd_hide_timer);
5648 rot.vkbd_hide_timer = NULL;
5650 rot.vkbd_show_prepare_done = EINA_FALSE;
5651 if (rot.vkbd_show_prepare_timer)
5652 ecore_timer_del(rot.vkbd_show_prepare_timer);
5653 rot.vkbd_show_prepare_timer = NULL;
5654 if (rot.vkbd_show_timer)
5655 ecore_timer_del(rot.vkbd_show_timer);
5656 rot.vkbd_show_timer = NULL;
5658 else if ((rot.vkbd_prediction) &&
5659 (rot.vkbd_prediction == bd))
5660 rot.vkbd_prediction = NULL;
5663 evas_object_del(bd->bg_object);
5664 e_canvas_del(bd->bg_ecore_evas);
5665 ecore_evas_free(bd->bg_ecore_evas);
5666 ecore_x_window_free(bd->client.shell_win);
5667 e_focus_setdown(bd);
5668 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5669 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5670 ecore_x_window_free(bd->win);
5672 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5673 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5674 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5675 borders = eina_list_remove(borders, bd);
5676 focus_stack = eina_list_remove(focus_stack, bd);
5677 raise_stack = eina_list_remove(raise_stack, bd);
5679 e_container_border_remove(bd);
5685 _e_border_del_dangling_ref_check(void *data)
5691 printf("EEK EEK border still around 1 second after being deleted!\n");
5692 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5693 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5694 bd->client.icccm.name, bd->client.icccm.class);
5695 // e_object_breadcrumb_debug(E_OBJECT(bd));
5702 _e_border_del(E_Border *bd)
5704 E_Event_Border_Remove *ev;
5707 #ifdef _F_BORDER_HOOK_PATCH_
5708 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5719 focus_next = eina_list_remove(focus_next, bd);
5721 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5723 if ((drag_border) && (drag_border->data == bd))
5725 e_object_del(E_OBJECT(drag_border));
5728 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5730 if (bd->border_locks_dialog)
5732 e_object_del(E_OBJECT(bd->border_locks_dialog));
5733 bd->border_locks_dialog = NULL;
5735 if (bd->border_remember_dialog)
5737 e_object_del(E_OBJECT(bd->border_remember_dialog));
5738 bd->border_remember_dialog = NULL;
5740 if (bd->border_border_dialog)
5742 e_object_del(E_OBJECT(bd->border_border_dialog));
5743 bd->border_border_dialog = NULL;
5745 if (bd->border_prop_dialog)
5747 e_object_del(E_OBJECT(bd->border_prop_dialog));
5748 bd->border_prop_dialog = NULL;
5751 e_int_border_menu_del(bd);
5753 if (bd->raise_timer)
5755 ecore_timer_del(bd->raise_timer);
5756 bd->raise_timer = NULL;
5758 if (!bd->already_unparented)
5760 ecore_x_window_reparent(bd->client.win,
5761 bd->zone->container->manager->root,
5762 bd->x + bd->client_inset.l,
5763 bd->y + bd->client_inset.t);
5764 ecore_x_window_save_set_del(bd->client.win);
5765 bd->already_unparented = 1;
5766 // bd->client.win = 0;
5768 bd->already_unparented = 1;
5770 if ((!bd->new_client) && (!stopping))
5772 ev = E_NEW(E_Event_Border_Remove, 1);
5774 e_object_ref(E_OBJECT(bd));
5775 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5776 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5781 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5782 if (bd->parent->modal == bd)
5784 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5785 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5786 bd->parent->lock_close = 0;
5787 bd->parent->saved.event_mask = 0;
5788 bd->parent->modal = NULL;
5792 EINA_LIST_FREE(bd->transients, child)
5794 child->parent = NULL;
5797 #ifdef _F_DEICONIFY_APPROVE_
5798 bd->client.e.state.deiconify_approve.render_done = 0;
5800 E_Border *ancestor_bd;
5801 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5802 if ((ancestor_bd) &&
5803 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5805 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5806 bd->client.e.state.deiconify_approve.ancestor = NULL;
5808 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5809 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5811 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5813 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5814 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5815 e_border_uniconify(ancestor_bd);
5820 if (bd->client.e.state.deiconify_approve.wait_timer)
5822 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5823 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5826 if (bd->client.e.state.deiconify_approve.req_list)
5828 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5830 child->client.e.state.deiconify_approve.render_done = 0;
5831 child->client.e.state.deiconify_approve.ancestor = NULL;
5838 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5839 if (bd->leader->modal == bd)
5840 bd->leader->modal = NULL;
5843 EINA_LIST_FREE(bd->group, child)
5845 child->leader = NULL;
5849 #ifdef PRINT_LOTS_OF_DEBUG
5851 _e_border_print(E_Border *bd,
5860 "\tBorderless: %s\n",
5861 bd, bd->client.icccm.name, bd->client.icccm.title,
5862 bd->borderless ? "TRUE" : "FALSE");
5868 _e_border_cb_window_show_request(void *data __UNUSED__,
5869 int ev_type __UNUSED__,
5874 Ecore_X_Event_Window_Show_Request *e;
5877 bd = e_border_find_by_client_window(e->win);
5878 if (!bd) return ECORE_CALLBACK_PASS_ON;
5880 if ((e_config->wm_win_rotation) &&
5881 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
5883 (rot.vkbd_hide_prepare_timer))
5885 con = bd->zone->container;
5886 bd = e_border_new(con, e->win, 0, 0);
5891 if (!bd->lock_client_iconify)
5892 e_border_uniconify(bd);
5896 /* FIXME: make border "urgent" for a bit - it wants attention */
5897 /* e_border_show(bd); */
5898 if (!bd->lock_client_stacking)
5901 return ECORE_CALLBACK_PASS_ON;
5905 _e_border_cb_window_destroy(void *data __UNUSED__,
5906 int ev_type __UNUSED__,
5910 Ecore_X_Event_Window_Destroy *e;
5913 bd = e_border_find_by_client_window(e->win);
5914 if (!bd) return ECORE_CALLBACK_PASS_ON;
5915 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
5916 #ifdef _F_ZONE_WINDOW_ROTATION_
5917 if (e_config->wm_win_rotation)
5919 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
5921 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
5922 if (!rot.vkbd_hide_prepare_timer)
5924 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
5925 e_border_hide(bd, 0);
5926 if (!rot.vkbd_hide_prepare_timer)
5928 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
5929 e_object_del(E_OBJECT(bd));
5932 return ECORE_CALLBACK_PASS_ON;
5936 e_border_hide(bd, 0);
5937 e_object_del(E_OBJECT(bd));
5938 return ECORE_CALLBACK_PASS_ON;
5942 _e_border_cb_window_hide(void *data __UNUSED__,
5943 int ev_type __UNUSED__,
5946 E_Border *bd = NULL;
5947 Ecore_X_Event_Window_Hide *e;
5950 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
5951 // not interested in hide events from windows other than the window in question
5952 if (e->win != e->event_win)
5954 bd = e_border_find_by_client_window(e->win);
5955 if (!bd) return ECORE_CALLBACK_PASS_ON;
5956 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
5960 (bd->zone->container->manager->root == e->event_win)))
5961 return ECORE_CALLBACK_PASS_ON;
5964 if (!bd) bd = e_border_find_by_client_window(e->win);
5965 // printf(" bd = %p\n", bd);
5968 if (ecore_x_window_visible_get(e->win))
5970 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
5971 ecore_x_window_hide(e->win);
5973 return ECORE_CALLBACK_PASS_ON;
5976 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
5977 if (bd->ignore_first_unmap > 0)
5979 bd->ignore_first_unmap--;
5980 return ECORE_CALLBACK_PASS_ON;
5982 /* Don't delete hidden or iconified windows */
5983 #ifdef _F_USE_EXTENDED_ICONIFY_
5984 if (bd->await_hide_event > 0)
5986 if ((bd->iconic) || (bd->await_hide_event > 0))
5989 // printf(" Don't delete hidden or iconified windows\n");
5990 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
5991 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
5992 if (bd->await_hide_event > 0)
5994 bd->await_hide_event--;
5998 // printf(" hide really\n");
5999 /* Only hide the border if it is visible */
6000 if (bd->visible) e_border_hide(bd, 1);
6005 // printf(" hide2\n");
6006 #ifdef _F_USE_EXTENDED_ICONIFY_
6014 #ifdef _F_ZONE_WINDOW_ROTATION_
6015 if (e_config->wm_win_rotation)
6017 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6019 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6020 if (!rot.vkbd_hide_prepare_timer)
6022 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6023 e_border_hide(bd, 0);
6024 if (!rot.vkbd_hide_prepare_timer)
6026 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6027 e_object_del(E_OBJECT(bd));
6030 return ECORE_CALLBACK_PASS_ON;
6034 e_border_hide(bd, 0);
6035 e_object_del(E_OBJECT(bd));
6037 return ECORE_CALLBACK_PASS_ON;
6041 _e_border_cb_window_reparent(void *data __UNUSED__,
6042 int ev_type __UNUSED__,
6043 void *ev __UNUSED__)
6047 Ecore_X_Event_Window_Reparent *e;
6050 bd = e_border_find_by_client_window(e->win);
6052 if (e->parent == bd->client.shell_win) return 1;
6053 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6057 e_border_hide(bd, 0);
6058 e_object_del(E_OBJECT(bd));
6060 return ECORE_CALLBACK_PASS_ON;
6064 _e_border_cb_window_configure_request(void *data __UNUSED__,
6065 int ev_type __UNUSED__,
6069 Ecore_X_Event_Window_Configure_Request *e;
6072 bd = e_border_find_by_client_window(e->win);
6075 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6076 if (!e_util_container_window_find(e->win))
6077 ecore_x_window_configure(e->win, e->value_mask,
6078 e->x, e->y, e->w, e->h, e->border,
6079 e->abovewin, e->detail);
6080 return ECORE_CALLBACK_PASS_ON;
6083 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6084 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6090 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6092 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6094 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6095 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6101 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6102 w = e->w + bd->client_inset.l + bd->client_inset.r;
6103 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6104 h = e->h + bd->client_inset.t + bd->client_inset.b;
6105 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6107 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6109 bd->saved.x = x - bd->zone->x;
6110 bd->saved.y = y - bd->zone->y;
6115 e_border_move_resize(bd, x, y, w, h);
6117 else if (!bd->lock_client_location)
6119 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6121 bd->saved.x = x - bd->zone->x;
6122 bd->saved.y = y - bd->zone->y;
6125 e_border_move(bd, x, y);
6127 else if (!bd->lock_client_size)
6129 if ((bd->shaded) || (bd->shading))
6135 if ((bd->shade.dir == E_DIRECTION_UP) ||
6136 (bd->shade.dir == E_DIRECTION_DOWN))
6138 e_border_resize(bd, w, bd->h);
6143 e_border_resize(bd, bd->w, h);
6149 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6155 e_border_resize(bd, w, h);
6161 if (!bd->lock_client_location)
6163 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6165 bd->saved.x = x - bd->zone->x;
6166 bd->saved.y = y - bd->zone->y;
6169 e_border_move(bd, x, y);
6173 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6174 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6180 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6181 w = e->w + bd->client_inset.l + bd->client_inset.r;
6182 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6183 h = e->h + bd->client_inset.t + bd->client_inset.b;
6184 #ifdef _F_ZONE_WINDOW_ROTATION_
6185 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6187 if (!bd->lock_client_size)
6189 if ((bd->shaded) || (bd->shading))
6195 if ((bd->shade.dir == E_DIRECTION_UP) ||
6196 (bd->shade.dir == E_DIRECTION_DOWN))
6198 e_border_resize(bd, w, bd->h);
6203 e_border_resize(bd, bd->w, h);
6209 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6214 zx = zy = zw = zh = 0;
6217 * This code does resize and move a window on a
6218 * X configure request into an useful geometry.
6219 * This is really useful for size jumping file dialogs.
6224 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6226 if (e_config->geometry_auto_resize_limit == 1)
6235 e_border_resize(bd, w, h);
6237 if (e_config->geometry_auto_move == 1)
6239 /* z{x,y,w,h} are only set here; FIXME! */
6242 // move window horizontal if resize to not useful geometry
6243 if (bd->x + bd->w > zx + zw)
6244 rx = zx + zw - bd->w;
6245 else if (bd->x < zx)
6248 // move window vertical if resize to not useful geometry
6249 if (bd->y + bd->h > zy + zh)
6250 ry = zy + zh - bd->h;
6251 else if (bd->y < zy)
6254 e_border_move(bd, rx, ry);
6260 if (!bd->lock_client_stacking)
6262 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6263 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6267 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6269 obd = e_border_find_by_client_window(e->abovewin);
6272 e_border_stack_above(bd, obd);
6276 ecore_x_window_configure(bd->win,
6277 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6278 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6280 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6281 /* FIXME: need to rebuiuld border list from current stacking */
6284 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6286 obd = e_border_find_by_client_window(e->abovewin);
6289 e_border_stack_below(bd, obd);
6293 ecore_x_window_configure(bd->win,
6294 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6295 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6297 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6298 /* FIXME: need to rebuiuld border list from current stacking */
6301 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6305 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6309 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6314 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6316 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6320 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6324 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6328 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6332 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6339 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6340 _e_border_client_move_resize_send(bd);
6341 return ECORE_CALLBACK_PASS_ON;
6345 _e_border_cb_window_resize_request(void *data __UNUSED__,
6346 int ev_type __UNUSED__,
6350 Ecore_X_Event_Window_Resize_Request *e;
6353 bd = e_border_find_by_client_window(e->win);
6356 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6357 ecore_x_window_resize(e->win, e->w, e->h);
6358 return ECORE_CALLBACK_PASS_ON;
6363 w = e->w + bd->client_inset.l + bd->client_inset.r;
6364 h = e->h + bd->client_inset.t + bd->client_inset.b;
6365 if ((bd->shaded) || (bd->shading))
6371 if ((bd->shade.dir == E_DIRECTION_UP) ||
6372 (bd->shade.dir == E_DIRECTION_DOWN))
6374 e_border_resize(bd, w, bd->h);
6379 e_border_resize(bd, bd->w, h);
6384 e_border_resize(bd, w, h);
6387 _e_border_client_move_resize_send(bd);
6388 return ECORE_CALLBACK_PASS_ON;
6392 _e_border_cb_window_gravity(void *data __UNUSED__,
6393 int ev_type __UNUSED__,
6394 void *ev __UNUSED__)
6397 // Ecore_X_Event_Window_Gravity *e;
6400 // bd = e_border_find_by_client_window(e->win);
6401 // if (!bd) return 1;
6406 _e_border_cb_window_stack_request(void *data __UNUSED__,
6407 int ev_type __UNUSED__,
6411 Ecore_X_Event_Window_Stack_Request *e;
6414 bd = e_border_find_by_client_window(e->win);
6417 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6418 if (!e_util_container_window_find(e->win))
6420 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6421 ecore_x_window_raise(e->win);
6422 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6423 ecore_x_window_lower(e->win);
6425 return ECORE_CALLBACK_PASS_ON;
6427 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6429 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6431 return ECORE_CALLBACK_PASS_ON;
6435 _e_border_cb_window_property(void *data __UNUSED__,
6436 int ev_type __UNUSED__,
6440 Ecore_X_Event_Window_Property *e;
6443 bd = e_border_find_by_client_window(e->win);
6444 if (!bd) return ECORE_CALLBACK_PASS_ON;
6445 if (e->atom == ECORE_X_ATOM_WM_NAME)
6447 if ((!bd->client.netwm.name) &&
6448 (!bd->client.netwm.fetch.name))
6450 bd->client.icccm.fetch.title = 1;
6454 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6456 bd->client.netwm.fetch.name = 1;
6459 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6461 bd->client.icccm.fetch.name_class = 1;
6464 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6466 if ((!bd->client.netwm.icon_name) &&
6467 (!bd->client.netwm.fetch.icon_name))
6469 bd->client.icccm.fetch.icon_name = 1;
6473 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6475 bd->client.netwm.fetch.icon_name = 1;
6478 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6480 bd->client.icccm.fetch.machine = 1;
6483 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6485 bd->client.icccm.fetch.protocol = 1;
6488 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6490 bd->client.icccm.fetch.hints = 1;
6493 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6495 bd->client.icccm.fetch.size_pos_hints = 1;
6498 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6501 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6502 (!bd->client.netwm.fetch.type))
6505 bd->client.mwm.fetch.hints = 1;
6511 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6513 bd->client.icccm.fetch.transient_for = 1;
6516 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6518 bd->client.icccm.fetch.client_leader = 1;
6521 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6523 bd->client.icccm.fetch.window_role = 1;
6526 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6528 bd->client.netwm.fetch.icon = 1;
6531 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6533 bd->client.qtopia.fetch.soft_menu = 1;
6536 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6538 bd->client.qtopia.fetch.soft_menus = 1;
6541 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6543 bd->client.vkbd.fetch.state = 1;
6546 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6548 bd->client.vkbd.fetch.vkbd = 1;
6551 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6553 bd->client.illume.conformant.fetch.conformant = 1;
6556 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6558 bd->client.illume.quickpanel.fetch.state = 1;
6561 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6563 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6566 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6568 bd->client.illume.quickpanel.fetch.priority.major = 1;
6571 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6573 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6576 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6578 bd->client.illume.quickpanel.fetch.zone = 1;
6581 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6583 bd->client.illume.drag.fetch.locked = 1;
6586 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6588 bd->client.illume.drag.fetch.drag = 1;
6591 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6593 bd->client.illume.win_state.fetch.state = 1;
6597 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6599 bd->client.netwm.fetch.user_time = 1;
6602 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6604 bd->client.netwm.fetch.strut = 1;
6607 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6609 bd->client.netwm.fetch.strut = 1;
6613 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6615 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6617 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6619 bd->client.e.fetch.video_position = 1;
6622 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6624 bd->client.e.fetch.video_parent = 1;
6627 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6629 bd->client.netwm.fetch.state = 1;
6632 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6633 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6635 bd->client.e.fetch.profile_list = 1;
6639 #ifdef _F_ZONE_WINDOW_ROTATION_
6640 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6642 if (e_config->wm_win_rotation)
6644 bd->client.e.fetch.rot.support = 1;
6648 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6649 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6650 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6651 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6653 if (e_config->wm_win_rotation)
6655 bd->client.e.fetch.rot.geom_hint = 1;
6659 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6661 if (e_config->wm_win_rotation)
6663 bd->client.e.fetch.rot.app_set = 1;
6667 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6669 if (e_config->wm_win_rotation)
6671 bd->client.e.fetch.rot.preferred_rot = 1;
6675 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6677 if (e_config->wm_win_rotation)
6679 bd->client.e.fetch.rot.available_rots = 1;
6685 return ECORE_CALLBACK_PASS_ON;
6689 _e_border_cb_window_colormap(void *data __UNUSED__,
6690 int ev_type __UNUSED__,
6694 Ecore_X_Event_Window_Colormap *e;
6697 bd = e_border_find_by_client_window(e->win);
6698 if (!bd) return ECORE_CALLBACK_PASS_ON;
6699 return ECORE_CALLBACK_PASS_ON;
6703 _e_border_cb_window_shape(void *data __UNUSED__,
6704 int ev_type __UNUSED__,
6708 Ecore_X_Event_Window_Shape *e;
6711 bd = e_border_find_by_client_window(e->win);
6713 if (e->type == ECORE_X_SHAPE_INPUT)
6717 bd->need_shape_merge = 1;
6718 // YYY bd->shaped_input = 1;
6719 bd->changes.shape_input = 1;
6723 return ECORE_CALLBACK_PASS_ON;
6728 bd->changes.shape = 1;
6730 return ECORE_CALLBACK_PASS_ON;
6732 bd = e_border_find_by_window(e->win);
6735 bd->need_shape_export = 1;
6737 return ECORE_CALLBACK_PASS_ON;
6739 bd = e_border_find_by_frame_window(e->win);
6742 bd->need_shape_merge = 1;
6744 return ECORE_CALLBACK_PASS_ON;
6746 return ECORE_CALLBACK_PASS_ON;
6750 _e_border_cb_window_focus_in(void *data __UNUSED__,
6751 int ev_type __UNUSED__,
6755 Ecore_X_Event_Window_Focus_In *e;
6758 bd = e_border_find_by_client_window(e->win);
6759 if (!bd) return ECORE_CALLBACK_PASS_ON;
6760 #ifdef INOUTDEBUG_FOCUS
6765 const char *modes[] = {
6767 "MODE_WHILE_GRABBED",
6771 const char *details[] = {
6775 "DETAIL_NON_LINEAR",
6776 "DETAIL_NON_LINEAR_VIRTUAL",
6778 "DETAIL_POINTER_ROOT",
6779 "DETAIL_DETAIL_NONE"
6783 ct[strlen(ct) - 1] = 0;
6784 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6789 details[e->detail]);
6791 DBG("%s cb focus in %d %d\n",
6792 e_border_name_get(bd),
6793 bd->client.icccm.accepts_focus,
6794 bd->client.icccm.take_focus);
6797 _e_border_pri_raise(bd);
6798 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6800 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6802 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6804 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6807 /* ignore focus in from !take_focus windows, we just gave it em */
6808 /* if (!bd->client.icccm.take_focus)
6809 * return ECORE_CALLBACK_PASS_ON; */
6811 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6812 if (e->time >= focus_time)
6813 e_border_focus_set(bd, 1, 0);
6814 return ECORE_CALLBACK_PASS_ON;
6818 _e_border_cb_window_focus_out(void *data __UNUSED__,
6819 int ev_type __UNUSED__,
6823 Ecore_X_Event_Window_Focus_Out *e;
6826 bd = e_border_find_by_client_window(e->win);
6827 if (!bd) return ECORE_CALLBACK_PASS_ON;
6828 #ifdef INOUTDEBUG_FOCUS
6833 const char *modes[] = {
6835 "MODE_WHILE_GRABBED",
6839 const char *details[] = {
6843 "DETAIL_NON_LINEAR",
6844 "DETAIL_NON_LINEAR_VIRTUAL",
6846 "DETAIL_POINTER_ROOT",
6847 "DETAIL_DETAIL_NONE"
6851 ct[strlen(ct) - 1] = 0;
6852 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6857 details[e->detail]);
6859 DBG("%s cb focus out %d %d",
6860 e_border_name_get(bd),
6861 bd->client.icccm.accepts_focus,
6862 bd->client.icccm.take_focus);
6865 _e_border_pri_norm(bd);
6866 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6868 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6869 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6870 return ECORE_CALLBACK_PASS_ON;
6871 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6872 return ECORE_CALLBACK_PASS_ON;
6874 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6876 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6877 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6878 return ECORE_CALLBACK_PASS_ON;
6879 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6880 return ECORE_CALLBACK_PASS_ON;
6881 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6882 return ECORE_CALLBACK_PASS_ON;
6883 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6884 return ECORE_CALLBACK_PASS_ON;
6886 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6888 /* for firefox/thunderbird (xul) menu walking */
6889 /* NB: why did i disable this before? */
6890 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6891 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6892 return ECORE_CALLBACK_PASS_ON;
6894 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6896 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6897 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6898 return ECORE_CALLBACK_PASS_ON;
6900 e_border_focus_set(bd, 0, 0);
6901 return ECORE_CALLBACK_PASS_ON;
6904 #if _F_BORDER_CLIP_TO_ZONE_
6906 _e_border_shape_input_clip_to_zone(E_Border *bd)
6908 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
6912 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
6913 bd->zone->w, bd->zone->h,
6914 bd->x, bd->y, bd->w, bd->h)))
6917 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
6918 E_RECTS_CLIP_TO_RECT(x, y, w, h,
6919 bd->zone->x, bd->zone->y,
6920 bd->zone->w, bd->zone->h);
6923 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
6924 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
6928 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
6929 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
6932 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
6935 _e_border_cb_client_message(void *data __UNUSED__,
6936 int ev_type __UNUSED__,
6939 Ecore_X_Event_Client_Message *e;
6943 #ifdef _F_DEICONIFY_APPROVE_
6944 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
6946 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
6948 bd = e_border_find_by_client_window(e->win);
6951 if (bd->client.e.state.deiconify_approve.support)
6953 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
6954 bd->client.e.state.deiconify_approve.render_done = 1;
6956 E_Border *ancestor_bd;
6957 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
6960 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
6961 bd->client.e.state.deiconify_approve.ancestor = NULL;
6968 ELBF(ELBT_BD, 0, bd->client.win,
6969 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
6971 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
6972 (ancestor_bd->client.e.state.deiconify_approve.render_done))
6974 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
6976 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
6977 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
6978 e_border_uniconify(ancestor_bd);
6982 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
6983 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
6988 return ECORE_CALLBACK_PASS_ON;
6992 #ifdef _F_ZONE_WINDOW_ROTATION_
6993 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
6995 bd = e_border_find_by_client_window(e->win);
6998 if (e_config->wm_win_rotation)
7000 Ecore_X_Event_Client_Message *msg = NULL;
7001 Ecore_X_Atom t = e->message_type;
7002 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7003 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7004 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7005 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7007 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7008 if (!msg) return ECORE_CALLBACK_PASS_ON;
7011 msg->message_type = e->message_type;
7012 msg->data.l[0] = e->data.l[0];
7013 msg->data.l[1] = e->data.l[1];
7014 msg->data.l[2] = e->data.l[2];
7015 msg->data.l[3] = e->data.l[3];
7016 msg->data.l[4] = e->data.l[4];
7017 rot.msgs = eina_list_append(rot.msgs, msg);
7019 rot.fetch = EINA_TRUE;
7022 return ECORE_CALLBACK_PASS_ON;
7025 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7027 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7028 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7030 if (e_config->wm_win_rotation)
7032 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7033 _e_border_rotation_list_remove(bd);
7037 return ECORE_CALLBACK_PASS_ON;
7041 _e_border_cb_window_state_request(void *data __UNUSED__,
7042 int ev_type __UNUSED__,
7046 Ecore_X_Event_Window_State_Request *e;
7050 bd = e_border_find_by_client_window(e->win);
7051 if (!bd) return ECORE_CALLBACK_PASS_ON;
7053 for (i = 0; i < 2; i++)
7054 e_hints_window_state_update(bd, e->state[i], e->action);
7056 return ECORE_CALLBACK_PASS_ON;
7060 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7061 int ev_type __UNUSED__,
7065 Ecore_X_Event_Window_Move_Resize_Request *e;
7068 bd = e_border_find_by_client_window(e->win);
7069 if (!bd) return ECORE_CALLBACK_PASS_ON;
7071 if ((bd->shaded) || (bd->shading) ||
7072 (bd->fullscreen) || (bd->moving) ||
7073 (bd->resize_mode != RESIZE_NONE))
7074 return ECORE_CALLBACK_PASS_ON;
7076 if ((e->button >= 1) && (e->button <= 3))
7078 bd->mouse.last_down[e->button - 1].mx = e->x;
7079 bd->mouse.last_down[e->button - 1].my = e->y;
7080 bd->mouse.last_down[e->button - 1].x = bd->x;
7081 bd->mouse.last_down[e->button - 1].y = bd->y;
7082 bd->mouse.last_down[e->button - 1].w = bd->w;
7083 bd->mouse.last_down[e->button - 1].h = bd->h;
7087 bd->moveinfo.down.x = bd->x;
7088 bd->moveinfo.down.y = bd->y;
7089 bd->moveinfo.down.w = bd->w;
7090 bd->moveinfo.down.h = bd->h;
7092 bd->mouse.current.mx = e->x;
7093 bd->mouse.current.my = e->y;
7094 bd->moveinfo.down.button = e->button;
7095 bd->moveinfo.down.mx = e->x;
7096 bd->moveinfo.down.my = e->y;
7099 if (!bd->lock_user_stacking)
7102 if (e->direction == MOVE)
7104 bd->cur_mouse_action = e_action_find("window_move");
7105 if (bd->cur_mouse_action)
7107 if ((!bd->cur_mouse_action->func.end_mouse) &&
7108 (!bd->cur_mouse_action->func.end))
7109 bd->cur_mouse_action = NULL;
7110 if (bd->cur_mouse_action)
7112 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7113 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7116 return ECORE_CALLBACK_PASS_ON;
7119 if (!_e_border_resize_begin(bd))
7120 return ECORE_CALLBACK_PASS_ON;
7122 switch (e->direction)
7125 bd->resize_mode = RESIZE_TL;
7126 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7130 bd->resize_mode = RESIZE_T;
7131 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7135 bd->resize_mode = RESIZE_TR;
7136 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7140 bd->resize_mode = RESIZE_R;
7141 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7145 bd->resize_mode = RESIZE_BR;
7146 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7150 bd->resize_mode = RESIZE_B;
7151 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7155 bd->resize_mode = RESIZE_BL;
7156 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7160 bd->resize_mode = RESIZE_L;
7161 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7165 return ECORE_CALLBACK_PASS_ON;
7168 bd->cur_mouse_action = e_action_find("window_resize");
7169 if (bd->cur_mouse_action)
7171 if ((!bd->cur_mouse_action->func.end_mouse) &&
7172 (!bd->cur_mouse_action->func.end))
7173 bd->cur_mouse_action = NULL;
7175 if (bd->cur_mouse_action)
7176 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7178 return ECORE_CALLBACK_PASS_ON;
7182 _e_border_cb_desktop_change(void *data __UNUSED__,
7183 int ev_type __UNUSED__,
7187 Ecore_X_Event_Desktop_Change *e;
7190 bd = e_border_find_by_client_window(e->win);
7193 if (e->desk == 0xffffffff)
7195 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7199 desk = e_desk_at_pos_get(bd->zone, e->desk);
7201 e_border_desk_set(bd, desk);
7206 ecore_x_netwm_desktop_set(e->win, e->desk);
7208 return ECORE_CALLBACK_PASS_ON;
7212 _e_border_cb_sync_alarm(void *data __UNUSED__,
7213 int ev_type __UNUSED__,
7217 Ecore_X_Event_Sync_Alarm *e;
7218 unsigned int serial;
7221 bd = e_border_find_by_alarm(e->alarm);
7222 if (!bd) return ECORE_CALLBACK_PASS_ON;
7224 if (bd->client.netwm.sync.wait)
7225 bd->client.netwm.sync.wait--;
7227 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7229 E_Border_Pending_Move_Resize *pnd = NULL;
7231 /* skip pending for which we didn't get a reply */
7232 while (bd->pending_move_resize)
7234 pnd = bd->pending_move_resize->data;
7235 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7237 if (serial == pnd->serial)
7249 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7250 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7255 bd->changes.size = 1;
7256 bd->changes.pos = 1;
7259 evas_render(bd->bg_evas);
7261 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7262 &bd->mouse.current.mx,
7263 &bd->mouse.current.my);
7265 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7266 _e_border_resize_handle(bd);
7268 return ECORE_CALLBACK_PASS_ON;
7272 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7273 int ev_type __UNUSED__,
7274 void *ev __UNUSED__)
7279 /* mark all borders for desktop/icon updates */
7280 EINA_LIST_FOREACH(borders, l, bd)
7284 efreet_desktop_free(bd->desktop);
7287 bd->changes.icon = 1;
7291 e_init_status_set(_("Desktop files scan done"));
7294 return ECORE_CALLBACK_PASS_ON;
7298 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7299 int ev_type __UNUSED__,
7300 void *ev __UNUSED__)
7305 /* mark all borders for desktop/icon updates */
7306 EINA_LIST_FOREACH(borders, l, bd)
7308 bd->changes.icon = 1;
7311 return ECORE_CALLBACK_PASS_ON;
7315 _e_border_cb_pointer_warp(void *data __UNUSED__,
7316 int ev_type __UNUSED__,
7319 E_Event_Pointer_Warp *e;
7322 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7323 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7324 return ECORE_CALLBACK_PASS_ON;
7328 _e_border_cb_signal_bind(void *data,
7329 Evas_Object *obj __UNUSED__,
7330 const char *emission,
7336 if (e_dnd_active()) return;
7337 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7342 _e_border_cb_mouse_in(void *data,
7343 int type __UNUSED__,
7346 Ecore_X_Event_Mouse_In *ev;
7351 #ifdef INOUTDEBUG_MOUSE
7356 const char *modes[] = {
7358 "MODE_WHILE_GRABBED",
7362 const char *details[] = {
7366 "DETAIL_NON_LINEAR",
7367 "DETAIL_NON_LINEAR_VIRTUAL",
7369 "DETAIL_POINTER_ROOT",
7370 "DETAIL_DETAIL_NONE"
7374 ct[strlen(ct) - 1] = 0;
7375 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7376 ev->win, ev->event_win,
7379 details[ev->detail]);
7382 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7383 if (ev->event_win == bd->win)
7385 e_focus_event_mouse_in(bd);
7388 if ((ev->win != bd->win) &&
7389 (ev->win != bd->event_win) &&
7390 (ev->event_win != bd->win) &&
7391 (ev->event_win != bd->event_win))
7392 return ECORE_CALLBACK_PASS_ON;
7394 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7396 bd->mouse.current.mx = ev->root.x;
7397 bd->mouse.current.my = ev->root.y;
7398 if (!bd->bg_evas_in)
7400 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7401 bd->bg_evas_in = EINA_TRUE;
7403 return ECORE_CALLBACK_PASS_ON;
7407 _e_border_cb_mouse_out(void *data,
7408 int type __UNUSED__,
7411 Ecore_X_Event_Mouse_Out *ev;
7416 #ifdef INOUTDEBUG_MOUSE
7421 const char *modes[] = {
7423 "MODE_WHILE_GRABBED",
7427 const char *details[] = {
7431 "DETAIL_NON_LINEAR",
7432 "DETAIL_NON_LINEAR_VIRTUAL",
7434 "DETAIL_POINTER_ROOT",
7435 "DETAIL_DETAIL_NONE"
7439 ct[strlen(ct) - 1] = 0;
7440 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7441 ev->win, ev->event_win,
7444 details[ev->detail]);
7447 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7448 if (ev->event_win == bd->win)
7451 return ECORE_CALLBACK_PASS_ON;
7452 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7453 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7454 return ECORE_CALLBACK_PASS_ON;
7455 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7456 return ECORE_CALLBACK_PASS_ON;
7457 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7458 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7459 return ECORE_CALLBACK_PASS_ON;
7460 e_focus_event_mouse_out(bd);
7463 if ((ev->win != bd->win) &&
7464 (ev->win != bd->event_win) &&
7465 (ev->event_win != bd->win) &&
7466 (ev->event_win != bd->event_win))
7467 return ECORE_CALLBACK_PASS_ON;
7469 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7471 bd->mouse.current.mx = ev->root.x;
7472 bd->mouse.current.my = ev->root.y;
7475 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7476 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7477 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7479 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7480 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7481 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7482 bd->bg_evas_in = EINA_FALSE;
7485 return ECORE_CALLBACK_PASS_ON;
7489 _e_border_cb_mouse_wheel(void *data,
7490 int type __UNUSED__,
7493 Ecore_Event_Mouse_Wheel *ev;
7498 if ((ev->event_window == bd->win) ||
7499 (ev->event_window == bd->event_win))
7501 bd->mouse.current.mx = ev->root.x;
7502 bd->mouse.current.my = ev->root.y;
7503 if (!bd->cur_mouse_action)
7504 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7507 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7508 return ECORE_CALLBACK_PASS_ON;
7512 _e_border_cb_mouse_down(void *data,
7513 int type __UNUSED__,
7516 Ecore_Event_Mouse_Button *ev;
7521 if ((ev->event_window == bd->win) ||
7522 (ev->event_window == bd->event_win))
7524 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7526 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7527 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7528 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7529 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7530 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7531 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7535 bd->moveinfo.down.x = bd->x + bd->fx.x;
7536 bd->moveinfo.down.y = bd->y + bd->fx.y;
7537 bd->moveinfo.down.w = bd->w;
7538 bd->moveinfo.down.h = bd->h;
7540 bd->mouse.current.mx = ev->root.x;
7541 bd->mouse.current.my = ev->root.y;
7542 if (!bd->cur_mouse_action)
7544 bd->cur_mouse_action =
7545 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7547 if (bd->cur_mouse_action)
7549 if ((!bd->cur_mouse_action->func.end_mouse) &&
7550 (!bd->cur_mouse_action->func.end))
7551 bd->cur_mouse_action = NULL;
7552 if (bd->cur_mouse_action)
7553 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7556 e_focus_event_mouse_down(bd);
7558 if (ev->window != ev->event_window)
7562 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7566 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7568 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7569 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7570 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7571 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7572 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7573 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7577 bd->moveinfo.down.x = bd->x + bd->fx.x;
7578 bd->moveinfo.down.y = bd->y + bd->fx.y;
7579 bd->moveinfo.down.w = bd->w;
7580 bd->moveinfo.down.h = bd->h;
7582 bd->mouse.current.mx = ev->root.x;
7583 bd->mouse.current.my = ev->root.y;
7588 else if (bd->resize_mode != RESIZE_NONE)
7594 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7596 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7597 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7598 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7600 return ECORE_CALLBACK_PASS_ON;
7604 _e_border_cb_mouse_up(void *data,
7605 int type __UNUSED__,
7608 Ecore_Event_Mouse_Button *ev;
7613 if ((ev->event_window == bd->win) ||
7614 (ev->event_window == bd->event_win))
7616 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7618 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7619 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7620 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7621 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7623 bd->mouse.current.mx = ev->root.x;
7624 bd->mouse.current.my = ev->root.y;
7625 /* also we dont pass the same params that went in - then again that */
7626 /* should be ok as we are just ending the action if it has an end */
7627 if (bd->cur_mouse_action)
7629 if (bd->cur_mouse_action->func.end_mouse)
7630 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7631 else if (bd->cur_mouse_action->func.end)
7632 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7633 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7634 bd->cur_mouse_action = NULL;
7638 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7639 e_focus_event_mouse_up(bd);
7642 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7643 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7645 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7646 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7647 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7648 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7650 bd->mouse.current.mx = ev->root.x;
7651 bd->mouse.current.my = ev->root.y;
7655 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7656 return ECORE_CALLBACK_PASS_ON;
7660 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7662 #ifdef _F_BORDER_CLIP_TO_ZONE_
7663 int new_x_max, new_y_max;
7664 int new_x_min, new_y_min;
7665 int margin_x, margin_y;
7667 margin_x = bd->w - 100;
7668 margin_y = bd->h - 100;
7670 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7671 new_x_min = bd->zone->x - margin_x;
7672 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7673 new_y_min = bd->zone->y - margin_y;
7675 if (x >= new_x_max) *new_x = new_x_max;
7676 else if (x <= new_x_min) *new_x = new_x_min;
7678 if (y >= new_y_max) *new_y = new_y_max;
7679 else if (y <= new_y_min) *new_y = new_y_min;
7684 _e_border_cb_mouse_move(void *data,
7685 int type __UNUSED__,
7688 Ecore_Event_Mouse_Move *ev;
7693 if ((ev->window != bd->event_win) &&
7694 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7695 bd->mouse.current.mx = ev->root.x;
7696 bd->mouse.current.my = ev->root.y;
7699 int x, y, new_x, new_y;
7701 Eina_List *skiplist = NULL;
7703 // FIXME: remove? sync what for when only moving?
7704 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7705 bd->client.netwm.sync.wait = 0;
7706 if ((bd->client.netwm.sync.request) &&
7707 (bd->client.netwm.sync.alarm) &&
7708 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7710 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7712 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7713 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7714 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7715 (bd->mouse.current.my - bd->moveinfo.down.my);
7719 x = bd->moveinfo.down.x +
7720 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7721 y = bd->moveinfo.down.y +
7722 (bd->mouse.current.my - bd->moveinfo.down.my);
7727 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7728 skiplist = eina_list_append(skiplist, bd);
7729 e_resist_container_border_position(bd->zone->container, skiplist,
7730 bd->x, bd->y, bd->w, bd->h,
7732 &new_x, &new_y, &new_w, &new_h);
7733 eina_list_free(skiplist);
7735 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7737 /* if (e_config->window_out_of_vscreen_limits_partly) */
7739 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7742 skiplist = eina_list_append(skiplist, bd);
7743 e_resist_container_border_position(bd->zone->container, skiplist,
7744 bd->x, bd->y, bd->w, bd->h,
7746 &new_x, &new_y, &new_w, &new_h);
7747 eina_list_free(skiplist);
7750 bd->shelf_fix.x = 0;
7751 bd->shelf_fix.y = 0;
7752 bd->shelf_fix.modified = 0;
7753 e_border_move(bd, new_x, new_y);
7754 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7756 else if (bd->resize_mode != RESIZE_NONE)
7758 if ((bd->client.netwm.sync.request) &&
7759 (bd->client.netwm.sync.alarm))
7761 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7763 E_Border_Pending_Move_Resize *pnd;
7765 if (bd->pending_move_resize)
7767 bd->changes.pos = 1;
7768 bd->changes.size = 1;
7770 _e_border_client_move_resize_send(bd);
7772 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7775 bd->client.netwm.sync.wait = 0;
7777 /* sync.wait is incremented when resize_handle sends
7778 * sync-request and decremented by sync-alarm cb. so
7779 * we resize here either on initial resize, timeout or
7780 * when no new resize-request was added by sync-alarm cb.
7782 if (!bd->client.netwm.sync.wait)
7783 _e_border_resize_handle(bd);
7786 _e_border_resize_handle(bd);
7792 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7794 bd->drag.x = ev->root.x;
7795 bd->drag.y = ev->root.y;
7801 dx = bd->drag.x - ev->root.x;
7802 dy = bd->drag.y - ev->root.y;
7803 if (((dx * dx) + (dy * dy)) >
7804 (e_config->drag_resist * e_config->drag_resist))
7807 if (bd->icon_object)
7809 Evas_Object *o = NULL;
7810 Evas_Coord x, y, w, h;
7811 const char *drag_types[] = { "enlightenment/border" };
7813 e_object_ref(E_OBJECT(bd));
7814 evas_object_geometry_get(bd->icon_object,
7816 drag_border = e_drag_new(bd->zone->container,
7817 bd->x + bd->fx.x + x,
7818 bd->y + bd->fx.y + y,
7819 drag_types, 1, bd, -1,
7821 _e_border_cb_drag_finished);
7822 o = e_border_icon_add(bd, drag_border->evas);
7825 /* FIXME: fallback icon for drag */
7826 o = evas_object_rectangle_add(drag_border->evas);
7827 evas_object_color_set(o, 255, 255, 255, 255);
7829 e_drag_object_set(drag_border, o);
7831 e_drag_resize(drag_border, w, h);
7832 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7838 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7840 return ECORE_CALLBACK_PASS_ON;
7844 _e_border_cb_grab_replay(void *data __UNUSED__,
7848 Ecore_Event_Mouse_Button *ev;
7850 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7852 if ((e_config->pass_click_on)
7853 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7854 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7859 bd = e_border_find_by_window(ev->event_window);
7862 if (bd->cur_mouse_action)
7863 return ECORE_CALLBACK_DONE;
7864 if (ev->event_window == bd->win)
7866 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7867 E_OBJECT(bd), ev, NULL))
7868 return ECORE_CALLBACK_PASS_ON;
7872 return ECORE_CALLBACK_DONE;
7876 _e_border_cb_drag_finished(E_Drag *drag,
7877 int dropped __UNUSED__)
7882 e_object_unref(E_OBJECT(bd));
7886 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7888 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7889 int ev_type __UNUSED__,
7892 E_Event_Desk_Window_Profile_Change *e;
7897 EINA_LIST_FOREACH(borders, l, bd)
7899 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
7901 bd->client.e.fetch.profile_list = 1;
7905 return ECORE_CALLBACK_PASS_ON;
7909 #ifdef _F_ZONE_WINDOW_ROTATION_
7911 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
7912 int ev_type __UNUSED__,
7915 E_Event_Zone_Rotation_Change_Begin *e = ev;
7916 Eina_Bool res = EINA_FALSE;
7918 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7919 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
7921 res = _e_border_rotation_zone_check(e->zone);
7922 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: result:%d (%d)", res, e->zone->rot.curr);
7925 e_manager_comp_screen_lock(e_manager_current_get());
7926 res = _e_border_rotation_zone_vkbd_check(e->zone);
7927 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd result:%d (%d)", res, e->zone->rot.curr);
7930 res = _e_border_rotation_transient_for_check(rot.vkbd,
7932 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd transient_for result:%d (%d)", res, e->zone->rot.curr);
7937 if (rot.prepare_timer)
7938 ecore_timer_del(rot.prepare_timer);
7939 rot.prepare_timer = NULL;
7942 ecore_timer_del(rot.done_timer);
7943 rot.done_timer = NULL;
7945 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
7946 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
7949 rot.prepare_timer = ecore_timer_add(4.0f,
7950 _e_border_rotation_change_prepare_timeout,
7952 rot.wait_prepare_done = EINA_TRUE;
7955 _e_border_rotation_start(e->zone, EINA_TRUE);
7959 /* there is no border which supports window manager rotation */
7960 e_zone_rotation_update_cancel(e->zone);
7962 return ECORE_CALLBACK_PASS_ON;
7966 _e_border_rotation_change_prepare_timeout(void *data)
7968 E_Zone *zone = data;
7969 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
7971 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
7973 if ((!rot.wait_prepare_done) ||
7975 (!_e_border_rotation_start(zone, EINA_FALSE)))
7977 if (rot.prepare_timer)
7978 ecore_timer_del(rot.prepare_timer);
7979 rot.prepare_timer = NULL;
7980 rot.wait_prepare_done = EINA_FALSE;
7982 return ECORE_CALLBACK_CANCEL;
7986 _e_border_rotation_change_request(E_Zone *zone __UNUSED__)
7988 Eina_List *l = NULL;
7989 E_Border_Rotation_Info *info = NULL;
7991 if (!e_config->wm_win_rotation) return;
7992 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
7993 rot.prepare_timer = NULL;
7994 rot.wait_prepare_done = EINA_FALSE;
7996 EINA_LIST_FOREACH(rot.list, l, info)
7998 if (!info->bd) continue;
7999 if ((zone->rot.block_count) &&
8000 (info->bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT)) continue;
8002 _e_border_event_border_rotation_change_begin_send(info->bd);
8004 ELBF(ELBT_ROT, 1, info->bd->client.win,
8005 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8006 info->ang, info->win_resize, info->w, info->h);
8008 ecore_x_e_window_rotation_change_prepare_send
8009 (info->bd->client.win, info->ang,
8010 info->win_resize, info->w, info->h);
8012 if (!info->bd->client.e.state.rot.pending_change_request)
8014 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8015 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8021 ecore_timer_del(rot.done_timer);
8022 rot.done_timer = ecore_timer_add(4.0f,
8023 _e_border_rotation_change_done_timeout,
8028 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8030 Eina_List *l = NULL;
8031 E_Border_Rotation_Info *info = NULL;
8033 if (send_request) _e_border_rotation_change_request(zone);
8036 EINA_LIST_FREE(rot.list, info)
8043 _e_border_rotation_list_remove(E_Border *bd)
8045 Eina_List *l = NULL;
8046 E_Border_Rotation_Info *info = NULL;
8047 E_Event_Border_Rotation_Change_End *ev = NULL;
8048 if (!e_config->wm_win_rotation) return;
8050 EINA_LIST_FOREACH(rot.list, l, info)
8054 rot.list = eina_list_remove(rot.list, info);
8059 if (bd->client.e.state.rot.wait_for_done)
8061 bd->client.e.state.rot.wait_for_done = 0;
8063 /* if we make the border event in the _e_border_free function,
8064 * then we may meet a crash problem, only work this at least e_border_hide.
8066 if (!e_object_is_del(E_OBJECT(bd)))
8068 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8072 e_object_ref(E_OBJECT(bd));
8073 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8075 _e_border_event_border_rotation_change_end_free,
8079 if (eina_list_count(rot.list) == 0)
8081 _e_border_rotation_change_done();
8087 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8089 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8090 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8091 _e_border_rotation_change_done();
8092 return ECORE_CALLBACK_CANCEL;
8096 _e_border_rotation_change_done(void)
8098 E_Manager *m = NULL;
8099 E_Border_Rotation_Info *info = NULL;
8101 if (!e_config->wm_win_rotation) return;
8103 if (rot.prepare_timer)
8104 ecore_timer_del(rot.prepare_timer);
8105 rot.prepare_timer = NULL;
8107 rot.wait_prepare_done = EINA_FALSE;
8110 ecore_timer_del(rot.done_timer);
8111 rot.done_timer = NULL;
8113 EINA_LIST_FREE(rot.list, info)
8117 info->bd->client.e.state.rot.wait_for_done = 0;
8118 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8125 m = e_manager_current_get();
8126 e_manager_comp_screen_unlock(m);
8127 e_zone_rotation_update_done(e_util_zone_current_get(m));
8131 _prev_angle_get(Ecore_X_Window win)
8133 int ret, count = 0, ang = -1;
8134 unsigned char* data = NULL;
8136 ret = ecore_x_window_prop_property_get
8137 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8138 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8140 if ((ret) && (data) && (count))
8141 ang = ((int *)data)[0];
8142 if (data) free(data);
8146 /* get proper rotation value using preferred rotation and list of available rotations */
8148 _e_border_rotation_get(E_Border *bd,
8152 int current_ang = bd->client.e.state.rot.curr;
8154 Eina_Bool found = EINA_FALSE;
8155 Eina_Bool found_curr_ang = EINA_FALSE;
8157 if (!e_config->wm_win_rotation) return ang;
8158 if (!bd->client.e.state.rot.app_set) return ang;
8160 if (bd->client.e.state.rot.preferred_rot != -1)
8162 ang = bd->client.e.state.rot.preferred_rot;
8163 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8165 else if ((bd->client.e.state.rot.available_rots) &&
8166 (bd->client.e.state.rot.count))
8168 for (i = 0; i < bd->client.e.state.rot.count; i++)
8170 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8176 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8177 found_curr_ang = EINA_TRUE;
8180 /* do nothing. this window wants to maintain current state.
8181 * for example, window's available_rots: 0, 90, 270,
8182 * current zone rotation request: 180. the WM does nothing
8187 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8188 ang = bd->client.e.state.rot.curr;
8190 ang = bd->client.e.state.rot.available_rots[0];
8195 /* In this case, border doesn't have a list of
8196 * available rotations, thus WM should request
8197 * rotation with '0' degree to the application.
8205 #define REGION_EQUAL_TO_ZONE(a, z) \
8206 ((((a)->x) == ((z)->x)) && \
8207 (((a)->y) == ((z)->y)) && \
8208 (((a)->w) == ((z)->w)) && \
8209 (((a)->h) == ((z)->h)))
8212 _e_border_rotation_check(E_Border *bd)
8214 E_Zone *zone = bd->zone;
8215 Eina_List *nl = NULL;
8216 int x, y, w, h, ang = 0;
8218 Eina_Bool resize = EINA_TRUE;
8219 Eina_Bool hint = EINA_FALSE;
8220 Eina_Bool move = EINA_TRUE;
8222 if (!e_config->wm_win_rotation) return EINA_FALSE;
8224 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8226 ang = zone->rot.curr;
8228 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8230 ELBF(ELBT_ROT, 1, bd->client.win,
8231 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8232 (rot.vkbd == bd) ? "vkbd" : "prediction",
8233 bd->parent ? bd->parent->client.win : 0,
8234 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8235 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8236 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8240 ang = bd->parent->client.e.state.rot.curr;
8241 if ((!bd->parent->client.e.state.rot.support) &&
8242 (!bd->parent->client.e.state.rot.app_set))
8249 if ((!bd->client.e.state.rot.app_set) &&
8250 (!bd->client.e.state.rot.support))
8252 /* hack for magnifier and keyboard popup */
8253 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8254 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8256 ELB(ELBT_BD, "MAG", bd->client.win);
8258 if ((rot.vkbd) && (rot.vkbd->visible))
8259 ang = rot.vkbd->client.e.state.rot.curr;
8260 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
8263 ELBF(ELBT_ROT, 1, bd->client.win, "MAG %d,%d %dx%d m:%d", x, y, w, h, move);
8264 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8270 if (bd->client.e.state.rot.app_set)
8272 /* utility type window should be rotated according to
8273 * rotation of the transient_for window.
8276 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8278 ang = bd->parent->client.e.state.rot.curr;
8279 if ((!bd->parent->client.e.state.rot.support) &&
8280 (!bd->parent->client.e.state.rot.app_set))
8282 /* if transient_for window doesn't support rotation feature,
8283 * then this window should't be rotated.
8284 * TODO: need to check whether window supports '0' degree or not.
8287 ELBF(ELBT_ROT, 0, bd->client.win,
8288 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8289 ang, bd->parent->client.win);
8293 ang = _e_border_rotation_get(bd->parent, ang);
8294 ELBF(ELBT_ROT, 0, bd->client.win,
8295 "GET ROT ang:%d Transient_For:0x%08x",
8296 ang, bd->parent->client.win);
8301 ang = _e_border_rotation_get(bd, ang);
8302 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8303 ang, bd->parent ? bd->parent->client.win : 0,
8304 bd->client.netwm.type);
8308 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
8311 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8312 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8313 bd->client.icccm.name, x, y, w, h);
8316 /* need to check previous rotation angle, this may be because
8317 * the window was unmapped with non-0 rotation degree.
8318 * and now, the window wants to show on the 0 degree zone,
8319 * thus the wm should request to rotate the window to 0 degree.
8323 _ang = _prev_angle_get(bd->client.win);
8325 bd->client.e.state.rot.curr = _ang;
8326 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8329 if (bd->client.e.state.rot.curr != ang)
8331 if ((rot.vkbd != bd) && (rot.vkbd_prediction != bd) &&
8332 /* check whether virtual keyboard is visible on the zone */
8333 (_e_border_rotation_zone_vkbd_check(bd->zone)) &&
8334 /* check whether virtual keyboard belongs to this border (transient_for) */
8335 (_e_border_rotation_vkbd_transient_for_check(bd)) &&
8336 /* check rotation of the virtual keyboard */
8337 (((rot.vkbd) && (rot.vkbd->client.e.state.rot.curr != ang)) ||
8338 ((rot.vkbd_prediction) && (rot.vkbd_prediction->client.e.state.rot.curr != ang))) &&
8339 (!rot.wait_prepare_done))
8341 ELB(ELBT_ROT, "DO VKBD ROT", bd->client.win);
8342 e_manager_comp_screen_lock(e_manager_current_get());
8344 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8345 rot.prepare_timer = NULL;
8347 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8348 rot.done_timer = NULL;
8350 ELB(ELBT_ROT, "send rot_change_prepare", rot.vkbd_ctrl_win);
8351 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8354 rot.prepare_timer = ecore_timer_add(4.0f,
8355 _e_border_rotation_change_prepare_timeout,
8357 rot.wait_prepare_done = EINA_TRUE;
8360 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8361 bd->client.e.state.rot.curr = ang;
8362 bd->client.e.state.rot.wait_for_done = 1;
8363 nl = eina_list_append(nl, bd);
8365 e_border_rotation_list_add_change_req(zone, nl);
8371 _e_border_rotation_zone_check(E_Zone *zone)
8373 Eina_Bool wait = EINA_FALSE;
8374 E_Border_List *l = NULL;
8375 E_Border *bd = NULL;
8377 if (!e_config->wm_win_rotation) return EINA_FALSE;
8379 l = e_container_border_list_last(zone->container);
8380 if (!l) return EINA_FALSE;
8381 while ((bd = e_container_border_list_prev(l)))
8383 if ((!bd) || (e_object_is_del(E_OBJECT(bd))) ||
8384 (!bd->visible) || (bd->zone != zone) ||
8385 (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8386 bd->x, bd->y, bd->w, bd->h))) continue;
8388 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8389 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)) ||
8390 ((REGION_EQUAL_TO_ZONE(bd, zone)) &&
8391 (bd->client.e.state.rot.preferred_rot != -1))) continue;
8393 if (_e_border_rotation_border_check(bd, zone->rot.curr))
8399 if (l) e_container_border_list_free(l);
8404 // check if border is rotatable in ang.
8406 _e_border_rotation_border_check(E_Border *bd, int ang)
8408 Eina_Bool wait = EINA_FALSE;
8410 if (!bd) return wait;
8412 if (((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8413 /* basically WM allows only fullscreen window to rotate */
8414 ((REGION_EQUAL_TO_ZONE(bd, bd->zone)) ||
8415 /* we don't like this kind of code.
8416 * it means that the WM also allows non-fullscreen window to rotate if it sets geom hint.
8417 * such as large editable window.
8419 ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE) && (bd->client.e.state.rot.geom_hint)) ||
8420 /* and floating mode window is also rotatable */
8421 (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) &&
8422 (bd->client.e.state.rot.preferred_rot == -1))
8426 if (bd->client.e.state.rot.app_set)
8428 if (bd->client.e.state.rot.available_rots &&
8429 bd->client.e.state.rot.count)
8431 Eina_Bool found = EINA_FALSE;
8432 for (i = 0; i < bd->client.e.state.rot.count; i++)
8434 if (bd->client.e.state.rot.available_rots[i] == ang)
8439 if ((found) && (ang != bd->client.e.state.rot.curr))
8445 ELB(ELBT_ROT, "ROT CANCEL for preferred rot", bd->client.win);
8452 ELB(ELBT_ROT, "DO ROT", 0);
8460 /* check whether virtual keyboard is visible on the zone */
8462 _e_border_rotation_zone_vkbd_check(E_Zone *zone)
8464 if (!e_config->wm_win_rotation) return EINA_FALSE;
8466 if ((rot.vkbd_ctrl_win) &&
8468 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8469 (rot.vkbd->visible) &&
8470 (rot.vkbd->zone == zone) &&
8471 (E_INTERSECTS(zone->x, zone->y,
8473 rot.vkbd->x, rot.vkbd->y,
8474 rot.vkbd->w, rot.vkbd->h)))
8481 /* check whether border is parent of the virtual keyboard */
8483 _e_border_rotation_vkbd_transient_for_check(E_Border *bd)
8485 if (!e_config->wm_win_rotation) return EINA_FALSE;
8487 if (rot.vkbd_ctrl_win)
8489 if ((rot.vkbd) && (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8492 if (rot.vkbd->parent == bd)
8496 if ((rot.vkbd_prediction) && (!e_object_is_del(E_OBJECT(rot.vkbd_prediction))) &&
8497 (rot.vkbd_prediction != bd))
8499 if (rot.vkbd_prediction == bd)
8507 // check if bd's parent is rotatable.
8509 _e_border_rotation_transient_for_check(E_Border *bd, int ang)
8511 Eina_Bool ret = EINA_FALSE;
8513 if (!e_config->wm_win_rotation) return EINA_FALSE;
8514 if (!bd) return EINA_FALSE;
8516 if (!bd->parent) ret = EINA_TRUE;
8519 if (_e_border_rotation_border_check(bd->parent, ang))
8527 e_border_rotation_list_add_change_req(E_Zone *zone, Eina_List *list)
8531 Eina_Bool ret = EINA_FALSE;
8533 if (e_border_rotation_list_add(list))
8535 EINA_LIST_FOREACH(list, l, bd)
8536 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, bd);
8537 _e_border_rotation_change_request(zone);
8545 e_border_rotation_list_add(Eina_List *list)
8548 E_Border *bd = NULL;
8549 E_Border_Rotation_Info *info = NULL;
8550 int x=0, y=0, w=0, h=0;
8552 if (!list) return EINA_FALSE;
8553 EINA_LIST_FOREACH(list, l, bd)
8555 info = E_NEW(E_Border_Rotation_Info, 1);
8556 if (!info) continue;
8559 info->ang = bd->client.e.state.rot.curr;
8560 info->win_resize = _e_border_rotation_pre_resize(bd, &x, &y, &w, &h);
8561 info->x = x; info->y = y;
8562 info->w = w; info->h = h;
8563 if (info->win_resize) bd->client.e.state.rot.pending_change_request = 1;
8564 rot.list = eina_list_append(rot.list, info);
8570 #define SIZE_EQUAL_TO_ZONE(a, z) \
8571 ((((a)->w) == ((z)->w)) && \
8572 (((a)->h) == ((z)->h)))
8574 _e_border_rotation_pre_resize(E_Border *bd, int *x, int *y, int *w, int *h)
8576 E_Zone *zone = bd->zone;
8577 int ang = bd->client.e.state.rot.curr;
8578 int diff = ang - bd->client.e.state.rot.prev;
8580 Eina_Bool move = EINA_FALSE;
8581 Eina_Bool hint = EINA_FALSE;
8582 Eina_Bool resize = EINA_FALSE;
8589 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
8591 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
8592 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
8593 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
8595 hint = _e_border_rotation_geom_get(bd, bd->zone, ang,
8596 &_x, &_y, &_w, &_h, &move);
8599 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
8601 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8602 bd->client.icccm.name, _x, _y, _w, _h);
8606 _x = bd->x; _y = bd->y;
8607 _w = bd->w; _h = bd->h;
8609 if ((diff != 180) && (diff != -180))
8617 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
8618 EINA_TRUE, EINA_TRUE);
8619 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
8620 bd->client.icccm.name, _x, _y, _w, _h);
8638 _e_border_rotation_start(E_Zone *zone, Eina_Bool without_vkbd)
8640 Eina_Bool wait = EINA_FALSE;
8641 E_Border_List *l = NULL;
8642 Eina_List *nl = NULL;
8643 E_Border *bd = NULL;
8644 E_Border_Rotation_Info *info = NULL;
8646 if (!e_config->wm_win_rotation) return EINA_FALSE;
8648 l = e_container_border_list_last(zone->container);
8649 if (!l) return EINA_FALSE;
8650 while ((bd = e_container_border_list_prev(l)))
8652 if ((!bd) || (e_object_is_del(E_OBJECT(bd)))) continue;
8654 if ((without_vkbd) &&
8655 (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE))
8660 if ((bd->visible) &&
8661 ((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8662 (bd->zone == zone) &&
8663 (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8664 bd->x, bd->y, bd->w, bd->h)))
8666 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8668 // check if this window is available to be rotate.
8669 if ((bd->client.e.state.rot.app_set) &&
8670 (bd->client.e.state.rot.preferred_rot != -1)) continue;
8672 /* check list of available rotations */
8673 int ang = zone->rot.curr;
8674 if (bd->client.e.state.rot.app_set)
8676 ang = _e_border_rotation_get(bd, ang);
8677 ELBF(ELBT_ROT, 0, bd->client.win, "returned ang:%d", ang);
8680 /* skip same angle */
8681 if (bd->client.e.state.rot.curr == ang)
8683 /* FIXME: hack for rotating vkbd:
8684 * even if angle of zone is not changed,
8685 * if preferred_rot of parent is set with specific angle, vkbd has to rotate, too.
8686 * all of other transient window like this case.
8689 (bd->parent->client.e.state.rot.preferred_rot != -1))
8690 ang = bd->parent->client.e.state.rot.preferred_rot;
8691 if (bd->client.e.state.rot.curr == ang)
8693 ELBF(ELBT_ROT, 0, bd->client.win, "SKIP ang:%d", ang);
8696 ELBF(ELBT_ROT, 0, bd->client.win, "rotate by parent ang:%d", ang);
8700 ELBF(ELBT_ROT, 0, bd->client.win, "ADD ROT_LIST curr:%d != ang:%d",
8701 bd->client.e.state.rot.curr, ang);
8704 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8705 bd->client.e.state.rot.curr = ang;
8706 bd->client.e.state.rot.wait_for_done = 1;
8707 nl = eina_list_append(nl, bd);
8709 /* check whether rotation is available for sub borders such as prediction and magnifier */
8712 Eina_List *_list = _e_border_sub_borders_new(bd);
8713 EINA_LIST_FOREACH(_list, ll, _child)
8715 if ((_child->client.e.state.rot.support) ||
8716 (_child->client.e.state.rot.app_set))
8717 _e_border_rotation_check(_child);
8719 eina_list_free(_list);
8725 if (l) e_container_border_list_free(l);
8727 wait = e_border_rotation_list_add_change_req(zone, nl);
8734 _e_border_cb_window_configure(void *data __UNUSED__,
8735 int ev_type __UNUSED__,
8738 Ecore_X_Event_Window_Configure *e = ev;
8739 if (!e) return ECORE_CALLBACK_PASS_ON;
8740 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8742 E_Border *bd = e_border_find_by_client_window(e->win);
8743 if (!bd) return ECORE_CALLBACK_PASS_ON;
8745 if (bd->client.e.state.rot.pending_change_request)
8747 if ((e->w == bd->w) && (e->h == bd->h))
8749 ELBF(ELBT_ROT, 0, bd->client.win,
8750 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8751 bd->client.e.state.rot.curr,
8754 bd->client.e.state.rot.pending_change_request = 0;
8756 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8757 bd->client.e.state.rot.curr);
8760 return ECORE_CALLBACK_PASS_ON;
8764 _e_border_rotation_geom_get(E_Border *bd,
8773 if (!e_config->wm_win_rotation) return EINA_FALSE;
8775 Eina_Bool res = EINA_FALSE;
8776 Eina_Bool _move = EINA_TRUE;
8786 if (move) *move = EINA_TRUE;
8788 if (bd->client.e.state.rot.geom_hint)
8793 _w = bd->client.e.state.rot.geom[0].w;
8794 _h = bd->client.e.state.rot.geom[0].h;
8795 if (_w == 0) _w = bd->w;
8796 if (_h == 0) _h = bd->h;
8797 _x = 0; _y = zone->h - _h;
8800 _w = bd->client.e.state.rot.geom[1].w;
8801 _h = bd->client.e.state.rot.geom[1].h;
8802 if (_w == 0) _w = bd->w;
8803 if (_h == 0) _h = bd->h;
8804 _x = zone->w - _w; _y = 0;
8807 _w = bd->client.e.state.rot.geom[2].w;
8808 _h = bd->client.e.state.rot.geom[2].h;
8809 if (_w == 0) _w = bd->w;
8810 if (_h == 0) _h = bd->h;
8814 _w = bd->client.e.state.rot.geom[3].w;
8815 _h = bd->client.e.state.rot.geom[3].h;
8816 if (_w == 0) _w = bd->w;
8817 if (_h == 0) _h = bd->h;
8827 if (!((rot.vkbd) && (rot.vkbd == bd)))
8831 if (move) *move = EINA_FALSE;
8839 _x = 0; _y = 0; _w = 0; _h = 0;
8844 if (move) _move = *move;
8846 ELBF(ELBT_ROT, 1, bd->client.win,
8847 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
8848 ang, _x, _y, _w, _h, _move);
8856 _e_border_post_move_resize_job(void *data)
8860 bd = (E_Border *)data;
8866 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
8867 ecore_x_window_move(tmp->win,
8869 bd->client_inset.l +
8871 tmp->client.e.state.video_position.x,
8873 bd->client_inset.t +
8875 tmp->client.e.state.video_position.y);
8877 if (bd->client.e.state.video)
8881 parent = bd->client.e.state.video_parent_border;
8882 ecore_x_window_move(bd->win,
8884 parent->client_inset.l +
8886 bd->client.e.state.video_position.x,
8888 parent->client_inset.t +
8890 bd->client.e.state.video_position.y);
8892 else if ((bd->post_move) && (bd->post_resize))
8894 ecore_x_window_move_resize(bd->win,
8899 else if (bd->post_move)
8901 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
8903 else if (bd->post_resize)
8905 ecore_x_window_resize(bd->win, bd->w, bd->h);
8908 if (bd->client.e.state.video)
8910 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
8912 bd->client.e.state.video_parent_border->x +
8913 bd->client.e.state.video_parent_border->client_inset.l +
8914 bd->client.e.state.video_parent_border->fx.x +
8915 bd->client.e.state.video_position.x,
8916 bd->client.e.state.video_parent_border->y +
8917 bd->client.e.state.video_parent_border->client_inset.t +
8918 bd->client.e.state.video_parent_border->fx.y +
8919 bd->client.e.state.video_position.y,
8927 bd->post_job = NULL;
8933 bd->post_resize = 0;
8934 bd->post_job = NULL;
8935 return ECORE_CALLBACK_CANCEL;
8939 _e_border_container_layout_hook(E_Container *con)
8941 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
8945 _e_border_eval0(E_Border *bd)
8947 int change_urgent = 0;
8949 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8950 Eina_Bool need_desk_set = EINA_FALSE;
8952 #ifdef _F_ZONE_WINDOW_ROTATION_
8953 Eina_Bool need_rotation_set = EINA_FALSE;
8955 if ((e_config->wm_win_rotation) &&
8956 (bd->client.icccm.fetch.transient_for))
8958 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8959 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
8961 need_rotation_set = EINA_TRUE;
8962 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
8967 if (e_object_is_del(E_OBJECT(bd)))
8969 CRI("_e_border_eval(%p) with deleted border!\n", bd);
8974 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
8976 bd->changes.border = 0;
8978 /* fetch any info queued to be fetched */
8979 if (bd->client.netwm.fetch.state)
8981 e_hints_window_state_get(bd);
8982 bd->client.netwm.fetch.state = 0;
8985 if (bd->client.icccm.fetch.client_leader)
8987 /* TODO: What do to if the client leader isn't mapped yet? */
8988 E_Border *bd_leader = NULL;
8990 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
8991 if (bd->client.icccm.client_leader)
8992 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
8995 if (bd->leader != bd_leader)
8997 bd->leader->group = eina_list_remove(bd->leader->group, bd);
8998 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9004 /* If this border is the leader of the group, don't register itself */
9005 if ((bd_leader) && (bd_leader != bd))
9007 bd_leader->group = eina_list_append(bd_leader->group, bd);
9008 bd->leader = bd_leader;
9009 /* Only set the window modal to the leader it there is no parent */
9010 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9011 ((!bd->parent) || (bd->parent->modal != bd)))
9013 bd->leader->modal = bd;
9014 if (bd->leader->focused)
9015 e_border_focus_set(bd, 1, 1);
9021 EINA_LIST_FOREACH(bd->leader->group, l, child)
9023 if ((child != bd) && (child->focused))
9024 e_border_focus_set(bd, 1, 1);
9029 bd->client.icccm.fetch.client_leader = 0;
9032 if (bd->client.icccm.fetch.title)
9034 char *title = ecore_x_icccm_title_get(bd->client.win);
9035 eina_stringshare_replace(&bd->client.icccm.title, title);
9036 if (title) free(title);
9039 edje_object_part_text_set(bd->bg_object, "e.text.title",
9040 bd->client.icccm.title);
9041 bd->client.icccm.fetch.title = 0;
9044 if (bd->client.netwm.fetch.name)
9047 ecore_x_netwm_name_get(bd->client.win, &name);
9048 eina_stringshare_replace(&bd->client.netwm.name, name);
9049 if (name) free(name);
9052 edje_object_part_text_set(bd->bg_object, "e.text.title",
9053 bd->client.netwm.name);
9054 bd->client.netwm.fetch.name = 0;
9057 if (bd->client.icccm.fetch.name_class)
9059 const char *pname, *pclass;
9060 char *nname, *nclass;
9062 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9063 pname = bd->client.icccm.name;
9064 pclass = bd->client.icccm.class;
9065 bd->client.icccm.name = eina_stringshare_add(nname);
9066 bd->client.icccm.class = eina_stringshare_add(nclass);
9067 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9068 e_bindings_mapping_change_enable(EINA_FALSE);
9069 #ifdef _F_ZONE_WINDOW_ROTATION_
9070 if (e_config->wm_win_rotation)
9072 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9074 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9075 (!strcmp(bd->client.icccm.class, "ISF")))
9077 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9078 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9081 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9082 (!strcmp(bd->client.icccm.class, "ISF")))
9084 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9085 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9086 rot.vkbd_prediction = bd;
9088 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9089 (!strcmp(bd->client.icccm.class, "ISF")))
9091 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9092 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9094 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9095 (!strcmp(bd->client.icccm.class, "ISF")))
9097 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9098 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9103 if (nname) free(nname);
9104 if (nclass) free(nclass);
9106 if (!((bd->client.icccm.name == pname) &&
9107 (bd->client.icccm.class == pclass)))
9108 bd->changes.icon = 1;
9110 if (pname) eina_stringshare_del(pname);
9111 if (pclass) eina_stringshare_del(pclass);
9112 bd->client.icccm.fetch.name_class = 0;
9113 bd->changes.icon = 1;
9116 if (bd->client.icccm.fetch.state)
9118 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9119 bd->client.icccm.fetch.state = 0;
9122 if (bd->client.e.fetch.state)
9124 e_hints_window_e_state_get(bd);
9125 bd->client.e.fetch.state = 0;
9128 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9129 if (bd->client.e.fetch.profile_list)
9131 const char **profiles = NULL;
9135 if (bd->client.e.state.profile)
9136 eina_stringshare_del(bd->client.e.state.profile);
9137 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9139 if (str) eina_stringshare_del(str);
9141 bd->client.e.state.profile = NULL;
9142 bd->client.e.state.profiles = NULL;
9143 bd->client.e.state.profile_list = 0;
9145 if (ecore_x_e_window_profile_list_get(bd->client.win,
9148 bd->client.e.state.profile_list = 1;
9149 for (i = 0; i < num; i++)
9151 str = eina_stringshare_add(profiles[i]);
9152 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9155 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9156 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9158 need_desk_set = EINA_TRUE;
9162 if (strcmp(bd->desk->window_profile,
9163 e_config->desktop_default_window_profile) != 0)
9165 ecore_x_e_window_profile_set(bd->client.win,
9166 bd->desk->window_profile);
9172 for (i = 0; i < num; i++)
9173 if (profiles[i]) free(profiles[i]);
9177 bd->client.e.fetch.profile_list = 0;
9180 #ifdef _F_ZONE_WINDOW_ROTATION_
9181 if ((e_config->wm_win_rotation) &&
9182 (bd->client.e.fetch.rot.support))
9185 unsigned int support = 0;
9187 ret = ecore_x_window_prop_card32_get
9189 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9192 bd->client.e.state.rot.support = 0;
9193 if ((ret == 1) && (support == 1))
9194 bd->client.e.state.rot.support = 1;
9196 if (bd->client.e.state.rot.support)
9197 need_rotation_set = EINA_TRUE;
9199 bd->client.e.fetch.rot.support = 0;
9201 if ((e_config->wm_win_rotation) &&
9202 (bd->client.e.fetch.rot.geom_hint))
9204 Eina_Rectangle r[4];
9206 bd->client.e.state.rot.geom_hint = 0;
9207 for (i = 0; i < 4; i++)
9209 r[i].x = bd->client.e.state.rot.geom[i].x;
9210 r[i].y = bd->client.e.state.rot.geom[i].y;
9211 r[i].w = bd->client.e.state.rot.geom[i].w;
9212 r[i].h = bd->client.e.state.rot.geom[i].h;
9214 bd->client.e.state.rot.geom[i].x = 0;
9215 bd->client.e.state.rot.geom[i].y = 0;
9216 bd->client.e.state.rot.geom[i].w = 0;
9217 bd->client.e.state.rot.geom[i].h = 0;
9220 for (i = 0; i < 4; i++)
9222 x = 0; y = 0; w = 0; h = 0;
9223 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9225 bd->client.e.state.rot.geom_hint = 1;
9226 bd->client.e.state.rot.geom[i].x = x;
9227 bd->client.e.state.rot.geom[i].y = y;
9228 bd->client.e.state.rot.geom[i].w = w;
9229 bd->client.e.state.rot.geom[i].h = h;
9231 if (!((r[i].x == x) && (r[i].y == y) &&
9232 (r[i].w == w) && (r[i].h == h)))
9234 need_rotation_set = EINA_TRUE;
9238 bd->client.e.fetch.rot.geom_hint = 0;
9240 if ((e_config->wm_win_rotation) &&
9241 (bd->client.e.fetch.rot.app_set))
9243 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9244 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9245 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9247 if (_prev_app_set != bd->client.e.state.rot.app_set)
9248 need_rotation_set = EINA_TRUE;
9250 bd->client.e.fetch.rot.app_set = 0;
9252 if ((e_config->wm_win_rotation) &&
9253 (bd->client.e.fetch.rot.preferred_rot))
9255 int r = 0, _prev_preferred_rot;
9256 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9257 bd->client.e.state.rot.preferred_rot = -1;
9258 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9260 bd->client.e.state.rot.preferred_rot = r;
9261 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9265 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9268 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9269 need_rotation_set = EINA_TRUE;
9271 bd->client.e.fetch.rot.preferred_rot = 0;
9273 if ((e_config->wm_win_rotation) &&
9274 (bd->client.e.fetch.rot.available_rots))
9276 Eina_Bool res, diff = EINA_FALSE;
9278 unsigned int count = 0, i = 0;
9279 int _prev_rots[4] = { -1, };
9281 if (bd->client.e.state.rot.available_rots)
9284 bd->client.e.state.rot.available_rots,
9285 (sizeof(int) * bd->client.e.state.rot.count));
9287 E_FREE(bd->client.e.state.rot.available_rots);
9290 bd->client.e.state.rot.count = 0;
9292 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9294 if ((res) && (count > 0) && (rots))
9296 bd->client.e.state.rot.available_rots = rots;
9297 bd->client.e.state.rot.count = count;
9299 for (i = 0; i < count; i++)
9301 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9302 if ((!diff) && (_prev_rots[i] != rots[i]))
9304 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9305 count, i, _prev_rots[i], rots[i]);
9312 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9316 if (diff) need_rotation_set = EINA_TRUE;
9317 bd->client.e.fetch.rot.available_rots = 0;
9320 if (bd->client.netwm.fetch.type)
9322 e_hints_window_type_get(bd);
9323 if ((!bd->lock_border) || (!bd->client.border.name))
9324 bd->client.border.changed = 1;
9326 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9328 if (!bd->client.netwm.state.skip_pager)
9330 bd->client.netwm.state.skip_pager = 1;
9331 bd->client.netwm.update.state = 1;
9333 if (!bd->client.netwm.state.skip_taskbar)
9335 bd->client.netwm.state.skip_taskbar = 1;
9336 bd->client.netwm.update.state = 1;
9339 bd->client.netwm.fetch.type = 0;
9341 if (bd->client.icccm.fetch.machine)
9343 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9345 if ((!machine) && (bd->client.icccm.client_leader))
9346 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9348 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9349 if (machine) free(machine);
9351 bd->client.icccm.fetch.machine = 0;
9354 if (bd->client.icccm.fetch.command)
9356 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9360 for (i = 0; i < bd->client.icccm.command.argc; i++)
9361 free(bd->client.icccm.command.argv[i]);
9362 free(bd->client.icccm.command.argv);
9364 bd->client.icccm.command.argc = 0;
9365 bd->client.icccm.command.argv = NULL;
9366 ecore_x_icccm_command_get(bd->client.win,
9367 &(bd->client.icccm.command.argc),
9368 &(bd->client.icccm.command.argv));
9369 if ((bd->client.icccm.client_leader) &&
9370 (!bd->client.icccm.command.argv))
9371 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9372 &(bd->client.icccm.command.argc),
9373 &(bd->client.icccm.command.argv));
9374 bd->client.icccm.fetch.command = 0;
9377 if (bd->client.icccm.fetch.hints)
9379 Eina_Bool accepts_focus, is_urgent;
9381 accepts_focus = EINA_TRUE;
9382 is_urgent = EINA_FALSE;
9383 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9384 if (ecore_x_icccm_hints_get(bd->client.win,
9386 &bd->client.icccm.initial_state,
9387 &bd->client.icccm.icon_pixmap,
9388 &bd->client.icccm.icon_mask,
9389 &bd->client.icccm.icon_window,
9390 &bd->client.icccm.window_group,
9393 bd->client.icccm.accepts_focus = accepts_focus;
9394 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9396 bd->client.icccm.urgent = is_urgent;
9398 /* If this is a new window, set the state as requested. */
9399 if ((bd->new_client) &&
9400 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9402 e_border_iconify(bd);
9403 e_border_hide(bd, 1);
9406 bd->client.icccm.fetch.hints = 0;
9409 if (bd->client.icccm.fetch.size_pos_hints)
9411 Eina_Bool request_pos;
9413 request_pos = EINA_FALSE;
9414 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9416 &bd->client.icccm.gravity,
9417 &bd->client.icccm.min_w,
9418 &bd->client.icccm.min_h,
9419 &bd->client.icccm.max_w,
9420 &bd->client.icccm.max_h,
9421 &bd->client.icccm.base_w,
9422 &bd->client.icccm.base_h,
9423 &bd->client.icccm.step_w,
9424 &bd->client.icccm.step_h,
9425 &bd->client.icccm.min_aspect,
9426 &bd->client.icccm.max_aspect))
9428 bd->client.icccm.request_pos = request_pos;
9433 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9434 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9435 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9436 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9437 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9438 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9439 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9440 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9441 // if doing a resize, fix it up
9442 if (bd->resize_mode != RESIZE_NONE)
9444 int x, y, w, h, new_w, new_h;
9452 e_border_resize_limit(bd, &new_w, &new_h);
9453 if ((bd->resize_mode == RESIZE_TL) ||
9454 (bd->resize_mode == RESIZE_L) ||
9455 (bd->resize_mode == RESIZE_BL))
9457 if ((bd->resize_mode == RESIZE_TL) ||
9458 (bd->resize_mode == RESIZE_T) ||
9459 (bd->resize_mode == RESIZE_TR))
9461 e_border_move_resize(bd, x, y, new_w, new_h);
9463 bd->client.icccm.fetch.size_pos_hints = 0;
9466 if (bd->client.icccm.fetch.protocol)
9469 Ecore_X_WM_Protocol *proto;
9471 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9474 for (i = 0; i < num; i++)
9476 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9477 bd->client.icccm.delete_request = 1;
9478 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9479 bd->client.icccm.take_focus = 1;
9480 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9481 bd->client.netwm.ping = 1;
9482 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9484 bd->client.netwm.sync.request = 1;
9485 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9486 &bd->client.netwm.sync.counter))
9487 bd->client.netwm.sync.request = 0;
9492 if (bd->client.netwm.ping)
9496 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9497 bd->ping_poller = NULL;
9499 bd->client.icccm.fetch.protocol = 0;
9501 if (bd->client.icccm.fetch.transient_for)
9503 /* TODO: What do to if the transient for isn't mapped yet? */
9504 E_Border *bd_parent = NULL;
9505 #ifdef _F_DEICONIFY_APPROVE_
9506 Eina_Bool change_parent = EINA_FALSE;
9509 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9510 if (bd->client.icccm.transient_for)
9511 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9512 /* If we already have a parent, remove it */
9515 if (bd_parent != bd->parent)
9517 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9518 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9524 if ((bd_parent) && (bd_parent != bd) &&
9525 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9527 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9528 bd->parent = bd_parent;
9529 #ifdef _F_DEICONIFY_APPROVE_
9530 change_parent = EINA_TRUE;
9535 e_border_layer_set(bd, bd->parent->layer);
9536 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9538 Ecore_X_Window_Attributes attr;
9539 bd->parent->modal = bd;
9540 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9541 bd->parent->saved.event_mask = attr.event_mask.mine;
9542 bd->parent->lock_close = 1;
9543 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9544 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9547 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9548 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9552 #ifdef _F_DEICONIFY_APPROVE_
9555 bd->client.e.state.deiconify_approve.render_done = 0;
9557 E_Border *ancestor_bd;
9558 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9559 if ((ancestor_bd) &&
9560 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9562 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9563 bd->client.e.state.deiconify_approve.ancestor = NULL;
9565 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9566 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9568 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9570 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9571 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9572 e_border_uniconify(ancestor_bd);
9578 bd->client.icccm.fetch.transient_for = 0;
9581 if (bd->client.icccm.fetch.window_role)
9583 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9584 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9585 if (role) free(role);
9587 bd->client.icccm.fetch.window_role = 0;
9590 if (bd->client.icccm.fetch.icon_name)
9592 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9593 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9594 if (icon_name) free(icon_name);
9596 bd->client.icccm.fetch.icon_name = 0;
9599 if (bd->client.netwm.fetch.icon_name)
9602 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9603 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9604 if (icon_name) free(icon_name);
9606 bd->client.netwm.fetch.icon_name = 0;
9609 if (bd->client.netwm.fetch.icon)
9612 if (bd->client.netwm.icons)
9614 for (i = 0; i < bd->client.netwm.num_icons; i++)
9616 free(bd->client.netwm.icons[i].data);
9617 bd->client.netwm.icons[i].data = NULL;
9619 free(bd->client.netwm.icons);
9621 bd->client.netwm.icons = NULL;
9622 bd->client.netwm.num_icons = 0;
9623 if (ecore_x_netwm_icons_get(bd->client.win,
9624 &bd->client.netwm.icons,
9625 &bd->client.netwm.num_icons))
9627 // unless the rest of e17 uses border icons OTHER than icon #0
9628 // then free the rest that we don't need anymore.
9629 for (i = 1; i < bd->client.netwm.num_icons; i++)
9631 free(bd->client.netwm.icons[i].data);
9632 bd->client.netwm.icons[i].data = NULL;
9634 bd->client.netwm.num_icons = 1;
9635 bd->changes.icon = 1;
9637 bd->client.netwm.fetch.icon = 0;
9639 if (bd->client.netwm.fetch.user_time)
9641 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9642 bd->client.netwm.fetch.user_time = 0;
9644 if (bd->client.netwm.fetch.strut)
9646 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9647 &bd->client.netwm.strut.left,
9648 &bd->client.netwm.strut.right,
9649 &bd->client.netwm.strut.top,
9650 &bd->client.netwm.strut.bottom,
9651 &bd->client.netwm.strut.left_start_y,
9652 &bd->client.netwm.strut.left_end_y,
9653 &bd->client.netwm.strut.right_start_y,
9654 &bd->client.netwm.strut.right_end_y,
9655 &bd->client.netwm.strut.top_start_x,
9656 &bd->client.netwm.strut.top_end_x,
9657 &bd->client.netwm.strut.bottom_start_x,
9658 &bd->client.netwm.strut.bottom_end_x))
9660 ecore_x_netwm_strut_get(bd->client.win,
9661 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9662 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9664 bd->client.netwm.strut.left_start_y = 0;
9665 bd->client.netwm.strut.left_end_y = 0;
9666 bd->client.netwm.strut.right_start_y = 0;
9667 bd->client.netwm.strut.right_end_y = 0;
9668 bd->client.netwm.strut.top_start_x = 0;
9669 bd->client.netwm.strut.top_end_x = 0;
9670 bd->client.netwm.strut.bottom_start_x = 0;
9671 bd->client.netwm.strut.bottom_end_x = 0;
9673 bd->client.netwm.fetch.strut = 0;
9675 if (bd->client.qtopia.fetch.soft_menu)
9677 e_hints_window_qtopia_soft_menu_get(bd);
9678 bd->client.qtopia.fetch.soft_menu = 0;
9681 if (bd->client.qtopia.fetch.soft_menus)
9683 e_hints_window_qtopia_soft_menus_get(bd);
9684 bd->client.qtopia.fetch.soft_menus = 0;
9687 if (bd->client.vkbd.fetch.state)
9689 e_hints_window_virtual_keyboard_state_get(bd);
9690 bd->client.vkbd.fetch.state = 0;
9693 if (bd->client.vkbd.fetch.vkbd)
9695 e_hints_window_virtual_keyboard_get(bd);
9696 bd->client.vkbd.fetch.vkbd = 0;
9699 if (bd->client.illume.conformant.fetch.conformant)
9701 bd->client.illume.conformant.conformant =
9702 ecore_x_e_illume_conformant_get(bd->client.win);
9703 bd->client.illume.conformant.fetch.conformant = 0;
9705 if (bd->client.illume.quickpanel.fetch.state)
9707 bd->client.illume.quickpanel.state =
9708 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9709 bd->client.illume.quickpanel.fetch.state = 0;
9711 if (bd->client.illume.quickpanel.fetch.quickpanel)
9713 bd->client.illume.quickpanel.quickpanel =
9714 ecore_x_e_illume_quickpanel_get(bd->client.win);
9715 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9717 if (bd->client.illume.quickpanel.fetch.priority.major)
9719 bd->client.illume.quickpanel.priority.major =
9720 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9721 bd->client.illume.quickpanel.fetch.priority.major = 0;
9723 if (bd->client.illume.quickpanel.fetch.priority.minor)
9725 bd->client.illume.quickpanel.priority.minor =
9726 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9727 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9729 if (bd->client.illume.quickpanel.fetch.zone)
9731 bd->client.illume.quickpanel.zone =
9732 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9733 bd->client.illume.quickpanel.fetch.zone = 0;
9735 if (bd->client.illume.drag.fetch.drag)
9737 bd->client.illume.drag.drag =
9738 ecore_x_e_illume_drag_get(bd->client.win);
9739 bd->client.illume.drag.fetch.drag = 0;
9741 if (bd->client.illume.drag.fetch.locked)
9743 bd->client.illume.drag.locked =
9744 ecore_x_e_illume_drag_locked_get(bd->client.win);
9745 bd->client.illume.drag.fetch.locked = 0;
9747 if (bd->client.illume.win_state.fetch.state)
9749 bd->client.illume.win_state.state =
9750 ecore_x_e_illume_window_state_get(bd->client.win);
9751 bd->client.illume.win_state.fetch.state = 0;
9753 if (bd->changes.shape)
9755 Ecore_X_Rectangle *rects;
9758 bd->changes.shape = 0;
9759 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9764 /* This doesn't fix the race, but makes it smaller. we detect
9765 * this and if cw and ch != client w/h then mark this as needing
9766 * a shape change again to fixup next event loop.
9768 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9769 if ((cw != bd->client.w) || (ch != bd->client.h))
9770 bd->changes.shape = 1;
9772 (rects[0].x == 0) &&
9773 (rects[0].y == 0) &&
9774 ((int)rects[0].width == cw) &&
9775 ((int)rects[0].height == ch))
9777 if (bd->client.shaped)
9779 bd->client.shaped = 0;
9780 if (!bd->bordername)
9781 bd->client.border.changed = 1;
9786 if (!bd->client.shaped)
9788 bd->client.shaped = 1;
9789 if (!bd->bordername)
9790 bd->client.border.changed = 1;
9797 // FIXME: no rects i think can mean... totally empty window
9798 bd->client.shaped = 0;
9799 if (!bd->bordername)
9800 bd->client.border.changed = 1;
9802 bd->need_shape_merge = 1;
9804 if (bd->changes.shape_input)
9806 Ecore_X_Rectangle *rects;
9809 bd->changes.shape_input = 0;
9810 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
9815 /* This doesn't fix the race, but makes it smaller. we detect
9816 * this and if cw and ch != client w/h then mark this as needing
9817 * a shape change again to fixup next event loop.
9819 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9820 if ((cw != bd->client.w) || (ch != bd->client.h))
9821 bd->changes.shape_input = 1;
9823 (rects[0].x == 0) &&
9824 (rects[0].y == 0) &&
9825 ((int)rects[0].width == cw) &&
9826 ((int)rects[0].height == ch))
9828 if (bd->shaped_input)
9830 bd->shaped_input = 0;
9831 if (!bd->bordername)
9832 bd->client.border.changed = 1;
9837 if (!bd->shaped_input)
9839 bd->shaped_input = 1;
9840 if (!bd->bordername)
9841 bd->client.border.changed = 1;
9848 bd->shaped_input = 1;
9849 if (!bd->bordername)
9850 bd->client.border.changed = 1;
9852 bd->need_shape_merge = 1;
9854 if (bd->client.mwm.fetch.hints)
9858 bd->client.mwm.exists =
9859 ecore_x_mwm_hints_get(bd->client.win,
9860 &bd->client.mwm.func,
9861 &bd->client.mwm.decor,
9862 &bd->client.mwm.input);
9863 pb = bd->client.mwm.borderless;
9864 bd->client.mwm.borderless = 0;
9865 if (bd->client.mwm.exists)
9867 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
9868 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
9869 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
9870 bd->client.mwm.borderless = 1;
9872 if (bd->client.mwm.borderless != pb)
9874 if ((!bd->lock_border) || (!bd->client.border.name))
9875 bd->client.border.changed = 1;
9877 bd->client.mwm.fetch.hints = 0;
9880 if (bd->client.e.fetch.video_parent)
9882 /* unlinking child/parent */
9883 if (bd->client.e.state.video_parent_border != NULL)
9885 bd->client.e.state.video_parent_border->client.e.state.video_child =
9887 (bd->client.e.state.video_parent_border->client.e.state.video_child,
9891 ecore_x_window_prop_card32_get(bd->client.win,
9892 ECORE_X_ATOM_E_VIDEO_PARENT,
9893 &bd->client.e.state.video_parent,
9896 /* linking child/parent */
9897 if (bd->client.e.state.video_parent != 0)
9902 EINA_LIST_FOREACH(borders, l, tmp)
9903 if (tmp->client.win == bd->client.e.state.video_parent)
9905 /* fprintf(stderr, "child added to parent \\o/\n"); */
9906 bd->client.e.state.video_parent_border = tmp;
9907 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
9909 if (bd->desk != tmp->desk)
9910 e_border_desk_set(bd, tmp->desk);
9915 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
9917 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
9920 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
9924 ecore_x_window_prop_card32_get(bd->client.win,
9925 ECORE_X_ATOM_E_VIDEO_POSITION,
9928 bd->client.e.state.video_position.x = xy[0];
9929 bd->client.e.state.video_position.y = xy[1];
9930 bd->client.e.state.video_position.updated = 1;
9931 bd->client.e.fetch.video_position = 0;
9932 bd->x = bd->client.e.state.video_position.x;
9933 bd->y = bd->client.e.state.video_position.y;
9935 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
9937 if (bd->client.netwm.update.state)
9939 e_hints_window_state_set(bd);
9940 /* Some stats might change the border, like modal */
9941 if (((!bd->lock_border) || (!bd->client.border.name)) &&
9942 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
9944 bd->client.border.changed = 1;
9948 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9950 bd->parent->modal = bd;
9951 if (bd->parent->focused)
9952 e_border_focus_set(bd, 1, 1);
9955 else if (bd->leader)
9957 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9959 bd->leader->modal = bd;
9960 if (bd->leader->focused)
9961 e_border_focus_set(bd, 1, 1);
9967 EINA_LIST_FOREACH(bd->leader->group, l, child)
9969 if ((child != bd) && (child->focused))
9970 e_border_focus_set(bd, 1, 1);
9975 bd->client.netwm.update.state = 0;
9980 E_Event_Border_Add *ev;
9981 E_Exec_Instance *inst;
9983 ev = E_NEW(E_Event_Border_Add, 1);
9985 e_object_ref(E_OBJECT(bd));
9986 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
9987 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
9989 if ((!bd->lock_border) || (!bd->client.border.name))
9990 bd->client.border.changed = 1;
9995 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
9996 ((bd->client.icccm.client_leader > 0) &&
9997 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10000 if (!strncmp(str, "E_START|", 8))
10004 id = atoi(str + 8);
10005 if (id > 0) bd->client.netwm.startup_id = id;
10010 /* It's ok not to have fetch flag, should only be set on startup
10011 * * and not changed. */
10012 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10014 if (bd->client.icccm.client_leader)
10016 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10017 bd->client.netwm.pid = -1;
10020 bd->client.netwm.pid = -1;
10023 if (!bd->re_manage)
10025 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10026 bd->client.netwm.pid);
10027 if ((inst) && (inst->used == 0))
10033 zone = e_container_zone_number_get(bd->zone->container,
10035 if (zone) e_border_zone_set(bd, zone);
10036 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10038 if (desk) e_border_desk_set(bd, desk);
10039 e_exec_instance_found(inst);
10042 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10044 E_Border *bdl = NULL;
10049 if (bd->leader) bdl = bd->leader;
10056 bl = e_container_border_list_first(bd->zone->container);
10057 while ((child = e_container_border_list_next(bl)))
10059 if (child == bd) continue;
10060 if (e_object_is_del(E_OBJECT(child))) continue;
10061 if ((bd->client.icccm.client_leader) &&
10062 (child->client.icccm.client_leader ==
10063 bd->client.icccm.client_leader))
10069 e_container_border_list_free(bl);
10074 e_border_zone_set(bd, bdl->zone);
10076 e_border_desk_set(bd, bdl->desk);
10078 e_border_stick(bd);
10084 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10087 E_Container *con = bd->zone->container;
10088 E_Desk *desk = NULL;
10091 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10093 desk = e_container_desk_window_profile_get(con, str);
10096 if (bd->desk != desk)
10098 bd->client.e.state.profile = eina_stringshare_add(str);
10099 if (bd->zone != desk->zone)
10100 e_border_zone_set(bd, desk->zone);
10101 e_border_desk_set(bd, desk);
10108 #ifdef _F_ZONE_WINDOW_ROTATION_
10109 if ((e_config->wm_win_rotation) &&
10110 (need_rotation_set) &&
10111 /* since this parts of code is processed before illume's layout hook handler is processed,
10112 * this border could be non-fullsize window at this time.
10113 * in this case, if we send rotation like message to window,
10114 * that window could have abnormal geometry.
10115 * so, we skip it in case new_client for now.*/
10118 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10119 Eina_Bool _rot = _e_border_rotation_check(bd);
10120 /* check whether rotation is available for sub borders such as prediction and magnifier */
10125 Eina_List *_list = _e_border_sub_borders_new(bd);
10126 EINA_LIST_FOREACH(_list, ll, _child)
10128 if ((_child->client.e.state.rot.support) ||
10129 (_child->client.e.state.rot.app_set))
10130 _e_border_rotation_check(_child);
10132 eina_list_free(_list);
10137 /* PRE_POST_FETCH calls e_remember apply for new client */
10138 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10139 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10140 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10142 if (bd->need_reparent)
10145 ecore_x_window_save_set_add(bd->client.win);
10146 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10149 if ((bd->new_client) && (bd->internal) &&
10150 (bd->internal_ecore_evas))
10151 ecore_evas_show(bd->internal_ecore_evas);
10152 ecore_x_window_show(bd->client.win);
10154 bd->need_reparent = 0;
10157 if ((bd->client.border.changed) && (!bd->shaded) &&
10158 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10160 const char *bordername;
10162 if (bd->fullscreen)
10163 bordername = "borderless";
10164 else if (bd->bordername)
10165 bordername = bd->bordername;
10166 else if ((bd->client.mwm.borderless) || (bd->borderless))
10167 bordername = "borderless";
10168 else if (((bd->client.icccm.transient_for != 0) ||
10169 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10170 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10171 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10172 bordername = "noresize_dialog";
10173 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10174 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10175 bordername = "noresize";
10176 else if (bd->client.shaped)
10177 bordername = "shaped";
10178 else if ((!bd->client.icccm.accepts_focus) &&
10179 (!bd->client.icccm.take_focus))
10180 bordername = "nofocus";
10181 else if (bd->client.icccm.urgent)
10182 bordername = "urgent";
10183 else if ((bd->client.icccm.transient_for != 0) ||
10184 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10185 bordername = "dialog";
10186 else if (bd->client.netwm.state.modal)
10187 bordername = "modal";
10188 else if ((bd->client.netwm.state.skip_taskbar) ||
10189 (bd->client.netwm.state.skip_pager))
10190 bordername = "skipped";
10191 else if ((bd->internal) && (bd->client.icccm.class) &&
10192 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10193 bordername = "internal_fileman";
10195 bordername = e_config->theme_default_border_style;
10196 if (!bordername) bordername = "default";
10198 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10204 bd->changes.border = 1;
10205 eina_stringshare_replace(&bd->client.border.name, bordername);
10209 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10210 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10211 bd->changes.size = 1;
10212 evas_object_del(bd->bg_object);
10214 o = edje_object_add(bd->bg_evas);
10215 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10216 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10217 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10219 if (bd->client.border.name != e_config->theme_default_border_style)
10221 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10222 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10226 ok = e_theme_edje_object_set(o, "base/theme/borders",
10227 "e/widgets/border/default/border");
10230 /* Reset default border style to default */
10231 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10232 e_config_save_queue();
10240 const char *shape_option, *argb_option;
10245 if ((e_config->use_composite) && (!bd->client.argb))
10247 argb_option = edje_object_data_get(o, "argb");
10248 if ((argb_option) && (!strcmp(argb_option, "1")))
10251 if (use_argb != bd->argb)
10252 _e_border_frame_replace(bd, use_argb);
10259 shape_option = edje_object_data_get(o, "shaped");
10260 if ((shape_option) && (!strcmp(shape_option, "1")))
10264 if (bd->client.netwm.name)
10265 edje_object_part_text_set(o, "e.text.title",
10266 bd->client.netwm.name);
10267 else if (bd->client.icccm.title)
10268 edje_object_part_text_set(o, "e.text.title",
10269 bd->client.icccm.title);
10273 evas_object_del(o);
10274 bd->bg_object = NULL;
10277 _e_border_client_inset_calc(bd);
10279 bd->w += (bd->client_inset.l + bd->client_inset.r);
10280 bd->h += (bd->client_inset.t + bd->client_inset.b);
10281 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10282 bd->changes.size = 1;
10283 /* really needed ? */
10284 ecore_x_window_move(bd->client.shell_win,
10285 bd->client_inset.l,
10286 bd->client_inset.t);
10288 if (bd->maximized != E_MAXIMIZE_NONE)
10290 E_Maximize maximized = bd->maximized;
10292 /* to force possible resizes */
10293 bd->maximized = E_MAXIMIZE_NONE;
10295 _e_border_maximize(bd, maximized);
10297 /* restore maximized state */
10298 bd->maximized = maximized;
10300 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10301 bd->maximized & E_MAXIMIZE_VERTICAL);
10305 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10306 _e_border_cb_signal_bind, bd);
10309 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10310 if (bd->icon_object)
10311 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10314 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10316 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10318 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10319 // FIXME: in eval -do differently
10320 // edje_object_message_signal_process(bd->bg_object);
10321 // e_border_frame_recalc(bd);
10323 evas_object_move(bd->bg_object, 0, 0);
10324 evas_object_resize(bd->bg_object, bd->w, bd->h);
10325 evas_object_show(bd->bg_object);
10328 bd->client.border.changed = 0;
10330 if (bd->icon_object)
10334 evas_object_show(bd->icon_object);
10335 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10338 evas_object_hide(bd->icon_object);
10342 if (rem_change) e_remember_update(bd);
10346 E_Event_Border_Urgent_Change *ev;
10348 if (bd->client.icccm.urgent)
10349 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10351 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10353 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10355 e_object_ref(E_OBJECT(bd));
10356 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10357 _e_border_event_border_urgent_change_free, NULL);
10360 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10363 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10365 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10367 E_Border* temp_bd = NULL;
10368 E_Border* top_focusable_bd = NULL;
10369 Eina_Bool is_fully_obscured = EINA_FALSE;
10370 Ecore_X_XRegion *visible_region = NULL;
10371 Ecore_X_XRegion *win_region = NULL;
10372 Ecore_X_Rectangle visible_rect, win_rect;
10375 // set the entire visible region as a root geometry
10376 visible_rect.x = bd->zone->x;
10377 visible_rect.y = bd->zone->y;
10378 visible_rect.width = bd->zone->w;
10379 visible_rect.height = bd->zone->h;
10381 visible_region = ecore_x_xregion_new();
10382 if (!visible_region) return;
10384 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10386 bl = e_container_border_list_last(bd->zone->container);
10387 while ((temp_bd = e_container_border_list_prev(bl)))
10389 if (temp_bd == bd) break;
10391 if (temp_bd == focused) continue;
10392 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10393 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10394 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10395 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10396 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10397 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10398 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10399 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10400 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10402 if (!top_focusable_bd)
10404 top_focusable_bd = temp_bd;
10407 win_rect.x = temp_bd->x;
10408 win_rect.y = temp_bd->y;
10409 win_rect.width = temp_bd->w;
10410 win_rect.height = temp_bd->h;
10412 // if it stick out or is bigger than the entire visible region,
10413 // clip it by the entire visible's geometry.
10414 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10415 win_rect.width, win_rect.height,
10416 visible_rect.x, visible_rect.y,
10417 (int)(visible_rect.width), (int)(visible_rect.height));
10419 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10421 win_region = ecore_x_xregion_new();
10424 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10425 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10426 ecore_x_xregion_free(win_region);
10429 if (ecore_x_xregion_is_empty(visible_region))
10431 is_fully_obscured = EINA_TRUE;
10439 if (is_fully_obscured == EINA_TRUE)
10441 e_border_focus_set(top_focusable_bd, 1, 1);
10445 e_border_focus_set(bd, 1, 1);
10448 if (visible_region) ecore_x_xregion_free(visible_region);
10449 e_container_border_list_free(bl);
10453 _e_border_latest_stacked_focus(E_Border *bd)
10456 int root_w, root_h;
10458 root_w = bd->zone->w;
10459 root_h = bd->zone->h;
10462 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10464 if (bd == temp_bd) continue;
10465 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10466 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10468 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10469 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10470 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10471 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10472 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10473 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10474 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10476 _e_border_latest_stacked_focus_check_set(temp_bd);
10483 _e_border_check_stack (E_Border *bd)
10485 E_Border* temp_bd = NULL;
10486 E_Border* top_bd = NULL;
10487 int passed_focus = 0;
10489 int root_w = bd->zone->w;
10490 int root_h = bd->zone->h;
10493 bl = e_container_border_list_last(bd->zone->container);
10494 while ((temp_bd = e_container_border_list_prev(bl)))
10496 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10497 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10498 if ((temp_bd != bd) &&
10499 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10501 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10502 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10503 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10504 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10505 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10506 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10507 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10513 e_border_focus_set_with_pointer(bd);
10520 e_border_focus_set_with_pointer(top_bd);
10529 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10531 if (!bd->lock_focus_out)
10533 e_border_focus_latest_set(bd);
10545 if (temp_bd == focused)
10551 e_container_border_list_free(bl);
10555 _e_border_focus_top_stack_set(E_Border* bd)
10558 int root_w, root_h;
10560 root_w = bd->zone->w;
10561 root_h = bd->zone->h;
10564 bl = e_container_border_list_last(bd->zone->container);
10565 while ((temp_bd = e_container_border_list_prev(bl)))
10567 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10568 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10569 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10571 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10572 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10573 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10574 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10575 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10576 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10577 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10579 if (!temp_bd->focused)
10581 /* this border is the top of the latest stack */
10582 e_border_focus_set (temp_bd, 1, 1);
10587 e_container_border_list_free(bl);
10592 _e_border_eval(E_Border *bd)
10594 E_Event_Border_Property *event;
10595 E_Border_Pending_Move_Resize *pnd;
10596 int rem_change = 0;
10597 int send_event = 1;
10599 if (e_object_is_del(E_OBJECT(bd)))
10601 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10606 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10608 if (bd->new_client)
10610 int zx = 0, zy = 0, zw = 0, zh = 0;
10613 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10616 * Limit maximum size of windows to useful geometry
10618 // TODO: temoporary limited maximize algorithm
10630 if ((rw != bd->w) || (rh != bd->h))
10634 e_border_resize (bd, bd->w, bd->h);
10640 bd->x -= bd->client_inset.l;
10641 bd->y -= bd->client_inset.t;
10642 bd->changes.pos = 1;
10645 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10648 Ecore_X_Window_Attributes *att;
10651 att = &bd->client.initial_attributes;
10652 bw = att->border * 2;
10653 switch (bd->client.icccm.gravity)
10655 case ECORE_X_GRAVITY_N:
10656 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10660 case ECORE_X_GRAVITY_NE:
10661 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10665 case ECORE_X_GRAVITY_E:
10666 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10667 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10670 case ECORE_X_GRAVITY_SE:
10671 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10672 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10675 case ECORE_X_GRAVITY_S:
10676 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10677 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10680 case ECORE_X_GRAVITY_SW:
10682 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10685 case ECORE_X_GRAVITY_W:
10687 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10690 case ECORE_X_GRAVITY_CENTER:
10691 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10692 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10695 case ECORE_X_GRAVITY_NW:
10702 * This ensures that windows that like to open with a x/y
10703 * position smaller than returned by e_zone_useful_geometry_get()
10704 * are moved to useful positions.
10707 if (e_config->geometry_auto_move)
10715 if (bd->x + bd->w > zx + zw)
10716 bd->x = zx + zw - bd->w;
10718 if (bd->y + bd->h > zy + zh)
10719 bd->y = zy + zh - bd->h;
10722 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10724 bd->changes.pos = 1;
10730 bd->changes.pos = 1;
10736 /* FIXME: special placement for dialogs etc. etc. etc goes
10738 /* FIXME: what if parent is not on this desktop - or zone? */
10739 if ((bd->parent) && (bd->parent->visible))
10741 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10742 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10743 bd->changes.pos = 1;
10747 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10749 /* TODO: Place in center of group */
10752 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10754 bd->x = zx + ((zw - bd->w) / 2);
10755 bd->y = zy + ((zh - bd->h) / 2);
10756 bd->changes.pos = 1;
10762 Eina_List *skiplist = NULL;
10766 new_x = zx + (rand() % (zw - bd->w));
10770 new_y = zy + (rand() % (zh - bd->h));
10774 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10776 skiplist = eina_list_append(skiplist, bd);
10778 e_place_desk_region_smart(bd->desk, skiplist,
10779 bd->x, bd->y, bd->w, bd->h,
10782 e_place_zone_region_smart(bd->zone, skiplist,
10783 bd->x, bd->y, bd->w, bd->h,
10785 eina_list_free(skiplist);
10787 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10789 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10794 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10795 bd->client_inset.t, &new_x, &new_y);
10799 bd->changes.pos = 1;
10802 EINA_LIST_FREE(bd->pending_move_resize, pnd)
10804 if ((!bd->lock_client_location) && (pnd->move))
10808 bd->changes.pos = 1;
10810 if (pnd->without_border)
10812 bd->x -= bd->client_inset.l;
10813 bd->y -= bd->client_inset.t;
10816 if ((!bd->lock_client_size) && (pnd->resize))
10818 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
10819 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
10820 bd->client.w = pnd->w;
10821 bd->client.h = pnd->h;
10822 bd->changes.size = 1;
10828 /* Recreate state */
10829 e_hints_window_init(bd);
10830 if ((bd->client.e.state.centered) &&
10831 ((!bd->remember) ||
10832 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
10834 bd->x = zx + (zw - bd->w) / 2;
10835 bd->y = zy + (zh - bd->h) / 2;
10836 bd->changes.pos = 1;
10840 _e_border_client_move_resize_send(bd);
10842 /* if the explicit geometry request asks for the app to be
10843 * in another zone - well move it there */
10847 zone = e_container_zone_at_point_get(bd->zone->container,
10848 bd->x + (bd->w / 2),
10849 bd->y + (bd->h / 2));
10851 zone = e_container_zone_at_point_get(bd->zone->container,
10855 zone = e_container_zone_at_point_get(bd->zone->container,
10859 zone = e_container_zone_at_point_get(bd->zone->container,
10861 bd->y + bd->h - 1);
10863 zone = e_container_zone_at_point_get(bd->zone->container,
10865 bd->y + bd->h - 1);
10866 if ((zone) && (zone != bd->zone))
10867 e_border_zone_set(bd, zone);
10871 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
10873 /* effect changes to the window border itself */
10874 if ((bd->changes.shading))
10876 /* show at start of unshade (but don't hide until end of shade) */
10878 ecore_x_window_raise(bd->client.shell_win);
10879 bd->changes.shading = 0;
10882 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
10885 ecore_x_window_lower(bd->client.shell_win);
10887 ecore_x_window_raise(bd->client.shell_win);
10888 bd->changes.shaded = 0;
10891 else if ((bd->changes.shaded) && (bd->changes.pos))
10894 ecore_x_window_lower(bd->client.shell_win);
10896 ecore_x_window_raise(bd->client.shell_win);
10897 bd->changes.size = 1;
10898 bd->changes.shaded = 0;
10901 else if ((bd->changes.shaded) && (bd->changes.size))
10904 ecore_x_window_lower(bd->client.shell_win);
10906 ecore_x_window_raise(bd->client.shell_win);
10907 bd->changes.shaded = 0;
10910 else if (bd->changes.shaded)
10913 ecore_x_window_lower(bd->client.shell_win);
10915 ecore_x_window_raise(bd->client.shell_win);
10916 bd->changes.size = 1;
10917 bd->changes.shaded = 0;
10921 if (bd->changes.size)
10923 int x = 0, y = 0, xx = 0, yy = 0;
10925 if ((bd->shaded) && (!bd->shading))
10927 evas_obscured_clear(bd->bg_evas);
10931 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
10932 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
10934 evas_obscured_clear(bd->bg_evas);
10935 evas_obscured_rectangle_add(bd->bg_evas,
10936 bd->client_inset.l, bd->client_inset.t, xx, yy);
10940 if (bd->shade.dir == E_DIRECTION_UP)
10942 y = yy - bd->client.h;
10944 else if (bd->shade.dir == E_DIRECTION_LEFT)
10946 x = xx - bd->client.w;
10951 if (bd->client.e.state.video)
10953 if (bd->client.e.state.video_position.updated)
10955 ecore_x_window_move(bd->win,
10956 bd->client.e.state.video_parent_border->x +
10957 bd->client.e.state.video_parent_border->client_inset.l +
10958 bd->client.e.state.video_parent_border->fx.x +
10959 bd->client.e.state.video_position.x,
10960 bd->client.e.state.video_parent_border->y +
10961 bd->client.e.state.video_parent_border->client_inset.t +
10962 bd->client.e.state.video_parent_border->fx.y +
10963 bd->client.e.state.video_position.y);
10964 bd->client.e.state.video_position.updated = 0;
10967 else if (!bd->changes.pos)
10969 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10970 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10971 bd->post_resize = 1;
10978 ecore_x_window_move_resize(bd->win,
10983 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
10984 ecore_x_window_move(tmp->win,
10985 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
10986 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
10989 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
10991 if ((!bd->shaded) || (bd->shading))
10992 ecore_x_window_move_resize(bd->client.shell_win,
10993 bd->client_inset.l, bd->client_inset.t, xx, yy);
10995 if (bd->internal_ecore_evas)
10996 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
10997 else if (!bd->client.e.state.video)
10998 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11000 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11001 evas_object_resize(bd->bg_object, bd->w, bd->h);
11002 e_container_shape_resize(bd->shape, bd->w, bd->h);
11003 if (bd->changes.pos)
11004 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11006 _e_border_client_move_resize_send(bd);
11008 bd->changes.pos = 0;
11009 bd->changes.size = 0;
11012 else if (bd->changes.pos)
11014 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11015 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11018 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11020 _e_border_client_move_resize_send(bd);
11022 bd->changes.pos = 0;
11026 if (bd->changes.reset_gravity)
11028 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11029 bd->changes.reset_gravity = 0;
11033 if (bd->need_shape_merge)
11035 _e_border_shape_input_rectangle_set(bd);
11036 if ((bd->shaped) || (bd->client.shaped))
11038 Ecore_X_Window twin, twin2;
11041 twin = ecore_x_window_override_new
11042 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11044 ecore_x_window_shape_window_set(twin, bd->bg_win);
11047 Ecore_X_Rectangle rects[4];
11051 rects[0].width = bd->w;
11052 rects[0].height = bd->client_inset.t;
11054 rects[1].y = bd->client_inset.t;
11055 rects[1].width = bd->client_inset.l;
11056 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11057 rects[2].x = bd->w - bd->client_inset.r;
11058 rects[2].y = bd->client_inset.t;
11059 rects[2].width = bd->client_inset.r;
11060 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11062 rects[3].y = bd->h - bd->client_inset.b;
11063 rects[3].width = bd->w;
11064 rects[3].height = bd->client_inset.b;
11065 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11067 twin2 = ecore_x_window_override_new
11068 (bd->zone->container->scratch_win, 0, 0,
11069 bd->w - bd->client_inset.l - bd->client_inset.r,
11070 bd->h - bd->client_inset.t - bd->client_inset.b);
11073 if ((bd->shading) || (bd->shaded))
11075 if (bd->shade.dir == E_DIRECTION_UP)
11076 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11077 else if (bd->shade.dir == E_DIRECTION_LEFT)
11078 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11080 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11082 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11083 bd->w - bd->client_inset.l - bd->client_inset.r,
11084 bd->h - bd->client_inset.t - bd->client_inset.b);
11085 ecore_x_window_shape_window_add_xy(twin, twin2,
11086 bd->client_inset.l,
11087 bd->client_inset.t);
11088 ecore_x_window_free(twin2);
11089 ecore_x_window_shape_window_set(bd->win, twin);
11090 ecore_x_window_free(twin);
11093 ecore_x_window_shape_mask_set(bd->win, 0);
11094 // bd->need_shape_export = 1;
11095 bd->need_shape_merge = 0;
11098 if (bd->need_shape_export)
11100 Ecore_X_Rectangle *rects, *orects;
11103 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11109 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11113 orects = bd->shape_rects;
11115 for (i = 0; i < num; i++)
11117 if (rects[i].x < 0)
11119 rects[i].width -= rects[i].x;
11122 if ((rects[i].x + (int)rects[i].width) > bd->w)
11123 rects[i].width = rects[i].width - rects[i].x;
11124 if (rects[i].y < 0)
11126 rects[i].height -= rects[i].y;
11129 if ((rects[i].y + (int)rects[i].height) > bd->h)
11130 rects[i].height = rects[i].height - rects[i].y;
11132 if ((orects[i].x != rects[i].x) ||
11133 (orects[i].y != rects[i].y) ||
11134 (orects[i].width != rects[i].width) ||
11135 (orects[i].height != rects[i].height))
11144 if (bd->client.shaped)
11145 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11147 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11148 E_FREE(bd->shape_rects);
11149 bd->shape_rects = rects;
11150 bd->shape_rects_num = num;
11151 e_container_shape_rects_set(bd->shape, rects, num);
11158 E_FREE(bd->shape_rects);
11159 bd->shape_rects = NULL;
11160 bd->shape_rects_num = 0;
11161 e_container_shape_rects_set(bd->shape, NULL, 0);
11163 bd->need_shape_export = 0;
11166 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11170 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11171 if ((!bd->placed) && (!bd->re_manage) &&
11172 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11173 (!((bd->client.icccm.transient_for != 0) ||
11174 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11175 (!bdmove) && (!bdresize))
11177 /* Set this window into moving state */
11179 bd->cur_mouse_action = e_action_find("window_move");
11180 if (bd->cur_mouse_action)
11182 if ((!bd->cur_mouse_action->func.end_mouse) &&
11183 (!bd->cur_mouse_action->func.end))
11184 bd->cur_mouse_action = NULL;
11185 if (bd->cur_mouse_action)
11187 bd->x = x - (bd->w >> 1);
11188 bd->y = y - (bd->client_inset.t >> 1);
11190 bd->changes.pos = 1;
11192 _e_border_client_move_resize_send(bd);
11197 _e_border_show(bd);
11199 if (bd->cur_mouse_action)
11201 bd->moveinfo.down.x = bd->x + bd->fx.x;
11202 bd->moveinfo.down.y = bd->y + bd->fx.y;
11203 bd->moveinfo.down.w = bd->w;
11204 bd->moveinfo.down.h = bd->h;
11205 bd->mouse.current.mx = x;
11206 bd->mouse.current.my = y;
11207 bd->moveinfo.down.button = 0;
11208 bd->moveinfo.down.mx = x;
11209 bd->moveinfo.down.my = y;
11212 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11213 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11214 if (e_config->border_raise_on_mouse_action)
11215 e_border_raise(bd);
11216 e_border_focus_set(bd, 1, 1);
11218 bd->changes.visible = 0;
11222 if (bd->changes.icon)
11226 efreet_desktop_free(bd->desktop);
11227 bd->desktop = NULL;
11229 if (bd->icon_object)
11231 evas_object_del(bd->icon_object);
11232 bd->icon_object = NULL;
11234 if (bd->remember && bd->remember->prop.desktop_file)
11236 const char *desktop = bd->remember->prop.desktop_file;
11238 bd->desktop = efreet_desktop_get(desktop);
11240 bd->desktop = efreet_util_desktop_name_find(desktop);
11244 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11245 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11246 bd->client.icccm.class);
11250 /* libreoffice and maybe others match window class
11251 with .desktop file name */
11252 if (bd->client.icccm.class)
11255 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11256 bd->desktop = efreet_util_desktop_file_id_find(buf);
11261 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11262 bd->client.netwm.pid);
11263 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11265 if (!bd->desktop && bd->client.icccm.name)
11267 /* this works for most cases as fallback. useful when app is
11268 run from a shell */
11269 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11271 if (!bd->desktop && bd->client.icccm.transient_for)
11273 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11274 if (bd2 && bd2->desktop)
11276 efreet_desktop_ref(bd2->desktop);
11277 bd->desktop = bd2->desktop;
11282 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11283 bd->desktop->orig_path);
11286 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11287 if ((bd->focused) && (bd->icon_object))
11288 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11291 evas_object_show(bd->icon_object);
11292 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11295 evas_object_hide(bd->icon_object);
11298 E_Event_Border_Icon_Change *ev;
11300 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11302 e_object_ref(E_OBJECT(bd));
11303 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11304 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11305 _e_border_event_border_icon_change_free, NULL);
11307 bd->changes.icon = 0;
11310 bd->new_client = 0;
11312 bd->changes.stack = 0;
11313 bd->changes.prop = 0;
11315 if ((bd->take_focus) || (bd->want_focus))
11317 bd->take_focus = 0;
11318 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11319 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11320 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11323 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11326 bd->want_focus = 0;
11327 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11328 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11329 _e_border_check_stack(bd);
11332 e_border_focus_set_with_pointer(bd);
11334 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11336 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11337 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11338 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11339 e_border_focused_get())))
11341 e_border_focus_set_with_pointer(bd);
11346 /* focus window by default when it is the only one on desk */
11347 E_Border *bd2 = NULL;
11349 EINA_LIST_FOREACH(focus_stack, l, bd2)
11351 if (bd == bd2) continue;
11352 if ((!bd2->iconic) && (bd2->visible) &&
11353 ((bd->desk == bd2->desk) || bd2->sticky))
11359 e_border_focus_set_with_pointer(bd);
11364 if (bd->need_maximize)
11367 max = bd->maximized;
11368 bd->maximized = E_MAXIMIZE_NONE;
11369 e_border_maximize(bd, max);
11370 bd->need_maximize = 0;
11373 if (bd->need_fullscreen)
11375 e_border_fullscreen(bd, e_config->fullscreen_policy);
11376 bd->need_fullscreen = 0;
11380 e_remember_update(bd);
11382 if (send_event) // FIXME: send only if a property changed - above need to
11383 { // check on that. for now - always send.
11384 event = E_NEW(E_Event_Border_Property, 1);
11385 event->border = bd;
11386 e_object_ref(E_OBJECT(bd));
11387 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11389 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11393 _e_border_moveinfo_gather(E_Border *bd,
11394 const char *source)
11396 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11397 else if (e_util_glob_match(source, "mouse,*,2"))
11398 bd->moveinfo.down.button = 2;
11399 else if (e_util_glob_match(source, "mouse,*,3"))
11400 bd->moveinfo.down.button = 3;
11401 else bd->moveinfo.down.button = 0;
11402 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11404 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11405 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11409 bd->moveinfo.down.mx = bd->mouse.current.mx;
11410 bd->moveinfo.down.my = bd->mouse.current.my;
11415 _e_border_resize_handle(E_Border *bd)
11418 int new_x, new_y, new_w, new_h;
11420 Eina_List *skiplist = NULL;
11427 if ((bd->resize_mode == RESIZE_TR) ||
11428 (bd->resize_mode == RESIZE_R) ||
11429 (bd->resize_mode == RESIZE_BR))
11431 if ((bd->moveinfo.down.button >= 1) &&
11432 (bd->moveinfo.down.button <= 3))
11433 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11434 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11436 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11438 else if ((bd->resize_mode == RESIZE_TL) ||
11439 (bd->resize_mode == RESIZE_L) ||
11440 (bd->resize_mode == RESIZE_BL))
11442 if ((bd->moveinfo.down.button >= 1) &&
11443 (bd->moveinfo.down.button <= 3))
11444 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11445 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11447 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11450 if ((bd->resize_mode == RESIZE_TL) ||
11451 (bd->resize_mode == RESIZE_T) ||
11452 (bd->resize_mode == RESIZE_TR))
11454 if ((bd->moveinfo.down.button >= 1) &&
11455 (bd->moveinfo.down.button <= 3))
11456 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11457 (bd->mouse.current.my - bd->moveinfo.down.my);
11459 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11461 else if ((bd->resize_mode == RESIZE_BL) ||
11462 (bd->resize_mode == RESIZE_B) ||
11463 (bd->resize_mode == RESIZE_BR))
11465 if ((bd->moveinfo.down.button >= 1) &&
11466 (bd->moveinfo.down.button <= 3))
11467 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11468 (bd->mouse.current.my - bd->moveinfo.down.my);
11470 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11476 if ((bd->resize_mode == RESIZE_TL) ||
11477 (bd->resize_mode == RESIZE_L) ||
11478 (bd->resize_mode == RESIZE_BL))
11480 if ((bd->resize_mode == RESIZE_TL) ||
11481 (bd->resize_mode == RESIZE_T) ||
11482 (bd->resize_mode == RESIZE_TR))
11485 skiplist = eina_list_append(skiplist, bd);
11486 e_resist_container_border_position(bd->zone->container, skiplist,
11487 bd->x, bd->y, bd->w, bd->h,
11489 &new_x, &new_y, &new_w, &new_h);
11490 eina_list_free(skiplist);
11494 e_border_resize_limit(bd, &new_w, &new_h);
11495 if ((bd->resize_mode == RESIZE_TL) ||
11496 (bd->resize_mode == RESIZE_L) ||
11497 (bd->resize_mode == RESIZE_BL))
11498 new_x += (w - new_w);
11499 if ((bd->resize_mode == RESIZE_TL) ||
11500 (bd->resize_mode == RESIZE_T) ||
11501 (bd->resize_mode == RESIZE_TR))
11502 new_y += (h - new_h);
11504 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11508 _e_border_shade_animator(void *data)
11510 E_Border *bd = data;
11512 double dur = bd->client.h / e_config->border_shade_speed;
11514 dt = ecore_loop_time_get() - bd->shade.start;
11517 if (val < 0.0) val = 0.0;
11518 else if (val > 1.0) val = 1.0;
11520 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11523 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11524 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11526 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11529 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11530 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11532 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11535 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11536 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11538 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11541 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11542 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11544 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11547 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11548 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11550 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11553 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11554 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11556 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11559 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11560 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11562 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11565 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11566 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11568 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11571 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11572 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11577 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11578 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11581 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11582 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11583 else if (bd->shade.val > .999)
11584 bd->shade.val = 1.0;
11586 if (bd->shade.dir == E_DIRECTION_UP)
11587 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11588 else if (bd->shade.dir == E_DIRECTION_DOWN)
11590 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11591 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11592 bd->changes.pos = 1;
11594 else if (bd->shade.dir == E_DIRECTION_LEFT)
11595 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11596 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11598 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11599 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11600 bd->changes.pos = 1;
11603 if ((bd->shaped) || (bd->client.shaped))
11605 bd->need_shape_merge = 1;
11606 bd->need_shape_export = 1;
11608 if (bd->shaped_input)
11610 bd->need_shape_merge = 1;
11612 bd->changes.size = 1;
11618 E_Event_Border_Resize *ev;
11621 bd->shaded = !(bd->shaded);
11622 bd->changes.size = 1;
11623 bd->changes.shaded = 1;
11624 bd->changes.shading = 1;
11626 bd->shade.anim = NULL;
11629 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11631 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11632 edje_object_message_signal_process(bd->bg_object);
11633 e_border_frame_recalc(bd);
11635 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11636 ev = E_NEW(E_Event_Border_Resize, 1);
11638 e_object_ref(E_OBJECT(bd));
11639 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11640 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11641 return ECORE_CALLBACK_CANCEL;
11643 return ECORE_CALLBACK_RENEW;
11647 _e_border_event_border_resize_free(void *data __UNUSED__,
11650 E_Event_Border_Resize *e;
11653 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11654 e_object_unref(E_OBJECT(e->border));
11659 _e_border_event_border_move_free(void *data __UNUSED__,
11662 E_Event_Border_Move *e;
11665 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11666 e_object_unref(E_OBJECT(e->border));
11671 _e_border_event_border_add_free(void *data __UNUSED__,
11674 E_Event_Border_Add *e;
11677 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11678 e_object_unref(E_OBJECT(e->border));
11683 _e_border_event_border_remove_free(void *data __UNUSED__,
11686 E_Event_Border_Remove *e;
11689 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11690 e_object_unref(E_OBJECT(e->border));
11695 _e_border_event_border_show_free(void *data __UNUSED__,
11698 E_Event_Border_Show *e;
11701 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11702 e_object_unref(E_OBJECT(e->border));
11707 _e_border_event_border_hide_free(void *data __UNUSED__,
11710 E_Event_Border_Hide *e;
11713 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11714 e_object_unref(E_OBJECT(e->border));
11719 _e_border_event_border_iconify_free(void *data __UNUSED__,
11722 E_Event_Border_Iconify *e;
11725 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11726 e_object_unref(E_OBJECT(e->border));
11731 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11734 E_Event_Border_Uniconify *e;
11737 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11738 e_object_unref(E_OBJECT(e->border));
11743 _e_border_event_border_stick_free(void *data __UNUSED__,
11746 E_Event_Border_Stick *e;
11749 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11750 e_object_unref(E_OBJECT(e->border));
11755 _e_border_event_border_unstick_free(void *data __UNUSED__,
11758 E_Event_Border_Unstick *e;
11761 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11762 e_object_unref(E_OBJECT(e->border));
11767 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11770 E_Event_Border_Zone_Set *e;
11773 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11774 e_object_unref(E_OBJECT(e->border));
11775 e_object_unref(E_OBJECT(e->zone));
11780 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11783 E_Event_Border_Desk_Set *e;
11786 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11787 e_object_unref(E_OBJECT(e->border));
11788 e_object_unref(E_OBJECT(e->desk));
11793 _e_border_event_border_stack_free(void *data __UNUSED__,
11796 E_Event_Border_Stack *e;
11799 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
11800 e_object_unref(E_OBJECT(e->border));
11803 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
11804 e_object_unref(E_OBJECT(e->stack));
11810 _e_border_event_border_icon_change_free(void *data __UNUSED__,
11813 E_Event_Border_Icon_Change *e;
11816 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
11817 e_object_unref(E_OBJECT(e->border));
11822 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
11825 E_Event_Border_Urgent_Change *e;
11828 e_object_unref(E_OBJECT(e->border));
11833 _e_border_event_border_focus_in_free(void *data __UNUSED__,
11836 E_Event_Border_Focus_In *e;
11839 e_object_unref(E_OBJECT(e->border));
11844 _e_border_event_border_focus_out_free(void *data __UNUSED__,
11847 E_Event_Border_Focus_Out *e;
11850 e_object_unref(E_OBJECT(e->border));
11855 _e_border_event_border_property_free(void *data __UNUSED__,
11858 E_Event_Border_Property *e;
11861 e_object_unref(E_OBJECT(e->border));
11866 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
11869 E_Event_Border_Fullscreen *e;
11872 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
11873 e_object_unref(E_OBJECT(e->border));
11878 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
11881 E_Event_Border_Unfullscreen *e;
11884 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
11885 e_object_unref(E_OBJECT(e->border));
11889 #ifdef _F_ZONE_WINDOW_ROTATION_
11891 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
11894 E_Event_Border_Rotation_Change_Begin *e;
11896 e_object_unref(E_OBJECT(e->border));
11901 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
11904 E_Event_Border_Rotation_Change_Cancel *e;
11906 e_object_unref(E_OBJECT(e->border));
11911 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
11914 E_Event_Border_Rotation_Change_End *e;
11916 e_object_unref(E_OBJECT(e->border));
11921 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
11923 E_Event_Border_Rotation_Change_Begin *ev = NULL;
11924 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
11928 e_object_ref(E_OBJECT(bd));
11929 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
11931 _e_border_event_border_rotation_change_begin_free,
11938 _e_border_zone_update(E_Border *bd)
11944 /* still within old zone - leave it there */
11945 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11946 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
11947 #if _F_BORDER_CLIP_TO_ZONE_
11949 _e_border_shape_input_clip_to_zone(bd);
11954 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11955 /* find a new zone */
11956 con = bd->zone->container;
11957 EINA_LIST_FOREACH(con->zones, l, zone)
11959 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11960 zone->x, zone->y, zone->w, zone->h))
11962 e_border_zone_set(bd, zone);
11963 #if _F_BORDER_CLIP_TO_ZONE_
11964 _e_border_shape_input_clip_to_zone(bd);
11965 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11972 _e_border_resize_begin(E_Border *bd)
11974 if (!bd->lock_user_stacking)
11976 if (e_config->border_raise_on_mouse_action)
11977 e_border_raise(bd);
11979 if ((bd->shaded) || (bd->shading) ||
11980 (bd->fullscreen) || (bd->lock_user_size))
11983 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
11989 if (bd->client.netwm.sync.request)
11991 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
11992 bd->client.netwm.sync.serial = 1;
11993 bd->client.netwm.sync.wait = 0;
11994 bd->client.netwm.sync.send_time = ecore_loop_time_get();
11997 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12004 _e_border_resize_end(E_Border *bd)
12008 e_grabinput_release(bd->win, bd->win);
12011 if (bd->client.netwm.sync.alarm)
12013 E_Border_Pending_Move_Resize *pnd;
12015 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12016 bd->client.netwm.sync.alarm = 0;
12017 /* resize to last geometry if sync alarm for it was not yet handled */
12018 if (bd->pending_move_resize)
12021 bd->changes.pos = 1;
12022 bd->changes.size = 1;
12023 _e_border_client_move_resize_send(bd);
12026 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12030 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12034 /* If this border was maximized, we need to unset Maximized state or
12035 * on restart, E still thinks it's maximized */
12036 if (bd->maximized != E_MAXIMIZE_NONE)
12037 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12038 bd->maximized & E_MAXIMIZE_NONE);
12043 _e_border_resize_update(E_Border *bd)
12045 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12049 _e_border_move_begin(E_Border *bd)
12051 if (!bd->lock_user_stacking)
12053 if (e_config->border_raise_on_mouse_action)
12054 e_border_raise(bd);
12056 if ((bd->fullscreen) || (bd->lock_user_location))
12059 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
12065 if (bd->client.netwm.sync.request)
12067 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12068 bd->client.netwm.sync.serial = 0;
12069 bd->client.netwm.sync.wait = 0;
12070 bd->client.netwm.sync.time = ecore_loop_time_get();
12073 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12080 _e_border_move_end(E_Border *bd)
12084 e_grabinput_release(bd->win, bd->win);
12088 if (bd->client.netwm.sync.alarm)
12090 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12091 bd->client.netwm.sync.alarm = 0;
12094 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12101 _e_border_move_update(E_Border *bd)
12103 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12107 _e_border_cb_ping_poller(void *data)
12117 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12118 if (bd->kill_timer)
12120 ecore_timer_del(bd->kill_timer);
12121 bd->kill_timer = NULL;
12127 /* if time between last ping and now is greater
12128 * than half the ping interval... */
12129 if ((ecore_loop_time_get() - bd->ping) >
12130 ((e_config->ping_clients_interval *
12131 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12136 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12137 /* FIXME: if below dialog is up - hide it now */
12139 if (bd->delete_requested)
12141 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12142 e_border_act_kill_begin(bd);
12146 bd->ping_poller = NULL;
12148 return ECORE_CALLBACK_CANCEL;
12152 _e_border_cb_kill_timer(void *data)
12157 // dont wait until it's hung -
12160 if (bd->client.netwm.pid > 1)
12161 kill(bd->client.netwm.pid, SIGKILL);
12163 bd->kill_timer = NULL;
12164 return ECORE_CALLBACK_CANCEL;
12168 _e_border_pointer_resize_begin(E_Border *bd)
12170 switch (bd->resize_mode)
12173 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12177 e_pointer_type_push(bd->pointer, bd, "resize_t");
12181 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12185 e_pointer_type_push(bd->pointer, bd, "resize_r");
12189 e_pointer_type_push(bd->pointer, bd, "resize_br");
12193 e_pointer_type_push(bd->pointer, bd, "resize_b");
12197 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12201 e_pointer_type_push(bd->pointer, bd, "resize_l");
12207 _e_border_pointer_resize_end(E_Border *bd)
12209 switch (bd->resize_mode)
12212 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12216 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12220 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12224 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12228 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12232 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12236 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12240 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12246 _e_border_pointer_move_begin(E_Border *bd)
12248 e_pointer_type_push(bd->pointer, bd, "move");
12252 _e_border_pointer_move_end(E_Border *bd)
12254 e_pointer_type_pop(bd->pointer, bd, "move");
12257 static Eina_List *_e_border_hooks = NULL;
12258 static int _e_border_hooks_delete = 0;
12259 static int _e_border_hooks_walking = 0;
12262 _e_border_hooks_clean(void)
12267 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12271 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12278 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12284 _e_border_hooks_walking++;
12285 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12287 if (bh->delete_me) continue;
12288 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12290 _e_border_hooks_walking--;
12291 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12292 _e_border_hooks_clean();
12295 EAPI E_Border_Hook *
12296 e_border_hook_add(E_Border_Hook_Point hookpoint,
12297 void (*func)(void *data,
12303 bh = E_NEW(E_Border_Hook, 1);
12304 if (!bh) return NULL;
12305 bh->hookpoint = hookpoint;
12308 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12313 e_border_hook_del(E_Border_Hook *bh)
12316 if (_e_border_hooks_walking == 0)
12318 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12322 _e_border_hooks_delete++;
12326 e_border_focus_track_freeze(void)
12328 focus_track_frozen++;
12332 e_border_focus_track_thaw(void)
12334 focus_track_frozen--;
12338 e_border_under_pointer_get(E_Desk *desk,
12341 E_Border *bd = NULL, *cbd;
12345 /* We need to ensure that we can get the container window for the
12346 * zone of either the given desk or the desk of the excluded
12347 * window, so return if neither is given */
12349 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12351 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12355 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12357 if (!cbd) continue;
12358 /* If a border was specified which should be excluded from the list
12359 * (because it will be closed shortly for example), skip */
12360 if ((exclude) && (cbd == exclude)) continue;
12361 if ((desk) && (cbd->desk != desk)) continue;
12362 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12364 /* If the layer is higher, the position of the window is higher
12365 * (always on top vs always below) */
12366 if (!bd || (cbd->layer > bd->layer))
12376 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12383 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12384 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12385 (y - warp_y) > 5 || (y - warp_y) < -5)
12387 /* User moved the mouse, so stop warping */
12392 /* We just use the same warp speed as configured
12393 * for the windowlist */
12394 spd = e_config->winlist_warp_speed;
12397 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12398 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12399 if (warp_x == x && warp_y == y)
12401 warp_x = warp_to_x;
12402 warp_y = warp_to_y;
12406 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12407 return ECORE_CALLBACK_RENEW;
12410 ecore_timer_del(warp_timer);
12412 return ECORE_CALLBACK_CANCEL;
12416 e_border_pointer_warp_to_center(E_Border *bd)
12420 /* Do not slide pointer when disabled (probably breaks focus
12421 * on sloppy/mouse focus but requested by users). */
12422 if (!e_config->pointer_slide) return 0;
12423 /* Only warp the pointer if it is not already in the area of
12424 * the given border */
12425 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12426 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12427 (y >= bd->y) && (y <= (bd->y + bd->h)))
12430 warp_to_x = bd->x + (bd->w / 2);
12431 if (warp_to_x < (bd->zone->x + 1))
12432 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12433 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12434 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12436 warp_to_y = bd->y + (bd->h / 2);
12437 if (warp_to_y < (bd->zone->y + 1))
12438 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12439 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12440 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12443 warp_to_win = bd->zone->container->win;
12444 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12446 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12451 e_border_comp_hidden_set(E_Border *bd,
12457 E_OBJECT_CHECK(bd);
12458 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12460 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12463 ecore_x_window_hide(tmp->win);
12465 ecore_x_window_show(tmp->win);
12468 if (bd->comp_hidden == hidden) return;
12470 bd->comp_hidden = hidden;
12472 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12474 ecore_x_composite_window_events_disable(bd->win);
12475 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12479 _e_border_shape_input_rectangle_set(bd);
12480 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12485 e_border_tmp_input_hidden_push(E_Border *bd)
12490 E_OBJECT_CHECK(bd);
12491 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12493 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12494 e_border_tmp_input_hidden_push(tmp);
12496 bd->tmp_input_hidden++;
12497 if (bd->tmp_input_hidden != 1) return;
12499 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12501 ecore_x_composite_window_events_disable(bd->win);
12502 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12506 _e_border_shape_input_rectangle_set(bd);
12507 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12512 e_border_tmp_input_hidden_pop(E_Border *bd)
12517 E_OBJECT_CHECK(bd);
12518 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12520 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12521 e_border_tmp_input_hidden_pop(tmp);
12523 bd->tmp_input_hidden--;
12524 if (bd->tmp_input_hidden != 0) return;
12526 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12528 ecore_x_composite_window_events_disable(bd->win);
12529 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12533 _e_border_shape_input_rectangle_set(bd);
12534 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12539 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12541 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12543 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12544 ((bd->parent->focused) &&
12545 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12550 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12551 e_desk_show(bd->desk);
12553 if (!bd->lock_user_iconify)
12554 e_border_uniconify(bd);
12556 if ((!bd->iconic) && (!bd->sticky))
12557 e_desk_show(bd->desk);
12558 if (!bd->lock_user_stacking) e_border_raise(bd);
12559 if (!bd->lock_focus_out)
12561 /* XXX ooffice does send this request for
12562 config dialogs when the main window gets focus.
12563 causing the pointer to jump back and forth. */
12564 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12565 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12566 ecore_x_pointer_warp(bd->zone->container->win,
12567 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12568 e_border_focus_set(bd, 1, 1);
12572 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/