2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * This file is a modified version of BSD licensed file and
5 * licensed under the Flora License, Version 1.1 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://floralicense.org/license/
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * Please, see the COPYING file for the original copyright owner and
22 //#define INOUTDEBUG_MOUSE 1
23 //#define INOUTDEBUG_FOCUS 1
25 /* These are compatible with netwm */
35 #define RESIZE_NONE 11
37 /* local subsystem functions */
38 static void _e_border_pri_raise(E_Border *bd);
39 static void _e_border_pri_norm(E_Border *bd);
40 static void _e_border_free(E_Border *bd);
41 static void _e_border_del(E_Border *bd);
43 #ifdef PRINT_LOTS_OF_DEBUG
44 #define E_PRINT_BORDER_INFO(X) \
45 _e_border_print(X, __PRETTY_FUNC__)
47 static void _e_border_print(E_Border *bd,
51 /* FIXME: these likely belong in a separate icccm/client handler */
52 /* and the border needs to become a dumb object that just does what its */
54 static Eina_Bool _e_border_cb_window_show_request(void *data,
57 static Eina_Bool _e_border_cb_window_destroy(void *data,
60 static Eina_Bool _e_border_cb_window_hide(void *data,
63 static Eina_Bool _e_border_cb_window_reparent(void *data,
66 static Eina_Bool _e_border_cb_window_configure_request(void *data,
69 static Eina_Bool _e_border_cb_window_resize_request(void *data,
72 static Eina_Bool _e_border_cb_window_gravity(void *data,
75 static Eina_Bool _e_border_cb_window_stack_request(void *data,
78 static Eina_Bool _e_border_cb_window_property(void *data,
81 static Eina_Bool _e_border_cb_window_colormap(void *data,
84 static Eina_Bool _e_border_cb_window_shape(void *data,
87 static Eina_Bool _e_border_cb_window_focus_in(void *data,
90 static Eina_Bool _e_border_cb_window_focus_out(void *data,
93 static Eina_Bool _e_border_cb_client_message(void *data,
97 static Eina_Bool _e_border_cb_window_state_request(void *data,
100 static Eina_Bool _e_border_cb_window_move_resize_request(void *data,
103 static Eina_Bool _e_border_cb_desktop_change(void *data,
106 static Eina_Bool _e_border_cb_sync_alarm(void *data,
109 static Eina_Bool _e_border_cb_efreet_cache_update(void *data,
112 static Eina_Bool _e_border_cb_config_icon_theme(void *data,
116 static Eina_Bool _e_border_cb_pointer_warp(void *data,
119 static void _e_border_cb_signal_bind(void *data,
121 const char *emission,
123 static Eina_Bool _e_border_cb_mouse_in(void *data,
126 static Eina_Bool _e_border_cb_mouse_out(void *data,
129 static Eina_Bool _e_border_cb_mouse_wheel(void *data,
132 static Eina_Bool _e_border_cb_mouse_down(void *data,
135 static Eina_Bool _e_border_cb_mouse_up(void *data,
138 static Eina_Bool _e_border_cb_mouse_move(void *data,
141 static Eina_Bool _e_border_cb_grab_replay(void *data,
144 static void _e_border_cb_drag_finished(E_Drag *drag,
146 #ifdef _F_USE_DESK_WINDOW_PROFILE_
147 static Eina_Bool _e_border_cb_desk_window_profile_change(void *data,
151 #ifdef _F_ZONE_WINDOW_ROTATION_
152 static Eina_Bool _e_border_cb_zone_rotation_change_begin(void *data,
155 static void _e_border_cb_rotation_sync_job(void *data);
156 static void _e_border_cb_rotation_async_job(void *data);
157 static Eina_Bool _e_border_rotation_change_prepare_timeout(void *data);
158 static void _e_border_rotation_change_request(E_Zone *zone);
159 static void _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush);
160 static Eina_Bool _e_border_rotation_change_done_timeout(void *data);
161 static void _e_border_rotation_change_done(void);
162 static Eina_Bool _e_border_rotation_geom_get(E_Border *bd,
170 static void _e_border_rotation_list_remove(E_Border *bd);
171 static Eina_Bool _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h);
172 static int _e_border_rotation_angle_get(E_Border *bd);
173 static Eina_Bool _e_border_rotation_zone_set(E_Zone *zone);
174 static Eina_Bool _e_border_rotatable_check(E_Border *bd, int ang);
175 static Eina_Bool _e_border_is_vkbd(E_Border *bd);
176 static Eina_Bool _e_border_cb_window_configure(void *data,
179 static Eina_Bool _e_border_vkbd_show_prepare_timeout(void *data);
180 static Eina_Bool _e_border_vkbd_hide_prepare_timeout(void *data);
181 static void _e_border_vkbd_show(E_Border *bd);
182 static void _e_border_vkbd_hide(E_Border *bd);
184 static void _e_border_move_resize_internal(E_Border *bd,
189 Eina_Bool without_border,
192 static void _e_border_eval(E_Border *bd);
193 static void _e_border_eval0(E_Border *bd);
194 static void _e_border_container_layout_hook(E_Container *con);
196 static void _e_border_moveinfo_gather(E_Border *bd,
198 static void _e_border_resize_handle(E_Border *bd);
200 static Eina_Bool _e_border_shade_animator(void *data);
202 static void _e_border_event_border_add_free(void *data,
204 static void _e_border_event_border_remove_free(void *data,
206 static void _e_border_event_border_zone_set_free(void *data,
208 static void _e_border_event_border_desk_set_free(void *data,
210 static void _e_border_event_border_stack_free(void *data,
212 static void _e_border_event_border_icon_change_free(void *data,
214 static void _e_border_event_border_urgent_change_free(void *data,
216 static void _e_border_event_border_focus_in_free(void *data,
218 static void _e_border_event_border_focus_out_free(void *data,
220 static void _e_border_event_border_resize_free(void *data,
222 static void _e_border_event_border_move_free(void *data,
224 static void _e_border_event_border_show_free(void *data,
226 static void _e_border_event_border_hide_free(void *data,
228 static void _e_border_event_border_iconify_free(void *data,
230 static void _e_border_event_border_uniconify_free(void *data,
232 static void _e_border_event_border_stick_free(void *data,
234 static void _e_border_event_border_unstick_free(void *data,
236 static void _e_border_event_border_property_free(void *data,
238 static void _e_border_event_border_fullscreen_free(void *data,
240 static void _e_border_event_border_unfullscreen_free(void *data,
242 #ifdef _F_ZONE_WINDOW_ROTATION_
243 static void _e_border_event_border_rotation_change_begin_free(void *data,
245 static void _e_border_event_border_rotation_change_cancel_free(void *data,
247 static void _e_border_event_border_rotation_change_end_free(void *data,
249 static void _e_border_event_border_rotation_change_begin_send(E_Border *bd);
252 static void _e_border_zone_update(E_Border *bd);
254 static int _e_border_resize_begin(E_Border *bd);
255 static int _e_border_resize_end(E_Border *bd);
256 static void _e_border_resize_update(E_Border *bd);
258 static int _e_border_move_begin(E_Border *bd);
259 static int _e_border_move_end(E_Border *bd);
260 static void _e_border_move_update(E_Border *bd);
262 static Eina_Bool _e_border_cb_ping_poller(void *data);
263 static Eina_Bool _e_border_cb_kill_timer(void *data);
265 static void _e_border_pointer_resize_begin(E_Border *bd);
266 static void _e_border_pointer_resize_end(E_Border *bd);
267 static void _e_border_pointer_move_begin(E_Border *bd);
268 static void _e_border_pointer_move_end(E_Border *bd);
270 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
273 static void _e_border_client_move_resize_send(E_Border *bd);
275 static void _e_border_frame_replace(E_Border *bd,
278 static void _e_border_shape_input_rectangle_set(E_Border* bd);
279 static void _e_border_show(E_Border *bd);
280 static void _e_border_hide(E_Border *bd);
283 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
284 static void _e_border_latest_stacked_focus (E_Border* bd);
285 static void _e_border_check_stack (E_Border *bd);
286 static void _e_border_focus_top_stack_set (E_Border* bd);
288 #if _F_BORDER_CLIP_TO_ZONE_
289 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
290 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
291 /* local subsystem globals */
292 static Eina_List *handlers = NULL;
293 static Eina_List *borders = NULL;
294 static Eina_Hash *borders_hash = NULL;
295 static E_Border *focused = NULL;
296 static E_Border *focusing = NULL;
297 static Eina_List *focus_next = NULL;
298 static Ecore_X_Time focus_time = 0;
300 static E_Border *bdresize = NULL;
301 static E_Border *bdmove = NULL;
302 static E_Drag *drag_border = NULL;
304 static int grabbed = 0;
306 static Eina_List *focus_stack = NULL;
307 static Eina_List *raise_stack = NULL;
309 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
310 static int screen_size_index = -1;
312 static int focus_track_frozen = 0;
314 static int warp_to = 0;
315 static int warp_to_x = 0;
316 static int warp_to_y = 0;
317 static int warp_x = 0;
318 static int warp_y = 0;
319 static Ecore_X_Window warp_to_win;
320 static Ecore_Timer *warp_timer = NULL;
322 #ifdef _F_ZONE_WINDOW_ROTATION_
323 typedef struct _E_Border_Rotation E_Border_Rotation;
324 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
326 struct _E_Border_Rotation
329 Eina_List *async_list;
331 Eina_Bool wait_prepare_done;
332 Ecore_Timer *prepare_timer;
333 Ecore_Timer *done_timer;
335 Ecore_Job *async_job;
337 Ecore_X_Window vkbd_ctrl_win;
339 E_Border *vkbd_prediction;
341 /* vkbd show/hide preprare */
342 Eina_Bool vkbd_show_prepare_done;
343 Ecore_Timer *vkbd_show_prepare_timer;
344 Ecore_Timer *vkbd_show_timer;
346 Eina_Bool vkbd_hide_prepare_done;
347 Ecore_Timer *vkbd_hide_prepare_timer;
348 Ecore_Timer *vkbd_hide_timer;
354 struct _E_Border_Rotation_Info
359 Eina_Bool win_resize;
362 static E_Border_Rotation rot =
385 EAPI int E_EVENT_BORDER_ADD = 0;
386 EAPI int E_EVENT_BORDER_REMOVE = 0;
387 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
388 EAPI int E_EVENT_BORDER_DESK_SET = 0;
389 EAPI int E_EVENT_BORDER_RESIZE = 0;
390 EAPI int E_EVENT_BORDER_MOVE = 0;
391 EAPI int E_EVENT_BORDER_SHOW = 0;
392 EAPI int E_EVENT_BORDER_HIDE = 0;
393 EAPI int E_EVENT_BORDER_ICONIFY = 0;
394 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
395 EAPI int E_EVENT_BORDER_STICK = 0;
396 EAPI int E_EVENT_BORDER_UNSTICK = 0;
397 EAPI int E_EVENT_BORDER_STACK = 0;
398 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
399 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
400 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
401 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
402 EAPI int E_EVENT_BORDER_PROPERTY = 0;
403 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
404 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
405 #ifdef _F_ZONE_WINDOW_ROTATION_
406 EAPI int E_EVENT_BORDER_ROTATION = 0; /* deprecated */
407 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = 0;
408 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = 0;
409 EAPI int E_EVENT_BORDER_ROTATION_CHANGE_END = 0;
412 #define GRAV_SET(bd, grav) \
413 ecore_x_window_gravity_set(bd->bg_win, grav); \
414 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
415 ecore_x_window_gravity_set(bd->client.win, grav);
418 _e_border_sub_borders_new(E_Border *bd)
420 Eina_List *list = NULL, *l;
424 EINA_LIST_FOREACH(bd->transients, l, child)
426 if (!eina_list_data_find(list, child))
427 list = eina_list_append(list, child);
429 bl = e_container_border_list_first(bd->zone->container);
430 while ((child = e_container_border_list_next(bl)))
432 if (e_object_is_del(E_OBJECT(child))) continue;
433 if (child == bd) continue;
435 if ((bd->client.icccm.client_leader) &&
436 (child->client.icccm.client_leader ==
437 bd->client.icccm.client_leader))
439 printf("bd %s in group with %s\n",
440 e_border_name_get(child),
441 e_border_name_get(bd));
442 if (!eina_list_data_find(list, child))
443 list = eina_list_append(list, child);
447 e_container_border_list_free(bl);
451 /* externally accessible functions */
455 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
458 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
460 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
461 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
462 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
463 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
464 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
468 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
469 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
470 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
471 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
472 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
473 #ifdef _F_ZONE_WINDOW_ROTATION_
474 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
477 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
479 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
480 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
481 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
482 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
483 #ifdef _F_USE_DESK_WINDOW_PROFILE_
484 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
486 #ifdef _F_ZONE_WINDOW_ROTATION_
487 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE_BEGIN, _e_border_cb_zone_rotation_change_begin, NULL));
490 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
492 E_EVENT_BORDER_ADD = ecore_event_type_new();
493 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
494 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
495 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
496 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
497 E_EVENT_BORDER_MOVE = ecore_event_type_new();
498 E_EVENT_BORDER_SHOW = ecore_event_type_new();
499 E_EVENT_BORDER_HIDE = ecore_event_type_new();
500 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
501 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
502 E_EVENT_BORDER_STICK = ecore_event_type_new();
503 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
504 E_EVENT_BORDER_STACK = ecore_event_type_new();
505 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
506 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
507 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
508 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
509 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
510 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
511 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
512 #ifdef _F_ZONE_WINDOW_ROTATION_
513 E_EVENT_BORDER_ROTATION = ecore_event_type_new(); /* deprecated */
514 E_EVENT_BORDER_ROTATION_CHANGE_BEGIN = ecore_event_type_new();
515 E_EVENT_BORDER_ROTATION_CHANGE_CANCEL = ecore_event_type_new();
516 E_EVENT_BORDER_ROTATION_CHANGE_END = ecore_event_type_new();
525 e_border_shutdown(void)
527 E_FREE_LIST(handlers, ecore_event_handler_del);
529 if (borders_hash) eina_hash_free(borders_hash);
531 e_int_border_menu_hooks_clear();
537 e_border_new(E_Container *con,
543 Ecore_X_Window_Attributes *att;
544 unsigned int managed, desk[2];
547 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
548 if (!bd) return NULL;
549 ecore_x_window_shadow_tree_flush();
550 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
554 /* FIXME: ewww - round trip */
555 bd->client.argb = ecore_x_window_argb_get(win);
557 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
560 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
561 ecore_x_window_shape_events_select(bd->win, 1);
563 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
564 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
566 bd->bg_ecore_evas = e_canvas_new(bd->win,
567 0, 0, bd->w, bd->h, 1, 0,
569 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
570 e_canvas_add(bd->bg_ecore_evas);
571 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
572 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
573 ecore_x_window_shape_events_select(bd->bg_win, 1);
574 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
575 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
577 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
579 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
580 ecore_x_window_container_manage(bd->client.shell_win);
581 if (!internal) ecore_x_window_client_manage(win);
582 /* FIXME: Round trip. XCB */
583 /* fetch needed to avoid grabbing the server as window may vanish */
584 att = &bd->client.initial_attributes;
585 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
587 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
588 e_canvas_del(bd->bg_ecore_evas);
589 ecore_evas_free(bd->bg_ecore_evas);
590 ecore_x_window_free(bd->client.shell_win);
591 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
592 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
593 ecore_x_window_free(bd->win);
598 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
599 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
601 /* FIXME: if first_map is 1 then we should ignore the first hide event
602 * or ensure the window is already hidden and events flushed before we
603 * create a border for it */
606 // printf("##- FIRST MAP\n");
611 // needed to be 1 for internal windw and on restart.
612 // bd->ignore_first_unmap = 2;
615 bd->client.win = win;
616 bd->zone = e_zone_current_get(con);
618 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
620 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
621 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
622 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
623 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
624 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
625 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
627 bd->client.icccm.title = NULL;
628 bd->client.icccm.name = NULL;
629 bd->client.icccm.class = NULL;
630 bd->client.icccm.icon_name = NULL;
631 bd->client.icccm.machine = NULL;
632 bd->client.icccm.min_w = 1;
633 bd->client.icccm.min_h = 1;
634 bd->client.icccm.max_w = 32767;
635 bd->client.icccm.max_h = 32767;
636 bd->client.icccm.base_w = 0;
637 bd->client.icccm.base_h = 0;
638 bd->client.icccm.step_w = -1;
639 bd->client.icccm.step_h = -1;
640 bd->client.icccm.min_aspect = 0.0;
641 bd->client.icccm.max_aspect = 0.0;
642 bd->client.icccm.accepts_focus = 1;
644 bd->client.netwm.pid = 0;
645 bd->client.netwm.name = NULL;
646 bd->client.netwm.icon_name = NULL;
647 bd->client.netwm.desktop = 0;
648 bd->client.netwm.state.modal = 0;
649 bd->client.netwm.state.sticky = 0;
650 bd->client.netwm.state.shaded = 0;
651 bd->client.netwm.state.hidden = 0;
652 bd->client.netwm.state.maximized_v = 0;
653 bd->client.netwm.state.maximized_h = 0;
654 bd->client.netwm.state.skip_taskbar = 0;
655 bd->client.netwm.state.skip_pager = 0;
656 bd->client.netwm.state.fullscreen = 0;
657 bd->client.netwm.state.stacking = E_STACKING_NONE;
658 bd->client.netwm.action.move = 0;
659 bd->client.netwm.action.resize = 0;
660 bd->client.netwm.action.minimize = 0;
661 bd->client.netwm.action.shade = 0;
662 bd->client.netwm.action.stick = 0;
663 bd->client.netwm.action.maximized_h = 0;
664 bd->client.netwm.action.maximized_v = 0;
665 bd->client.netwm.action.fullscreen = 0;
666 bd->client.netwm.action.change_desktop = 0;
667 bd->client.netwm.action.close = 0;
668 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
674 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
675 bd->client.icccm.fetch.command = 1;
678 Eina_Bool video_parent = EINA_FALSE;
679 Eina_Bool video_position = EINA_FALSE;
682 for (i = 0; i < at_num; i++)
684 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
685 bd->client.icccm.fetch.title = 1;
686 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
687 bd->client.icccm.fetch.name_class = 1;
688 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
689 bd->client.icccm.fetch.icon_name = 1;
690 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
691 bd->client.icccm.fetch.machine = 1;
692 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
693 bd->client.icccm.fetch.hints = 1;
694 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
695 bd->client.icccm.fetch.size_pos_hints = 1;
696 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
697 bd->client.icccm.fetch.protocol = 1;
698 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
699 bd->client.mwm.fetch.hints = 1;
700 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
702 bd->client.icccm.fetch.transient_for = 1;
703 bd->client.netwm.fetch.type = 1;
705 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
706 bd->client.icccm.fetch.client_leader = 1;
707 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
708 bd->client.icccm.fetch.window_role = 1;
709 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
710 bd->client.icccm.fetch.state = 1;
712 /* netwm, loop again, netwm will ignore some icccm, so we
713 * have to be sure that netwm is checked after */
714 for (i = 0; i < at_num; i++)
716 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
719 bd->client.icccm.fetch.title = 0;
720 bd->client.netwm.fetch.name = 1;
722 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
725 bd->client.icccm.fetch.icon_name = 0;
726 bd->client.netwm.fetch.icon_name = 1;
728 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
730 bd->client.netwm.fetch.icon = 1;
732 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
734 bd->client.netwm.fetch.user_time = 1;
736 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
738 DBG("ECORE_X_ATOM_NET_WM_STRUT");
739 bd->client.netwm.fetch.strut = 1;
741 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
743 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
744 bd->client.netwm.fetch.strut = 1;
746 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
749 bd->client.mwm.fetch.hints = 0;
751 bd->client.netwm.fetch.type = 1;
753 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
755 bd->client.netwm.fetch.state = 1;
758 /* other misc atoms */
759 for (i = 0; i < at_num; i++)
761 /* loop to check for own atoms */
762 if (atoms[i] == E_ATOM_WINDOW_STATE)
764 bd->client.e.fetch.state = 1;
766 /* loop to check for qtopia atoms */
767 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
768 bd->client.qtopia.fetch.soft_menu = 1;
769 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
770 bd->client.qtopia.fetch.soft_menus = 1;
771 /* loop to check for vkbd atoms */
772 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
773 bd->client.vkbd.fetch.state = 1;
774 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
775 bd->client.vkbd.fetch.vkbd = 1;
776 /* loop to check for illume atoms */
777 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
778 bd->client.illume.conformant.fetch.conformant = 1;
779 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
780 bd->client.illume.quickpanel.fetch.state = 1;
781 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
782 bd->client.illume.quickpanel.fetch.quickpanel = 1;
783 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
784 bd->client.illume.quickpanel.fetch.priority.major = 1;
785 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
786 bd->client.illume.quickpanel.fetch.priority.minor = 1;
787 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
788 bd->client.illume.quickpanel.fetch.zone = 1;
789 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
790 bd->client.illume.drag.fetch.locked = 1;
791 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
792 bd->client.illume.drag.fetch.drag = 1;
793 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
794 bd->client.illume.win_state.fetch.state = 1;
795 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
796 video_parent = EINA_TRUE;
797 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
798 video_position = EINA_TRUE;
799 #ifdef _F_USE_DESK_WINDOW_PROFILE_
800 /* loop to check for window profile list atom */
801 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
802 bd->client.e.fetch.profile_list = 1;
804 #ifdef _F_ZONE_WINDOW_ROTATION_
805 /* loop to check for wm rotation */
806 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
808 if (e_config->wm_win_rotation)
809 bd->client.e.fetch.rot.support = 1;
811 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
812 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
813 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
814 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
816 if (e_config->wm_win_rotation)
817 bd->client.e.fetch.rot.geom_hint = 1;
819 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
821 if (e_config->wm_win_rotation)
822 bd->client.e.fetch.rot.app_set = 1;
824 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
826 if (e_config->wm_win_rotation)
827 bd->client.e.fetch.rot.preferred_rot = 1;
829 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
831 if (e_config->wm_win_rotation)
832 bd->client.e.fetch.rot.available_rots = 1;
835 #ifdef _F_DEICONIFY_APPROVE_
836 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
838 bd->client.e.state.deiconify_approve.support = 1;
842 if (video_position && video_parent)
844 bd->client.e.state.video = 1;
845 bd->client.e.fetch.video_parent = 1;
846 bd->client.e.fetch.video_position = 1;
847 ecore_x_window_lower(bd->win);
848 ecore_x_composite_window_events_disable(bd->win);
849 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
850 fprintf(stderr, "We found a video window \\o/ %x\n", win);
855 bd->client.border.changed = 1;
857 bd->client.w = att->w;
858 bd->client.h = att->h;
860 bd->w = bd->client.w;
861 bd->h = bd->client.h;
863 bd->resize_mode = RESIZE_NONE;
865 bd->saved.layer = bd->layer;
866 bd->changes.icon = 1;
867 bd->changes.size = 1;
868 bd->changes.shape = 1;
869 bd->changes.shape_input = 1;
871 bd->offer_resistance = 1;
873 /* just to friggin make java happy - we're DELAYING the reparent until
876 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
877 bd->need_reparent = 1;
879 ecore_x_window_border_width_set(win, 0);
880 ecore_x_window_show(bd->event_win);
881 ecore_x_window_show(bd->client.shell_win);
882 bd->shape = e_container_shape_add(con);
887 #ifdef _F_ZONE_WINDOW_ROTATION_
888 bd->client.e.state.rot.preferred_rot = -1;
889 bd->client.e.state.rot.type = E_BORDER_ROTATION_TYPE_NORMAL;
890 bd->client.e.state.rot.changes = -1;
891 bd->client.e.state.rot.pending_show = 0;
892 bd->client.e.state.rot.curr = 0;
893 bd->client.e.state.rot.prev = 0;
896 // bd->zone = e_zone_current_get(con);
897 bd->desk = e_desk_current_get(bd->zone);
898 e_container_border_add(bd);
899 borders = eina_list_append(borders, bd);
900 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
904 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
905 "optimisations failing due to bizarre client behavior. will\n"
907 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
908 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
911 ELBF(ELBT_BD, 0, bd->client.win,
912 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
913 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
915 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
916 printf("optimisations failing due to bizarre client behavior. will\n");
917 printf("work around.\n");
918 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
919 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
922 ELBF(ELBT_BD, 0, bd->client.win,
923 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
924 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
927 #ifdef _F_ZONE_WINDOW_ROTATION_
928 if ((rot.vkbd) && (rot.vkbd == bd2))
930 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
931 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
932 rot.vkbd_hide_prepare_done);
934 if (rot.vkbd_hide_prepare_timer)
936 ecore_timer_del(rot.vkbd_hide_prepare_timer);
937 rot.vkbd_hide_prepare_timer = NULL;
939 e_object_unref(E_OBJECT(bd2));
942 _e_border_vkbd_hide(rot.vkbd);
944 if (rot.vkbd_ctrl_win)
946 ELB(ELBT_BD, "SET KBD_OFF", 0);
947 ecore_x_e_virtual_keyboard_state_set
948 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
950 rot.vkbd_hide_prepare_done = EINA_FALSE;
952 if (rot.vkbd_hide_timer)
953 ecore_timer_del(rot.vkbd_hide_timer);
954 rot.vkbd_hide_timer = NULL;
956 rot.vkbd_show_prepare_done = EINA_FALSE;
957 if (rot.vkbd_show_prepare_timer)
958 ecore_timer_del(rot.vkbd_show_prepare_timer);
959 rot.vkbd_show_prepare_timer = NULL;
960 if (rot.vkbd_show_timer)
961 ecore_timer_del(rot.vkbd_show_timer);
962 rot.vkbd_show_timer = NULL;
967 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
968 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
969 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
971 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
972 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
973 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
975 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
976 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
977 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
979 unsigned int zgeom[4];
981 zgeom[0] = bd->zone->x;
982 zgeom[1] = bd->zone->y;
983 zgeom[2] = bd->zone->w;
984 zgeom[3] = bd->zone->h;
985 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
987 e_desk_xy_get(bd->desk, &deskx, &desky);
990 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
991 #ifdef _F_USE_DESK_WINDOW_PROFILE_
992 if (strcmp(bd->desk->window_profile,
993 e_config->desktop_default_window_profile) != 0)
995 ecore_x_e_window_profile_set(bd->client.win,
996 bd->desk->window_profile);
1000 focus_stack = eina_list_append(focus_stack, bd);
1002 bd->pointer = e_pointer_window_new(bd->win, 0);
1007 e_border_res_change_geometry_save(E_Border *bd)
1010 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1012 if (bd->pre_res_change.valid) return;
1013 bd->pre_res_change.valid = 1;
1014 bd->pre_res_change.x = bd->x;
1015 bd->pre_res_change.y = bd->y;
1016 bd->pre_res_change.w = bd->w;
1017 bd->pre_res_change.h = bd->h;
1018 bd->pre_res_change.saved.x = bd->saved.x;
1019 bd->pre_res_change.saved.y = bd->saved.y;
1020 bd->pre_res_change.saved.w = bd->saved.w;
1021 bd->pre_res_change.saved.h = bd->saved.h;
1025 e_border_res_change_geometry_restore(E_Border *bd)
1029 unsigned char valid : 1;
1038 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1039 if (!bd->pre_res_change.valid) return;
1040 if (bd->new_client) return;
1042 ecore_x_window_shadow_tree_flush();
1043 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1047 e_border_unfullscreen(bd);
1048 e_border_fullscreen(bd, e_config->fullscreen_policy);
1050 else if (bd->maximized != E_MAXIMIZE_NONE)
1054 max = bd->maximized;
1055 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1056 e_border_maximize(bd, max);
1060 int x, y, w, h, zx, zy, zw, zh;
1062 bd->saved.x = bd->pre_res_change.saved.x;
1063 bd->saved.y = bd->pre_res_change.saved.y;
1064 bd->saved.w = bd->pre_res_change.saved.w;
1065 bd->saved.h = bd->pre_res_change.saved.h;
1067 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1069 if (bd->saved.w > zw)
1071 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1072 bd->saved.x = zx + zw - bd->saved.w;
1074 if (bd->saved.h > zh)
1076 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1077 bd->saved.y = zy + zh - bd->saved.h;
1079 x = bd->pre_res_change.x;
1080 y = bd->pre_res_change.y;
1081 w = bd->pre_res_change.w;
1082 h = bd->pre_res_change.h;
1087 if ((x + w) > (zx + zw))
1089 if ((y + h) > (zy + zh))
1091 e_border_move_resize(bd, x, y, w, h);
1093 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1097 e_border_zone_set(E_Border *bd,
1100 E_Event_Border_Zone_Set *ev;
1103 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1104 E_OBJECT_CHECK(zone);
1105 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1107 if (bd->zone == zone) return;
1109 /* if the window does not lie in the new zone, move it so that it does */
1110 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1113 /* first guess -- get offset from old zone, and apply to new zone */
1114 x = zone->x + (bd->x - bd->zone->x);
1115 y = zone->y + (bd->y - bd->zone->y);
1117 /* keep window from hanging off bottom and left */
1118 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1119 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1121 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1122 if (x < zone->x) x = zone->x;
1123 if (y < zone->y) y = zone->y;
1125 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1127 /* still not in zone at all, so just move it to closest edge */
1128 if (x < zone->x) x = zone->x;
1129 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1130 if (y < zone->y) y = zone->y;
1131 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1133 e_border_move(bd, x, y);
1138 if (bd->desk->zone != bd->zone)
1139 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1141 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1143 e_object_ref(E_OBJECT(bd));
1144 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1146 e_object_ref(E_OBJECT(zone));
1148 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1150 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1151 // XXXXXXXXXXXXXXXXXXXXXXXXX
1152 // XXX ZZZZZZZZZZZZZZZZZZZzz
1153 // need to adjust this if zone pos/size changes
1155 unsigned int zgeom[4];
1157 zgeom[0] = bd->zone->x;
1158 zgeom[1] = bd->zone->y;
1159 zgeom[2] = bd->zone->w;
1160 zgeom[3] = bd->zone->h;
1161 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1163 e_remember_update(bd);
1167 e_border_desk_set(E_Border *bd,
1170 E_Event_Border_Desk_Set *ev;
1174 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1175 E_OBJECT_CHECK(desk);
1176 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1177 if (bd->desk == desk) return;
1178 ecore_x_window_shadow_tree_flush();
1181 bd->desk->fullscreen_borders--;
1182 desk->fullscreen_borders++;
1184 old_desk = bd->desk;
1186 e_border_zone_set(bd, desk->zone);
1188 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1189 e_hints_window_desktop_set(bd);
1191 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1193 e_object_ref(E_OBJECT(bd));
1194 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1195 ev->desk = old_desk;
1196 e_object_ref(E_OBJECT(old_desk));
1197 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1199 if (bd->ignore_first_unmap != 1)
1201 if ((bd->desk->visible) || (bd->sticky))
1204 e_border_hide(bd, 1);
1207 if (e_config->transient.desktop)
1211 Eina_List *list = _e_border_sub_borders_new(bd);
1213 EINA_LIST_FOREACH(list, l, child)
1215 e_border_desk_set(child, bd->desk);
1217 eina_list_free(list);
1219 e_remember_update(bd);
1222 #ifdef _F_ZONE_WINDOW_ROTATION_
1224 _e_border_vkbd_state_check(E_Border *bd,
1227 Eina_Bool res = EINA_TRUE;
1228 if (!e_config->wm_win_rotation) return EINA_FALSE;
1229 if ((rot.vkbd) && (rot.vkbd == bd))
1233 if ((rot.vkbd_hide_prepare_done) ||
1234 (rot.vkbd_hide_prepare_timer))
1239 if ((rot.vkbd_show_prepare_done) ||
1240 (rot.vkbd_show_prepare_timer))
1248 _e_border_vkbd_show_timeout(void *data)
1250 E_Border *bd = data;
1251 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1252 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1254 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1256 if (rot.vkbd_ctrl_win)
1258 ELB(ELBT_BD, "SET KBD_ON", 0);
1259 ecore_x_e_virtual_keyboard_state_set
1260 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1265 rot.vkbd_show_prepare_done = EINA_FALSE;
1267 if (rot.vkbd_show_prepare_timer)
1268 ecore_timer_del(rot.vkbd_show_prepare_timer);
1269 rot.vkbd_show_prepare_timer = NULL;
1271 if (rot.vkbd_show_timer)
1272 ecore_timer_del(rot.vkbd_show_timer);
1273 rot.vkbd_show_timer = NULL;
1275 return ECORE_CALLBACK_CANCEL;
1279 _e_border_vkbd_hide_timeout(void *data)
1281 E_Border *bd = data;
1282 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1283 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1285 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1287 if (rot.vkbd_ctrl_win)
1289 ELB(ELBT_BD, "SET KBD_OFF", 0);
1290 ecore_x_e_virtual_keyboard_state_set
1291 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1294 e_object_unref(E_OBJECT(bd));
1297 rot.vkbd_hide_prepare_done = EINA_FALSE;
1299 if (rot.vkbd_hide_prepare_timer)
1300 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1301 rot.vkbd_hide_prepare_timer = NULL;
1303 if (rot.vkbd_hide_timer)
1304 ecore_timer_del(rot.vkbd_hide_timer);
1305 rot.vkbd_hide_timer = NULL;
1307 return ECORE_CALLBACK_CANCEL;
1311 _e_border_vkbd_show(E_Border *bd)
1313 if (!e_config->wm_win_rotation) return;
1314 rot.vkbd_show_prepare_done = EINA_TRUE;
1315 if (rot.vkbd_show_prepare_timer)
1316 ecore_timer_del(rot.vkbd_show_prepare_timer);
1317 rot.vkbd_show_prepare_timer = NULL;
1318 if (rot.vkbd_show_timer)
1319 ecore_timer_del(rot.vkbd_show_timer);
1320 rot.vkbd_show_timer = NULL;
1321 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1324 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1329 _e_border_vkbd_hide(E_Border *bd)
1331 if (!e_config->wm_win_rotation) return;
1332 rot.vkbd_hide_prepare_done = EINA_TRUE;
1333 if (rot.vkbd_hide_prepare_timer)
1334 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1335 rot.vkbd_hide_prepare_timer = NULL;
1336 if (rot.vkbd_hide_timer)
1337 ecore_timer_del(rot.vkbd_hide_timer);
1338 rot.vkbd_hide_timer = NULL;
1339 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1341 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
1342 e_border_hide(bd, 0);
1343 if (!e_object_is_del(E_OBJECT(bd)))
1345 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
1346 e_object_del(E_OBJECT(bd));
1348 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1353 _e_border_vkbd_show_prepare_timeout(void *data)
1355 E_Border *bd = data;
1356 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1357 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1359 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1360 _e_border_vkbd_show(bd);
1362 return ECORE_CALLBACK_CANCEL;
1366 _e_border_vkbd_hide_prepare_timeout(void *data)
1368 E_Border *bd = data;
1369 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1370 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1372 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1373 _e_border_vkbd_hide(bd);
1375 return ECORE_CALLBACK_CANCEL;
1380 e_border_show(E_Border *bd)
1382 E_Event_Border_Show *ev;
1383 unsigned int visible;
1386 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1387 if (bd->visible) return;
1388 #ifdef _F_ZONE_WINDOW_ROTATION_
1389 // newly created window that has to be rotated will be show after rotation done.
1390 // so, skip at this time. it will be called again after GETTING ROT_DONE.
1391 if ((bd->new_client) &&
1392 (bd->client.e.state.rot.changes != -1))
1394 // if this window is in withdrawn state, show this window right now.
1395 // that's because the window in withdrawn state can't render its canvas.
1396 // eventually, this window will not send the message of rotation done,
1397 // even if e17 request to rotation this window.
1398 if (bd->client.icccm.state != ECORE_X_WINDOW_STATE_HINT_NORMAL)
1399 e_hints_window_visible_set(bd);
1401 bd->client.e.state.rot.pending_show = 1;
1404 if ((e_config->wm_win_rotation) &&
1405 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1407 (!rot.vkbd_show_prepare_done))
1409 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1410 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1411 if (rot.vkbd_show_prepare_timer)
1412 ecore_timer_del(rot.vkbd_show_prepare_timer);
1413 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1414 _e_border_vkbd_show_prepare_timeout,
1418 ELB(ELBT_BD, "SHOW", bd->client.win);
1420 ecore_x_window_shadow_tree_flush();
1421 e_container_shape_show(bd->shape);
1422 if (!bd->need_reparent)
1423 ecore_x_window_show(bd->client.win);
1424 e_hints_window_visible_set(bd);
1427 bd->changes.visible = 1;
1430 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1431 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1433 ev = E_NEW(E_Event_Border_Show, 1);
1435 e_object_ref(E_OBJECT(bd));
1436 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1437 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1439 #ifdef _F_ZONE_WINDOW_ROTATION_
1440 if ((e_config->wm_win_rotation) &&
1441 ((bd->client.e.state.rot.support) ||
1442 (bd->client.e.state.rot.app_set)))
1444 ELB(ELBT_ROT, "CHECK", bd->client.win);
1445 int rotation = _e_border_rotation_angle_get(bd);
1446 if (rotation != -1) e_border_rotation_set(bd, rotation);
1452 e_border_hide(E_Border *bd,
1455 unsigned int visible;
1458 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1460 #ifdef _F_ZONE_WINDOW_ROTATION_
1461 if ((e_config->wm_win_rotation) &&
1462 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1464 (!rot.vkbd_hide_prepare_done) &&
1467 Eina_Bool need_prepare = EINA_TRUE;
1468 E_Border *child = NULL;
1471 if (e_object_is_del(E_OBJECT(bd->parent)))
1472 need_prepare = EINA_FALSE;
1475 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1476 if (bd->parent->modal == bd)
1478 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1479 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1480 bd->parent->lock_close = 0;
1481 bd->parent->saved.event_mask = 0;
1482 bd->parent->modal = NULL;
1488 need_prepare = EINA_FALSE;
1490 EINA_LIST_FREE(bd->transients, child)
1492 child->parent = NULL;
1495 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1499 e_object_ref(E_OBJECT(bd));
1500 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1501 if (rot.vkbd_hide_prepare_timer)
1502 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1503 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1504 _e_border_vkbd_hide_prepare_timeout,
1510 e_object_ref(E_OBJECT(bd));
1512 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1513 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1515 /* cleanup code from _e_border_vkbd_hide() */
1516 rot.vkbd_hide_prepare_done = EINA_TRUE;
1517 if (rot.vkbd_hide_prepare_timer)
1518 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1519 rot.vkbd_hide_prepare_timer = NULL;
1520 if (rot.vkbd_hide_timer)
1521 ecore_timer_del(rot.vkbd_hide_timer);
1522 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1525 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1527 if (!bd->visible) goto send_event;
1528 ecore_x_window_shadow_tree_flush();
1530 _e_border_move_end(bd);
1531 if (bd->resize_mode != RESIZE_NONE)
1533 _e_border_pointer_resize_end(bd);
1534 bd->resize_mode = RESIZE_NONE;
1535 _e_border_resize_end(bd);
1538 e_container_shape_hide(bd->shape);
1539 if (!bd->iconic) e_hints_window_hidden_set(bd);
1542 bd->changes.visible = 1;
1544 if (!bd->need_reparent)
1546 if ((bd->focused) ||
1547 (e_grabinput_last_focus_win_get() == bd->client.win))
1549 e_border_focus_set(bd, 0, 1);
1557 con = e_container_current_get(e_manager_current_get());
1558 zone = e_zone_current_get(con);
1559 desk = e_desk_current_get(zone);
1562 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1563 e_border_focus_set(bd->parent, 1, 1);
1564 else if (e_config->focus_revert_on_hide_or_close)
1566 /* When using pointer focus, the border under the
1567 * pointer (if any) gets focused, in sloppy/click
1568 * focus the last focused window on the current
1569 * desk gets focus */
1570 if (e_config->focus_policy == E_FOCUS_MOUSE)
1572 pbd = e_border_under_pointer_get(desk, bd);
1574 e_border_focus_set(pbd, 1, 1);
1576 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1577 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1578 (e_config->focus_policy == E_FOCUS_CLICK))
1579 _e_border_latest_stacked_focus(bd);
1583 e_desk_last_focused_focus(desk);
1593 /* Make sure that this border isn't deleted */
1594 bd->await_hide_event++;
1596 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1597 ecore_x_window_hide(bd->client.win);
1602 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1604 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1611 #ifdef _F_ZONE_WINDOW_ROTATION_
1612 _e_border_rotation_list_remove(bd);
1615 E_Event_Border_Hide *ev;
1617 ev = E_NEW(E_Event_Border_Hide, 1);
1619 e_object_ref(E_OBJECT(bd));
1620 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1621 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1626 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1630 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1631 setpriority(PRIO_PROCESS, pid, newpri);
1632 // shouldnt need to do this as default ionice class is "none" (0), and
1633 // this inherits io priority FROM nice level
1634 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1635 // IOPRIO_PRIO_VALUE(2, 5));
1639 char *file, buf[PATH_MAX];
1643 // yes - this is /proc specific... so this may not work on some
1644 // os's - works on linux. too bad for others.
1645 files = ecore_file_ls("/proc");
1646 EINA_LIST_FREE(files, file)
1648 if (isdigit(file[0]))
1650 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1651 f = fopen(buf, "r");
1656 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1662 _pri_adj(pid2, set, adj, EINA_TRUE,
1663 adj_children, do_children);
1665 _pri_adj(pid2, set, adj, use_adj,
1666 adj_children, do_children);
1678 _e_border_pri_raise(E_Border *bd)
1680 if (bd->client.netwm.pid <= 0) return;
1681 if (bd->client.netwm.pid == getpid()) return;
1682 _pri_adj(bd->client.netwm.pid,
1683 e_config->priority - 1, -1, EINA_FALSE,
1684 // EINA_TRUE, EINA_TRUE);
1685 EINA_TRUE, EINA_FALSE);
1686 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1687 // bd->client.netwm.pid, e_border_name_get(bd));
1691 _e_border_pri_norm(E_Border *bd)
1693 if (bd->client.netwm.pid <= 0) return;
1694 if (bd->client.netwm.pid == getpid()) return;
1695 _pri_adj(bd->client.netwm.pid,
1696 e_config->priority, 1, EINA_FALSE,
1697 // EINA_TRUE, EINA_TRUE);
1698 EINA_TRUE, EINA_FALSE);
1699 // printf("WIN: pid %i, title %s (NORMAL)\n",
1700 // bd->client.netwm.pid, e_border_name_get(bd));
1704 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1707 Ecore_Evas *bg_ecore_evas;
1713 bg_ecore_evas = bd->bg_ecore_evas;
1715 /* unregister old frame window */
1716 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1717 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1719 e_focus_setdown(bd);
1720 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1721 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1723 if (bd->icon_object)
1724 evas_object_del(bd->icon_object);
1726 evas_object_del(bd->bg_object);
1727 e_canvas_del(bg_ecore_evas);
1728 ecore_evas_free(bg_ecore_evas);
1731 e_object_del(E_OBJECT(bd->pointer));
1733 /* create new frame */
1735 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1736 bd->x, bd->y, bd->w, bd->h);
1739 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1740 bd->x, bd->y, bd->w, bd->h);
1741 ecore_x_window_shape_events_select(bd->win, 1);
1744 ecore_x_window_configure(bd->win,
1745 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1746 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1748 win, ECORE_X_WINDOW_STACK_BELOW);
1750 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1751 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1754 bd->bg_ecore_evas = e_canvas_new(bd->win,
1755 0, 0, bd->w, bd->h, 1, 0,
1758 e_canvas_add(bd->bg_ecore_evas);
1759 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1761 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1762 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1763 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1765 ecore_x_window_shape_events_select(bd->bg_win, 1);
1767 /* move client with shell win over to new frame */
1768 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1769 bd->client_inset.l, bd->client_inset.t);
1771 bd->pointer = e_pointer_window_new(bd->win, 0);
1773 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1774 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1781 ecore_evas_show(bd->bg_ecore_evas);
1782 ecore_x_window_show(bd->win);
1784 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1785 ecore_x_window_show(tmp->win);
1788 bd->bg_object = edje_object_add(bd->bg_evas);
1789 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1790 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1792 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1794 /* cleanup old frame */
1795 ecore_x_window_free(win);
1799 _e_border_client_move_resize_send(E_Border *bd)
1801 if (bd->internal_ecore_evas)
1802 ecore_evas_managed_move(bd->internal_ecore_evas,
1803 bd->x + bd->fx.x + bd->client_inset.l,
1804 bd->y + bd->fx.y + bd->client_inset.t);
1806 ecore_x_icccm_move_resize_send(bd->client.win,
1807 bd->x + bd->fx.x + bd->client_inset.l,
1808 bd->y + bd->fx.y + bd->client_inset.t,
1814 _e_border_pending_move_resize_add(E_Border *bd,
1821 Eina_Bool without_border,
1822 unsigned int serial)
1824 E_Border_Pending_Move_Resize *pnd;
1826 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1828 pnd->resize = resize;
1830 pnd->without_border = without_border;
1835 pnd->serial = serial;
1836 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1840 _e_border_move_internal(E_Border *bd,
1843 Eina_Bool without_border)
1845 E_Event_Border_Move *ev;
1848 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1850 ecore_x_window_shadow_tree_flush();
1853 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1859 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1861 if (e_config->allow_manip)
1864 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1869 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1874 else if (e_config->allow_manip)
1882 x -= bd->client_inset.l;
1883 y -= bd->client_inset.t;
1885 if (bd->move_intercept_cb)
1888 px = bd->x, py = bd->y;
1889 bd->move_intercept_cb(bd, x, y);
1890 if ((bd->x == px) && (bd->y == py)) return;
1892 else if ((x == bd->x) && (y == bd->y)) return;
1893 bd->pre_res_change.valid = 0;
1897 bd->changes.pos = 1;
1899 if (bd->client.netwm.sync.request)
1901 bd->client.netwm.sync.wait++;
1902 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1905 _e_border_client_move_resize_send(bd);
1906 _e_border_move_update(bd);
1907 ev = E_NEW(E_Event_Border_Move, 1);
1909 e_object_ref(E_OBJECT(bd));
1910 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1911 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1912 _e_border_zone_update(bd);
1916 * Move window to coordinates that already account border decorations.
1918 * This call will consider given position already accounts border
1919 * decorations, so it will not be considered later. This will just
1920 * work properly with borders that have being evaluated and border
1921 * decorations are known (border->client_inset).
1923 * @parm x horizontal position to place window.
1924 * @parm y vertical position to place window.
1926 * @see e_border_move_without_border()
1929 e_border_move(E_Border *bd,
1936 _e_border_move_internal(bd, x, y, 0);
1941 * Set a callback which will be called just prior to updating the
1942 * move coordinates for a border
1945 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1947 bd->move_intercept_cb = cb;
1951 * Move window to coordinates that do not account border decorations yet.
1953 * This call will consider given position does not account border
1954 * decoration, so these values (border->client_inset) will be
1955 * accounted automatically. This is specially useful when it is a new
1956 * client and has not be evaluated yet, in this case
1957 * border->client_inset will be zeroed and no information is known. It
1958 * will mark pending requests so border will be accounted on
1959 * evalutation phase.
1961 * @parm x horizontal position to place window.
1962 * @parm y vertical position to place window.
1964 * @see e_border_move()
1967 e_border_move_without_border(E_Border *bd,
1974 _e_border_move_internal(bd, x, y, 1);
1978 e_border_center(E_Border *bd)
1982 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1984 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1985 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1989 e_border_center_pos_get(E_Border *bd,
1995 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1997 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1998 if (x) *x = zx + (zw - bd->w) / 2;
1999 if (y) *y = zy + (zh - bd->h) / 2;
2003 e_border_fx_offset(E_Border *bd,
2008 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2010 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
2014 bd->changes.pos = 1;
2017 if (bd->moving) _e_border_move_update(bd);
2021 _e_border_move_resize_internal(E_Border *bd,
2026 Eina_Bool without_border,
2029 E_Event_Border_Move *mev;
2030 E_Event_Border_Resize *rev;
2033 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2035 ecore_x_window_shadow_tree_flush();
2039 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
2045 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
2047 if (e_config->allow_manip)
2050 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2056 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2063 if (e_config->allow_manip)
2071 x -= bd->client_inset.l;
2072 y -= bd->client_inset.t;
2073 w += (bd->client_inset.l + bd->client_inset.r);
2074 h += (bd->client_inset.t + bd->client_inset.b);
2077 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2078 (w == bd->w) && (h == bd->h))
2081 bd->pre_res_change.valid = 0;
2084 bd->changes.pos = 1;
2090 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2091 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2093 if ((bd->shaped) || (bd->client.shaped))
2095 bd->need_shape_merge = 1;
2096 bd->need_shape_export = 1;
2098 if (bd->shaped_input)
2100 bd->need_shape_merge = 1;
2103 if (bd->internal_ecore_evas)
2106 bd->changes.size = 1;
2110 if (bdresize && bd->client.netwm.sync.request)
2112 bd->client.netwm.sync.wait++;
2113 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2114 * when no move is intended. The border geometry is set above anyways.
2116 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2117 bd->client.netwm.sync.serial);
2118 ecore_x_netwm_sync_request_send(bd->client.win,
2119 bd->client.netwm.sync.serial++);
2124 bd->changes.size = 1;
2128 _e_border_client_move_resize_send(bd);
2130 _e_border_resize_update(bd);
2133 mev = E_NEW(E_Event_Border_Move, 1);
2135 e_object_ref(E_OBJECT(bd));
2136 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2137 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2140 rev = E_NEW(E_Event_Border_Resize, 1);
2142 e_object_ref(E_OBJECT(bd));
2143 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2144 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2145 _e_border_zone_update(bd);
2149 * Move and resize window to values that already account border decorations.
2151 * This call will consider given values already accounts border
2152 * decorations, so it will not be considered later. This will just
2153 * work properly with borders that have being evaluated and border
2154 * decorations are known (border->client_inset).
2156 * @parm x horizontal position to place window.
2157 * @parm y vertical position to place window.
2158 * @parm w horizontal window size.
2159 * @parm h vertical window size.
2161 * @see e_border_move_resize_without_border()
2164 e_border_move_resize(E_Border *bd,
2173 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2177 * Move and resize window to values that do not account border decorations yet.
2179 * This call will consider given values already accounts border
2180 * decorations, so it will not be considered later. This will just
2181 * work properly with borders that have being evaluated and border
2182 * decorations are known (border->client_inset).
2184 * @parm x horizontal position to place window.
2185 * @parm y vertical position to place window.
2186 * @parm w horizontal window size.
2187 * @parm h vertical window size.
2189 * @see e_border_move_resize()
2192 e_border_move_resize_without_border(E_Border *bd,
2201 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2205 * Resize window to values that already account border decorations.
2207 * This call will consider given size already accounts border
2208 * decorations, so it will not be considered later. This will just
2209 * work properly with borders that have being evaluated and border
2210 * decorations are known (border->client_inset).
2212 * @parm w horizontal window size.
2213 * @parm h vertical window size.
2215 * @see e_border_resize_without_border()
2218 e_border_resize(E_Border *bd,
2225 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2229 * Resize window to values that do not account border decorations yet.
2231 * This call will consider given size does not account border
2232 * decoration, so these values (border->client_inset) will be
2233 * accounted automatically. This is specially useful when it is a new
2234 * client and has not be evaluated yet, in this case
2235 * border->client_inset will be zeroed and no information is known. It
2236 * will mark pending requests so border will be accounted on
2237 * evalutation phase.
2239 * @parm w horizontal window size.
2240 * @parm h vertical window size.
2242 * @see e_border_resize()
2245 e_border_resize_without_border(E_Border *bd,
2252 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2256 e_border_layer_set(E_Border *bd,
2262 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2264 ecore_x_window_shadow_tree_flush();
2266 oldraise = e_config->transient.raise;
2270 bd->saved.layer = layer;
2274 if (e_config->transient.layer)
2278 Eina_List *list = _e_border_sub_borders_new(bd);
2280 /* We need to set raise to one, else the child wont
2281 * follow to the new layer. It should be like this,
2282 * even if the user usually doesn't want to raise
2285 e_config->transient.raise = 1;
2286 EINA_LIST_FOREACH(list, l, child)
2288 e_border_layer_set(child, layer);
2292 e_config->transient.raise = oldraise;
2296 e_border_raise(E_Border *bd)
2298 E_Event_Border_Stack *ev;
2299 E_Border *last = NULL, *child;
2303 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2305 ecore_x_window_shadow_tree_flush();
2307 if (e_config->transient.raise)
2309 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2310 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2313 Eina_List *list = _e_border_sub_borders_new(bd);
2315 EINA_LIST_REVERSE_FOREACH(list, l, child)
2317 /* Don't stack iconic transients. If the user wants these shown,
2318 * thats another option.
2323 e_border_stack_below(child, last);
2328 /* First raise the border to find out which border we will end up above */
2329 above = e_container_border_raise(child);
2333 /* We ended up above a border, now we must stack this border to
2334 * generate the stacking event, and to check if this transient
2335 * has other transients etc.
2337 e_border_stack_above(child, above);
2341 /* If we didn't end up above any border, we are on the bottom! */
2342 e_border_lower(child);
2348 eina_list_free(list);
2349 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2353 EINA_LIST_FOREACH(bd->transients, l, child)
2355 /* Don't stack iconic transients. If the user wants these shown,
2356 * thats another option.
2360 child->layer = bd->layer;
2361 if (!last) last = child;
2362 e_border_raise (child);
2369 ev = E_NEW(E_Event_Border_Stack, 1);
2371 e_object_ref(E_OBJECT(bd));
2375 e_container_border_stack_below(bd, last);
2377 e_object_ref(E_OBJECT(last));
2378 ev->type = E_STACKING_BELOW;
2384 /* If we don't have any children, raise this border */
2385 above = e_container_border_raise(bd);
2386 e_border_raise_latest_set(bd);
2389 /* We ended up above a border */
2391 e_object_ref(E_OBJECT(above));
2392 ev->type = E_STACKING_ABOVE;
2396 /* No border to raise above, same as a lower! */
2398 ev->type = E_STACKING_ABOVE;
2402 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2403 e_remember_update(bd);
2407 e_border_lower(E_Border *bd)
2409 E_Event_Border_Stack *ev;
2410 E_Border *last = NULL, *child;
2414 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2416 ecore_x_window_shadow_tree_flush();
2418 if (e_config->transient.lower)
2420 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2421 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2424 Eina_List *list = _e_border_sub_borders_new(bd);
2426 EINA_LIST_REVERSE_FOREACH(list, l, child)
2428 /* Don't stack iconic transients. If the user wants these shown,
2429 * thats another option.
2434 e_border_stack_below(child, last);
2439 /* First lower the border to find out which border we will end up below */
2440 below = e_container_border_lower(child);
2444 /* We ended up below a border, now we must stack this border to
2445 * generate the stacking event, and to check if this transient
2446 * has other transients etc.
2448 e_border_stack_below(child, below);
2452 /* If we didn't end up below any border, we are on top! */
2453 e_border_raise(child);
2459 eina_list_free(list);
2461 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2465 EINA_LIST_FOREACH(bd->transients, l, child)
2467 /* Don't stack iconic transients. If the user wants these shown,
2468 * thats another option.
2472 child->layer = bd->layer;
2473 e_border_lower (child);
2481 ev = E_NEW(E_Event_Border_Stack, 1);
2483 e_object_ref(E_OBJECT(bd));
2487 e_container_border_stack_below(bd, last);
2489 e_object_ref(E_OBJECT(last));
2490 ev->type = E_STACKING_BELOW;
2496 /* If we don't have any children, lower this border */
2497 below = e_container_border_lower(bd);
2500 /* We ended up below a border */
2502 e_object_ref(E_OBJECT(below));
2503 ev->type = E_STACKING_BELOW;
2507 /* No border to hide under, same as a raise! */
2509 ev->type = E_STACKING_BELOW;
2513 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2514 e_remember_update(bd);
2518 e_border_stack_above(E_Border *bd,
2521 /* TODO: Should stack above allow the border to change level */
2522 E_Event_Border_Stack *ev;
2523 E_Border *last = NULL, *child;
2527 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2529 ecore_x_window_shadow_tree_flush();
2531 if (e_config->transient.raise)
2533 Eina_List *list = _e_border_sub_borders_new(bd);
2535 EINA_LIST_REVERSE_FOREACH(list, l, child)
2537 /* Don't stack iconic transients. If the user wants these shown,
2538 * thats another option.
2543 e_border_stack_below(child, last);
2545 e_border_stack_above(child, above);
2549 eina_list_free(list);
2552 ev = E_NEW(E_Event_Border_Stack, 1);
2554 e_object_ref(E_OBJECT(bd));
2558 e_container_border_stack_below(bd, last);
2560 e_object_ref(E_OBJECT(last));
2561 ev->type = E_STACKING_BELOW;
2565 e_container_border_stack_above(bd, above);
2567 e_object_ref(E_OBJECT(above));
2568 ev->type = E_STACKING_ABOVE;
2571 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2572 e_remember_update(bd);
2576 e_border_stack_below(E_Border *bd,
2579 /* TODO: Should stack below allow the border to change level */
2580 E_Event_Border_Stack *ev;
2581 E_Border *last = NULL, *child;
2585 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2587 ecore_x_window_shadow_tree_flush();
2589 if (e_config->transient.lower)
2591 Eina_List *list = _e_border_sub_borders_new(bd);
2593 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2595 /* Don't stack iconic transients. If the user wants these shown,
2596 * thats another option.
2601 e_border_stack_below(child, last);
2603 e_border_stack_below(child, below);
2607 eina_list_free(list);
2610 ev = E_NEW(E_Event_Border_Stack, 1);
2612 e_object_ref(E_OBJECT(bd));
2616 e_container_border_stack_below(bd, last);
2618 e_object_ref(E_OBJECT(last));
2619 ev->type = E_STACKING_BELOW;
2623 e_container_border_stack_below(bd, below);
2625 e_object_ref(E_OBJECT(below));
2626 ev->type = E_STACKING_BELOW;
2629 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2630 e_remember_update(bd);
2634 e_border_focus_latest_set(E_Border *bd)
2636 focus_stack = eina_list_remove(focus_stack, bd);
2637 focus_stack = eina_list_prepend(focus_stack, bd);
2641 e_border_raise_latest_set(E_Border *bd)
2643 raise_stack = eina_list_remove(raise_stack, bd);
2644 raise_stack = eina_list_prepend(raise_stack, bd);
2648 * Sets the focus to the given border if necessary
2649 * There are 3 cases of different focus_policy-configurations:
2651 * - E_FOCUS_CLICK: just set the focus, the most simple one
2653 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2654 * warp the pointer to the window. If this fails (because
2655 * the pointer is already in the window), just set the focus.
2657 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2658 * last window which was focused, if the mouse is on the
2659 * desktop. So, we need to look if there is another window
2660 * under the pointer and warp to pointer to the right
2661 * one if so (also, we set the focus afterwards). In case
2662 * there is no window under pointer, the pointer is on the
2663 * desktop and so we just set the focus.
2666 * This function is to be called when setting the focus was not
2667 * explicitly triggered by the user (by moving the mouse or
2668 * clicking for example), but implicitly (by closing a window,
2669 * the last focused window should get focus).
2673 e_border_focus_set_with_pointer(E_Border *bd)
2675 #ifdef PRINT_LOTS_OF_DEBUG
2676 E_PRINT_BORDER_INFO(bd);
2678 /* note: this is here as it seems there are enough apps that do not even
2679 * expect us to emulate a look of focus but not actually set x input
2680 * focus as we do - so simply abort any focuse set on such windows */
2681 /* be strict about accepting focus hint */
2682 if ((!bd->client.icccm.accepts_focus) &&
2683 (!bd->client.icccm.take_focus)) return;
2684 if (bd->lock_focus_out) return;
2686 e_border_focus_set(bd, 1, 1);
2688 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2689 if (!bd->visible) return;
2691 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2693 if (!e_border_under_pointer_get(bd->desk, bd))
2695 e_border_pointer_warp_to_center(bd);
2700 e_border_pointer_warp_to_center(bd);
2705 e_border_focus_set(E_Border *bd,
2709 E_Border *bd_unfocus = NULL;
2710 Eina_Bool focus_changed = EINA_FALSE;
2713 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2714 /* note: this is here as it seems there are enough apps that do not even
2715 * expect us to emulate a look of focus but not actually set x input
2716 * focus as we do - so simply abort any focuse set on such windows */
2717 /* be strict about accepting focus hint */
2718 if ((!bd->client.icccm.accepts_focus) &&
2719 (!bd->client.icccm.take_focus))
2721 if ((set) && (focus) && (bd->lock_focus_out)) return;
2723 /* dont focus an iconified window. that's silly! */
2728 e_border_uniconify(bd);
2729 if (!focus_track_frozen)
2730 e_border_focus_latest_set(bd);
2733 else if (!bd->visible)
2737 /* FIXME: hack for deskflip animation:
2738 * dont update focus when sliding previous desk */
2739 else if ((!bd->sticky) &&
2740 (bd->desk != e_desk_current_get(bd->desk->zone)))
2746 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2748 e_border_focus_set(bd->modal, focus, set);
2751 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2753 e_border_focus_set(bd->leader->modal, focus, set);
2761 if (bd->visible && bd->changes.visible)
2766 else if ((!bd->focused) ||
2767 (focus_next && (bd != eina_list_data_get(focus_next))))
2771 if ((l = eina_list_data_find_list(focus_next, bd)))
2772 focus_next = eina_list_promote_list(focus_next, l);
2774 focus_next = eina_list_prepend(focus_next, bd);
2776 if ((bd->client.icccm.take_focus) &&
2777 (bd->client.icccm.accepts_focus))
2779 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2780 /* TODO what if the client didn't take focus ? */
2782 else if (!bd->client.icccm.accepts_focus)
2784 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2786 else if (!bd->client.icccm.take_focus)
2788 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2789 /* e_border_focus_set(bd, 1, 0); */
2799 if (focused) bd_unfocus = focused;
2800 if (focusing == bd) focusing = NULL;
2805 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2807 if ((bd2->fullscreen) &&
2809 (bd2->zone == bd->zone) &&
2810 ((bd2->desk == bd->desk) ||
2811 (bd2->sticky) || (bd->sticky)))
2813 Eina_Bool unfocus_is_parent = EINA_FALSE;
2814 E_Border *bd_parent;
2816 bd_parent = bd->parent;
2819 if (bd_parent == bd2)
2821 unfocus_is_parent = EINA_TRUE;
2824 bd_parent = bd->parent;
2826 if ((!unfocus_is_parent) &&
2827 (!e_config->allow_above_fullscreen))
2829 e_border_iconify(bd2);
2834 focus_changed = EINA_TRUE;
2840 focus_next = eina_list_remove(focus_next, bd);
2841 if (bd == focusing) focusing = NULL;
2843 if ((bd->focused) &&
2844 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2846 Eina_Bool wasfocused = EINA_FALSE;
2849 /* should always be the case. anyway */
2853 wasfocused = EINA_TRUE;
2856 if ((set) && (!focus_next) && (!focusing))
2858 e_grabinput_focus(bd->zone->container->bg_win,
2859 E_FOCUS_METHOD_PASSIVE);
2861 if ((bd->fullscreen) && (wasfocused))
2863 Eina_Bool have_vis_child = EINA_FALSE;
2867 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2870 (bd2->zone == bd->zone) &&
2871 ((bd2->desk == bd->desk) ||
2872 (bd2->sticky) || (bd->sticky)))
2874 if (bd2->parent == bd)
2876 have_vis_child = EINA_TRUE;
2881 if ((!have_vis_child) &&
2882 (!e_config->allow_above_fullscreen))
2883 e_border_iconify(bd);
2889 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2890 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2892 E_Event_Border_Focus_Out *ev;
2894 bd_unfocus->focused = 0;
2895 e_focus_event_focus_out(bd_unfocus);
2897 if (bd_unfocus->raise_timer)
2898 ecore_timer_del(bd_unfocus->raise_timer);
2899 bd_unfocus->raise_timer = NULL;
2901 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2902 if (bd_unfocus->icon_object)
2903 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2905 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2906 ev->border = bd_unfocus;
2907 e_object_ref(E_OBJECT(bd_unfocus));
2909 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2910 _e_border_event_border_focus_out_free, NULL);
2911 if ((bd_unfocus->fullscreen) &&
2912 (bd != bd_unfocus) &&
2913 (bd->zone == bd_unfocus->zone) &&
2914 ((bd->desk == bd_unfocus->desk) ||
2915 (bd->sticky) || (bd_unfocus->sticky)))
2917 Eina_Bool unfocus_is_parent = EINA_FALSE;
2918 E_Border *bd_parent;
2920 bd_parent = bd->parent;
2923 if (bd_parent == bd_unfocus)
2925 unfocus_is_parent = EINA_TRUE;
2928 bd_parent = bd->parent;
2930 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2932 e_border_iconify(bd_unfocus);
2939 E_Event_Border_Focus_In *ev;
2941 e_focus_event_focus_in(bd);
2943 if (!focus_track_frozen)
2944 e_border_focus_latest_set(bd);
2946 e_hints_active_window_set(bd->zone->container->manager, bd);
2948 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2949 if (bd->icon_object)
2950 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2952 ev = E_NEW(E_Event_Border_Focus_In, 1);
2954 e_object_ref(E_OBJECT(bd));
2956 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2957 _e_border_event_border_focus_in_free, NULL);
2962 e_border_shade(E_Border *bd,
2965 E_Event_Border_Resize *ev;
2970 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2971 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2972 ((bd->maximized) && (!e_config->allow_manip))) return;
2973 if ((bd->client.border.name) &&
2974 (!strcmp("borderless", bd->client.border.name))) return;
2976 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2977 ecore_x_window_hide(tmp->win);
2979 ecore_x_window_shadow_tree_flush();
2981 bd->shade.x = bd->x;
2982 bd->shade.y = bd->y;
2983 bd->shade.dir = dir;
2985 e_hints_window_shaded_set(bd, 1);
2986 e_hints_window_shade_direction_set(bd, dir);
2988 if (e_config->border_shade_animate)
2990 bd->shade.start = ecore_loop_time_get();
2992 bd->changes.shading = 1;
2995 if (bd->shade.dir == E_DIRECTION_UP ||
2996 bd->shade.dir == E_DIRECTION_LEFT)
2997 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2999 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3001 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3002 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
3006 if (bd->shade.dir == E_DIRECTION_UP)
3008 bd->h = bd->client_inset.t + bd->client_inset.b;
3010 else if (bd->shade.dir == E_DIRECTION_DOWN)
3012 bd->h = bd->client_inset.t + bd->client_inset.b;
3013 bd->y = bd->y + bd->client.h;
3014 bd->changes.pos = 1;
3016 else if (bd->shade.dir == E_DIRECTION_LEFT)
3018 bd->w = bd->client_inset.l + bd->client_inset.r;
3020 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3022 bd->w = bd->client_inset.l + bd->client_inset.r;
3023 bd->x = bd->x + bd->client.w;
3024 bd->changes.pos = 1;
3027 if ((bd->shaped) || (bd->client.shaped))
3029 bd->need_shape_merge = 1;
3030 bd->need_shape_export = 1;
3032 if (bd->shaped_input)
3034 bd->need_shape_merge = 1;
3037 bd->changes.size = 1;
3039 bd->changes.shaded = 1;
3041 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
3042 e_border_frame_recalc(bd);
3043 ev = E_NEW(E_Event_Border_Resize, 1);
3045 /* The resize is added in the animator when animation complete */
3046 /* For non-animated, we add it immediately with the new size */
3047 e_object_ref(E_OBJECT(bd));
3048 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3049 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3052 e_remember_update(bd);
3056 e_border_unshade(E_Border *bd,
3059 E_Event_Border_Resize *ev;
3064 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3065 if ((!bd->shaded) || (bd->shading))
3068 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3069 ecore_x_window_show(tmp->win);
3071 ecore_x_window_shadow_tree_flush();
3073 bd->shade.dir = dir;
3075 e_hints_window_shaded_set(bd, 0);
3076 e_hints_window_shade_direction_set(bd, dir);
3078 if (bd->shade.dir == E_DIRECTION_UP ||
3079 bd->shade.dir == E_DIRECTION_LEFT)
3081 bd->shade.x = bd->x;
3082 bd->shade.y = bd->y;
3086 bd->shade.x = bd->x - bd->client.w;
3087 bd->shade.y = bd->y - bd->client.h;
3089 if (e_config->border_shade_animate)
3091 bd->shade.start = ecore_loop_time_get();
3093 bd->changes.shading = 1;
3096 if (bd->shade.dir == E_DIRECTION_UP)
3098 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3099 ecore_x_window_move_resize(bd->client.win, 0,
3100 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3102 bd->client.w, bd->client.h);
3104 else if (bd->shade.dir == E_DIRECTION_LEFT)
3106 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3107 ecore_x_window_move_resize(bd->client.win,
3108 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3110 0, bd->client.w, bd->client.h);
3113 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3115 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3116 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3120 if (bd->shade.dir == E_DIRECTION_UP)
3122 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3124 else if (bd->shade.dir == E_DIRECTION_DOWN)
3126 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3127 bd->y = bd->y - bd->client.h;
3128 bd->changes.pos = 1;
3130 else if (bd->shade.dir == E_DIRECTION_LEFT)
3132 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3134 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3136 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3137 bd->x = bd->x - bd->client.w;
3138 bd->changes.pos = 1;
3140 if ((bd->shaped) || (bd->client.shaped))
3142 bd->need_shape_merge = 1;
3143 bd->need_shape_export = 1;
3145 if (bd->shaped_input)
3147 bd->need_shape_merge = 1;
3150 bd->changes.size = 1;
3152 bd->changes.shaded = 1;
3154 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3155 e_border_frame_recalc(bd);
3156 ev = E_NEW(E_Event_Border_Resize, 1);
3158 /* The resize is added in the animator when animation complete */
3159 /* For non-animated, we add it immediately with the new size */
3160 e_object_ref(E_OBJECT(bd));
3161 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3162 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3165 e_remember_update(bd);
3169 _e_border_client_inset_calc(E_Border *bd)
3172 Evas_Coord cx, cy, cw, ch;
3176 evas_object_resize(bd->bg_object, 1000, 1000);
3177 edje_object_message_signal_process(bd->bg_object);
3178 edje_object_calc_force(bd->bg_object);
3179 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3180 bd->client_inset.l = cx;
3181 bd->client_inset.r = 1000 - (cx + cw);
3182 bd->client_inset.t = cy;
3183 bd->client_inset.b = 1000 - (cy + ch);
3187 bd->client_inset.l = 0;
3188 bd->client_inset.r = 0;
3189 bd->client_inset.t = 0;
3190 bd->client_inset.b = 0;
3193 ecore_x_netwm_frame_size_set(bd->client.win,
3194 bd->client_inset.l, bd->client_inset.r,
3195 bd->client_inset.t, bd->client_inset.b);
3196 ecore_x_e_frame_size_set(bd->client.win,
3197 bd->client_inset.l, bd->client_inset.r,
3198 bd->client_inset.t, bd->client_inset.b);
3202 _e_border_maximize(E_Border *bd, E_Maximize max)
3204 int x1, yy1, x2, y2;
3207 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3211 zx = zy = zw = zh = 0;
3213 switch (max & E_MAXIMIZE_TYPE)
3215 case E_MAXIMIZE_NONE:
3219 case E_MAXIMIZE_FULLSCREEN:
3225 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3226 _e_border_client_inset_calc(bd);
3228 e_border_resize_limit(bd, &w, &h);
3229 /* center x-direction */
3230 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3231 /* center y-direction */
3232 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3234 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3235 cy = bd->zone->y + (bd->zone->h / 2);
3238 switch (max & E_MAXIMIZE_DIRECTION)
3240 case E_MAXIMIZE_BOTH:
3241 e_border_move_resize(bd, x1, yy1, w, h);
3244 case E_MAXIMIZE_VERTICAL:
3245 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3248 case E_MAXIMIZE_HORIZONTAL:
3249 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3252 case E_MAXIMIZE_LEFT:
3253 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3256 case E_MAXIMIZE_RIGHT:
3257 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3259 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3260 case E_MAXIMIZE_TOP:
3261 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3263 case E_MAXIMIZE_BOTTOM:
3264 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3270 case E_MAXIMIZE_SMART:
3271 case E_MAXIMIZE_EXPAND:
3273 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3285 if (bd->x < zx) // window left not useful coordinates
3287 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3288 x1 = zx + zw - bd->w;
3289 else // window normal position
3292 if (bd->y < zy) // window top not useful coordinates
3294 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3295 yy1 = zy + zh - bd->h;
3296 else // window normal position
3299 switch (max & E_MAXIMIZE_DIRECTION)
3301 case E_MAXIMIZE_BOTH:
3302 e_border_move_resize(bd, zx, zy, zw, zh);
3305 case E_MAXIMIZE_VERTICAL:
3306 e_border_move_resize(bd, x1, zy, w, zh);
3309 case E_MAXIMIZE_HORIZONTAL:
3310 e_border_move_resize(bd, zx, yy1, zw, h);
3313 case E_MAXIMIZE_LEFT:
3314 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3317 case E_MAXIMIZE_RIGHT:
3318 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3322 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3325 case E_MAXIMIZE_FILL:
3328 x2 = bd->zone->x + bd->zone->w;
3329 y2 = bd->zone->y + bd->zone->h;
3331 /* walk through all shelves */
3332 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3334 /* walk through all windows */
3335 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3341 e_border_resize_limit(bd, &w, &h);
3342 /* center x-direction */
3343 x1 = x1 + (pw - w) / 2;
3344 /* center y-direction */
3345 yy1 = yy1 + (ph - h) / 2;
3347 switch (max & E_MAXIMIZE_DIRECTION)
3349 case E_MAXIMIZE_BOTH:
3350 e_border_move_resize(bd, x1, yy1, w, h);
3353 case E_MAXIMIZE_VERTICAL:
3354 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3357 case E_MAXIMIZE_HORIZONTAL:
3358 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3361 case E_MAXIMIZE_LEFT:
3362 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3365 case E_MAXIMIZE_RIGHT:
3366 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3374 e_border_maximize(E_Border *bd,
3378 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3380 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3382 if ((bd->shaded) || (bd->shading)) return;
3383 ecore_x_window_shadow_tree_flush();
3385 e_border_unfullscreen(bd);
3386 /* Only allow changes in vertical/ horizontal maximization */
3387 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3388 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3391 bd->need_maximize = 1;
3392 bd->maximized &= ~E_MAXIMIZE_TYPE;
3393 bd->maximized |= max;
3397 bd->pre_res_change.valid = 0;
3398 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3400 /* Horizontal hasn't been set */
3401 bd->saved.x = bd->x - bd->zone->x;
3402 bd->saved.w = bd->w;
3404 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3406 /* Vertical hasn't been set */
3407 bd->saved.y = bd->y - bd->zone->y;
3408 bd->saved.h = bd->h;
3411 bd->saved.zone = bd->zone->num;
3412 e_hints_window_size_set(bd);
3416 _e_border_maximize(bd, max);
3419 /* Remove previous type */
3420 bd->maximized &= ~E_MAXIMIZE_TYPE;
3421 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3422 bd->maximized |= max;
3424 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3425 bd->maximized & E_MAXIMIZE_VERTICAL);
3426 e_remember_update(bd);
3430 e_border_unmaximize(E_Border *bd,
3434 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3435 if (!(max & E_MAXIMIZE_DIRECTION))
3437 CRI("BUG: Unmaximize call without direction!");
3441 if ((bd->shaded) || (bd->shading)) return;
3442 ecore_x_window_shadow_tree_flush();
3443 /* Remove directions not used */
3444 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3445 /* Can only remove existing maximization directions */
3447 if (bd->maximized & E_MAXIMIZE_TYPE)
3449 bd->pre_res_change.valid = 0;
3450 bd->need_maximize = 0;
3452 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3456 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3457 _e_border_client_inset_calc(bd);
3460 bd->maximized = E_MAXIMIZE_NONE;
3461 _e_border_move_resize_internal(bd,
3462 bd->zone->x + bd->saved.x,
3463 bd->zone->y + bd->saved.y,
3464 bd->saved.w, bd->saved.h, 0, 1);
3465 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3466 e_hints_window_size_unset(bd);
3477 if (max & E_MAXIMIZE_VERTICAL)
3479 /* Remove vertical */
3481 y = bd->saved.y + bd->zone->y;
3482 bd->saved.h = bd->saved.y = 0;
3483 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3484 bd->maximized &= ~E_MAXIMIZE_LEFT;
3485 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3487 if (max & E_MAXIMIZE_HORIZONTAL)
3489 /* Remove horizontal */
3491 x = bd->saved.x + bd->zone->x;
3492 bd->saved.w = bd->saved.x = 0;
3493 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3496 e_border_resize_limit(bd, &w, &h);
3498 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3500 bd->maximized = E_MAXIMIZE_NONE;
3501 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3502 e_hints_window_size_unset(bd);
3503 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3507 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3508 e_hints_window_size_set(bd);
3511 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3512 bd->maximized & E_MAXIMIZE_VERTICAL);
3514 e_remember_update(bd);
3518 e_border_fullscreen(E_Border *bd,
3519 E_Fullscreen policy)
3521 E_Event_Border_Fullscreen *ev;
3524 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3526 if ((bd->shaded) || (bd->shading)) return;
3527 ecore_x_window_shadow_tree_flush();
3530 bd->need_fullscreen = 1;
3533 if (!bd->fullscreen)
3535 bd->pre_res_change.valid = 0;
3537 bd->saved.x = bd->x - bd->zone->x;
3538 bd->saved.y = bd->y - bd->zone->y;
3539 bd->saved.w = bd->client.w;
3540 bd->saved.h = bd->client.h;
3541 bd->saved.maximized = bd->maximized;
3542 bd->saved.zone = bd->zone->num;
3545 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3546 e_hints_window_size_set(bd);
3548 bd->client_inset.l = 0;
3549 bd->client_inset.r = 0;
3550 bd->client_inset.t = 0;
3551 bd->client_inset.b = 0;
3553 bd->desk->fullscreen_borders++;
3555 /* e_zone_fullscreen_set(bd->zone, 1); */
3556 bd->saved.layer = bd->layer;
3557 if (!e_config->allow_above_fullscreen)
3558 e_border_layer_set(bd, 250);
3560 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3561 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3563 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3565 else if (policy == E_FULLSCREEN_ZOOM)
3567 Ecore_X_Randr_Screen_Size_MM *sizes;
3568 int num_sizes, i, best_size_index = 0;
3570 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3572 &screen_size.height,
3574 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3578 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3579 int best_dist = INT_MAX, dist;
3581 for (i = 0; i < num_sizes; i++)
3583 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3585 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3586 if (dist < best_dist)
3588 best_size.width = sizes[i].width;
3589 best_size.height = sizes[i].height;
3591 best_size_index = i;
3595 if (((best_size.width != -1) && (best_size.height != -1)) &&
3596 ((best_size.width != screen_size.width) ||
3597 (best_size.height != screen_size.height)))
3599 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3601 screen_size_index = best_size_index;
3602 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3606 screen_size.width = -1;
3607 screen_size.height = -1;
3608 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3613 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3617 e_hints_window_fullscreen_set(bd, 1);
3618 e_hints_window_size_unset(bd);
3619 bd->client.border.changed = 1;
3622 bd->fullscreen_policy = policy;
3624 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3626 e_object_ref(E_OBJECT(bd));
3627 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3628 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3630 e_remember_update(bd);
3634 e_border_unfullscreen(E_Border *bd)
3636 E_Event_Border_Unfullscreen *ev;
3639 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3640 if ((bd->shaded) || (bd->shading)) return;
3641 ecore_x_window_shadow_tree_flush();
3644 bd->pre_res_change.valid = 0;
3646 bd->need_fullscreen = 0;
3647 bd->desk->fullscreen_borders--;
3649 if ((screen_size.width != -1) && (screen_size.height != -1))
3651 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3653 screen_size.width = -1;
3654 screen_size.height = -1;
3656 e_border_move_resize(bd,
3657 bd->saved.x + bd->zone->x,
3658 bd->saved.y + bd->zone->y,
3659 bd->saved.w, bd->saved.h);
3661 if (bd->saved.maximized)
3662 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3663 bd->saved.maximized);
3665 e_border_layer_set(bd, bd->saved.layer);
3667 e_hints_window_fullscreen_set(bd, 0);
3668 bd->client.border.changed = 1;
3671 bd->fullscreen_policy = 0;
3673 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3675 e_object_ref(E_OBJECT(bd));
3676 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3677 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3679 e_remember_update(bd);
3683 e_border_iconify(E_Border *bd)
3685 E_Event_Border_Iconify *ev;
3686 unsigned int iconic;
3689 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3690 if (bd->shading) return;
3691 ecore_x_window_shadow_tree_flush();
3695 e_border_hide(bd, 1);
3696 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3697 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3700 e_hints_window_iconic_set(bd);
3701 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3703 ev = E_NEW(E_Event_Border_Iconify, 1);
3705 e_object_ref(E_OBJECT(bd));
3706 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3707 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3709 if (e_config->transient.iconify)
3713 Eina_List *list = _e_border_sub_borders_new(bd);
3715 EINA_LIST_FOREACH(list, l, child)
3717 e_border_iconify(child);
3719 eina_list_free(list);
3721 e_remember_update(bd);
3724 #ifdef _F_DEICONIFY_APPROVE_
3726 _e_border_uniconify_timeout(void *data)
3733 if (!e_object_is_del(E_OBJECT(bd)))
3735 ELB(ELBT_BD, "TIMEOUT UNICONIFY_APPROVE", bd->client.win);
3736 bd->client.e.state.deiconify_approve.render_done = 1;
3737 if (bd->client.e.state.deiconify_approve.req_list)
3739 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child_bd)
3741 child_bd->client.e.state.deiconify_approve.render_done = 1;
3742 child_bd->client.e.state.deiconify_approve.ancestor = NULL;
3745 bd->client.e.state.deiconify_approve.req_list = NULL;
3746 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3747 e_border_uniconify(bd);
3750 return ECORE_CALLBACK_CANCEL;
3754 _e_border_deiconify_approve_send(E_Border *bd, E_Border *bd_ancestor)
3756 if (!bd || !bd_ancestor) return;
3758 if (e_config->deiconify_approve)
3760 if (e_config->transient.iconify)
3764 Eina_List *list = _e_border_sub_borders_new(bd);
3765 EINA_LIST_FOREACH(list, l, child)
3767 #ifdef _F_ZONE_WINDOW_ROTATION_
3768 if ((e_config->wm_win_rotation) &&
3769 ((child->client.e.state.rot.support) ||
3770 (child->client.e.state.rot.app_set)))
3772 ELB(ELBT_ROT, "CHECK_DEICONIFY CHILD", child->client.win);
3773 int rotation = _e_border_rotation_angle_get(bd);
3774 if (rotation != -1) e_border_rotation_set(bd, rotation);
3777 _e_border_deiconify_approve_send(child, bd_ancestor);
3778 if (child->client.e.state.deiconify_approve.support)
3780 ELBF(ELBT_BD, 0, child->client.win,
3781 "SEND DEICONIFY_APPROVE. ancestor:%x", bd_ancestor->client.win);
3783 ecore_x_client_message32_send(child->client.win,
3784 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3785 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3786 child->client.win, 0, 0, 0, 0);
3787 child->client.e.state.deiconify_approve.ancestor = bd_ancestor;
3788 bd_ancestor->client.e.state.deiconify_approve.req_list = eina_list_append(bd_ancestor->client.e.state.deiconify_approve.req_list, child);
3791 eina_list_free(list);
3797 _e_border_deiconify_approve_send_all_transient(E_Border *bd)
3799 E_Border *bd_ancestor;
3802 if (e_config->deiconify_approve)
3804 #ifdef _F_ZONE_WINDOW_ROTATION_
3805 if ((e_config->wm_win_rotation) &&
3806 ((bd->client.e.state.rot.support) ||
3807 (bd->client.e.state.rot.app_set)))
3809 ELB(ELBT_ROT, "CHECK_DEICONIFY", bd->client.win);
3810 int rotation = _e_border_rotation_angle_get(bd);
3811 if (rotation != -1) e_border_rotation_set(bd, rotation);
3815 if (e_config->transient.iconify)
3817 _e_border_deiconify_approve_send(bd, bd_ancestor);
3820 if (bd->client.e.state.deiconify_approve.support)
3822 ELBF(ELBT_BD, 0, bd->client.win,
3823 "SEND DEICONIFY_APPROVE.. ancestor:%x", bd_ancestor->client.win);
3825 ecore_x_client_message32_send(bd->client.win,
3826 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3827 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3828 bd->client.win, 0, 0, 0, 0);
3829 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3836 e_border_uniconify(E_Border *bd)
3839 E_Event_Border_Uniconify *ev;
3840 unsigned int iconic;
3843 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3845 #ifdef _F_DEICONIFY_APPROVE_
3846 if (e_config->deiconify_approve)
3848 if (bd->client.e.state.deiconify_approve.support)
3850 if (bd->client.e.state.deiconify_approve.wait_timer)
3852 ELB(ELBT_BD, "DEICONIFY_APPROVE WAIT_TIMER is already running", bd->client.win);
3855 if (bd->client.e.state.deiconify_approve.render_done == 0)
3857 ELB(ELBT_BD, "DEICONIFY_APPROVE to all transient", bd->client.win);
3858 _e_border_deiconify_approve_send_all_transient(bd);
3862 bd->client.e.state.deiconify_approve.render_done = 0;
3866 #if _F_ZONE_WINDOW_ROTATION_
3867 if (!bd->client.win)
3869 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3874 if (bd->shading) return;
3875 ecore_x_window_shadow_tree_flush();
3880 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3881 desk = e_desk_current_get(bd->desk->zone);
3882 #ifdef _F_USE_EXTENDED_ICONIFY_
3883 if (e_manager_comp_evas_get(bd->zone->container->manager))
3885 if (bd->await_hide_event > 0)
3886 bd->await_hide_event--;
3889 e_border_desk_set(bd, desk);
3891 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3894 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3896 ev = E_NEW(E_Event_Border_Uniconify, 1);
3898 e_object_ref(E_OBJECT(bd));
3899 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3900 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3902 if (e_config->transient.iconify)
3906 Eina_List *list = _e_border_sub_borders_new(bd);
3908 EINA_LIST_FOREACH(list, l, child)
3910 e_border_uniconify(child);
3912 eina_list_free(list);
3914 e_remember_update(bd);
3918 e_border_stick(E_Border *bd)
3920 E_Event_Border_Stick *ev;
3923 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3924 if (bd->sticky) return;
3926 e_hints_window_sticky_set(bd, 1);
3929 if (e_config->transient.desktop)
3933 Eina_List *list = _e_border_sub_borders_new(bd);
3935 EINA_LIST_FOREACH(list, l, child)
3938 e_hints_window_sticky_set(child, 1);
3939 e_border_show(child);
3941 eina_list_free(list);
3944 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
3945 ev = E_NEW(E_Event_Border_Stick, 1);
3947 e_object_ref(E_OBJECT(bd));
3948 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
3949 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
3950 e_remember_update(bd);
3954 e_border_unstick(E_Border *bd)
3956 E_Event_Border_Unstick *ev;
3959 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3960 /* Set the desk before we unstick the border */
3961 if (!bd->sticky) return;
3963 e_hints_window_sticky_set(bd, 0);
3965 if (e_config->transient.desktop)
3969 Eina_List *list = _e_border_sub_borders_new(bd);
3971 EINA_LIST_FOREACH(list, l, child)
3974 e_hints_window_sticky_set(child, 0);
3976 eina_list_free(list);
3979 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
3980 ev = E_NEW(E_Event_Border_Unstick, 1);
3982 e_object_ref(E_OBJECT(bd));
3983 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
3984 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
3986 e_border_desk_set(bd, e_desk_current_get(bd->zone));
3987 e_remember_update(bd);
3991 e_border_pinned_set(E_Border *bd,
3999 bd->borderless = set;
4000 bd->user_skip_winlist = set;
4004 stacking = E_STACKING_BELOW;
4009 stacking = E_STACKING_NONE;
4012 e_border_layer_set(bd, layer);
4013 e_hints_window_stacking_set(bd, stacking);
4015 bd->client.border.changed = 1;
4021 e_border_find_by_client_window(Ecore_X_Window win)
4025 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4026 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4027 (bd->client.win == win))
4033 e_border_find_all_by_client_window(Ecore_X_Window win)
4037 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4038 if ((bd) && (bd->client.win == win))
4044 e_border_find_by_frame_window(Ecore_X_Window win)
4048 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4049 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4050 (bd->bg_win == win))
4056 e_border_find_by_window(Ecore_X_Window win)
4060 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
4061 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4068 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
4073 EINA_LIST_FOREACH(borders, l, bd)
4075 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
4076 (bd->client.netwm.sync.alarm == al))
4083 e_border_focused_get(void)
4089 _e_border_shape_input_rectangle_set(E_Border* bd)
4093 if ((bd->visible) && (bd->shaped_input))
4095 Ecore_X_Rectangle rects[4];
4096 Ecore_X_Window twin, twin2;
4099 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
4100 0, 0, bd->w, bd->h);
4103 rects[0].width = bd->w;
4104 rects[0].height = bd->client_inset.t;
4106 rects[1].y = bd->client_inset.t;
4107 rects[1].width = bd->client_inset.l;
4108 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4109 rects[2].x = bd->w - bd->client_inset.r;
4110 rects[2].y = bd->client_inset.t;
4111 rects[2].width = bd->client_inset.r;
4112 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
4114 rects[3].y = bd->h - bd->client_inset.b;
4115 rects[3].width = bd->w;
4116 rects[3].height = bd->client_inset.b;
4117 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
4119 twin2 = ecore_x_window_override_new
4120 (bd->zone->container->scratch_win, 0, 0,
4121 bd->w - bd->client_inset.l - bd->client_inset.r,
4122 bd->h - bd->client_inset.t - bd->client_inset.b);
4125 if ((bd->shading) || (bd->shaded))
4127 if (bd->shade.dir == E_DIRECTION_UP)
4128 y = bd->h - bd->client_inset.t - bd->client_inset.b -
4130 else if (bd->shade.dir == E_DIRECTION_LEFT)
4131 x = bd->w - bd->client_inset.l - bd->client_inset.r -
4134 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
4136 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
4137 bd->w - bd->client_inset.l - bd->client_inset.r,
4138 bd->h - bd->client_inset.t - bd->client_inset.b);
4139 ecore_x_window_shape_input_window_add_xy(twin, twin2,
4141 bd->client_inset.t);
4142 ecore_x_window_shape_input_window_set(bd->win, twin);
4143 ecore_x_window_free(twin2);
4144 ecore_x_window_free(twin);
4148 if (bd->visible) // not shaped input
4150 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4151 ecore_x_composite_window_events_enable(bd->win);
4153 ecore_x_composite_window_events_disable(bd->win);
4157 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4158 ecore_x_composite_window_events_enable(bd->win);
4160 ecore_x_composite_window_events_disable(bd->win);
4166 e_border_idler_before(void)
4175 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4177 EINA_LIST_FOREACH(man->containers, cl, con)
4182 // pass 1 - eval0. fetch properties on new or on change and
4183 // call hooks to decide what to do - maybe move/resize
4184 bl = e_container_border_list_last(con);
4185 while ((bd = e_container_border_list_prev(bl)))
4187 if (bd->changed) _e_border_eval0(bd);
4189 e_container_border_list_free(bl);
4191 // layout hook - this is where a hook gets to figure out what to
4193 _e_border_container_layout_hook(con);
4195 // pass 2 - show windows needing show
4196 bl = e_container_border_list_last(con);
4197 while ((bd = e_container_border_list_prev(bl)))
4199 if ((bd->changes.visible) && (bd->visible) &&
4200 (!bd->new_client) && (!bd->changes.pos) &&
4201 (!bd->changes.size))
4204 bd->changes.visible = 0;
4207 e_container_border_list_free(bl);
4209 // pass 3 - hide windows needing hide and eval (main eval)
4210 bl = e_container_border_list_first(con);
4211 while ((bd = e_container_border_list_next(bl)))
4213 if (e_object_is_del(E_OBJECT(bd))) continue;
4215 if ((bd->changes.visible) && (!bd->visible))
4218 bd->changes.visible = 0;
4221 if (bd->changed) _e_border_eval(bd);
4223 if ((bd->changes.visible) && (bd->visible))
4226 bd->changes.visible = 0;
4229 e_container_border_list_free(bl);
4235 E_Border *bd = NULL, *bd2;
4237 EINA_LIST_FREE(focus_next, bd2)
4238 if ((!bd) && (bd2->visible)) bd = bd2;
4242 /* TODO revert focus when lost here ? */
4248 /* already focused. but anyway dont be so strict, this
4249 fcks up illume setting focus on internal windows */
4254 focus_time = ecore_x_current_time_get();
4258 if ((bd->client.icccm.take_focus) &&
4259 (bd->client.icccm.accepts_focus))
4261 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4262 /* TODO what if the client didn't take focus ? */
4264 else if (!bd->client.icccm.accepts_focus)
4266 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4268 else if (!bd->client.icccm.take_focus)
4270 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4271 /* e_border_focus_set(bd, 1, 0); */
4275 #ifdef _F_ZONE_WINDOW_ROTATION_
4276 if ((e_config->wm_win_rotation) &&
4279 Ecore_X_Event_Client_Message *msg = NULL;
4281 EINA_LIST_FREE(rot.msgs, msg)
4283 t = msg->message_type;
4284 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4286 if ((rot.vkbd_ctrl_win) &&
4287 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4290 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4291 if (rot.vkbd_show_prepare_timer)
4292 _e_border_vkbd_show(rot.vkbd);
4294 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4297 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4299 if ((rot.vkbd_ctrl_win) &&
4300 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4303 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4304 if (rot.vkbd_hide_prepare_timer)
4306 _e_border_vkbd_hide(rot.vkbd);
4307 rot.vkbd_hide_prepare_timer = NULL;
4308 e_object_unref(E_OBJECT(rot.vkbd));
4311 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4314 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4316 rot.vkbd_ctrl_win = msg->data.l[0];
4317 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4319 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4321 if ((rot.vkbd_ctrl_win) &&
4322 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4324 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4325 E_Manager *m = e_manager_current_get();
4326 E_Zone *zone = NULL;
4327 if (m) zone = e_util_zone_current_get(m);
4328 if ((zone) && (rot.wait_prepare_done))
4332 _e_border_rotation_change_request(zone);
4333 if (rot.prepare_timer)
4334 ecore_timer_del(rot.prepare_timer);
4335 rot.prepare_timer = NULL;
4336 rot.wait_prepare_done = EINA_FALSE;
4345 rot.fetch = EINA_FALSE;
4351 e_border_client_list(void)
4353 /* FIXME: This should be a somewhat ordered list */
4357 static Ecore_X_Window action_input_win = 0;
4358 static E_Border *action_border = NULL;
4359 static Ecore_Event_Handler *action_handler_key = NULL;
4360 static Ecore_Event_Handler *action_handler_mouse = NULL;
4361 static Ecore_Timer *action_timer = NULL;
4362 static Ecore_X_Rectangle action_orig;
4365 _e_border_show(E_Border *bd)
4370 ecore_evas_show(bd->bg_ecore_evas);
4378 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4380 _e_border_shape_input_rectangle_set(bd);
4382 // ecore_x_composite_window_events_enable(bd->win);
4383 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4386 ecore_x_window_show(bd->win);
4388 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4389 ecore_x_window_show(tmp->win);
4393 _e_border_hide(E_Border *bd)
4398 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4400 ecore_x_window_hide(bd->win);
4401 ecore_evas_hide(bd->bg_ecore_evas);
4403 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4404 ecore_x_window_hide(tmp->win);
4408 ecore_x_composite_window_events_disable(bd->win);
4409 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4414 _e_border_action_input_win_del(void)
4416 if (!action_input_win)
4419 e_grabinput_release(action_input_win, action_input_win);
4420 ecore_x_window_free(action_input_win);
4421 action_input_win = 0;
4426 _e_border_action_input_win_new(E_Border *bd)
4428 if (!action_input_win)
4430 Ecore_X_Window parent = bd->zone->container->win;
4431 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4432 if (!action_input_win)
4436 ecore_x_window_show(action_input_win);
4437 if (e_grabinput_get(action_input_win, 0, action_input_win))
4440 _e_border_action_input_win_del();
4445 _e_border_action_finish(void)
4447 _e_border_action_input_win_del();
4451 ecore_timer_del(action_timer);
4452 action_timer = NULL;
4455 if (action_handler_key)
4457 ecore_event_handler_del(action_handler_key);
4458 action_handler_key = NULL;
4461 if (action_handler_mouse)
4463 ecore_event_handler_del(action_handler_mouse);
4464 action_handler_mouse = NULL;
4467 action_border = NULL;
4471 _e_border_action_init(E_Border *bd)
4473 action_orig.x = bd->x;
4474 action_orig.y = bd->y;
4475 action_orig.width = bd->w;
4476 action_orig.height = bd->h;
4482 _e_border_action_restore_orig(E_Border *bd)
4484 if (action_border != bd)
4487 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4491 _e_border_key_down_modifier_apply(int modifier,
4494 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4496 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4509 _e_border_action_move_timeout(void *data __UNUSED__)
4511 _e_border_move_end(action_border);
4512 _e_border_action_finish();
4513 return ECORE_CALLBACK_CANCEL;
4517 _e_border_action_move_timeout_add(void)
4520 ecore_timer_del(action_timer);
4521 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4525 _e_border_move_key_down(void *data __UNUSED__,
4526 int type __UNUSED__,
4529 Ecore_Event_Key *ev = event;
4532 if (ev->event_window != action_input_win)
4533 return ECORE_CALLBACK_PASS_ON;
4536 fputs("ERROR: no action_border!\n", stderr);
4540 x = action_border->x;
4541 y = action_border->y;
4543 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4544 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4545 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4546 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4547 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4548 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4549 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4550 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4551 else if (strcmp(ev->key, "Return") == 0)
4553 else if (strcmp(ev->key, "Escape") == 0)
4555 _e_border_action_restore_orig(action_border);
4558 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4559 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4562 e_border_move(action_border, x, y);
4563 _e_border_action_move_timeout_add();
4565 return ECORE_CALLBACK_PASS_ON;
4568 _e_border_move_end(action_border);
4569 _e_border_action_finish();
4570 return ECORE_CALLBACK_DONE;
4574 _e_border_move_mouse_down(void *data __UNUSED__,
4575 int type __UNUSED__,
4578 Ecore_Event_Mouse_Button *ev = event;
4580 if (ev->event_window != action_input_win)
4581 return ECORE_CALLBACK_PASS_ON;
4584 fputs("ERROR: no action_border!\n", stderr);
4586 _e_border_move_end(action_border);
4587 _e_border_action_finish();
4588 return ECORE_CALLBACK_DONE;
4592 e_border_act_move_keyboard(E_Border *bd)
4597 if (!_e_border_move_begin(bd))
4600 if (!_e_border_action_input_win_new(bd))
4602 _e_border_move_end(bd);
4606 _e_border_action_init(bd);
4607 _e_border_action_move_timeout_add();
4608 _e_border_move_update(bd);
4610 if (action_handler_key)
4611 ecore_event_handler_del(action_handler_key);
4612 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4614 if (action_handler_mouse)
4615 ecore_event_handler_del(action_handler_mouse);
4616 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4620 _e_border_action_resize_timeout(void *data __UNUSED__)
4622 _e_border_resize_end(action_border);
4623 _e_border_action_finish();
4624 return ECORE_CALLBACK_CANCEL;
4628 _e_border_action_resize_timeout_add(void)
4631 ecore_timer_del(action_timer);
4632 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4636 _e_border_resize_key_down(void *data __UNUSED__,
4637 int type __UNUSED__,
4640 Ecore_Event_Key *ev = event;
4643 if (ev->event_window != action_input_win)
4644 return ECORE_CALLBACK_PASS_ON;
4647 fputs("ERROR: no action_border!\n", stderr);
4651 w = action_border->w;
4652 h = action_border->h;
4654 dx = e_config->border_keyboard.resize.dx;
4655 if (dx < action_border->client.icccm.step_w)
4656 dx = action_border->client.icccm.step_w;
4657 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4658 if (dx < action_border->client.icccm.step_w)
4659 dx = action_border->client.icccm.step_w;
4661 dy = e_config->border_keyboard.resize.dy;
4662 if (dy < action_border->client.icccm.step_h)
4663 dy = action_border->client.icccm.step_h;
4664 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4665 if (dy < action_border->client.icccm.step_h)
4666 dy = action_border->client.icccm.step_h;
4668 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4670 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4672 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4674 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4676 else if (strcmp(ev->key, "Return") == 0)
4678 else if (strcmp(ev->key, "Escape") == 0)
4680 _e_border_action_restore_orig(action_border);
4683 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4684 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4687 e_border_resize_limit(action_border, &w, &h);
4688 e_border_resize(action_border, w, h);
4689 _e_border_action_resize_timeout_add();
4691 return ECORE_CALLBACK_PASS_ON;
4694 _e_border_resize_end(action_border);
4695 _e_border_action_finish();
4696 return ECORE_CALLBACK_DONE;
4700 _e_border_resize_mouse_down(void *data __UNUSED__,
4701 int type __UNUSED__,
4704 Ecore_Event_Mouse_Button *ev = event;
4706 if (ev->event_window != action_input_win)
4707 return ECORE_CALLBACK_PASS_ON;
4710 fputs("ERROR: no action_border!\n", stderr);
4712 _e_border_resize_end(action_border);
4713 _e_border_action_finish();
4714 return ECORE_CALLBACK_DONE;
4718 e_border_act_resize_keyboard(E_Border *bd)
4723 if (!_e_border_resize_begin(bd))
4726 if (!_e_border_action_input_win_new(bd))
4728 _e_border_resize_end(bd);
4732 _e_border_action_init(bd);
4733 _e_border_action_resize_timeout_add();
4734 _e_border_resize_update(bd);
4736 if (action_handler_key)
4737 ecore_event_handler_del(action_handler_key);
4738 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4740 if (action_handler_mouse)
4741 ecore_event_handler_del(action_handler_mouse);
4742 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4746 e_border_act_move_begin(E_Border *bd,
4747 Ecore_Event_Mouse_Button *ev)
4750 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4751 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4752 if (!_e_border_move_begin(bd))
4755 e_zone_edge_disable();
4757 _e_border_pointer_move_begin(bd);
4762 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4763 _e_border_moveinfo_gather(bd, source);
4768 e_border_act_move_end(E_Border *bd,
4769 Ecore_Event_Mouse_Button *ev __UNUSED__)
4772 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4773 if (!bd->moving) return;
4775 _e_border_pointer_move_end(bd);
4776 e_zone_edge_enable();
4777 _e_border_move_end(bd);
4778 e_zone_flip_coords_handle(bd->zone, -1, -1);
4782 e_border_act_resize_begin(E_Border *bd,
4783 Ecore_Event_Mouse_Button *ev)
4786 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4787 if (bd->lock_user_size) return;
4788 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4789 if (!_e_border_resize_begin(bd))
4791 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4793 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4795 bd->resize_mode = RESIZE_TL;
4796 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4800 bd->resize_mode = RESIZE_BL;
4801 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4806 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4808 bd->resize_mode = RESIZE_TR;
4809 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4813 bd->resize_mode = RESIZE_BR;
4814 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4817 _e_border_pointer_resize_begin(bd);
4822 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4823 _e_border_moveinfo_gather(bd, source);
4828 e_border_act_resize_end(E_Border *bd,
4829 Ecore_Event_Mouse_Button *ev __UNUSED__)
4832 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4833 if (bd->resize_mode != RESIZE_NONE)
4835 _e_border_pointer_resize_end(bd);
4836 bd->resize_mode = RESIZE_NONE;
4837 _e_border_resize_end(bd);
4838 bd->changes.reset_gravity = 1;
4844 e_border_act_menu_begin(E_Border *bd,
4845 Ecore_Event_Mouse_Button *ev,
4849 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4852 e_int_border_menu_show(bd,
4853 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4854 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4861 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4862 e_int_border_menu_show(bd, x, y, key, 0);
4867 e_border_act_close_begin(E_Border *bd)
4870 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4871 if (bd->lock_close) return;
4872 if (bd->client.icccm.delete_request)
4874 bd->delete_requested = 1;
4875 ecore_x_window_delete_request_send(bd->client.win);
4876 if (bd->client.netwm.ping)
4879 else if (e_config->kill_if_close_not_possible)
4881 e_border_act_kill_begin(bd);
4886 e_border_act_kill_begin(E_Border *bd)
4889 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4890 if (bd->internal) return;
4891 if (bd->lock_close) return;
4892 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4894 kill(bd->client.netwm.pid, SIGINT);
4895 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4896 _e_border_cb_kill_timer, bd);
4900 if (!bd->internal) ecore_x_kill(bd->client.win);
4905 e_border_icon_add(E_Border *bd,
4910 E_OBJECT_CHECK_RETURN(bd, NULL);
4911 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4916 if (!bd->internal_icon)
4918 o = e_icon_add(evas);
4919 e_util_icon_theme_set(o, "enlightenment");
4923 if (!bd->internal_icon_key)
4927 ext = strrchr(bd->internal_icon, '.');
4928 if ((ext) && ((!strcmp(ext, ".edj"))))
4930 o = edje_object_add(evas);
4931 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4932 e_util_icon_theme_set(o, "enlightenment");
4936 o = e_icon_add(evas);
4937 e_icon_file_set(o, bd->internal_icon);
4941 o = e_icon_add(evas);
4942 if (!e_util_icon_theme_set(o, bd->internal_icon))
4943 e_util_icon_theme_set(o, "enlightenment");
4948 o = edje_object_add(evas);
4949 edje_object_file_set(o, bd->internal_icon,
4950 bd->internal_icon_key);
4955 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
4957 if (bd->client.netwm.icons)
4959 o = e_icon_add(evas);
4960 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4961 bd->client.netwm.icons[0].width,
4962 bd->client.netwm.icons[0].height);
4963 e_icon_alpha_set(o, 1);
4969 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
4971 o = e_icon_add(evas);
4974 e_icon_fdo_icon_set(o, bd->desktop->icon);
4978 else if (bd->client.netwm.icons)
4980 o = e_icon_add(evas);
4981 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4982 bd->client.netwm.icons[0].width,
4983 bd->client.netwm.icons[0].height);
4984 e_icon_alpha_set(o, 1);
4989 o = e_icon_add(evas);
4990 e_util_icon_theme_set(o, "unknown");
4995 e_border_button_bindings_ungrab_all(void)
5000 EINA_LIST_FOREACH(borders, l, bd)
5002 e_focus_setdown(bd);
5003 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5004 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5009 e_border_button_bindings_grab_all(void)
5014 EINA_LIST_FOREACH(borders, l, bd)
5016 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5017 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
5023 e_border_focus_stack_get(void)
5029 e_border_raise_stack_get(void)
5035 e_border_lost_windows_get(E_Zone *zone)
5037 Eina_List *list = NULL, *l;
5039 int loss_overlap = 5;
5041 E_OBJECT_CHECK_RETURN(zone, NULL);
5042 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
5043 EINA_LIST_FOREACH(borders, l, bd)
5048 if ((bd->zone != zone) ||
5049 (bd->zone->container != zone->container))
5052 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
5053 bd->zone->y + loss_overlap,
5054 bd->zone->w - (2 * loss_overlap),
5055 bd->zone->h - (2 * loss_overlap),
5056 bd->x, bd->y, bd->w, bd->h))
5058 list = eina_list_append(list, bd);
5060 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
5061 bd->zone->w, bd->zone->h,
5062 bd->x, bd->y, bd->w, bd->h)) &&
5065 Ecore_X_Rectangle *rect;
5068 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
5074 for (i = 0; i < num; i++)
5076 if (E_INTERSECTS(bd->zone->x + loss_overlap,
5077 bd->zone->y + loss_overlap,
5078 bd->zone->w - (2 * loss_overlap),
5079 bd->zone->h - (2 * loss_overlap),
5080 rect[i].x, rect[i].y,
5081 (int)rect[i].width, (int)rect[i].height))
5089 list = eina_list_append(list, bd);
5097 e_border_ping(E_Border *bd)
5100 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5101 if (!e_config->ping_clients) return;
5103 ecore_x_netwm_ping_send(bd->client.win);
5104 bd->ping = ecore_loop_time_get();
5105 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
5106 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
5107 e_config->ping_clients_interval,
5108 _e_border_cb_ping_poller, bd);
5112 e_border_move_cancel(void)
5116 if (bdmove->cur_mouse_action)
5121 e_object_ref(E_OBJECT(bd));
5122 if (bd->cur_mouse_action->func.end_mouse)
5123 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5124 else if (bd->cur_mouse_action->func.end)
5125 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5126 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5127 bd->cur_mouse_action = NULL;
5128 e_object_unref(E_OBJECT(bd));
5131 _e_border_move_end(bdmove);
5136 e_border_resize_cancel(void)
5140 if (bdresize->cur_mouse_action)
5145 e_object_ref(E_OBJECT(bd));
5146 if (bd->cur_mouse_action->func.end_mouse)
5147 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5148 else if (bd->cur_mouse_action->func.end)
5149 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5150 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5151 bd->cur_mouse_action = NULL;
5152 e_object_unref(E_OBJECT(bd));
5156 bdresize->resize_mode = RESIZE_NONE;
5157 _e_border_resize_end(bdresize);
5163 e_border_frame_recalc(E_Border *bd)
5165 if (!bd->bg_object) return;
5167 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5168 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5170 _e_border_client_inset_calc(bd);
5172 bd->w += (bd->client_inset.l + bd->client_inset.r);
5173 bd->h += (bd->client_inset.t + bd->client_inset.b);
5176 bd->changes.size = 1;
5177 if ((bd->shaped) || (bd->client.shaped))
5179 bd->need_shape_merge = 1;
5180 bd->need_shape_export = 1;
5182 if (bd->shaped_input)
5184 bd->need_shape_merge = 1;
5186 _e_border_client_move_resize_send(bd);
5190 e_border_immortal_windows_get(void)
5192 Eina_List *list = NULL, *l;
5195 EINA_LIST_FOREACH(borders, l, bd)
5198 list = eina_list_append(list, bd);
5204 e_border_name_get(const E_Border *bd)
5206 E_OBJECT_CHECK_RETURN(bd, "");
5207 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5208 if (bd->client.netwm.name)
5209 return bd->client.netwm.name;
5210 else if (bd->client.icccm.title)
5211 return bd->client.icccm.title;
5216 e_border_signal_move_begin(E_Border *bd,
5218 const char *src __UNUSED__)
5221 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5223 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5224 if (!_e_border_move_begin(bd)) return;
5226 _e_border_pointer_move_begin(bd);
5227 e_zone_edge_disable();
5228 _e_border_moveinfo_gather(bd, sig);
5229 if (bd->cur_mouse_action)
5231 if ((!bd->cur_mouse_action->func.end_mouse) &&
5232 (!bd->cur_mouse_action->func.end))
5233 bd->cur_mouse_action = NULL;
5235 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5237 bd->cur_mouse_action = e_action_find("window_move");
5238 if (bd->cur_mouse_action)
5239 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5243 e_border_signal_move_end(E_Border *bd,
5244 const char *sig __UNUSED__,
5245 const char *src __UNUSED__)
5248 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5249 if (!bd->moving) return;
5251 _e_border_pointer_move_end(bd);
5252 e_zone_edge_enable();
5253 _e_border_move_end(bd);
5254 e_zone_flip_coords_handle(bd->zone, -1, -1);
5258 e_border_resizing_get(E_Border *bd)
5260 E_OBJECT_CHECK_RETURN(bd, 0);
5261 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5262 if (bd->resize_mode == RESIZE_NONE) return 0;
5267 e_border_signal_resize_begin(E_Border *bd,
5270 const char *src __UNUSED__)
5272 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5273 int resize_mode = RESIZE_BR;
5276 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5278 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5279 if (!_e_border_resize_begin(bd))
5281 if (!strcmp(dir, "tl"))
5283 resize_mode = RESIZE_TL;
5284 grav = ECORE_X_GRAVITY_SE;
5286 else if (!strcmp(dir, "t"))
5288 resize_mode = RESIZE_T;
5289 grav = ECORE_X_GRAVITY_S;
5291 else if (!strcmp(dir, "tr"))
5293 resize_mode = RESIZE_TR;
5294 grav = ECORE_X_GRAVITY_SW;
5296 else if (!strcmp(dir, "r"))
5298 resize_mode = RESIZE_R;
5299 grav = ECORE_X_GRAVITY_W;
5301 else if (!strcmp(dir, "br"))
5303 resize_mode = RESIZE_BR;
5304 grav = ECORE_X_GRAVITY_NW;
5306 else if (!strcmp(dir, "b"))
5308 resize_mode = RESIZE_B;
5309 grav = ECORE_X_GRAVITY_N;
5311 else if (!strcmp(dir, "bl"))
5313 resize_mode = RESIZE_BL;
5314 grav = ECORE_X_GRAVITY_NE;
5316 else if (!strcmp(dir, "l"))
5318 resize_mode = RESIZE_L;
5319 grav = ECORE_X_GRAVITY_E;
5321 bd->resize_mode = resize_mode;
5322 _e_border_pointer_resize_begin(bd);
5323 _e_border_moveinfo_gather(bd, sig);
5325 if (bd->cur_mouse_action)
5327 if ((!bd->cur_mouse_action->func.end_mouse) &&
5328 (!bd->cur_mouse_action->func.end))
5329 bd->cur_mouse_action = NULL;
5331 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5333 bd->cur_mouse_action = e_action_find("window_resize");
5334 if (bd->cur_mouse_action)
5335 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5339 e_border_signal_resize_end(E_Border *bd,
5340 const char *dir __UNUSED__,
5341 const char *sig __UNUSED__,
5342 const char *src __UNUSED__)
5345 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5346 if (bd->resize_mode == RESIZE_NONE) return;
5347 _e_border_resize_handle(bd);
5348 _e_border_pointer_resize_end(bd);
5349 bd->resize_mode = RESIZE_NONE;
5350 _e_border_resize_end(bd);
5351 bd->changes.reset_gravity = 1;
5356 e_border_resize_limit(E_Border *bd,
5363 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5364 *w -= bd->client_inset.l + bd->client_inset.r;
5365 *h -= bd->client_inset.t + bd->client_inset.b;
5368 if ((bd->client.icccm.base_w >= 0) &&
5369 (bd->client.icccm.base_h >= 0))
5373 tw = *w - bd->client.icccm.base_w;
5374 th = *h - bd->client.icccm.base_h;
5377 a = (double)(tw) / (double)(th);
5378 if ((bd->client.icccm.min_aspect != 0.0) &&
5379 (a < bd->client.icccm.min_aspect))
5381 th = tw / bd->client.icccm.max_aspect;
5382 *h = th + bd->client.icccm.base_h;
5384 else if ((bd->client.icccm.max_aspect != 0.0) &&
5385 (a > bd->client.icccm.max_aspect))
5387 tw = th * bd->client.icccm.max_aspect;
5388 *w = tw + bd->client.icccm.base_w;
5393 a = (double)*w / (double)*h;
5394 if ((bd->client.icccm.min_aspect != 0.0) &&
5395 (a < bd->client.icccm.min_aspect))
5396 *h = *w / bd->client.icccm.min_aspect;
5397 else if ((bd->client.icccm.max_aspect != 0.0) &&
5398 (a > bd->client.icccm.max_aspect))
5399 *w = *h * bd->client.icccm.max_aspect;
5401 if (bd->client.icccm.step_w > 0)
5403 if (bd->client.icccm.base_w >= 0)
5404 *w = bd->client.icccm.base_w +
5405 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5406 bd->client.icccm.step_w);
5408 *w = bd->client.icccm.min_w +
5409 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5410 bd->client.icccm.step_w);
5412 if (bd->client.icccm.step_h > 0)
5414 if (bd->client.icccm.base_h >= 0)
5415 *h = bd->client.icccm.base_h +
5416 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5417 bd->client.icccm.step_h);
5419 *h = bd->client.icccm.min_h +
5420 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5421 bd->client.icccm.step_h);
5427 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5428 else if (*w < bd->client.icccm.min_w)
5429 *w = bd->client.icccm.min_w;
5430 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5431 else if (*h < bd->client.icccm.min_h)
5432 *h = bd->client.icccm.min_h;
5434 *w += bd->client_inset.l + bd->client_inset.r;
5435 *h += bd->client_inset.t + bd->client_inset.b;
5438 /* local subsystem functions */
5440 _e_border_free(E_Border *bd)
5442 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5445 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5447 bd->client.e.state.video_parent_border->client.e.state.video_child =
5449 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5452 if (bd->client.e.state.video_child)
5456 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5458 tmp->client.e.state.video_parent_border = NULL;
5463 efreet_desktop_free(bd->desktop);
5468 ecore_idle_enterer_del(bd->post_job);
5469 bd->post_job = NULL;
5473 e_object_del(E_OBJECT(bd->pointer));
5477 _e_border_resize_end(bd);
5479 _e_border_move_end(bd);
5480 /* TODO: Other states to end before dying? */
5482 if (bd->cur_mouse_action)
5484 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5485 bd->cur_mouse_action = NULL;
5488 E_FREE(bd->shape_rects);
5489 bd->shape_rects_num = 0;
5491 if (bd->dangling_ref_check)
5493 ecore_timer_del(bd->dangling_ref_check);
5494 bd->dangling_ref_check = NULL;
5499 ecore_timer_del(bd->kill_timer);
5500 bd->kill_timer = NULL;
5502 if (bd->ping_poller)
5504 ecore_poller_del(bd->ping_poller);
5505 bd->ping_poller = NULL;
5507 E_FREE_LIST(bd->pending_move_resize, free);
5509 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5510 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5512 if (bd->border_locks_dialog)
5514 e_object_del(E_OBJECT(bd->border_locks_dialog));
5515 bd->border_locks_dialog = NULL;
5517 if (bd->border_remember_dialog)
5519 e_object_del(E_OBJECT(bd->border_remember_dialog));
5520 bd->border_remember_dialog = NULL;
5522 if (bd->border_border_dialog)
5524 e_object_del(E_OBJECT(bd->border_border_dialog));
5525 bd->border_border_dialog = NULL;
5527 if (bd->border_prop_dialog)
5529 e_object_del(E_OBJECT(bd->border_prop_dialog));
5530 bd->border_prop_dialog = NULL;
5533 e_int_border_menu_del(bd);
5538 focus_next = eina_list_remove(focus_next, bd);
5540 if ((focused == bd) ||
5541 (e_grabinput_last_focus_win_get() == bd->client.win))
5543 if ((!focus_next) && (!focusing))
5545 e_grabinput_focus(bd->zone->container->bg_win,
5546 E_FOCUS_METHOD_PASSIVE);
5547 e_hints_active_window_set(bd->zone->container->manager, NULL);
5552 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5558 bd->remember = NULL;
5559 e_remember_unuse(rem);
5561 if (!bd->already_unparented)
5563 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5564 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5565 ecore_x_window_save_set_del(bd->client.win);
5566 bd->already_unparented = 1;
5568 if (bd->group) eina_list_free(bd->group);
5569 if (bd->transients) eina_list_free(bd->transients);
5570 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5571 if (bd->client.netwm.icons)
5574 for (i = 0; i < bd->client.netwm.num_icons; i++)
5575 free(bd->client.netwm.icons[i].data);
5576 free(bd->client.netwm.icons);
5578 if (bd->client.netwm.extra_types)
5579 free(bd->client.netwm.extra_types);
5580 if (bd->client.border.name)
5581 eina_stringshare_del(bd->client.border.name);
5583 eina_stringshare_del(bd->bordername);
5584 if (bd->client.icccm.name)
5585 eina_stringshare_del(bd->client.icccm.name);
5586 if (bd->client.icccm.class)
5588 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5589 e_bindings_mapping_change_enable(EINA_TRUE);
5590 eina_stringshare_del(bd->client.icccm.class);
5592 if (bd->client.icccm.title)
5593 eina_stringshare_del(bd->client.icccm.title);
5594 if (bd->client.icccm.icon_name)
5595 eina_stringshare_del(bd->client.icccm.icon_name);
5596 if (bd->client.icccm.machine)
5597 eina_stringshare_del(bd->client.icccm.machine);
5598 if (bd->client.icccm.window_role)
5599 eina_stringshare_del(bd->client.icccm.window_role);
5601 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5605 for (i = 0; i < bd->client.icccm.command.argc; i++)
5606 free(bd->client.icccm.command.argv[i]);
5607 free(bd->client.icccm.command.argv);
5609 if (bd->client.netwm.name)
5610 eina_stringshare_del(bd->client.netwm.name);
5611 if (bd->client.netwm.icon_name)
5612 eina_stringshare_del(bd->client.netwm.icon_name);
5613 e_object_del(E_OBJECT(bd->shape));
5614 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5615 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5616 if (bd->icon_object) evas_object_del(bd->icon_object);
5617 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5618 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5620 if (str) eina_stringshare_del(str);
5622 bd->client.e.state.profiles = NULL;
5623 if (bd->client.e.state.profile)
5624 eina_stringshare_del(bd->client.e.state.profile);
5625 bd->client.e.state.profile = NULL;
5627 #ifdef _F_ZONE_WINDOW_ROTATION_
5628 if (e_config->wm_win_rotation)
5630 bd->client.e.fetch.rot.app_set = 0;
5631 bd->client.e.state.rot.preferred_rot = -1;
5633 if (bd->client.e.state.rot.available_rots)
5634 E_FREE(bd->client.e.state.rot.available_rots);
5636 _e_border_rotation_list_remove(bd);
5637 if ((rot.vkbd) && (rot.vkbd == bd))
5639 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5641 if (rot.vkbd_ctrl_win)
5643 ELB(ELBT_BD, "SET KBD_OFF", 0);
5644 ecore_x_e_virtual_keyboard_state_set
5645 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5648 rot.vkbd_hide_prepare_done = EINA_FALSE;
5649 if (rot.vkbd_hide_prepare_timer)
5650 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5651 rot.vkbd_hide_prepare_timer = NULL;
5652 if (rot.vkbd_hide_timer)
5653 ecore_timer_del(rot.vkbd_hide_timer);
5654 rot.vkbd_hide_timer = NULL;
5656 rot.vkbd_show_prepare_done = EINA_FALSE;
5657 if (rot.vkbd_show_prepare_timer)
5658 ecore_timer_del(rot.vkbd_show_prepare_timer);
5659 rot.vkbd_show_prepare_timer = NULL;
5660 if (rot.vkbd_show_timer)
5661 ecore_timer_del(rot.vkbd_show_timer);
5662 rot.vkbd_show_timer = NULL;
5664 else if ((rot.vkbd_prediction) &&
5665 (rot.vkbd_prediction == bd))
5666 rot.vkbd_prediction = NULL;
5669 evas_object_del(bd->bg_object);
5670 e_canvas_del(bd->bg_ecore_evas);
5671 ecore_evas_free(bd->bg_ecore_evas);
5672 ecore_x_window_free(bd->client.shell_win);
5673 e_focus_setdown(bd);
5674 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5675 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5676 ecore_x_window_free(bd->win);
5678 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5679 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5680 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5681 borders = eina_list_remove(borders, bd);
5682 focus_stack = eina_list_remove(focus_stack, bd);
5683 raise_stack = eina_list_remove(raise_stack, bd);
5685 e_container_border_remove(bd);
5691 _e_border_del_dangling_ref_check(void *data)
5697 printf("EEK EEK border still around 1 second after being deleted!\n");
5698 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5699 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5700 bd->client.icccm.name, bd->client.icccm.class);
5701 // e_object_breadcrumb_debug(E_OBJECT(bd));
5708 _e_border_del(E_Border *bd)
5710 E_Event_Border_Remove *ev;
5713 #ifdef _F_BORDER_HOOK_PATCH_
5714 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5725 focus_next = eina_list_remove(focus_next, bd);
5727 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5729 if ((drag_border) && (drag_border->data == bd))
5731 e_object_del(E_OBJECT(drag_border));
5734 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5736 if (bd->border_locks_dialog)
5738 e_object_del(E_OBJECT(bd->border_locks_dialog));
5739 bd->border_locks_dialog = NULL;
5741 if (bd->border_remember_dialog)
5743 e_object_del(E_OBJECT(bd->border_remember_dialog));
5744 bd->border_remember_dialog = NULL;
5746 if (bd->border_border_dialog)
5748 e_object_del(E_OBJECT(bd->border_border_dialog));
5749 bd->border_border_dialog = NULL;
5751 if (bd->border_prop_dialog)
5753 e_object_del(E_OBJECT(bd->border_prop_dialog));
5754 bd->border_prop_dialog = NULL;
5757 e_int_border_menu_del(bd);
5759 if (bd->raise_timer)
5761 ecore_timer_del(bd->raise_timer);
5762 bd->raise_timer = NULL;
5764 if (!bd->already_unparented)
5766 ecore_x_window_reparent(bd->client.win,
5767 bd->zone->container->manager->root,
5768 bd->x + bd->client_inset.l,
5769 bd->y + bd->client_inset.t);
5770 ecore_x_window_save_set_del(bd->client.win);
5771 bd->already_unparented = 1;
5772 // bd->client.win = 0;
5774 bd->already_unparented = 1;
5776 if ((!bd->new_client) && (!stopping))
5778 ev = E_NEW(E_Event_Border_Remove, 1);
5780 e_object_ref(E_OBJECT(bd));
5781 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5782 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5787 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5788 if (bd->parent->modal == bd)
5790 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5791 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5792 bd->parent->lock_close = 0;
5793 bd->parent->saved.event_mask = 0;
5794 bd->parent->modal = NULL;
5798 EINA_LIST_FREE(bd->transients, child)
5800 child->parent = NULL;
5803 #ifdef _F_DEICONIFY_APPROVE_
5804 bd->client.e.state.deiconify_approve.render_done = 0;
5806 E_Border *ancestor_bd;
5807 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
5808 if ((ancestor_bd) &&
5809 (!e_object_is_del(E_OBJECT(ancestor_bd))))
5811 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
5812 bd->client.e.state.deiconify_approve.ancestor = NULL;
5814 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
5815 (ancestor_bd->client.e.state.deiconify_approve.render_done))
5817 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
5819 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
5820 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
5821 e_border_uniconify(ancestor_bd);
5826 if (bd->client.e.state.deiconify_approve.wait_timer)
5828 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5829 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5832 if (bd->client.e.state.deiconify_approve.req_list)
5834 EINA_LIST_FREE(bd->client.e.state.deiconify_approve.req_list, child)
5836 child->client.e.state.deiconify_approve.render_done = 0;
5837 child->client.e.state.deiconify_approve.ancestor = NULL;
5842 #ifdef _F_ZONE_WINDOW_ROTATION_
5843 if (rot.list) _e_border_rotation_list_remove(bd);
5847 E_Border_Rotation_Info *info = NULL;
5849 EINA_LIST_FOREACH(rot.async_list, l, info)
5852 rot.async_list = eina_list_remove(rot.async_list, info);
5860 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5861 if (bd->leader->modal == bd)
5862 bd->leader->modal = NULL;
5865 EINA_LIST_FREE(bd->group, child)
5867 child->leader = NULL;
5871 #ifdef PRINT_LOTS_OF_DEBUG
5873 _e_border_print(E_Border *bd,
5882 "\tBorderless: %s\n",
5883 bd, bd->client.icccm.name, bd->client.icccm.title,
5884 bd->borderless ? "TRUE" : "FALSE");
5890 _e_border_cb_window_show_request(void *data __UNUSED__,
5891 int ev_type __UNUSED__,
5896 Ecore_X_Event_Window_Show_Request *e;
5899 bd = e_border_find_by_client_window(e->win);
5900 if (!bd) return ECORE_CALLBACK_PASS_ON;
5902 if ((e_config->wm_win_rotation) &&
5903 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
5905 (rot.vkbd_hide_prepare_timer))
5907 con = bd->zone->container;
5908 bd = e_border_new(con, e->win, 0, 0);
5913 if (!bd->lock_client_iconify)
5914 e_border_uniconify(bd);
5918 /* FIXME: make border "urgent" for a bit - it wants attention */
5919 /* e_border_show(bd); */
5920 if (!bd->lock_client_stacking)
5923 return ECORE_CALLBACK_PASS_ON;
5927 _e_border_cb_window_destroy(void *data __UNUSED__,
5928 int ev_type __UNUSED__,
5932 Ecore_X_Event_Window_Destroy *e;
5935 bd = e_border_find_by_client_window(e->win);
5936 if (!bd) return ECORE_CALLBACK_PASS_ON;
5937 ELB(ELBT_BD, "X_WIN_DEL", bd->client.win);
5938 #ifdef _F_ZONE_WINDOW_ROTATION_
5939 if (e_config->wm_win_rotation)
5941 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
5943 ELB(ELBT_BD, "X_DEL_NOTIFY", bd->client.win);
5944 if (!rot.vkbd_hide_prepare_timer)
5946 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
5947 e_border_hide(bd, 0);
5948 if (!rot.vkbd_hide_prepare_timer)
5950 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
5951 e_object_del(E_OBJECT(bd));
5954 return ECORE_CALLBACK_PASS_ON;
5958 e_border_hide(bd, 0);
5959 e_object_del(E_OBJECT(bd));
5960 return ECORE_CALLBACK_PASS_ON;
5964 _e_border_cb_window_hide(void *data __UNUSED__,
5965 int ev_type __UNUSED__,
5968 E_Border *bd = NULL;
5969 Ecore_X_Event_Window_Hide *e;
5972 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
5973 // not interested in hide events from windows other than the window in question
5974 if (e->win != e->event_win)
5976 bd = e_border_find_by_client_window(e->win);
5977 if (!bd) return ECORE_CALLBACK_PASS_ON;
5978 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
5982 (bd->zone->container->manager->root == e->event_win)))
5983 return ECORE_CALLBACK_PASS_ON;
5986 if (!bd) bd = e_border_find_by_client_window(e->win);
5987 // printf(" bd = %p\n", bd);
5990 if (ecore_x_window_visible_get(e->win))
5992 ELB(ELBT_BD, "FORCE UNMAP client window", e->win);
5993 ecore_x_window_hide(e->win);
5995 return ECORE_CALLBACK_PASS_ON;
5998 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
5999 if (bd->ignore_first_unmap > 0)
6001 bd->ignore_first_unmap--;
6002 return ECORE_CALLBACK_PASS_ON;
6004 /* Don't delete hidden or iconified windows */
6005 #ifdef _F_USE_EXTENDED_ICONIFY_
6006 if (bd->await_hide_event > 0)
6008 if ((bd->iconic) || (bd->await_hide_event > 0))
6011 // printf(" Don't delete hidden or iconified windows\n");
6012 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
6013 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
6014 if (bd->await_hide_event > 0)
6016 bd->await_hide_event--;
6020 // printf(" hide really\n");
6021 /* Only hide the border if it is visible */
6022 if (bd->visible) e_border_hide(bd, 1);
6027 // printf(" hide2\n");
6028 #ifdef _F_USE_EXTENDED_ICONIFY_
6036 #ifdef _F_ZONE_WINDOW_ROTATION_
6037 if (e_config->wm_win_rotation)
6039 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD)
6041 ELB(ELBT_BD, "X_UNMAP_NOTIFY", bd->client.win);
6042 if (!rot.vkbd_hide_prepare_timer)
6044 ELB(ELBT_BD, "HIDE VKBD", bd->client.win);
6045 e_border_hide(bd, 0);
6046 if (!rot.vkbd_hide_prepare_timer)
6048 ELB(ELBT_BD, "DEL VKBD", bd->client.win);
6049 e_object_del(E_OBJECT(bd));
6052 return ECORE_CALLBACK_PASS_ON;
6056 e_border_hide(bd, 0);
6057 e_object_del(E_OBJECT(bd));
6059 return ECORE_CALLBACK_PASS_ON;
6063 _e_border_cb_window_reparent(void *data __UNUSED__,
6064 int ev_type __UNUSED__,
6065 void *ev __UNUSED__)
6069 Ecore_X_Event_Window_Reparent *e;
6072 bd = e_border_find_by_client_window(e->win);
6074 if (e->parent == bd->client.shell_win) return 1;
6075 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
6079 e_border_hide(bd, 0);
6080 e_object_del(E_OBJECT(bd));
6082 return ECORE_CALLBACK_PASS_ON;
6086 _e_border_cb_window_configure_request(void *data __UNUSED__,
6087 int ev_type __UNUSED__,
6091 Ecore_X_Event_Window_Configure_Request *e;
6094 bd = e_border_find_by_client_window(e->win);
6097 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6098 if (!e_util_container_window_find(e->win))
6099 ecore_x_window_configure(e->win, e->value_mask,
6100 e->x, e->y, e->w, e->h, e->border,
6101 e->abovewin, e->detail);
6102 return ECORE_CALLBACK_PASS_ON;
6105 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
6106 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
6112 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
6114 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
6116 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6117 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6123 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6124 w = e->w + bd->client_inset.l + bd->client_inset.r;
6125 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6126 h = e->h + bd->client_inset.t + bd->client_inset.b;
6127 if ((!bd->lock_client_location) && (!bd->lock_client_size))
6129 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6131 bd->saved.x = x - bd->zone->x;
6132 bd->saved.y = y - bd->zone->y;
6137 e_border_move_resize(bd, x, y, w, h);
6139 else if (!bd->lock_client_location)
6141 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6143 bd->saved.x = x - bd->zone->x;
6144 bd->saved.y = y - bd->zone->y;
6147 e_border_move(bd, x, y);
6149 else if (!bd->lock_client_size)
6151 if ((bd->shaded) || (bd->shading))
6157 if ((bd->shade.dir == E_DIRECTION_UP) ||
6158 (bd->shade.dir == E_DIRECTION_DOWN))
6160 e_border_resize(bd, w, bd->h);
6165 e_border_resize(bd, bd->w, h);
6171 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6177 e_border_resize(bd, w, h);
6183 if (!bd->lock_client_location)
6185 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
6187 bd->saved.x = x - bd->zone->x;
6188 bd->saved.y = y - bd->zone->y;
6191 e_border_move(bd, x, y);
6195 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
6196 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
6202 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
6203 w = e->w + bd->client_inset.l + bd->client_inset.r;
6204 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
6205 h = e->h + bd->client_inset.t + bd->client_inset.b;
6206 #ifdef _F_ZONE_WINDOW_ROTATION_
6207 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
6209 if (!bd->lock_client_size)
6211 if ((bd->shaded) || (bd->shading))
6217 if ((bd->shade.dir == E_DIRECTION_UP) ||
6218 (bd->shade.dir == E_DIRECTION_DOWN))
6220 e_border_resize(bd, w, bd->h);
6225 e_border_resize(bd, bd->w, h);
6231 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
6236 zx = zy = zw = zh = 0;
6239 * This code does resize and move a window on a
6240 * X configure request into an useful geometry.
6241 * This is really useful for size jumping file dialogs.
6246 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
6248 if (e_config->geometry_auto_resize_limit == 1)
6257 e_border_resize(bd, w, h);
6259 if (e_config->geometry_auto_move == 1)
6261 /* z{x,y,w,h} are only set here; FIXME! */
6264 // move window horizontal if resize to not useful geometry
6265 if (bd->x + bd->w > zx + zw)
6266 rx = zx + zw - bd->w;
6267 else if (bd->x < zx)
6270 // move window vertical if resize to not useful geometry
6271 if (bd->y + bd->h > zy + zh)
6272 ry = zy + zh - bd->h;
6273 else if (bd->y < zy)
6276 e_border_move(bd, rx, ry);
6282 if (!bd->lock_client_stacking)
6284 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6285 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6289 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6291 obd = e_border_find_by_client_window(e->abovewin);
6294 e_border_stack_above(bd, obd);
6298 ecore_x_window_configure(bd->win,
6299 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6300 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6302 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6303 /* FIXME: need to rebuiuld border list from current stacking */
6306 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6308 obd = e_border_find_by_client_window(e->abovewin);
6311 e_border_stack_below(bd, obd);
6315 ecore_x_window_configure(bd->win,
6316 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6317 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6319 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6320 /* FIXME: need to rebuiuld border list from current stacking */
6323 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6327 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6331 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6336 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6338 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6342 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6346 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6350 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6354 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6361 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6362 _e_border_client_move_resize_send(bd);
6363 return ECORE_CALLBACK_PASS_ON;
6367 _e_border_cb_window_resize_request(void *data __UNUSED__,
6368 int ev_type __UNUSED__,
6372 Ecore_X_Event_Window_Resize_Request *e;
6375 bd = e_border_find_by_client_window(e->win);
6378 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6379 ecore_x_window_resize(e->win, e->w, e->h);
6380 return ECORE_CALLBACK_PASS_ON;
6385 w = e->w + bd->client_inset.l + bd->client_inset.r;
6386 h = e->h + bd->client_inset.t + bd->client_inset.b;
6387 if ((bd->shaded) || (bd->shading))
6393 if ((bd->shade.dir == E_DIRECTION_UP) ||
6394 (bd->shade.dir == E_DIRECTION_DOWN))
6396 e_border_resize(bd, w, bd->h);
6401 e_border_resize(bd, bd->w, h);
6406 e_border_resize(bd, w, h);
6409 _e_border_client_move_resize_send(bd);
6410 return ECORE_CALLBACK_PASS_ON;
6414 _e_border_cb_window_gravity(void *data __UNUSED__,
6415 int ev_type __UNUSED__,
6416 void *ev __UNUSED__)
6419 // Ecore_X_Event_Window_Gravity *e;
6422 // bd = e_border_find_by_client_window(e->win);
6423 // if (!bd) return 1;
6428 _e_border_cb_window_stack_request(void *data __UNUSED__,
6429 int ev_type __UNUSED__,
6433 Ecore_X_Event_Window_Stack_Request *e;
6436 bd = e_border_find_by_client_window(e->win);
6439 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6440 if (!e_util_container_window_find(e->win))
6442 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6443 ecore_x_window_raise(e->win);
6444 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6445 ecore_x_window_lower(e->win);
6447 return ECORE_CALLBACK_PASS_ON;
6449 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6451 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6453 return ECORE_CALLBACK_PASS_ON;
6457 _e_border_cb_window_property(void *data __UNUSED__,
6458 int ev_type __UNUSED__,
6462 Ecore_X_Event_Window_Property *e;
6465 bd = e_border_find_by_client_window(e->win);
6466 if (!bd) return ECORE_CALLBACK_PASS_ON;
6467 if (e->atom == ECORE_X_ATOM_WM_NAME)
6469 if ((!bd->client.netwm.name) &&
6470 (!bd->client.netwm.fetch.name))
6472 bd->client.icccm.fetch.title = 1;
6476 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6478 bd->client.netwm.fetch.name = 1;
6481 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6483 bd->client.icccm.fetch.name_class = 1;
6486 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6488 if ((!bd->client.netwm.icon_name) &&
6489 (!bd->client.netwm.fetch.icon_name))
6491 bd->client.icccm.fetch.icon_name = 1;
6495 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6497 bd->client.netwm.fetch.icon_name = 1;
6500 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6502 bd->client.icccm.fetch.machine = 1;
6505 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6507 bd->client.icccm.fetch.protocol = 1;
6510 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6512 bd->client.icccm.fetch.hints = 1;
6515 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6517 bd->client.icccm.fetch.size_pos_hints = 1;
6520 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6523 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6524 (!bd->client.netwm.fetch.type))
6527 bd->client.mwm.fetch.hints = 1;
6533 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6535 bd->client.icccm.fetch.transient_for = 1;
6538 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6540 bd->client.icccm.fetch.client_leader = 1;
6543 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6545 bd->client.icccm.fetch.window_role = 1;
6548 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6550 bd->client.netwm.fetch.icon = 1;
6553 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6555 bd->client.qtopia.fetch.soft_menu = 1;
6558 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6560 bd->client.qtopia.fetch.soft_menus = 1;
6563 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6565 bd->client.vkbd.fetch.state = 1;
6568 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6570 bd->client.vkbd.fetch.vkbd = 1;
6573 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6575 bd->client.illume.conformant.fetch.conformant = 1;
6578 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6580 bd->client.illume.quickpanel.fetch.state = 1;
6583 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6585 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6588 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6590 bd->client.illume.quickpanel.fetch.priority.major = 1;
6593 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6595 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6598 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6600 bd->client.illume.quickpanel.fetch.zone = 1;
6603 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6605 bd->client.illume.drag.fetch.locked = 1;
6608 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6610 bd->client.illume.drag.fetch.drag = 1;
6613 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6615 bd->client.illume.win_state.fetch.state = 1;
6619 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6621 bd->client.netwm.fetch.user_time = 1;
6624 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6626 bd->client.netwm.fetch.strut = 1;
6629 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6631 bd->client.netwm.fetch.strut = 1;
6635 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6637 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6639 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6641 bd->client.e.fetch.video_position = 1;
6644 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6646 bd->client.e.fetch.video_parent = 1;
6649 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6651 bd->client.netwm.fetch.state = 1;
6654 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6655 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6657 bd->client.e.fetch.profile_list = 1;
6661 #ifdef _F_ZONE_WINDOW_ROTATION_
6662 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6664 if (e_config->wm_win_rotation)
6666 bd->client.e.fetch.rot.support = 1;
6670 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6671 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6672 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6673 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6675 if (e_config->wm_win_rotation)
6677 bd->client.e.fetch.rot.geom_hint = 1;
6681 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6683 if (e_config->wm_win_rotation)
6685 bd->client.e.fetch.rot.app_set = 1;
6689 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6691 if (e_config->wm_win_rotation)
6693 bd->client.e.fetch.rot.preferred_rot = 1;
6697 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6699 if (e_config->wm_win_rotation)
6701 bd->client.e.fetch.rot.available_rots = 1;
6707 return ECORE_CALLBACK_PASS_ON;
6711 _e_border_cb_window_colormap(void *data __UNUSED__,
6712 int ev_type __UNUSED__,
6716 Ecore_X_Event_Window_Colormap *e;
6719 bd = e_border_find_by_client_window(e->win);
6720 if (!bd) return ECORE_CALLBACK_PASS_ON;
6721 return ECORE_CALLBACK_PASS_ON;
6725 _e_border_cb_window_shape(void *data __UNUSED__,
6726 int ev_type __UNUSED__,
6730 Ecore_X_Event_Window_Shape *e;
6733 bd = e_border_find_by_client_window(e->win);
6735 if (e->type == ECORE_X_SHAPE_INPUT)
6739 bd->need_shape_merge = 1;
6740 // YYY bd->shaped_input = 1;
6741 bd->changes.shape_input = 1;
6745 return ECORE_CALLBACK_PASS_ON;
6750 bd->changes.shape = 1;
6752 return ECORE_CALLBACK_PASS_ON;
6754 bd = e_border_find_by_window(e->win);
6757 bd->need_shape_export = 1;
6759 return ECORE_CALLBACK_PASS_ON;
6761 bd = e_border_find_by_frame_window(e->win);
6764 bd->need_shape_merge = 1;
6766 return ECORE_CALLBACK_PASS_ON;
6768 return ECORE_CALLBACK_PASS_ON;
6772 _e_border_cb_window_focus_in(void *data __UNUSED__,
6773 int ev_type __UNUSED__,
6777 Ecore_X_Event_Window_Focus_In *e;
6780 bd = e_border_find_by_client_window(e->win);
6781 if (!bd) return ECORE_CALLBACK_PASS_ON;
6782 #ifdef INOUTDEBUG_FOCUS
6787 const char *modes[] = {
6789 "MODE_WHILE_GRABBED",
6793 const char *details[] = {
6797 "DETAIL_NON_LINEAR",
6798 "DETAIL_NON_LINEAR_VIRTUAL",
6800 "DETAIL_POINTER_ROOT",
6801 "DETAIL_DETAIL_NONE"
6805 ct[strlen(ct) - 1] = 0;
6806 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6811 details[e->detail]);
6813 DBG("%s cb focus in %d %d\n",
6814 e_border_name_get(bd),
6815 bd->client.icccm.accepts_focus,
6816 bd->client.icccm.take_focus);
6819 _e_border_pri_raise(bd);
6820 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6822 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6824 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6826 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6829 /* ignore focus in from !take_focus windows, we just gave it em */
6830 /* if (!bd->client.icccm.take_focus)
6831 * return ECORE_CALLBACK_PASS_ON; */
6833 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6834 if (e->time >= focus_time)
6835 e_border_focus_set(bd, 1, 0);
6836 return ECORE_CALLBACK_PASS_ON;
6840 _e_border_cb_window_focus_out(void *data __UNUSED__,
6841 int ev_type __UNUSED__,
6845 Ecore_X_Event_Window_Focus_Out *e;
6848 bd = e_border_find_by_client_window(e->win);
6849 if (!bd) return ECORE_CALLBACK_PASS_ON;
6850 #ifdef INOUTDEBUG_FOCUS
6855 const char *modes[] = {
6857 "MODE_WHILE_GRABBED",
6861 const char *details[] = {
6865 "DETAIL_NON_LINEAR",
6866 "DETAIL_NON_LINEAR_VIRTUAL",
6868 "DETAIL_POINTER_ROOT",
6869 "DETAIL_DETAIL_NONE"
6873 ct[strlen(ct) - 1] = 0;
6874 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6879 details[e->detail]);
6881 DBG("%s cb focus out %d %d",
6882 e_border_name_get(bd),
6883 bd->client.icccm.accepts_focus,
6884 bd->client.icccm.take_focus);
6887 _e_border_pri_norm(bd);
6888 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6890 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6891 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6892 return ECORE_CALLBACK_PASS_ON;
6893 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6894 return ECORE_CALLBACK_PASS_ON;
6896 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6898 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6899 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6900 return ECORE_CALLBACK_PASS_ON;
6901 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6902 return ECORE_CALLBACK_PASS_ON;
6903 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6904 return ECORE_CALLBACK_PASS_ON;
6905 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6906 return ECORE_CALLBACK_PASS_ON;
6908 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6910 /* for firefox/thunderbird (xul) menu walking */
6911 /* NB: why did i disable this before? */
6912 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6913 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6914 return ECORE_CALLBACK_PASS_ON;
6916 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6918 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6919 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6920 return ECORE_CALLBACK_PASS_ON;
6922 e_border_focus_set(bd, 0, 0);
6923 return ECORE_CALLBACK_PASS_ON;
6926 #if _F_BORDER_CLIP_TO_ZONE_
6928 _e_border_shape_input_clip_to_zone(E_Border *bd)
6930 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
6934 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
6935 bd->zone->w, bd->zone->h,
6936 bd->x, bd->y, bd->w, bd->h)))
6939 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
6940 E_RECTS_CLIP_TO_RECT(x, y, w, h,
6941 bd->zone->x, bd->zone->y,
6942 bd->zone->w, bd->zone->h);
6945 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
6946 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
6950 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
6951 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
6954 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
6957 _e_border_cb_client_message(void *data __UNUSED__,
6958 int ev_type __UNUSED__,
6961 Ecore_X_Event_Client_Message *e;
6965 #ifdef _F_DEICONIFY_APPROVE_
6966 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
6968 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
6970 bd = e_border_find_by_client_window(e->win);
6973 if (bd->client.e.state.deiconify_approve.support)
6975 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
6976 bd->client.e.state.deiconify_approve.render_done = 1;
6978 E_Border *ancestor_bd;
6979 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
6982 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
6983 bd->client.e.state.deiconify_approve.ancestor = NULL;
6990 ELBF(ELBT_BD, 0, bd->client.win,
6991 "RECEIVE DEICONIFY_APPROVE.. ancestor:%x", ancestor_bd->client.win);
6993 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
6994 (ancestor_bd->client.e.state.deiconify_approve.render_done))
6996 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
6998 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
6999 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
7000 e_border_uniconify(ancestor_bd);
7004 ELB(ELBT_BD, "Unset DEICONIFY_APPROVE render_done", ancestor_bd->client.win);
7005 ancestor_bd->client.e.state.deiconify_approve.render_done = 0;
7010 return ECORE_CALLBACK_PASS_ON;
7014 #ifdef _F_ZONE_WINDOW_ROTATION_
7015 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7017 bd = e_border_find_by_client_window(e->win);
7020 if (e_config->wm_win_rotation)
7022 Ecore_X_Event_Client_Message *msg = NULL;
7023 Ecore_X_Atom t = e->message_type;
7024 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
7025 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
7026 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
7027 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
7029 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
7030 if (!msg) return ECORE_CALLBACK_PASS_ON;
7033 msg->message_type = e->message_type;
7034 msg->data.l[0] = e->data.l[0];
7035 msg->data.l[1] = e->data.l[1];
7036 msg->data.l[2] = e->data.l[2];
7037 msg->data.l[3] = e->data.l[3];
7038 msg->data.l[4] = e->data.l[4];
7039 rot.msgs = eina_list_append(rot.msgs, msg);
7041 rot.fetch = EINA_TRUE;
7044 return ECORE_CALLBACK_PASS_ON;
7047 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
7049 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
7050 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
7052 if (e_config->wm_win_rotation)
7054 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
7056 _e_border_rotation_list_remove(bd);
7057 if (bd->client.e.state.rot.pending_show)
7059 ELB(ELBT_BD, "SHOW_BD (PEND)", bd->client.win);
7061 bd->client.e.state.rot.pending_show = 0;
7067 return ECORE_CALLBACK_PASS_ON;
7071 _e_border_cb_window_state_request(void *data __UNUSED__,
7072 int ev_type __UNUSED__,
7076 Ecore_X_Event_Window_State_Request *e;
7080 bd = e_border_find_by_client_window(e->win);
7081 if (!bd) return ECORE_CALLBACK_PASS_ON;
7083 for (i = 0; i < 2; i++)
7084 e_hints_window_state_update(bd, e->state[i], e->action);
7086 return ECORE_CALLBACK_PASS_ON;
7090 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
7091 int ev_type __UNUSED__,
7095 Ecore_X_Event_Window_Move_Resize_Request *e;
7098 bd = e_border_find_by_client_window(e->win);
7099 if (!bd) return ECORE_CALLBACK_PASS_ON;
7101 if ((bd->shaded) || (bd->shading) ||
7102 (bd->fullscreen) || (bd->moving) ||
7103 (bd->resize_mode != RESIZE_NONE))
7104 return ECORE_CALLBACK_PASS_ON;
7106 if ((e->button >= 1) && (e->button <= 3))
7108 bd->mouse.last_down[e->button - 1].mx = e->x;
7109 bd->mouse.last_down[e->button - 1].my = e->y;
7110 bd->mouse.last_down[e->button - 1].x = bd->x;
7111 bd->mouse.last_down[e->button - 1].y = bd->y;
7112 bd->mouse.last_down[e->button - 1].w = bd->w;
7113 bd->mouse.last_down[e->button - 1].h = bd->h;
7117 bd->moveinfo.down.x = bd->x;
7118 bd->moveinfo.down.y = bd->y;
7119 bd->moveinfo.down.w = bd->w;
7120 bd->moveinfo.down.h = bd->h;
7122 bd->mouse.current.mx = e->x;
7123 bd->mouse.current.my = e->y;
7124 bd->moveinfo.down.button = e->button;
7125 bd->moveinfo.down.mx = e->x;
7126 bd->moveinfo.down.my = e->y;
7129 if (!bd->lock_user_stacking)
7132 if (e->direction == MOVE)
7134 bd->cur_mouse_action = e_action_find("window_move");
7135 if (bd->cur_mouse_action)
7137 if ((!bd->cur_mouse_action->func.end_mouse) &&
7138 (!bd->cur_mouse_action->func.end))
7139 bd->cur_mouse_action = NULL;
7140 if (bd->cur_mouse_action)
7142 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7143 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7146 return ECORE_CALLBACK_PASS_ON;
7149 if (!_e_border_resize_begin(bd))
7150 return ECORE_CALLBACK_PASS_ON;
7152 switch (e->direction)
7155 bd->resize_mode = RESIZE_TL;
7156 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
7160 bd->resize_mode = RESIZE_T;
7161 GRAV_SET(bd, ECORE_X_GRAVITY_S);
7165 bd->resize_mode = RESIZE_TR;
7166 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
7170 bd->resize_mode = RESIZE_R;
7171 GRAV_SET(bd, ECORE_X_GRAVITY_W);
7175 bd->resize_mode = RESIZE_BR;
7176 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7180 bd->resize_mode = RESIZE_B;
7181 GRAV_SET(bd, ECORE_X_GRAVITY_N);
7185 bd->resize_mode = RESIZE_BL;
7186 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
7190 bd->resize_mode = RESIZE_L;
7191 GRAV_SET(bd, ECORE_X_GRAVITY_E);
7195 return ECORE_CALLBACK_PASS_ON;
7198 bd->cur_mouse_action = e_action_find("window_resize");
7199 if (bd->cur_mouse_action)
7201 if ((!bd->cur_mouse_action->func.end_mouse) &&
7202 (!bd->cur_mouse_action->func.end))
7203 bd->cur_mouse_action = NULL;
7205 if (bd->cur_mouse_action)
7206 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7208 return ECORE_CALLBACK_PASS_ON;
7212 _e_border_cb_desktop_change(void *data __UNUSED__,
7213 int ev_type __UNUSED__,
7217 Ecore_X_Event_Desktop_Change *e;
7220 bd = e_border_find_by_client_window(e->win);
7223 if (e->desk == 0xffffffff)
7225 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
7229 desk = e_desk_at_pos_get(bd->zone, e->desk);
7231 e_border_desk_set(bd, desk);
7236 ecore_x_netwm_desktop_set(e->win, e->desk);
7238 return ECORE_CALLBACK_PASS_ON;
7242 _e_border_cb_sync_alarm(void *data __UNUSED__,
7243 int ev_type __UNUSED__,
7247 Ecore_X_Event_Sync_Alarm *e;
7248 unsigned int serial;
7251 bd = e_border_find_by_alarm(e->alarm);
7252 if (!bd) return ECORE_CALLBACK_PASS_ON;
7254 if (bd->client.netwm.sync.wait)
7255 bd->client.netwm.sync.wait--;
7257 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
7259 E_Border_Pending_Move_Resize *pnd = NULL;
7261 /* skip pending for which we didn't get a reply */
7262 while (bd->pending_move_resize)
7264 pnd = bd->pending_move_resize->data;
7265 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
7267 if (serial == pnd->serial)
7279 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
7280 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7285 bd->changes.size = 1;
7286 bd->changes.pos = 1;
7289 evas_render(bd->bg_evas);
7291 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7292 &bd->mouse.current.mx,
7293 &bd->mouse.current.my);
7295 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7296 _e_border_resize_handle(bd);
7298 return ECORE_CALLBACK_PASS_ON;
7302 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7303 int ev_type __UNUSED__,
7304 void *ev __UNUSED__)
7309 /* mark all borders for desktop/icon updates */
7310 EINA_LIST_FOREACH(borders, l, bd)
7314 efreet_desktop_free(bd->desktop);
7317 bd->changes.icon = 1;
7321 e_init_status_set(_("Desktop files scan done"));
7324 return ECORE_CALLBACK_PASS_ON;
7328 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7329 int ev_type __UNUSED__,
7330 void *ev __UNUSED__)
7335 /* mark all borders for desktop/icon updates */
7336 EINA_LIST_FOREACH(borders, l, bd)
7338 bd->changes.icon = 1;
7341 return ECORE_CALLBACK_PASS_ON;
7345 _e_border_cb_pointer_warp(void *data __UNUSED__,
7346 int ev_type __UNUSED__,
7349 E_Event_Pointer_Warp *e;
7352 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7353 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7354 return ECORE_CALLBACK_PASS_ON;
7358 _e_border_cb_signal_bind(void *data,
7359 Evas_Object *obj __UNUSED__,
7360 const char *emission,
7366 if (e_dnd_active()) return;
7367 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7372 _e_border_cb_mouse_in(void *data,
7373 int type __UNUSED__,
7376 Ecore_X_Event_Mouse_In *ev;
7381 #ifdef INOUTDEBUG_MOUSE
7386 const char *modes[] = {
7388 "MODE_WHILE_GRABBED",
7392 const char *details[] = {
7396 "DETAIL_NON_LINEAR",
7397 "DETAIL_NON_LINEAR_VIRTUAL",
7399 "DETAIL_POINTER_ROOT",
7400 "DETAIL_DETAIL_NONE"
7404 ct[strlen(ct) - 1] = 0;
7405 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7406 ev->win, ev->event_win,
7409 details[ev->detail]);
7412 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7413 if (ev->event_win == bd->win)
7415 e_focus_event_mouse_in(bd);
7418 if ((ev->win != bd->win) &&
7419 (ev->win != bd->event_win) &&
7420 (ev->event_win != bd->win) &&
7421 (ev->event_win != bd->event_win))
7422 return ECORE_CALLBACK_PASS_ON;
7424 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7426 bd->mouse.current.mx = ev->root.x;
7427 bd->mouse.current.my = ev->root.y;
7428 if (!bd->bg_evas_in)
7430 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7431 bd->bg_evas_in = EINA_TRUE;
7433 return ECORE_CALLBACK_PASS_ON;
7437 _e_border_cb_mouse_out(void *data,
7438 int type __UNUSED__,
7441 Ecore_X_Event_Mouse_Out *ev;
7446 #ifdef INOUTDEBUG_MOUSE
7451 const char *modes[] = {
7453 "MODE_WHILE_GRABBED",
7457 const char *details[] = {
7461 "DETAIL_NON_LINEAR",
7462 "DETAIL_NON_LINEAR_VIRTUAL",
7464 "DETAIL_POINTER_ROOT",
7465 "DETAIL_DETAIL_NONE"
7469 ct[strlen(ct) - 1] = 0;
7470 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7471 ev->win, ev->event_win,
7474 details[ev->detail]);
7477 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7478 if (ev->event_win == bd->win)
7481 return ECORE_CALLBACK_PASS_ON;
7482 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7483 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7484 return ECORE_CALLBACK_PASS_ON;
7485 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7486 return ECORE_CALLBACK_PASS_ON;
7487 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7488 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7489 return ECORE_CALLBACK_PASS_ON;
7490 e_focus_event_mouse_out(bd);
7493 if ((ev->win != bd->win) &&
7494 (ev->win != bd->event_win) &&
7495 (ev->event_win != bd->win) &&
7496 (ev->event_win != bd->event_win))
7497 return ECORE_CALLBACK_PASS_ON;
7499 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7501 bd->mouse.current.mx = ev->root.x;
7502 bd->mouse.current.my = ev->root.y;
7505 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7506 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7507 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7509 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7510 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7511 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7512 bd->bg_evas_in = EINA_FALSE;
7515 return ECORE_CALLBACK_PASS_ON;
7519 _e_border_cb_mouse_wheel(void *data,
7520 int type __UNUSED__,
7523 Ecore_Event_Mouse_Wheel *ev;
7528 if ((ev->event_window == bd->win) ||
7529 (ev->event_window == bd->event_win))
7531 bd->mouse.current.mx = ev->root.x;
7532 bd->mouse.current.my = ev->root.y;
7533 if (!bd->cur_mouse_action)
7534 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7537 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7538 return ECORE_CALLBACK_PASS_ON;
7542 _e_border_cb_mouse_down(void *data,
7543 int type __UNUSED__,
7546 Ecore_Event_Mouse_Button *ev;
7551 if ((ev->event_window == bd->win) ||
7552 (ev->event_window == bd->event_win))
7554 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7556 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7557 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7558 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7559 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7560 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7561 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7565 bd->moveinfo.down.x = bd->x + bd->fx.x;
7566 bd->moveinfo.down.y = bd->y + bd->fx.y;
7567 bd->moveinfo.down.w = bd->w;
7568 bd->moveinfo.down.h = bd->h;
7570 bd->mouse.current.mx = ev->root.x;
7571 bd->mouse.current.my = ev->root.y;
7572 if (!bd->cur_mouse_action)
7574 bd->cur_mouse_action =
7575 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7577 if (bd->cur_mouse_action)
7579 if ((!bd->cur_mouse_action->func.end_mouse) &&
7580 (!bd->cur_mouse_action->func.end))
7581 bd->cur_mouse_action = NULL;
7582 if (bd->cur_mouse_action)
7583 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7586 e_focus_event_mouse_down(bd);
7588 if (ev->window != ev->event_window)
7592 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7596 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7598 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7599 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7600 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7601 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7602 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7603 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7607 bd->moveinfo.down.x = bd->x + bd->fx.x;
7608 bd->moveinfo.down.y = bd->y + bd->fx.y;
7609 bd->moveinfo.down.w = bd->w;
7610 bd->moveinfo.down.h = bd->h;
7612 bd->mouse.current.mx = ev->root.x;
7613 bd->mouse.current.my = ev->root.y;
7618 else if (bd->resize_mode != RESIZE_NONE)
7624 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7626 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7627 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7628 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7630 return ECORE_CALLBACK_PASS_ON;
7634 _e_border_cb_mouse_up(void *data,
7635 int type __UNUSED__,
7638 Ecore_Event_Mouse_Button *ev;
7643 if ((ev->event_window == bd->win) ||
7644 (ev->event_window == bd->event_win))
7646 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7648 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7649 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7650 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7651 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7653 bd->mouse.current.mx = ev->root.x;
7654 bd->mouse.current.my = ev->root.y;
7655 /* also we dont pass the same params that went in - then again that */
7656 /* should be ok as we are just ending the action if it has an end */
7657 if (bd->cur_mouse_action)
7659 if (bd->cur_mouse_action->func.end_mouse)
7660 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7661 else if (bd->cur_mouse_action->func.end)
7662 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7663 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7664 bd->cur_mouse_action = NULL;
7668 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7669 e_focus_event_mouse_up(bd);
7672 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7673 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7675 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7676 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7677 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7678 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7680 bd->mouse.current.mx = ev->root.x;
7681 bd->mouse.current.my = ev->root.y;
7685 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7686 return ECORE_CALLBACK_PASS_ON;
7690 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7692 #ifdef _F_BORDER_CLIP_TO_ZONE_
7693 int new_x_max, new_y_max;
7694 int new_x_min, new_y_min;
7695 int margin_x, margin_y;
7697 margin_x = bd->w - 100;
7698 margin_y = bd->h - 100;
7700 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7701 new_x_min = bd->zone->x - margin_x;
7702 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7703 new_y_min = bd->zone->y - margin_y;
7705 if (x >= new_x_max) *new_x = new_x_max;
7706 else if (x <= new_x_min) *new_x = new_x_min;
7708 if (y >= new_y_max) *new_y = new_y_max;
7709 else if (y <= new_y_min) *new_y = new_y_min;
7714 _e_border_cb_mouse_move(void *data,
7715 int type __UNUSED__,
7718 Ecore_Event_Mouse_Move *ev;
7723 if ((ev->window != bd->event_win) &&
7724 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7725 bd->mouse.current.mx = ev->root.x;
7726 bd->mouse.current.my = ev->root.y;
7729 int x, y, new_x, new_y;
7731 Eina_List *skiplist = NULL;
7733 // FIXME: remove? sync what for when only moving?
7734 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7735 bd->client.netwm.sync.wait = 0;
7736 if ((bd->client.netwm.sync.request) &&
7737 (bd->client.netwm.sync.alarm) &&
7738 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7740 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7742 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7743 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7744 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7745 (bd->mouse.current.my - bd->moveinfo.down.my);
7749 x = bd->moveinfo.down.x +
7750 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7751 y = bd->moveinfo.down.y +
7752 (bd->mouse.current.my - bd->moveinfo.down.my);
7757 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7758 skiplist = eina_list_append(skiplist, bd);
7759 e_resist_container_border_position(bd->zone->container, skiplist,
7760 bd->x, bd->y, bd->w, bd->h,
7762 &new_x, &new_y, &new_w, &new_h);
7763 eina_list_free(skiplist);
7765 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7767 /* if (e_config->window_out_of_vscreen_limits_partly) */
7769 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7772 skiplist = eina_list_append(skiplist, bd);
7773 e_resist_container_border_position(bd->zone->container, skiplist,
7774 bd->x, bd->y, bd->w, bd->h,
7776 &new_x, &new_y, &new_w, &new_h);
7777 eina_list_free(skiplist);
7780 bd->shelf_fix.x = 0;
7781 bd->shelf_fix.y = 0;
7782 bd->shelf_fix.modified = 0;
7783 e_border_move(bd, new_x, new_y);
7784 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7786 else if (bd->resize_mode != RESIZE_NONE)
7788 if ((bd->client.netwm.sync.request) &&
7789 (bd->client.netwm.sync.alarm))
7791 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7793 E_Border_Pending_Move_Resize *pnd;
7795 if (bd->pending_move_resize)
7797 bd->changes.pos = 1;
7798 bd->changes.size = 1;
7800 _e_border_client_move_resize_send(bd);
7802 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7805 bd->client.netwm.sync.wait = 0;
7807 /* sync.wait is incremented when resize_handle sends
7808 * sync-request and decremented by sync-alarm cb. so
7809 * we resize here either on initial resize, timeout or
7810 * when no new resize-request was added by sync-alarm cb.
7812 if (!bd->client.netwm.sync.wait)
7813 _e_border_resize_handle(bd);
7816 _e_border_resize_handle(bd);
7822 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7824 bd->drag.x = ev->root.x;
7825 bd->drag.y = ev->root.y;
7831 dx = bd->drag.x - ev->root.x;
7832 dy = bd->drag.y - ev->root.y;
7833 if (((dx * dx) + (dy * dy)) >
7834 (e_config->drag_resist * e_config->drag_resist))
7837 if (bd->icon_object)
7839 Evas_Object *o = NULL;
7840 Evas_Coord x, y, w, h;
7841 const char *drag_types[] = { "enlightenment/border" };
7843 e_object_ref(E_OBJECT(bd));
7844 evas_object_geometry_get(bd->icon_object,
7846 drag_border = e_drag_new(bd->zone->container,
7847 bd->x + bd->fx.x + x,
7848 bd->y + bd->fx.y + y,
7849 drag_types, 1, bd, -1,
7851 _e_border_cb_drag_finished);
7852 o = e_border_icon_add(bd, drag_border->evas);
7855 /* FIXME: fallback icon for drag */
7856 o = evas_object_rectangle_add(drag_border->evas);
7857 evas_object_color_set(o, 255, 255, 255, 255);
7859 e_drag_object_set(drag_border, o);
7861 e_drag_resize(drag_border, w, h);
7862 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7868 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7870 return ECORE_CALLBACK_PASS_ON;
7874 _e_border_cb_grab_replay(void *data __UNUSED__,
7878 Ecore_Event_Mouse_Button *ev;
7880 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7882 if ((e_config->pass_click_on)
7883 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7884 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7889 bd = e_border_find_by_window(ev->event_window);
7892 if (bd->cur_mouse_action)
7893 return ECORE_CALLBACK_DONE;
7894 if (ev->event_window == bd->win)
7896 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7897 E_OBJECT(bd), ev, NULL))
7898 return ECORE_CALLBACK_PASS_ON;
7902 return ECORE_CALLBACK_DONE;
7906 _e_border_cb_drag_finished(E_Drag *drag,
7907 int dropped __UNUSED__)
7912 e_object_unref(E_OBJECT(bd));
7916 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7918 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7919 int ev_type __UNUSED__,
7922 E_Event_Desk_Window_Profile_Change *e;
7927 EINA_LIST_FOREACH(borders, l, bd)
7929 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
7931 bd->client.e.fetch.profile_list = 1;
7935 return ECORE_CALLBACK_PASS_ON;
7939 #ifdef _F_ZONE_WINDOW_ROTATION_
7941 _e_border_cb_zone_rotation_change_begin(void *data __UNUSED__,
7942 int ev_type __UNUSED__,
7945 E_Event_Zone_Rotation_Change_Begin *e = ev;
7947 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7948 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
7950 if (!_e_border_rotation_zone_set(e->zone))
7952 /* there is no border which supports window manager rotation */
7953 e_zone_rotation_update_cancel(e->zone);
7955 return ECORE_CALLBACK_PASS_ON;
7959 _e_border_cb_rotation_sync_job(void *data)
7961 E_Zone *zone = data;
7963 E_Border_Rotation_Info *info = NULL;
7965 ELB(ELBT_ROT, "DO ROTATION SYNC_JOB", zone->id);
7969 EINA_LIST_FOREACH(rot.list, l, info)
7970 _e_border_hook_call(E_BORDER_HOOK_ROTATION_LIST_ADD, info->bd);
7971 if (!rot.wait_prepare_done)
7973 _e_border_rotation_change_request(zone);
7980 ELB(ELBT_ROT, "DEL SYNC_JOB", zone->id);
7981 ecore_job_del(rot.sync_job);
7982 rot.sync_job = NULL;
7987 _e_border_cb_rotation_async_job(void *data)
7989 E_Zone *zone = data;
7991 if (rot.list) goto end;
7993 ELB(ELBT_ROT, "FLUSH ASYNC LIST TO ROT_CHANGE_REQ", zone->id);
7995 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
7996 rot.async_list = NULL;
8002 ELB(ELBT_ROT, "DEL ASYNC_JOB", zone->id);
8003 ecore_job_del(rot.async_job);
8004 rot.async_job = NULL;
8009 _e_border_rotation_change_prepare_timeout(void *data)
8011 E_Zone *zone = data;
8012 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8014 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
8016 if ((zone) && (rot.wait_prepare_done))
8020 _e_border_rotation_change_request(zone);
8021 if (rot.prepare_timer)
8022 ecore_timer_del(rot.prepare_timer);
8023 rot.prepare_timer = NULL;
8024 rot.wait_prepare_done = EINA_FALSE;
8027 return ECORE_CALLBACK_CANCEL;
8031 _e_border_rotation_change_request(E_Zone *zone)
8033 if (!e_config->wm_win_rotation) return;
8034 if (!rot.list) return;
8035 if (eina_list_count(rot.list) <= 0) return;
8036 if (zone->rot.block_count) return;
8038 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8039 rot.prepare_timer = NULL;
8040 rot.wait_prepare_done = EINA_FALSE;
8042 _e_border_rotation_list_flush(rot.list, EINA_FALSE);
8045 ecore_timer_del(rot.done_timer);
8046 ELB(ELBT_ROT, "ADD TIMEOUT ROT_DONE", zone->id);
8047 rot.done_timer = ecore_timer_add(5.0f,
8048 _e_border_rotation_change_done_timeout,
8053 _e_border_rotation_list_flush(Eina_List *list, Eina_Bool flush)
8056 E_Border_Rotation_Info *info =NULL;
8059 EINA_LIST_FOREACH (list, l, info)
8061 if (!info->bd) continue;
8062 if ((info->bd->client.e.state.rot.wait_for_done) &&
8063 (info->bd->client.e.state.rot.wait_done_ang == info->ang)) continue;
8065 _e_border_event_border_rotation_change_begin_send(info->bd);
8068 info->win_resize = _e_border_rotation_pre_resize(info->bd, info->ang, &x, &y, &w, &h);
8069 info->bd->client.e.state.rot.pending_change_request = info->win_resize;
8071 info->x = x; info->y = y;
8072 info->w = w; info->h = h;
8074 ELBF(ELBT_ROT, 1, info->bd->client.win,
8075 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8076 info->ang, info->win_resize, info->w, info->h);
8078 ecore_x_e_window_rotation_change_prepare_send
8079 (info->bd->client.win, info->ang,
8080 info->win_resize, info->w, info->h);
8082 if (!info->bd->client.e.state.rot.pending_change_request)
8084 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8085 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8087 info->bd->client.e.state.rot.wait_for_done = 1;
8088 info->bd->client.e.state.rot.wait_done_ang = info->ang;
8094 EINA_LIST_FREE(list, info)
8100 e_border_rotation_list_clear(E_Zone *zone, Eina_Bool send_request)
8102 E_Border_Rotation_Info *info = NULL;
8104 if (send_request) _e_border_rotation_change_request(zone);
8107 EINA_LIST_FREE(rot.list, info)
8114 _e_border_rotation_list_remove(E_Border *bd)
8116 Eina_List *l = NULL;
8117 E_Border_Rotation_Info *info = NULL;
8118 E_Event_Border_Rotation_Change_End *ev = NULL;
8119 Eina_Bool found = EINA_FALSE;
8121 if (!e_config->wm_win_rotation) return;
8123 EINA_LIST_FOREACH(rot.list, l, info)
8127 rot.list = eina_list_remove(rot.list, info);
8133 if (bd->client.e.state.rot.wait_for_done)
8135 bd->client.e.state.rot.wait_for_done = 0;
8137 /* if we make the border event in the _e_border_free function,
8138 * then we may meet a crash problem, only work this at least e_border_hide.
8140 if (!e_object_is_del(E_OBJECT(bd)))
8142 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
8146 e_object_ref(E_OBJECT(bd));
8147 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_END,
8149 _e_border_event_border_rotation_change_end_free,
8155 (eina_list_count(rot.list) == 0))
8157 _e_border_rotation_change_done();
8163 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
8165 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
8166 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
8167 _e_border_rotation_change_done();
8168 return ECORE_CALLBACK_CANCEL;
8172 _e_border_rotation_change_done(void)
8174 E_Manager *m = NULL;
8175 E_Border_Rotation_Info *info = NULL;
8177 if (!e_config->wm_win_rotation) return;
8179 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8180 rot.prepare_timer = NULL;
8182 rot.wait_prepare_done = EINA_FALSE;
8184 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8185 rot.done_timer = NULL;
8187 EINA_LIST_FREE(rot.list, info)
8191 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
8192 if (info->bd->client.e.state.rot.pending_show)
8194 ELB(ELBT_ROT, "SHOW PEND(TIMEOUT)", info->bd->client.win);
8195 e_border_show(info->bd);
8196 info->bd->client.e.state.rot.pending_show = 0;
8198 info->bd->client.e.state.rot.wait_for_done = 0;
8203 _e_border_rotation_list_flush(rot.async_list, EINA_TRUE);
8206 rot.async_list = NULL;
8208 m = e_manager_current_get();
8209 e_manager_comp_screen_unlock(m);
8210 e_zone_rotation_update_done(e_util_zone_current_get(m));
8214 _prev_angle_get(Ecore_X_Window win)
8216 int ret, count = 0, ang = -1;
8217 unsigned char* data = NULL;
8219 ret = ecore_x_window_prop_property_get
8220 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
8221 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
8223 if ((ret) && (data) && (count))
8224 ang = ((int *)data)[0];
8225 if (data) free(data);
8229 /* get proper rotation value using preferred rotation and list of available rotations */
8231 _e_border_rotation_get(E_Border *bd,
8235 int current_ang = bd->client.e.state.rot.curr;
8237 Eina_Bool found = EINA_FALSE;
8238 Eina_Bool found_curr_ang = EINA_FALSE;
8240 if (!e_config->wm_win_rotation) return ang;
8241 if (!bd->client.e.state.rot.app_set) return ang;
8243 if (bd->client.e.state.rot.preferred_rot != -1)
8245 ang = bd->client.e.state.rot.preferred_rot;
8246 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
8248 else if ((bd->client.e.state.rot.available_rots) &&
8249 (bd->client.e.state.rot.count))
8251 for (i = 0; i < bd->client.e.state.rot.count; i++)
8253 if (bd->client.e.state.rot.available_rots[i] == base_ang)
8259 if (bd->client.e.state.rot.available_rots[i] == current_ang)
8260 found_curr_ang = EINA_TRUE;
8263 /* do nothing. this window wants to maintain current state.
8264 * for example, window's available_rots: 0, 90, 270,
8265 * current zone rotation request: 180. the WM does nothing
8270 if ((bd->client.e.state.rot.curr != -1) && (found_curr_ang))
8271 ang = bd->client.e.state.rot.curr;
8273 ang = bd->client.e.state.rot.available_rots[0];
8278 /* In this case, border doesn't have a list of
8279 * available rotations, thus WM should request
8280 * rotation with '0' degree to the application.
8289 _e_border_rotation_angle_get(E_Border *bd)
8291 E_Zone *zone = bd->zone;
8296 if (!e_config->wm_win_rotation) return ret;
8297 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) return ret;
8299 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
8301 if (bd->parent) will_ang = bd->parent->client.e.state.rot.curr;
8302 else will_ang = zone->rot.curr;
8304 if (bd->client.vkbd.win_type != E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
8306 ELBF(ELBT_ROT, 1, bd->client.win,
8307 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
8308 (rot.vkbd == bd) ? "vkbd" : "prediction",
8309 bd->parent ? bd->parent->client.win : 0,
8310 bd->parent ? bd->parent->client.e.state.rot.support : -1,
8311 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
8312 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
8316 will_ang = bd->parent->client.e.state.rot.curr;
8317 if ((!bd->parent->client.e.state.rot.support) &&
8318 (!bd->parent->client.e.state.rot.app_set))
8325 if ((!bd->client.e.state.rot.app_set) &&
8326 (!bd->client.e.state.rot.support))
8328 /* hack for magnifier and keyboard popup */
8329 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
8330 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
8332 ELB(ELBT_BD, "MAG", bd->client.win);
8334 if ((rot.vkbd) && (rot.vkbd->visible))
8335 will_ang = rot.vkbd->client.e.state.rot.curr;
8339 if (bd->client.e.state.rot.app_set)
8341 /* utility type window should be rotated according to
8342 * rotation of the transient_for window.
8345 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
8347 will_ang = bd->parent->client.e.state.rot.curr;
8348 if ((!bd->parent->client.e.state.rot.support) &&
8349 (!bd->parent->client.e.state.rot.app_set))
8351 /* if transient_for window doesn't support rotation feature,
8352 * then this window should't be rotated.
8353 * TODO: need to check whether window supports '0' degree or not.
8356 ELBF(ELBT_ROT, 0, bd->client.win,
8357 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
8358 will_ang, bd->parent->client.win);
8362 will_ang = _e_border_rotation_get(bd->parent, will_ang);
8363 ELBF(ELBT_ROT, 0, bd->client.win,
8364 "GET ROT ang:%d Transient_For:0x%08x",
8365 will_ang, bd->parent->client.win);
8370 will_ang = _e_border_rotation_get(bd, will_ang);
8371 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8372 will_ang, bd->parent ? bd->parent->client.win : 0,
8373 bd->client.netwm.type);
8379 _ang = _prev_angle_get(bd->client.win);
8381 bd->client.e.state.rot.curr = _ang;
8382 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8385 if (bd->client.e.state.rot.curr != will_ang)
8393 _e_border_rotation_zone_set(E_Zone *zone)
8395 E_Border_List *l = NULL;
8396 E_Border *bd = NULL;
8397 Eina_Bool ret = EINA_FALSE;
8399 if (!e_config->wm_win_rotation) return EINA_FALSE;
8401 l = e_container_border_list_last(zone->container);
8404 /* step 1. make the list needs to be rotated. */
8405 while ((bd = e_container_border_list_prev(l)))
8409 // if this window have parent,
8410 // it will be rotated when parent do rotate itself.
8412 if (bd->parent) continue;
8414 // this type is set by illume.
8415 // if it's not normal type window, will be rotated by illume.
8417 if (bd->client.e.state.rot.type != E_BORDER_ROTATION_TYPE_NORMAL) continue;
8419 if ((!bd->visible) ||
8420 (!E_INTERSECTS(bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h,
8421 bd->x, bd->y, bd->w, bd->h))) continue;
8423 if (_e_border_rotatable_check(bd, zone->rot.curr))
8425 ELBF(ELBT_ROT, 0, bd->client.win, "ROT_SET(main) curr:%d != TOBE:%d",
8426 bd->client.e.state.rot.curr, zone->rot.curr);
8428 ret = e_border_rotation_set(bd, zone->rot.curr);
8431 if (l) e_container_border_list_free(l);
8437 e_border_rotation_set(E_Border *bd, int rotation)
8439 E_Zone *zone = bd->zone;
8440 E_Border_Rotation_Info *info = NULL;
8441 Eina_List *list, *l;
8444 if (rotation < 0) return EINA_FALSE;
8446 /* step 1. check if rotation */
8447 if (!_e_border_rotatable_check(bd, rotation)) return EINA_FALSE;
8449 /* step 2. add to async/sync list */
8450 if ((!zone->rot.block_count) &&
8452 (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))))
8454 // send rotation change request later.
8455 // and no need to wait message of rotation done.
8458 info = E_NEW(E_Border_Rotation_Info, 1);
8459 if (!info) return EINA_FALSE;
8460 ELB(ELBT_ROT, "ADD ASYNC LIST", 0);
8462 info->ang = rotation;
8463 rot.async_list = eina_list_append(rot.async_list, info);
8465 // add job for sending event.
8468 ELB(ELBT_ROT, "ADD ASYNC_JOB", bd->client.win);
8469 rot.async_job = ecore_job_add(_e_border_cb_rotation_async_job, zone);
8475 info = E_NEW(E_Border_Rotation_Info, 1);
8476 if (!info) return EINA_FALSE;
8477 ELB(ELBT_ROT, "ADD SYNC LIST", 0);
8479 info->ang = rotation;
8480 rot.list = eina_list_append(rot.list, info);
8482 // add job for sending event.
8485 ELB(ELBT_ROT, "ADD SYNC_JOB", bd->client.win);
8486 rot.sync_job = ecore_job_add(_e_border_cb_rotation_sync_job, zone);
8489 // if there is windows over 2 that has to be rotated or is existed window needs resizing,
8491 // but, DO NOT lock the screen when rotation block state.
8492 if ((!zone->rot.block_count) &&
8493 ((eina_list_count(rot.list) == 2)))
8494 e_manager_comp_screen_lock(e_manager_current_get());
8497 /* step 3. search rotatable window in this window's child */
8498 list = _e_border_sub_borders_new(bd);
8499 EINA_LIST_FOREACH(list, l, child)
8501 if (_e_border_rotatable_check(child, rotation))
8503 ELBF(ELBT_ROT, 0, child->client.win, "ROT_SET(child) curr:%d != TOBE:%d",
8504 bd->client.e.state.rot.curr, rotation);
8505 e_border_rotation_set(child, rotation);
8509 /* step 4. if there is vkbd window, send message to prepare rotation */
8510 if (_e_border_is_vkbd(bd))
8512 ELB(ELBT_ROT, "PENDING ROT_REQ UNTIL GET PREP_DONE", rot.vkbd_ctrl_win);
8513 if (rot.prepare_timer)
8514 ecore_timer_del(rot.prepare_timer);
8515 rot.prepare_timer = NULL;
8518 ecore_timer_del(rot.done_timer);
8519 rot.done_timer = NULL;
8521 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
8522 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8525 rot.prepare_timer = ecore_timer_add(4.0f,
8526 _e_border_rotation_change_prepare_timeout,
8529 rot.wait_prepare_done = EINA_TRUE;
8532 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8533 bd->client.e.state.rot.curr = rotation;
8538 // check if border is rotatable in ang.
8540 _e_border_rotatable_check(E_Border *bd, int ang)
8542 Eina_Bool ret = EINA_FALSE;
8544 if (!bd) return ret;
8545 if (ang < 0) return ret;
8546 if ((!bd->client.e.state.rot.support) && (!bd->client.e.state.rot.app_set)) return ret;
8547 if (e_object_is_del(E_OBJECT(bd))) return ret;
8549 // same with current angle of window, then false return.
8550 if (ang == bd->client.e.state.rot.curr) return ret;
8552 /* basically WM allows only fullscreen window to rotate */
8553 if (bd->client.e.state.rot.preferred_rot == -1)
8557 if (bd->client.e.state.rot.app_set)
8559 if (bd->client.e.state.rot.available_rots &&
8560 bd->client.e.state.rot.count)
8562 Eina_Bool found = EINA_FALSE;
8563 for (i = 0; i < bd->client.e.state.rot.count; i++)
8565 if (bd->client.e.state.rot.available_rots[i] == ang)
8570 if (found) ret = EINA_TRUE;
8575 ELB(ELBT_ROT, "DO ROT", 0);
8579 // if it has preferred rotation angle,
8580 // it will be rotated at border's evaluation time.
8582 else if (bd->client.e.state.rot.preferred_rot == ang) ret = EINA_TRUE;
8587 /* check whether virtual keyboard is visible on the zone */
8589 _e_border_is_vkbd(E_Border *bd)
8591 if (!e_config->wm_win_rotation) return EINA_FALSE;
8593 if ((rot.vkbd_ctrl_win) &&
8595 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8596 (rot.vkbd->visible) &&
8597 (rot.vkbd->zone == bd->zone) &&
8598 (E_INTERSECTS(bd->zone->x, bd->zone->y,
8599 bd->zone->w, bd->zone->h,
8600 rot.vkbd->x, rot.vkbd->y,
8601 rot.vkbd->w, rot.vkbd->h)))
8609 _e_border_rotation_change_floating_pos(E_Border *bd, int *x, int *y)
8612 int min_title_width=96;
8614 if (!bd) return EINA_FALSE;
8615 if (!x || !y) return EINA_FALSE;
8620 // Portrait -> Landscape, x= pre_x*2, y=pre_y/2
8621 // Landscape -> Portrait, x= pre_x/2, y=pre_y*2
8622 // guaranteeing the minimum size of titlebar shown, min_title_width
8623 // so user can initiate drag&drop action after rotation changed.
8624 if (bd->client.e.state.rot.curr == 0)
8626 if (bd->client.e.state.rot.prev == 90)
8628 new_x = (bd->zone->h - bd->h - bd->y) / 2;
8631 else if (bd->client.e.state.rot.prev == 270)
8634 new_y = (bd->zone->w - bd->w - bd->x) * 2;
8636 else if (bd->client.e.state.rot.prev == 180)
8638 new_x = bd->zone->w - bd->x - bd->w;
8639 new_y = bd->zone->h - bd->y - bd->h;
8642 if(new_x + bd->w < min_title_width)
8644 new_x = min_title_width - bd->w;
8646 else if(new_x > bd->zone->w - min_title_width)
8648 new_x = bd->zone->w - min_title_width;
8651 else if (bd->client.e.state.rot.curr == 90)
8653 if (bd->client.e.state.rot.prev == 0)
8656 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8658 else if (bd->client.e.state.rot.prev == 270)
8660 new_x = bd->zone->w - bd->x - bd->w;
8661 new_y = bd->zone->h - bd->y - bd->h;
8663 else if (bd->client.e.state.rot.prev == 180)
8665 new_x = (bd->zone->h - bd->y - bd->h) / 2;
8666 new_y = bd->zone->h - (2 * (bd->zone->w - bd->x - bd->w)) - bd->w;
8669 if(new_y > bd->zone->h - min_title_width)
8671 new_y = bd->zone->h - min_title_width;
8673 else if(new_y < min_title_width - bd->w)
8675 new_y = min_title_width - bd->w;
8678 else if (bd->client.e.state.rot.curr == 270)
8680 if (bd->client.e.state.rot.prev == 0)
8682 new_x = bd->zone->w - bd->h - (bd->y / 2);
8685 else if (bd->client.e.state.rot.prev == 90)
8687 new_x = bd->zone->w - bd->x - bd->w;
8688 new_y = bd->zone->h - bd->y - bd->h;
8690 else if (bd->client.e.state.rot.prev == 180)
8692 new_x = bd->zone->w - bd->x - bd->w;
8693 new_y = bd->zone->h - bd->y - bd->h;
8695 new_x = bd->zone->w - bd->h - ((bd->zone->h - bd->y - bd->h) / 2);
8696 new_y = (bd->zone->w - bd->x - bd->w) * 2;
8699 if(new_y > bd->zone->h - min_title_width)
8701 new_y = bd->zone->h - min_title_width;
8703 else if( new_y + bd->w < min_title_width)
8705 new_y = min_title_width - bd->w ;
8708 else if (bd->client.e.state.rot.curr == 180)
8710 if (bd->client.e.state.rot.prev == 0)
8712 new_x = bd->zone->w - bd->x - bd->w;
8713 new_y = bd->zone->h - bd->y - bd->h;
8715 else if (bd->client.e.state.rot.prev == 90)
8717 new_x = bd->zone->w - ((bd->zone->h - bd->h - bd->y) / 2) - bd->h;
8718 new_y = bd->zone->h - (2 * bd->x) - bd->w;
8720 else if (bd->client.e.state.rot.prev == 270)
8722 new_x = bd->zone->w - (bd->y / 2) - bd->h;
8723 new_y = bd->zone->h - ((bd->zone->w - bd->w - bd->x) * 2) - bd->w;
8726 if(new_x + bd->w < min_title_width)
8728 new_x = min_title_width - bd->w;
8730 else if(new_x > bd->zone->w - min_title_width)
8732 new_x = bd->zone->w - min_title_width;
8736 ELBF(ELBT_ROT, 0, bd->client.win,
8737 "Floating Mode. ANGLE (%d->%d), POS (%d,%d) -> (%d,%d)",
8738 bd->client.e.state.rot.prev, bd->client.e.state.rot.curr,
8739 bd->x, bd->y, new_x, new_y);
8741 if ((new_x == *x) &&
8753 #define SIZE_EQUAL_TO_ZONE(a, z) \
8754 ((((a)->w) == ((z)->w)) && \
8755 (((a)->h) == ((z)->h)))
8757 _e_border_rotation_pre_resize(E_Border *bd, int rotation, int *x, int *y, int *w, int *h)
8759 E_Zone *zone = bd->zone;
8762 Eina_Bool move = EINA_FALSE;
8763 Eina_Bool hint = EINA_FALSE;
8764 Eina_Bool resize = EINA_FALSE;
8771 if (SIZE_EQUAL_TO_ZONE(bd, zone)) return resize;
8773 ELB(ELBT_ROT, "SIZE DIFF WITH ZONE", 0);
8774 ELBF(ELBT_ROT, 0, bd->client.win, "ORIGIN_SIZE name:%s (%d,%d) %dx%d",
8775 bd->client.icccm.name, bd->x, bd->y, bd->w, bd->h);
8777 hint = _e_border_rotation_geom_get(bd, bd->zone, rotation,
8778 &_x, &_y, &_w, &_h, &move);
8781 _e_border_move_resize_internal(bd, _x, _y, _w, _h, EINA_TRUE, move);
8783 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
8784 bd->client.icccm.name, _x, _y, _w, _h);
8788 _x = bd->x; _y = bd->y;
8789 _w = bd->w; _h = bd->h;
8791 if (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)
8792 move = _e_border_rotation_change_floating_pos(bd, &_x, &_y);
8796 rot_dif = bd->client.e.state.rot.prev - rotation;
8797 if (rot_dif < 0) rot_dif = -rot_dif;
8806 _e_border_move_resize_internal(bd, _x, _y, _w, _h,
8807 EINA_TRUE, EINA_TRUE);
8808 ELBF(ELBT_ROT, 0, bd->client.win, "MANUAL_RESIZE name:%s (%d,%d) %dx%d",
8809 bd->client.icccm.name, _x, _y, _w, _h);
8814 if (!resize && move)
8815 _e_border_move_internal(bd, _x, _y, EINA_TRUE);
8830 _e_border_cb_window_configure(void *data __UNUSED__,
8831 int ev_type __UNUSED__,
8834 Ecore_X_Event_Window_Configure *e = ev;
8835 E_Border_Rotation_Info *info = NULL;
8837 Eina_Bool found = EINA_FALSE;
8839 if (!e) return ECORE_CALLBACK_PASS_ON;
8840 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8842 E_Border *bd = e_border_find_by_client_window(e->win);
8843 if (!bd) return ECORE_CALLBACK_PASS_ON;
8845 if (bd->client.e.state.rot.pending_change_request)
8847 if ((e->w == bd->w) && (e->h == bd->h))
8849 ELB(ELBT_BD, "GET CONFIGURE_NOTI (ROTATION)", bd->client.win);
8850 bd->client.e.state.rot.pending_change_request = 0;
8852 if ((bd->client.e.state.rot.wait_for_done) &&
8853 (bd->client.e.state.rot.wait_done_ang == bd->client.e.state.rot.curr)) goto end;
8855 // if this window is rotation dependent window and zone is blocked to rotate,
8856 // then skip here, request will be sent after cancel block.
8857 if ((bd->client.e.state.rot.type == E_BORDER_ROTATION_TYPE_DEPENDENT) &&
8858 (bd->zone->rot.block_count)) goto end;
8860 EINA_LIST_FOREACH(rot.list, l, info)
8861 if (info->bd == bd) found = EINA_TRUE;
8862 // send request message if it's async rotation window,
8863 // even if wait prepare done.
8864 if ((found) && (rot.wait_prepare_done)) goto end;
8866 ELBF(ELBT_ROT, 0, bd->client.win,
8867 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8868 bd->client.e.state.rot.curr,
8870 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8871 bd->client.e.state.rot.curr);
8872 bd->client.e.state.rot.wait_for_done = 1;
8873 bd->client.e.state.rot.wait_done_ang = bd->client.e.state.rot.curr;
8878 return ECORE_CALLBACK_PASS_ON;
8882 _e_border_rotation_geom_get(E_Border *bd,
8891 if (!e_config->wm_win_rotation) return EINA_FALSE;
8893 Eina_Bool res = EINA_FALSE;
8894 Eina_Bool _move = EINA_TRUE;
8904 if (move) *move = EINA_TRUE;
8906 if (bd->client.e.state.rot.geom_hint)
8911 _w = bd->client.e.state.rot.geom[0].w;
8912 _h = bd->client.e.state.rot.geom[0].h;
8913 if (_w == 0) _w = bd->w;
8914 if (_h == 0) _h = bd->h;
8915 _x = 0; _y = zone->h - _h;
8918 _w = bd->client.e.state.rot.geom[1].w;
8919 _h = bd->client.e.state.rot.geom[1].h;
8920 if (_w == 0) _w = bd->w;
8921 if (_h == 0) _h = bd->h;
8922 _x = zone->w - _w; _y = 0;
8925 _w = bd->client.e.state.rot.geom[2].w;
8926 _h = bd->client.e.state.rot.geom[2].h;
8927 if (_w == 0) _w = bd->w;
8928 if (_h == 0) _h = bd->h;
8932 _w = bd->client.e.state.rot.geom[3].w;
8933 _h = bd->client.e.state.rot.geom[3].h;
8934 if (_w == 0) _w = bd->w;
8935 if (_h == 0) _h = bd->h;
8945 if (!((rot.vkbd) && (rot.vkbd == bd)))
8949 if (move) *move = EINA_FALSE;
8957 _x = 0; _y = 0; _w = 0; _h = 0;
8962 if (move) _move = *move;
8964 ELBF(ELBT_ROT, 1, bd->client.win,
8965 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
8966 ang, _x, _y, _w, _h, _move);
8974 _e_border_post_move_resize_job(void *data)
8978 bd = (E_Border *)data;
8984 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
8985 ecore_x_window_move(tmp->win,
8987 bd->client_inset.l +
8989 tmp->client.e.state.video_position.x,
8991 bd->client_inset.t +
8993 tmp->client.e.state.video_position.y);
8995 if (bd->client.e.state.video)
8999 parent = bd->client.e.state.video_parent_border;
9000 ecore_x_window_move(bd->win,
9002 parent->client_inset.l +
9004 bd->client.e.state.video_position.x,
9006 parent->client_inset.t +
9008 bd->client.e.state.video_position.y);
9010 else if ((bd->post_move) && (bd->post_resize))
9012 ecore_x_window_move_resize(bd->win,
9017 else if (bd->post_move)
9019 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
9021 else if (bd->post_resize)
9023 ecore_x_window_resize(bd->win, bd->w, bd->h);
9026 if (bd->client.e.state.video)
9028 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
9030 bd->client.e.state.video_parent_border->x +
9031 bd->client.e.state.video_parent_border->client_inset.l +
9032 bd->client.e.state.video_parent_border->fx.x +
9033 bd->client.e.state.video_position.x,
9034 bd->client.e.state.video_parent_border->y +
9035 bd->client.e.state.video_parent_border->client_inset.t +
9036 bd->client.e.state.video_parent_border->fx.y +
9037 bd->client.e.state.video_position.y,
9045 bd->post_job = NULL;
9051 bd->post_resize = 0;
9052 bd->post_job = NULL;
9053 return ECORE_CALLBACK_CANCEL;
9057 _e_border_container_layout_hook(E_Container *con)
9059 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
9063 _e_border_eval0(E_Border *bd)
9065 int change_urgent = 0;
9067 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9068 Eina_Bool need_desk_set = EINA_FALSE;
9070 #ifdef _F_ZONE_WINDOW_ROTATION_
9071 Eina_Bool need_rotation_set = EINA_FALSE;
9073 if ((e_config->wm_win_rotation) &&
9074 (bd->client.icccm.fetch.transient_for))
9076 if (((rot.vkbd) && (rot.vkbd == bd)) ||
9077 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
9079 need_rotation_set = EINA_TRUE;
9080 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
9085 if (e_object_is_del(E_OBJECT(bd)))
9087 CRI("_e_border_eval(%p) with deleted border!\n", bd);
9092 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
9094 bd->changes.border = 0;
9096 /* fetch any info queued to be fetched */
9097 if (bd->client.netwm.fetch.state)
9099 e_hints_window_state_get(bd);
9100 bd->client.netwm.fetch.state = 0;
9103 if (bd->client.icccm.fetch.client_leader)
9105 /* TODO: What do to if the client leader isn't mapped yet? */
9106 E_Border *bd_leader = NULL;
9108 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
9109 if (bd->client.icccm.client_leader)
9110 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
9113 if (bd->leader != bd_leader)
9115 bd->leader->group = eina_list_remove(bd->leader->group, bd);
9116 if (bd->leader->modal == bd) bd->leader->modal = NULL;
9122 /* If this border is the leader of the group, don't register itself */
9123 if ((bd_leader) && (bd_leader != bd))
9125 bd_leader->group = eina_list_append(bd_leader->group, bd);
9126 bd->leader = bd_leader;
9127 /* Only set the window modal to the leader it there is no parent */
9128 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
9129 ((!bd->parent) || (bd->parent->modal != bd)))
9131 bd->leader->modal = bd;
9132 if (bd->leader->focused)
9133 e_border_focus_set(bd, 1, 1);
9139 EINA_LIST_FOREACH(bd->leader->group, l, child)
9141 if ((child != bd) && (child->focused))
9142 e_border_focus_set(bd, 1, 1);
9147 bd->client.icccm.fetch.client_leader = 0;
9150 if (bd->client.icccm.fetch.title)
9152 char *title = ecore_x_icccm_title_get(bd->client.win);
9153 eina_stringshare_replace(&bd->client.icccm.title, title);
9154 if (title) free(title);
9157 edje_object_part_text_set(bd->bg_object, "e.text.title",
9158 bd->client.icccm.title);
9159 bd->client.icccm.fetch.title = 0;
9162 if (bd->client.netwm.fetch.name)
9165 ecore_x_netwm_name_get(bd->client.win, &name);
9166 eina_stringshare_replace(&bd->client.netwm.name, name);
9167 if (name) free(name);
9170 edje_object_part_text_set(bd->bg_object, "e.text.title",
9171 bd->client.netwm.name);
9172 bd->client.netwm.fetch.name = 0;
9175 if (bd->client.icccm.fetch.name_class)
9177 const char *pname, *pclass;
9178 char *nname, *nclass;
9180 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
9181 pname = bd->client.icccm.name;
9182 pclass = bd->client.icccm.class;
9183 bd->client.icccm.name = eina_stringshare_add(nname);
9184 bd->client.icccm.class = eina_stringshare_add(nclass);
9185 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
9186 e_bindings_mapping_change_enable(EINA_FALSE);
9187 #ifdef _F_ZONE_WINDOW_ROTATION_
9188 if (e_config->wm_win_rotation)
9190 if ((bd->client.icccm.name) && (bd->client.icccm.class))
9192 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
9193 (!strcmp(bd->client.icccm.class, "ISF")))
9195 ELB(ELBT_BD, "SET VKBD", bd->client.win);
9196 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
9199 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
9200 (!strcmp(bd->client.icccm.class, "ISF")))
9202 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
9203 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
9204 rot.vkbd_prediction = bd;
9206 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
9207 (!strcmp(bd->client.icccm.class, "ISF")))
9209 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
9210 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
9212 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
9213 (!strcmp(bd->client.icccm.class, "ISF")))
9215 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
9216 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
9221 if (nname) free(nname);
9222 if (nclass) free(nclass);
9224 if (!((bd->client.icccm.name == pname) &&
9225 (bd->client.icccm.class == pclass)))
9226 bd->changes.icon = 1;
9228 if (pname) eina_stringshare_del(pname);
9229 if (pclass) eina_stringshare_del(pclass);
9230 bd->client.icccm.fetch.name_class = 0;
9231 bd->changes.icon = 1;
9234 if (bd->client.icccm.fetch.state)
9236 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
9237 bd->client.icccm.fetch.state = 0;
9240 if (bd->client.e.fetch.state)
9242 e_hints_window_e_state_get(bd);
9243 bd->client.e.fetch.state = 0;
9246 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9247 if (bd->client.e.fetch.profile_list)
9249 const char **profiles = NULL;
9253 if (bd->client.e.state.profile)
9254 eina_stringshare_del(bd->client.e.state.profile);
9255 EINA_LIST_FREE(bd->client.e.state.profiles, str)
9257 if (str) eina_stringshare_del(str);
9259 bd->client.e.state.profile = NULL;
9260 bd->client.e.state.profiles = NULL;
9261 bd->client.e.state.profile_list = 0;
9263 if (ecore_x_e_window_profile_list_get(bd->client.win,
9266 bd->client.e.state.profile_list = 1;
9267 for (i = 0; i < num; i++)
9269 str = eina_stringshare_add(profiles[i]);
9270 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
9273 /* We should set desk to contain given border after creating E_BORDER_ADD event.
9274 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
9276 need_desk_set = EINA_TRUE;
9280 if (strcmp(bd->desk->window_profile,
9281 e_config->desktop_default_window_profile) != 0)
9283 ecore_x_e_window_profile_set(bd->client.win,
9284 bd->desk->window_profile);
9290 for (i = 0; i < num; i++)
9291 if (profiles[i]) free(profiles[i]);
9295 bd->client.e.fetch.profile_list = 0;
9298 #ifdef _F_ZONE_WINDOW_ROTATION_
9299 if ((e_config->wm_win_rotation) &&
9300 (bd->client.e.fetch.rot.support))
9303 unsigned int support = 0;
9305 ret = ecore_x_window_prop_card32_get
9307 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
9310 bd->client.e.state.rot.support = 0;
9311 if ((ret == 1) && (support == 1))
9312 bd->client.e.state.rot.support = 1;
9314 if (bd->client.e.state.rot.support)
9315 need_rotation_set = EINA_TRUE;
9317 bd->client.e.fetch.rot.support = 0;
9319 if ((e_config->wm_win_rotation) &&
9320 (bd->client.e.fetch.rot.geom_hint))
9322 Eina_Rectangle r[4];
9324 bd->client.e.state.rot.geom_hint = 0;
9325 for (i = 0; i < 4; i++)
9327 r[i].x = bd->client.e.state.rot.geom[i].x;
9328 r[i].y = bd->client.e.state.rot.geom[i].y;
9329 r[i].w = bd->client.e.state.rot.geom[i].w;
9330 r[i].h = bd->client.e.state.rot.geom[i].h;
9332 bd->client.e.state.rot.geom[i].x = 0;
9333 bd->client.e.state.rot.geom[i].y = 0;
9334 bd->client.e.state.rot.geom[i].w = 0;
9335 bd->client.e.state.rot.geom[i].h = 0;
9338 for (i = 0; i < 4; i++)
9340 x = 0; y = 0; w = 0; h = 0;
9341 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
9343 bd->client.e.state.rot.geom_hint = 1;
9344 bd->client.e.state.rot.geom[i].x = x;
9345 bd->client.e.state.rot.geom[i].y = y;
9346 bd->client.e.state.rot.geom[i].w = w;
9347 bd->client.e.state.rot.geom[i].h = h;
9349 if (!((r[i].x == x) && (r[i].y == y) &&
9350 (r[i].w == w) && (r[i].h == h)))
9352 need_rotation_set = EINA_TRUE;
9356 bd->client.e.fetch.rot.geom_hint = 0;
9358 if ((e_config->wm_win_rotation) &&
9359 (bd->client.e.fetch.rot.app_set))
9361 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
9362 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
9363 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
9365 if (_prev_app_set != bd->client.e.state.rot.app_set)
9366 need_rotation_set = EINA_TRUE;
9368 bd->client.e.fetch.rot.app_set = 0;
9370 if ((e_config->wm_win_rotation) &&
9371 (bd->client.e.fetch.rot.preferred_rot))
9373 int r = 0, _prev_preferred_rot;
9374 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
9375 bd->client.e.state.rot.preferred_rot = -1;
9376 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
9378 bd->client.e.state.rot.preferred_rot = r;
9379 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
9383 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
9386 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
9387 need_rotation_set = EINA_TRUE;
9389 bd->client.e.fetch.rot.preferred_rot = 0;
9391 if ((e_config->wm_win_rotation) &&
9392 (bd->client.e.fetch.rot.available_rots))
9394 Eina_Bool res, diff = EINA_FALSE;
9396 unsigned int count = 0, i = 0;
9397 int _prev_rots[4] = { -1, };
9399 if (bd->client.e.state.rot.available_rots)
9402 bd->client.e.state.rot.available_rots,
9403 (sizeof(int) * bd->client.e.state.rot.count));
9405 E_FREE(bd->client.e.state.rot.available_rots);
9408 bd->client.e.state.rot.count = 0;
9410 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
9412 if ((res) && (count > 0) && (rots))
9414 bd->client.e.state.rot.available_rots = rots;
9415 bd->client.e.state.rot.count = count;
9417 for (i = 0; i < count; i++)
9419 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
9420 if ((!diff) && (_prev_rots[i] != rots[i]))
9422 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
9423 count, i, _prev_rots[i], rots[i]);
9430 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9434 if (diff) need_rotation_set = EINA_TRUE;
9435 bd->client.e.fetch.rot.available_rots = 0;
9438 if (bd->client.netwm.fetch.type)
9440 e_hints_window_type_get(bd);
9441 if ((!bd->lock_border) || (!bd->client.border.name))
9442 bd->client.border.changed = 1;
9444 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9446 if (!bd->client.netwm.state.skip_pager)
9448 bd->client.netwm.state.skip_pager = 1;
9449 bd->client.netwm.update.state = 1;
9451 if (!bd->client.netwm.state.skip_taskbar)
9453 bd->client.netwm.state.skip_taskbar = 1;
9454 bd->client.netwm.update.state = 1;
9457 bd->client.netwm.fetch.type = 0;
9459 if (bd->client.icccm.fetch.machine)
9461 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9463 if ((!machine) && (bd->client.icccm.client_leader))
9464 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9466 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9467 if (machine) free(machine);
9469 bd->client.icccm.fetch.machine = 0;
9472 if (bd->client.icccm.fetch.command)
9474 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9478 for (i = 0; i < bd->client.icccm.command.argc; i++)
9479 free(bd->client.icccm.command.argv[i]);
9480 free(bd->client.icccm.command.argv);
9482 bd->client.icccm.command.argc = 0;
9483 bd->client.icccm.command.argv = NULL;
9484 ecore_x_icccm_command_get(bd->client.win,
9485 &(bd->client.icccm.command.argc),
9486 &(bd->client.icccm.command.argv));
9487 if ((bd->client.icccm.client_leader) &&
9488 (!bd->client.icccm.command.argv))
9489 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9490 &(bd->client.icccm.command.argc),
9491 &(bd->client.icccm.command.argv));
9492 bd->client.icccm.fetch.command = 0;
9495 if (bd->client.icccm.fetch.hints)
9497 Eina_Bool accepts_focus, is_urgent;
9499 accepts_focus = EINA_TRUE;
9500 is_urgent = EINA_FALSE;
9501 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9502 if (ecore_x_icccm_hints_get(bd->client.win,
9504 &bd->client.icccm.initial_state,
9505 &bd->client.icccm.icon_pixmap,
9506 &bd->client.icccm.icon_mask,
9507 &bd->client.icccm.icon_window,
9508 &bd->client.icccm.window_group,
9511 bd->client.icccm.accepts_focus = accepts_focus;
9512 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9514 bd->client.icccm.urgent = is_urgent;
9516 /* If this is a new window, set the state as requested. */
9517 if ((bd->new_client) &&
9518 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9520 e_border_iconify(bd);
9521 e_border_hide(bd, 1);
9524 bd->client.icccm.fetch.hints = 0;
9527 if (bd->client.icccm.fetch.size_pos_hints)
9529 Eina_Bool request_pos;
9531 request_pos = EINA_FALSE;
9532 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9534 &bd->client.icccm.gravity,
9535 &bd->client.icccm.min_w,
9536 &bd->client.icccm.min_h,
9537 &bd->client.icccm.max_w,
9538 &bd->client.icccm.max_h,
9539 &bd->client.icccm.base_w,
9540 &bd->client.icccm.base_h,
9541 &bd->client.icccm.step_w,
9542 &bd->client.icccm.step_h,
9543 &bd->client.icccm.min_aspect,
9544 &bd->client.icccm.max_aspect))
9546 bd->client.icccm.request_pos = request_pos;
9551 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9552 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9553 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9554 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9555 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9556 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9557 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9558 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9559 // if doing a resize, fix it up
9560 if (bd->resize_mode != RESIZE_NONE)
9562 int x, y, w, h, new_w, new_h;
9570 e_border_resize_limit(bd, &new_w, &new_h);
9571 if ((bd->resize_mode == RESIZE_TL) ||
9572 (bd->resize_mode == RESIZE_L) ||
9573 (bd->resize_mode == RESIZE_BL))
9575 if ((bd->resize_mode == RESIZE_TL) ||
9576 (bd->resize_mode == RESIZE_T) ||
9577 (bd->resize_mode == RESIZE_TR))
9579 e_border_move_resize(bd, x, y, new_w, new_h);
9581 bd->client.icccm.fetch.size_pos_hints = 0;
9584 if (bd->client.icccm.fetch.protocol)
9587 Ecore_X_WM_Protocol *proto;
9589 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9592 for (i = 0; i < num; i++)
9594 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9595 bd->client.icccm.delete_request = 1;
9596 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9597 bd->client.icccm.take_focus = 1;
9598 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9599 bd->client.netwm.ping = 1;
9600 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9602 bd->client.netwm.sync.request = 1;
9603 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9604 &bd->client.netwm.sync.counter))
9605 bd->client.netwm.sync.request = 0;
9610 if (bd->client.netwm.ping)
9614 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9615 bd->ping_poller = NULL;
9617 bd->client.icccm.fetch.protocol = 0;
9619 if (bd->client.icccm.fetch.transient_for)
9621 /* TODO: What do to if the transient for isn't mapped yet? */
9622 E_Border *bd_parent = NULL;
9623 #ifdef _F_DEICONIFY_APPROVE_
9624 Eina_Bool change_parent = EINA_FALSE;
9627 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9628 if (bd->client.icccm.transient_for)
9629 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9630 /* If we already have a parent, remove it */
9633 if (bd_parent != bd->parent)
9635 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9636 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9642 if ((bd_parent) && (bd_parent != bd) &&
9643 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9645 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9646 bd->parent = bd_parent;
9647 #ifdef _F_DEICONIFY_APPROVE_
9648 change_parent = EINA_TRUE;
9653 e_border_layer_set(bd, bd->parent->layer);
9654 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9656 Ecore_X_Window_Attributes attr;
9657 bd->parent->modal = bd;
9658 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9659 bd->parent->saved.event_mask = attr.event_mask.mine;
9660 bd->parent->lock_close = 1;
9661 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9662 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9665 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9666 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9670 #ifdef _F_DEICONIFY_APPROVE_
9673 bd->client.e.state.deiconify_approve.render_done = 0;
9675 E_Border *ancestor_bd;
9676 ancestor_bd = bd->client.e.state.deiconify_approve.ancestor;
9677 if ((ancestor_bd) &&
9678 (!e_object_is_del(E_OBJECT(ancestor_bd))))
9680 ancestor_bd->client.e.state.deiconify_approve.req_list = eina_list_remove(ancestor_bd->client.e.state.deiconify_approve.req_list, bd);
9681 bd->client.e.state.deiconify_approve.ancestor = NULL;
9683 if ((ancestor_bd->client.e.state.deiconify_approve.req_list == NULL) &&
9684 (ancestor_bd->client.e.state.deiconify_approve.render_done))
9686 if (ancestor_bd->client.e.state.deiconify_approve.wait_timer)
9688 ecore_timer_del(ancestor_bd->client.e.state.deiconify_approve.wait_timer);
9689 ancestor_bd->client.e.state.deiconify_approve.wait_timer = NULL;
9690 e_border_uniconify(ancestor_bd);
9696 bd->client.icccm.fetch.transient_for = 0;
9699 if (bd->client.icccm.fetch.window_role)
9701 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9702 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9703 if (role) free(role);
9705 bd->client.icccm.fetch.window_role = 0;
9708 if (bd->client.icccm.fetch.icon_name)
9710 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9711 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9712 if (icon_name) free(icon_name);
9714 bd->client.icccm.fetch.icon_name = 0;
9717 if (bd->client.netwm.fetch.icon_name)
9720 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9721 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9722 if (icon_name) free(icon_name);
9724 bd->client.netwm.fetch.icon_name = 0;
9727 if (bd->client.netwm.fetch.icon)
9730 if (bd->client.netwm.icons)
9732 for (i = 0; i < bd->client.netwm.num_icons; i++)
9734 free(bd->client.netwm.icons[i].data);
9735 bd->client.netwm.icons[i].data = NULL;
9737 free(bd->client.netwm.icons);
9739 bd->client.netwm.icons = NULL;
9740 bd->client.netwm.num_icons = 0;
9741 if (ecore_x_netwm_icons_get(bd->client.win,
9742 &bd->client.netwm.icons,
9743 &bd->client.netwm.num_icons))
9745 // unless the rest of e17 uses border icons OTHER than icon #0
9746 // then free the rest that we don't need anymore.
9747 for (i = 1; i < bd->client.netwm.num_icons; i++)
9749 free(bd->client.netwm.icons[i].data);
9750 bd->client.netwm.icons[i].data = NULL;
9752 bd->client.netwm.num_icons = 1;
9753 bd->changes.icon = 1;
9755 bd->client.netwm.fetch.icon = 0;
9757 if (bd->client.netwm.fetch.user_time)
9759 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9760 bd->client.netwm.fetch.user_time = 0;
9762 if (bd->client.netwm.fetch.strut)
9764 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9765 &bd->client.netwm.strut.left,
9766 &bd->client.netwm.strut.right,
9767 &bd->client.netwm.strut.top,
9768 &bd->client.netwm.strut.bottom,
9769 &bd->client.netwm.strut.left_start_y,
9770 &bd->client.netwm.strut.left_end_y,
9771 &bd->client.netwm.strut.right_start_y,
9772 &bd->client.netwm.strut.right_end_y,
9773 &bd->client.netwm.strut.top_start_x,
9774 &bd->client.netwm.strut.top_end_x,
9775 &bd->client.netwm.strut.bottom_start_x,
9776 &bd->client.netwm.strut.bottom_end_x))
9778 ecore_x_netwm_strut_get(bd->client.win,
9779 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9780 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9782 bd->client.netwm.strut.left_start_y = 0;
9783 bd->client.netwm.strut.left_end_y = 0;
9784 bd->client.netwm.strut.right_start_y = 0;
9785 bd->client.netwm.strut.right_end_y = 0;
9786 bd->client.netwm.strut.top_start_x = 0;
9787 bd->client.netwm.strut.top_end_x = 0;
9788 bd->client.netwm.strut.bottom_start_x = 0;
9789 bd->client.netwm.strut.bottom_end_x = 0;
9791 bd->client.netwm.fetch.strut = 0;
9793 if (bd->client.qtopia.fetch.soft_menu)
9795 e_hints_window_qtopia_soft_menu_get(bd);
9796 bd->client.qtopia.fetch.soft_menu = 0;
9799 if (bd->client.qtopia.fetch.soft_menus)
9801 e_hints_window_qtopia_soft_menus_get(bd);
9802 bd->client.qtopia.fetch.soft_menus = 0;
9805 if (bd->client.vkbd.fetch.state)
9807 e_hints_window_virtual_keyboard_state_get(bd);
9808 bd->client.vkbd.fetch.state = 0;
9811 if (bd->client.vkbd.fetch.vkbd)
9813 e_hints_window_virtual_keyboard_get(bd);
9814 bd->client.vkbd.fetch.vkbd = 0;
9817 if (bd->client.illume.conformant.fetch.conformant)
9819 bd->client.illume.conformant.conformant =
9820 ecore_x_e_illume_conformant_get(bd->client.win);
9821 bd->client.illume.conformant.fetch.conformant = 0;
9823 if (bd->client.illume.quickpanel.fetch.state)
9825 bd->client.illume.quickpanel.state =
9826 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9827 bd->client.illume.quickpanel.fetch.state = 0;
9829 if (bd->client.illume.quickpanel.fetch.quickpanel)
9831 bd->client.illume.quickpanel.quickpanel =
9832 ecore_x_e_illume_quickpanel_get(bd->client.win);
9833 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9835 if (bd->client.illume.quickpanel.fetch.priority.major)
9837 bd->client.illume.quickpanel.priority.major =
9838 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9839 bd->client.illume.quickpanel.fetch.priority.major = 0;
9841 if (bd->client.illume.quickpanel.fetch.priority.minor)
9843 bd->client.illume.quickpanel.priority.minor =
9844 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9845 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9847 if (bd->client.illume.quickpanel.fetch.zone)
9849 bd->client.illume.quickpanel.zone =
9850 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9851 bd->client.illume.quickpanel.fetch.zone = 0;
9853 if (bd->client.illume.drag.fetch.drag)
9855 bd->client.illume.drag.drag =
9856 ecore_x_e_illume_drag_get(bd->client.win);
9857 bd->client.illume.drag.fetch.drag = 0;
9859 if (bd->client.illume.drag.fetch.locked)
9861 bd->client.illume.drag.locked =
9862 ecore_x_e_illume_drag_locked_get(bd->client.win);
9863 bd->client.illume.drag.fetch.locked = 0;
9865 if (bd->client.illume.win_state.fetch.state)
9867 bd->client.illume.win_state.state =
9868 ecore_x_e_illume_window_state_get(bd->client.win);
9869 bd->client.illume.win_state.fetch.state = 0;
9871 if (bd->changes.shape)
9873 Ecore_X_Rectangle *rects;
9876 bd->changes.shape = 0;
9877 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9882 /* This doesn't fix the race, but makes it smaller. we detect
9883 * this and if cw and ch != client w/h then mark this as needing
9884 * a shape change again to fixup next event loop.
9886 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9887 if ((cw != bd->client.w) || (ch != bd->client.h))
9888 bd->changes.shape = 1;
9890 (rects[0].x == 0) &&
9891 (rects[0].y == 0) &&
9892 ((int)rects[0].width == cw) &&
9893 ((int)rects[0].height == ch))
9895 if (bd->client.shaped)
9897 bd->client.shaped = 0;
9898 if (!bd->bordername)
9899 bd->client.border.changed = 1;
9904 if (!bd->client.shaped)
9906 bd->client.shaped = 1;
9907 if (!bd->bordername)
9908 bd->client.border.changed = 1;
9915 // FIXME: no rects i think can mean... totally empty window
9916 bd->client.shaped = 0;
9917 if (!bd->bordername)
9918 bd->client.border.changed = 1;
9920 bd->need_shape_merge = 1;
9922 if (bd->changes.shape_input)
9924 Ecore_X_Rectangle *rects;
9927 bd->changes.shape_input = 0;
9928 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
9933 /* This doesn't fix the race, but makes it smaller. we detect
9934 * this and if cw and ch != client w/h then mark this as needing
9935 * a shape change again to fixup next event loop.
9937 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9938 if ((cw != bd->client.w) || (ch != bd->client.h))
9939 bd->changes.shape_input = 1;
9941 (rects[0].x == 0) &&
9942 (rects[0].y == 0) &&
9943 ((int)rects[0].width == cw) &&
9944 ((int)rects[0].height == ch))
9946 if (bd->shaped_input)
9948 bd->shaped_input = 0;
9949 if (!bd->bordername)
9950 bd->client.border.changed = 1;
9955 if (!bd->shaped_input)
9957 bd->shaped_input = 1;
9958 if (!bd->bordername)
9959 bd->client.border.changed = 1;
9966 bd->shaped_input = 1;
9967 if (!bd->bordername)
9968 bd->client.border.changed = 1;
9970 bd->need_shape_merge = 1;
9972 if (bd->client.mwm.fetch.hints)
9976 bd->client.mwm.exists =
9977 ecore_x_mwm_hints_get(bd->client.win,
9978 &bd->client.mwm.func,
9979 &bd->client.mwm.decor,
9980 &bd->client.mwm.input);
9981 pb = bd->client.mwm.borderless;
9982 bd->client.mwm.borderless = 0;
9983 if (bd->client.mwm.exists)
9985 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
9986 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
9987 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
9988 bd->client.mwm.borderless = 1;
9990 if (bd->client.mwm.borderless != pb)
9992 if ((!bd->lock_border) || (!bd->client.border.name))
9993 bd->client.border.changed = 1;
9995 bd->client.mwm.fetch.hints = 0;
9998 if (bd->client.e.fetch.video_parent)
10000 /* unlinking child/parent */
10001 if (bd->client.e.state.video_parent_border != NULL)
10003 bd->client.e.state.video_parent_border->client.e.state.video_child =
10005 (bd->client.e.state.video_parent_border->client.e.state.video_child,
10009 ecore_x_window_prop_card32_get(bd->client.win,
10010 ECORE_X_ATOM_E_VIDEO_PARENT,
10011 &bd->client.e.state.video_parent,
10014 /* linking child/parent */
10015 if (bd->client.e.state.video_parent != 0)
10020 EINA_LIST_FOREACH(borders, l, tmp)
10021 if (tmp->client.win == bd->client.e.state.video_parent)
10023 /* fprintf(stderr, "child added to parent \\o/\n"); */
10024 bd->client.e.state.video_parent_border = tmp;
10025 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
10027 if (bd->desk != tmp->desk)
10028 e_border_desk_set(bd, tmp->desk);
10033 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
10035 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
10038 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
10040 unsigned int xy[2];
10042 ecore_x_window_prop_card32_get(bd->client.win,
10043 ECORE_X_ATOM_E_VIDEO_POSITION,
10046 bd->client.e.state.video_position.x = xy[0];
10047 bd->client.e.state.video_position.y = xy[1];
10048 bd->client.e.state.video_position.updated = 1;
10049 bd->client.e.fetch.video_position = 0;
10050 bd->x = bd->client.e.state.video_position.x;
10051 bd->y = bd->client.e.state.video_position.y;
10053 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
10055 if (bd->client.netwm.update.state)
10057 e_hints_window_state_set(bd);
10058 /* Some stats might change the border, like modal */
10059 if (((!bd->lock_border) || (!bd->client.border.name)) &&
10060 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10062 bd->client.border.changed = 1;
10066 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10068 bd->parent->modal = bd;
10069 if (bd->parent->focused)
10070 e_border_focus_set(bd, 1, 1);
10073 else if (bd->leader)
10075 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
10077 bd->leader->modal = bd;
10078 if (bd->leader->focused)
10079 e_border_focus_set(bd, 1, 1);
10085 EINA_LIST_FOREACH(bd->leader->group, l, child)
10087 if ((child != bd) && (child->focused))
10088 e_border_focus_set(bd, 1, 1);
10093 bd->client.netwm.update.state = 0;
10096 if (bd->new_client)
10098 E_Event_Border_Add *ev;
10099 E_Exec_Instance *inst;
10101 ev = E_NEW(E_Event_Border_Add, 1);
10103 e_object_ref(E_OBJECT(bd));
10104 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
10105 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
10107 if ((!bd->lock_border) || (!bd->client.border.name))
10108 bd->client.border.changed = 1;
10113 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
10114 ((bd->client.icccm.client_leader > 0) &&
10115 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
10118 if (!strncmp(str, "E_START|", 8))
10122 id = atoi(str + 8);
10123 if (id > 0) bd->client.netwm.startup_id = id;
10128 /* It's ok not to have fetch flag, should only be set on startup
10129 * * and not changed. */
10130 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
10132 if (bd->client.icccm.client_leader)
10134 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
10135 bd->client.netwm.pid = -1;
10138 bd->client.netwm.pid = -1;
10141 if (!bd->re_manage)
10143 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
10144 bd->client.netwm.pid);
10145 if ((inst) && (inst->used == 0))
10151 zone = e_container_zone_number_get(bd->zone->container,
10153 if (zone) e_border_zone_set(bd, zone);
10154 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
10156 if (desk) e_border_desk_set(bd, desk);
10157 e_exec_instance_found(inst);
10160 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
10162 E_Border *bdl = NULL;
10167 if (bd->leader) bdl = bd->leader;
10174 bl = e_container_border_list_first(bd->zone->container);
10175 while ((child = e_container_border_list_next(bl)))
10177 if (child == bd) continue;
10178 if (e_object_is_del(E_OBJECT(child))) continue;
10179 if ((bd->client.icccm.client_leader) &&
10180 (child->client.icccm.client_leader ==
10181 bd->client.icccm.client_leader))
10187 e_container_border_list_free(bl);
10192 e_border_zone_set(bd, bdl->zone);
10194 e_border_desk_set(bd, bdl->desk);
10196 e_border_stick(bd);
10202 #ifdef _F_USE_DESK_WINDOW_PROFILE_
10205 E_Container *con = bd->zone->container;
10206 E_Desk *desk = NULL;
10209 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
10211 desk = e_container_desk_window_profile_get(con, str);
10214 if (bd->desk != desk)
10216 bd->client.e.state.profile = eina_stringshare_add(str);
10217 if (bd->zone != desk->zone)
10218 e_border_zone_set(bd, desk->zone);
10219 e_border_desk_set(bd, desk);
10227 /* PRE_POST_FETCH calls e_remember apply for new client */
10228 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
10229 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
10230 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
10232 #ifdef _F_ZONE_WINDOW_ROTATION_
10233 if (e_config->wm_win_rotation)
10235 if (need_rotation_set)
10237 Eina_Bool hint = EINA_FALSE;
10239 int x, y, w, h, move;
10241 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
10242 bd->client.e.state.rot.changes = _e_border_rotation_angle_get(bd);
10244 if (bd->client.e.state.rot.changes != -1)
10246 ang = bd->client.e.state.rot.changes;
10249 else ang = bd->client.e.state.rot.curr;
10251 hint = _e_border_rotation_geom_get(bd, bd->zone, ang, &x, &y, &w, &h, &move);
10254 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
10255 ELBF(ELBT_ROT, 0, bd->client.win, "RESIZE_BY_HINT name:%s (%d,%d) %dx%d",
10256 bd->client.icccm.name, x, y, w, h);
10262 if (bd->need_reparent)
10265 ecore_x_window_save_set_add(bd->client.win);
10266 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
10269 if ((bd->new_client) && (bd->internal) &&
10270 (bd->internal_ecore_evas))
10271 ecore_evas_show(bd->internal_ecore_evas);
10272 ecore_x_window_show(bd->client.win);
10274 bd->need_reparent = 0;
10277 if ((bd->client.border.changed) && (!bd->shaded) &&
10278 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
10280 const char *bordername;
10282 if (bd->fullscreen)
10283 bordername = "borderless";
10284 else if (bd->bordername)
10285 bordername = bd->bordername;
10286 else if ((bd->client.mwm.borderless) || (bd->borderless))
10287 bordername = "borderless";
10288 else if (((bd->client.icccm.transient_for != 0) ||
10289 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
10290 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10291 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10292 bordername = "noresize_dialog";
10293 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
10294 (bd->client.icccm.min_h == bd->client.icccm.max_h))
10295 bordername = "noresize";
10296 else if (bd->client.shaped)
10297 bordername = "shaped";
10298 else if ((!bd->client.icccm.accepts_focus) &&
10299 (!bd->client.icccm.take_focus))
10300 bordername = "nofocus";
10301 else if (bd->client.icccm.urgent)
10302 bordername = "urgent";
10303 else if ((bd->client.icccm.transient_for != 0) ||
10304 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10305 bordername = "dialog";
10306 else if (bd->client.netwm.state.modal)
10307 bordername = "modal";
10308 else if ((bd->client.netwm.state.skip_taskbar) ||
10309 (bd->client.netwm.state.skip_pager))
10310 bordername = "skipped";
10311 else if ((bd->internal) && (bd->client.icccm.class) &&
10312 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
10313 bordername = "internal_fileman";
10315 bordername = e_config->theme_default_border_style;
10316 if (!bordername) bordername = "default";
10318 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
10324 bd->changes.border = 1;
10325 eina_stringshare_replace(&bd->client.border.name, bordername);
10329 bd->w -= (bd->client_inset.l + bd->client_inset.r);
10330 bd->h -= (bd->client_inset.t + bd->client_inset.b);
10331 bd->changes.size = 1;
10332 evas_object_del(bd->bg_object);
10334 o = edje_object_add(bd->bg_evas);
10335 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
10336 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10337 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
10339 if (bd->client.border.name != e_config->theme_default_border_style)
10341 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
10342 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
10346 ok = e_theme_edje_object_set(o, "base/theme/borders",
10347 "e/widgets/border/default/border");
10350 /* Reset default border style to default */
10351 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
10352 e_config_save_queue();
10360 const char *shape_option, *argb_option;
10365 if ((e_config->use_composite) && (!bd->client.argb))
10367 argb_option = edje_object_data_get(o, "argb");
10368 if ((argb_option) && (!strcmp(argb_option, "1")))
10371 if (use_argb != bd->argb)
10372 _e_border_frame_replace(bd, use_argb);
10379 shape_option = edje_object_data_get(o, "shaped");
10380 if ((shape_option) && (!strcmp(shape_option, "1")))
10384 if (bd->client.netwm.name)
10385 edje_object_part_text_set(o, "e.text.title",
10386 bd->client.netwm.name);
10387 else if (bd->client.icccm.title)
10388 edje_object_part_text_set(o, "e.text.title",
10389 bd->client.icccm.title);
10393 evas_object_del(o);
10394 bd->bg_object = NULL;
10397 _e_border_client_inset_calc(bd);
10399 bd->w += (bd->client_inset.l + bd->client_inset.r);
10400 bd->h += (bd->client_inset.t + bd->client_inset.b);
10401 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
10402 bd->changes.size = 1;
10403 /* really needed ? */
10404 ecore_x_window_move(bd->client.shell_win,
10405 bd->client_inset.l,
10406 bd->client_inset.t);
10408 if (bd->maximized != E_MAXIMIZE_NONE)
10410 E_Maximize maximized = bd->maximized;
10412 /* to force possible resizes */
10413 bd->maximized = E_MAXIMIZE_NONE;
10415 _e_border_maximize(bd, maximized);
10417 /* restore maximized state */
10418 bd->maximized = maximized;
10420 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
10421 bd->maximized & E_MAXIMIZE_VERTICAL);
10425 edje_object_signal_callback_add(bd->bg_object, "*", "*",
10426 _e_border_cb_signal_bind, bd);
10429 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
10430 if (bd->icon_object)
10431 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10434 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
10436 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
10438 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
10439 // FIXME: in eval -do differently
10440 // edje_object_message_signal_process(bd->bg_object);
10441 // e_border_frame_recalc(bd);
10443 evas_object_move(bd->bg_object, 0, 0);
10444 evas_object_resize(bd->bg_object, bd->w, bd->h);
10445 evas_object_show(bd->bg_object);
10448 bd->client.border.changed = 0;
10450 if (bd->icon_object)
10454 evas_object_show(bd->icon_object);
10455 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10458 evas_object_hide(bd->icon_object);
10462 if (rem_change) e_remember_update(bd);
10466 E_Event_Border_Urgent_Change *ev;
10468 if (bd->client.icccm.urgent)
10469 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
10471 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
10473 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
10475 e_object_ref(E_OBJECT(bd));
10476 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
10477 _e_border_event_border_urgent_change_free, NULL);
10480 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10483 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10485 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10487 E_Border* temp_bd = NULL;
10488 E_Border* top_focusable_bd = NULL;
10489 Eina_Bool is_fully_obscured = EINA_FALSE;
10490 Ecore_X_XRegion *visible_region = NULL;
10491 Ecore_X_XRegion *win_region = NULL;
10492 Ecore_X_Rectangle visible_rect, win_rect;
10495 // set the entire visible region as a root geometry
10496 visible_rect.x = bd->zone->x;
10497 visible_rect.y = bd->zone->y;
10498 visible_rect.width = bd->zone->w;
10499 visible_rect.height = bd->zone->h;
10501 visible_region = ecore_x_xregion_new();
10502 if (!visible_region) return;
10504 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10506 bl = e_container_border_list_last(bd->zone->container);
10507 while ((temp_bd = e_container_border_list_prev(bl)))
10509 if (temp_bd == bd) break;
10511 if (temp_bd == focused) continue;
10512 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10513 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10514 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10515 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10516 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10517 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10518 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10519 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10520 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10522 if (!top_focusable_bd)
10524 top_focusable_bd = temp_bd;
10527 win_rect.x = temp_bd->x;
10528 win_rect.y = temp_bd->y;
10529 win_rect.width = temp_bd->w;
10530 win_rect.height = temp_bd->h;
10532 // if it stick out or is bigger than the entire visible region,
10533 // clip it by the entire visible's geometry.
10534 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10535 win_rect.width, win_rect.height,
10536 visible_rect.x, visible_rect.y,
10537 (int)(visible_rect.width), (int)(visible_rect.height));
10539 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10541 win_region = ecore_x_xregion_new();
10544 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10545 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10546 ecore_x_xregion_free(win_region);
10549 if (ecore_x_xregion_is_empty(visible_region))
10551 is_fully_obscured = EINA_TRUE;
10559 if (is_fully_obscured == EINA_TRUE)
10561 e_border_focus_set(top_focusable_bd, 1, 1);
10565 e_border_focus_set(bd, 1, 1);
10568 if (visible_region) ecore_x_xregion_free(visible_region);
10569 e_container_border_list_free(bl);
10573 _e_border_latest_stacked_focus(E_Border *bd)
10576 int root_w, root_h;
10578 root_w = bd->zone->w;
10579 root_h = bd->zone->h;
10582 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10584 if (bd == temp_bd) continue;
10585 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10586 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10588 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10589 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10590 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10591 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10592 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10593 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10594 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10596 _e_border_latest_stacked_focus_check_set(temp_bd);
10603 _e_border_check_stack (E_Border *bd)
10605 E_Border* temp_bd = NULL;
10606 E_Border* top_bd = NULL;
10607 int passed_focus = 0;
10609 int root_w = bd->zone->w;
10610 int root_h = bd->zone->h;
10613 bl = e_container_border_list_last(bd->zone->container);
10614 while ((temp_bd = e_container_border_list_prev(bl)))
10616 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10617 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10618 if ((temp_bd != bd) &&
10619 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10621 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10622 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10623 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10624 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10625 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10626 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10627 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10633 e_border_focus_set_with_pointer(bd);
10640 e_border_focus_set_with_pointer(top_bd);
10649 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10651 if (!bd->lock_focus_out)
10653 e_border_focus_latest_set(bd);
10665 if (temp_bd == focused)
10671 e_container_border_list_free(bl);
10675 _e_border_focus_top_stack_set(E_Border* bd)
10678 int root_w, root_h;
10680 root_w = bd->zone->w;
10681 root_h = bd->zone->h;
10684 bl = e_container_border_list_last(bd->zone->container);
10685 while ((temp_bd = e_container_border_list_prev(bl)))
10687 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10688 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10689 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10691 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10692 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10693 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10694 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10695 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10696 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10697 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10699 if (!temp_bd->focused)
10701 /* this border is the top of the latest stack */
10702 e_border_focus_set (temp_bd, 1, 1);
10707 e_container_border_list_free(bl);
10712 _e_border_eval(E_Border *bd)
10714 E_Event_Border_Property *event;
10715 E_Border_Pending_Move_Resize *pnd;
10716 int rem_change = 0;
10717 int send_event = 1;
10719 if (e_object_is_del(E_OBJECT(bd)))
10721 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10726 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10728 if (bd->new_client)
10730 int zx = 0, zy = 0, zw = 0, zh = 0;
10733 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10736 * Limit maximum size of windows to useful geometry
10738 // TODO: temoporary limited maximize algorithm
10750 if ((rw != bd->w) || (rh != bd->h))
10754 e_border_resize (bd, bd->w, bd->h);
10760 bd->x -= bd->client_inset.l;
10761 bd->y -= bd->client_inset.t;
10762 bd->changes.pos = 1;
10765 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10768 Ecore_X_Window_Attributes *att;
10771 att = &bd->client.initial_attributes;
10772 bw = att->border * 2;
10773 switch (bd->client.icccm.gravity)
10775 case ECORE_X_GRAVITY_N:
10776 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10780 case ECORE_X_GRAVITY_NE:
10781 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10785 case ECORE_X_GRAVITY_E:
10786 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10787 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10790 case ECORE_X_GRAVITY_SE:
10791 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10792 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10795 case ECORE_X_GRAVITY_S:
10796 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10797 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10800 case ECORE_X_GRAVITY_SW:
10802 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10805 case ECORE_X_GRAVITY_W:
10807 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10810 case ECORE_X_GRAVITY_CENTER:
10811 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10812 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10815 case ECORE_X_GRAVITY_NW:
10822 * This ensures that windows that like to open with a x/y
10823 * position smaller than returned by e_zone_useful_geometry_get()
10824 * are moved to useful positions.
10827 if (e_config->geometry_auto_move)
10835 if (bd->x + bd->w > zx + zw)
10836 bd->x = zx + zw - bd->w;
10838 if (bd->y + bd->h > zy + zh)
10839 bd->y = zy + zh - bd->h;
10842 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10844 bd->changes.pos = 1;
10850 bd->changes.pos = 1;
10856 /* FIXME: special placement for dialogs etc. etc. etc goes
10858 /* FIXME: what if parent is not on this desktop - or zone? */
10859 if ((bd->parent) && (bd->parent->visible))
10861 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10862 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10863 bd->changes.pos = 1;
10867 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10869 /* TODO: Place in center of group */
10872 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10874 bd->x = zx + ((zw - bd->w) / 2);
10875 bd->y = zy + ((zh - bd->h) / 2);
10876 bd->changes.pos = 1;
10882 Eina_List *skiplist = NULL;
10886 new_x = zx + (rand() % (zw - bd->w));
10890 new_y = zy + (rand() % (zh - bd->h));
10894 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10896 skiplist = eina_list_append(skiplist, bd);
10898 e_place_desk_region_smart(bd->desk, skiplist,
10899 bd->x, bd->y, bd->w, bd->h,
10902 e_place_zone_region_smart(bd->zone, skiplist,
10903 bd->x, bd->y, bd->w, bd->h,
10905 eina_list_free(skiplist);
10907 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10909 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10914 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10915 bd->client_inset.t, &new_x, &new_y);
10919 bd->changes.pos = 1;
10922 EINA_LIST_FREE(bd->pending_move_resize, pnd)
10924 if ((!bd->lock_client_location) && (pnd->move))
10928 bd->changes.pos = 1;
10930 if (pnd->without_border)
10932 bd->x -= bd->client_inset.l;
10933 bd->y -= bd->client_inset.t;
10936 if ((!bd->lock_client_size) && (pnd->resize))
10938 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
10939 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
10940 bd->client.w = pnd->w;
10941 bd->client.h = pnd->h;
10942 bd->changes.size = 1;
10948 /* Recreate state */
10949 e_hints_window_init(bd);
10950 if ((bd->client.e.state.centered) &&
10951 ((!bd->remember) ||
10952 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
10954 bd->x = zx + (zw - bd->w) / 2;
10955 bd->y = zy + (zh - bd->h) / 2;
10956 bd->changes.pos = 1;
10960 _e_border_client_move_resize_send(bd);
10962 /* if the explicit geometry request asks for the app to be
10963 * in another zone - well move it there */
10967 zone = e_container_zone_at_point_get(bd->zone->container,
10968 bd->x + (bd->w / 2),
10969 bd->y + (bd->h / 2));
10971 zone = e_container_zone_at_point_get(bd->zone->container,
10975 zone = e_container_zone_at_point_get(bd->zone->container,
10979 zone = e_container_zone_at_point_get(bd->zone->container,
10981 bd->y + bd->h - 1);
10983 zone = e_container_zone_at_point_get(bd->zone->container,
10985 bd->y + bd->h - 1);
10986 if ((zone) && (zone != bd->zone))
10987 e_border_zone_set(bd, zone);
10991 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
10993 /* effect changes to the window border itself */
10994 if ((bd->changes.shading))
10996 /* show at start of unshade (but don't hide until end of shade) */
10998 ecore_x_window_raise(bd->client.shell_win);
10999 bd->changes.shading = 0;
11002 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
11005 ecore_x_window_lower(bd->client.shell_win);
11007 ecore_x_window_raise(bd->client.shell_win);
11008 bd->changes.shaded = 0;
11011 else if ((bd->changes.shaded) && (bd->changes.pos))
11014 ecore_x_window_lower(bd->client.shell_win);
11016 ecore_x_window_raise(bd->client.shell_win);
11017 bd->changes.size = 1;
11018 bd->changes.shaded = 0;
11021 else if ((bd->changes.shaded) && (bd->changes.size))
11024 ecore_x_window_lower(bd->client.shell_win);
11026 ecore_x_window_raise(bd->client.shell_win);
11027 bd->changes.shaded = 0;
11030 else if (bd->changes.shaded)
11033 ecore_x_window_lower(bd->client.shell_win);
11035 ecore_x_window_raise(bd->client.shell_win);
11036 bd->changes.size = 1;
11037 bd->changes.shaded = 0;
11041 if (bd->changes.size)
11043 int x = 0, y = 0, xx = 0, yy = 0;
11045 if ((bd->shaded) && (!bd->shading))
11047 evas_obscured_clear(bd->bg_evas);
11051 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
11052 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
11054 evas_obscured_clear(bd->bg_evas);
11055 evas_obscured_rectangle_add(bd->bg_evas,
11056 bd->client_inset.l, bd->client_inset.t, xx, yy);
11060 if (bd->shade.dir == E_DIRECTION_UP)
11062 y = yy - bd->client.h;
11064 else if (bd->shade.dir == E_DIRECTION_LEFT)
11066 x = xx - bd->client.w;
11071 if (bd->client.e.state.video)
11073 if (bd->client.e.state.video_position.updated)
11075 ecore_x_window_move(bd->win,
11076 bd->client.e.state.video_parent_border->x +
11077 bd->client.e.state.video_parent_border->client_inset.l +
11078 bd->client.e.state.video_parent_border->fx.x +
11079 bd->client.e.state.video_position.x,
11080 bd->client.e.state.video_parent_border->y +
11081 bd->client.e.state.video_parent_border->client_inset.t +
11082 bd->client.e.state.video_parent_border->fx.y +
11083 bd->client.e.state.video_position.y);
11084 bd->client.e.state.video_position.updated = 0;
11087 else if (!bd->changes.pos)
11089 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11090 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11091 bd->post_resize = 1;
11098 ecore_x_window_move_resize(bd->win,
11103 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
11104 ecore_x_window_move(tmp->win,
11105 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
11106 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
11109 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
11111 if ((!bd->shaded) || (bd->shading))
11112 ecore_x_window_move_resize(bd->client.shell_win,
11113 bd->client_inset.l, bd->client_inset.t, xx, yy);
11115 if (bd->internal_ecore_evas)
11116 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
11117 else if (!bd->client.e.state.video)
11118 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
11120 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
11121 evas_object_resize(bd->bg_object, bd->w, bd->h);
11122 e_container_shape_resize(bd->shape, bd->w, bd->h);
11123 if (bd->changes.pos)
11124 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11126 _e_border_client_move_resize_send(bd);
11128 bd->changes.pos = 0;
11129 bd->changes.size = 0;
11132 else if (bd->changes.pos)
11134 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
11135 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
11138 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
11140 _e_border_client_move_resize_send(bd);
11142 bd->changes.pos = 0;
11146 if (bd->changes.reset_gravity)
11148 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
11149 bd->changes.reset_gravity = 0;
11153 if (bd->need_shape_merge)
11155 _e_border_shape_input_rectangle_set(bd);
11156 if ((bd->shaped) || (bd->client.shaped))
11158 Ecore_X_Window twin, twin2;
11161 twin = ecore_x_window_override_new
11162 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
11164 ecore_x_window_shape_window_set(twin, bd->bg_win);
11167 Ecore_X_Rectangle rects[4];
11171 rects[0].width = bd->w;
11172 rects[0].height = bd->client_inset.t;
11174 rects[1].y = bd->client_inset.t;
11175 rects[1].width = bd->client_inset.l;
11176 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11177 rects[2].x = bd->w - bd->client_inset.r;
11178 rects[2].y = bd->client_inset.t;
11179 rects[2].width = bd->client_inset.r;
11180 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
11182 rects[3].y = bd->h - bd->client_inset.b;
11183 rects[3].width = bd->w;
11184 rects[3].height = bd->client_inset.b;
11185 ecore_x_window_shape_rectangles_set(twin, rects, 4);
11187 twin2 = ecore_x_window_override_new
11188 (bd->zone->container->scratch_win, 0, 0,
11189 bd->w - bd->client_inset.l - bd->client_inset.r,
11190 bd->h - bd->client_inset.t - bd->client_inset.b);
11193 if ((bd->shading) || (bd->shaded))
11195 if (bd->shade.dir == E_DIRECTION_UP)
11196 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
11197 else if (bd->shade.dir == E_DIRECTION_LEFT)
11198 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
11200 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
11202 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
11203 bd->w - bd->client_inset.l - bd->client_inset.r,
11204 bd->h - bd->client_inset.t - bd->client_inset.b);
11205 ecore_x_window_shape_window_add_xy(twin, twin2,
11206 bd->client_inset.l,
11207 bd->client_inset.t);
11208 ecore_x_window_free(twin2);
11209 ecore_x_window_shape_window_set(bd->win, twin);
11210 ecore_x_window_free(twin);
11213 ecore_x_window_shape_mask_set(bd->win, 0);
11214 // bd->need_shape_export = 1;
11215 bd->need_shape_merge = 0;
11218 if (bd->need_shape_export)
11220 Ecore_X_Rectangle *rects, *orects;
11223 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
11229 if ((num == bd->shape_rects_num) && (bd->shape_rects))
11233 orects = bd->shape_rects;
11235 for (i = 0; i < num; i++)
11237 if (rects[i].x < 0)
11239 rects[i].width -= rects[i].x;
11242 if ((rects[i].x + (int)rects[i].width) > bd->w)
11243 rects[i].width = rects[i].width - rects[i].x;
11244 if (rects[i].y < 0)
11246 rects[i].height -= rects[i].y;
11249 if ((rects[i].y + (int)rects[i].height) > bd->h)
11250 rects[i].height = rects[i].height - rects[i].y;
11252 if ((orects[i].x != rects[i].x) ||
11253 (orects[i].y != rects[i].y) ||
11254 (orects[i].width != rects[i].width) ||
11255 (orects[i].height != rects[i].height))
11264 if (bd->client.shaped)
11265 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
11267 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
11268 E_FREE(bd->shape_rects);
11269 bd->shape_rects = rects;
11270 bd->shape_rects_num = num;
11271 e_container_shape_rects_set(bd->shape, rects, num);
11278 E_FREE(bd->shape_rects);
11279 bd->shape_rects = NULL;
11280 bd->shape_rects_num = 0;
11281 e_container_shape_rects_set(bd->shape, NULL, 0);
11283 bd->need_shape_export = 0;
11286 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
11290 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
11291 if ((!bd->placed) && (!bd->re_manage) &&
11292 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
11293 (!((bd->client.icccm.transient_for != 0) ||
11294 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
11295 (!bdmove) && (!bdresize))
11297 /* Set this window into moving state */
11299 bd->cur_mouse_action = e_action_find("window_move");
11300 if (bd->cur_mouse_action)
11302 if ((!bd->cur_mouse_action->func.end_mouse) &&
11303 (!bd->cur_mouse_action->func.end))
11304 bd->cur_mouse_action = NULL;
11305 if (bd->cur_mouse_action)
11307 bd->x = x - (bd->w >> 1);
11308 bd->y = y - (bd->client_inset.t >> 1);
11310 bd->changes.pos = 1;
11312 _e_border_client_move_resize_send(bd);
11317 _e_border_show(bd);
11319 if (bd->cur_mouse_action)
11321 bd->moveinfo.down.x = bd->x + bd->fx.x;
11322 bd->moveinfo.down.y = bd->y + bd->fx.y;
11323 bd->moveinfo.down.w = bd->w;
11324 bd->moveinfo.down.h = bd->h;
11325 bd->mouse.current.mx = x;
11326 bd->mouse.current.my = y;
11327 bd->moveinfo.down.button = 0;
11328 bd->moveinfo.down.mx = x;
11329 bd->moveinfo.down.my = y;
11332 e_object_ref(E_OBJECT(bd->cur_mouse_action));
11333 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
11334 if (e_config->border_raise_on_mouse_action)
11335 e_border_raise(bd);
11336 e_border_focus_set(bd, 1, 1);
11338 bd->changes.visible = 0;
11342 if (bd->changes.icon)
11346 efreet_desktop_free(bd->desktop);
11347 bd->desktop = NULL;
11349 if (bd->icon_object)
11351 evas_object_del(bd->icon_object);
11352 bd->icon_object = NULL;
11354 if (bd->remember && bd->remember->prop.desktop_file)
11356 const char *desktop = bd->remember->prop.desktop_file;
11358 bd->desktop = efreet_desktop_get(desktop);
11360 bd->desktop = efreet_util_desktop_name_find(desktop);
11364 if ((bd->client.icccm.name) && (bd->client.icccm.class))
11365 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
11366 bd->client.icccm.class);
11370 /* libreoffice and maybe others match window class
11371 with .desktop file name */
11372 if (bd->client.icccm.class)
11375 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
11376 bd->desktop = efreet_util_desktop_file_id_find(buf);
11381 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
11382 bd->client.netwm.pid);
11383 if (bd->desktop) efreet_desktop_ref(bd->desktop);
11385 if (!bd->desktop && bd->client.icccm.name)
11387 /* this works for most cases as fallback. useful when app is
11388 run from a shell */
11389 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
11391 if (!bd->desktop && bd->client.icccm.transient_for)
11393 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
11394 if (bd2 && bd2->desktop)
11396 efreet_desktop_ref(bd2->desktop);
11397 bd->desktop = bd2->desktop;
11402 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
11403 bd->desktop->orig_path);
11406 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
11407 if ((bd->focused) && (bd->icon_object))
11408 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
11411 evas_object_show(bd->icon_object);
11412 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
11415 evas_object_hide(bd->icon_object);
11418 E_Event_Border_Icon_Change *ev;
11420 ev = E_NEW(E_Event_Border_Icon_Change, 1);
11422 e_object_ref(E_OBJECT(bd));
11423 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
11424 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
11425 _e_border_event_border_icon_change_free, NULL);
11427 bd->changes.icon = 0;
11430 bd->new_client = 0;
11432 bd->changes.stack = 0;
11433 bd->changes.prop = 0;
11435 if (bd->client.e.state.rot.changes != -1)
11437 e_border_rotation_set(bd, bd->client.e.state.rot.changes);
11438 bd->client.e.state.rot.changes = -1;
11441 if ((bd->take_focus) || (bd->want_focus))
11443 bd->take_focus = 0;
11444 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11445 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
11446 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
11449 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
11452 bd->want_focus = 0;
11453 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
11454 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
11455 _e_border_check_stack(bd);
11458 e_border_focus_set_with_pointer(bd);
11460 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
11462 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
11463 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
11464 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
11465 e_border_focused_get())))
11467 e_border_focus_set_with_pointer(bd);
11472 /* focus window by default when it is the only one on desk */
11473 E_Border *bd2 = NULL;
11475 EINA_LIST_FOREACH(focus_stack, l, bd2)
11477 if (bd == bd2) continue;
11478 if ((!bd2->iconic) && (bd2->visible) &&
11479 ((bd->desk == bd2->desk) || bd2->sticky))
11485 e_border_focus_set_with_pointer(bd);
11490 if (bd->need_maximize)
11493 max = bd->maximized;
11494 bd->maximized = E_MAXIMIZE_NONE;
11495 e_border_maximize(bd, max);
11496 bd->need_maximize = 0;
11499 if (bd->need_fullscreen)
11501 e_border_fullscreen(bd, e_config->fullscreen_policy);
11502 bd->need_fullscreen = 0;
11506 e_remember_update(bd);
11508 if (send_event) // FIXME: send only if a property changed - above need to
11509 { // check on that. for now - always send.
11510 event = E_NEW(E_Event_Border_Property, 1);
11511 event->border = bd;
11512 e_object_ref(E_OBJECT(bd));
11513 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11515 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11519 _e_border_moveinfo_gather(E_Border *bd,
11520 const char *source)
11522 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11523 else if (e_util_glob_match(source, "mouse,*,2"))
11524 bd->moveinfo.down.button = 2;
11525 else if (e_util_glob_match(source, "mouse,*,3"))
11526 bd->moveinfo.down.button = 3;
11527 else bd->moveinfo.down.button = 0;
11528 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11530 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11531 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11535 bd->moveinfo.down.mx = bd->mouse.current.mx;
11536 bd->moveinfo.down.my = bd->mouse.current.my;
11541 _e_border_resize_handle(E_Border *bd)
11544 int new_x, new_y, new_w, new_h;
11546 Eina_List *skiplist = NULL;
11553 if ((bd->resize_mode == RESIZE_TR) ||
11554 (bd->resize_mode == RESIZE_R) ||
11555 (bd->resize_mode == RESIZE_BR))
11557 if ((bd->moveinfo.down.button >= 1) &&
11558 (bd->moveinfo.down.button <= 3))
11559 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11560 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11562 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11564 else if ((bd->resize_mode == RESIZE_TL) ||
11565 (bd->resize_mode == RESIZE_L) ||
11566 (bd->resize_mode == RESIZE_BL))
11568 if ((bd->moveinfo.down.button >= 1) &&
11569 (bd->moveinfo.down.button <= 3))
11570 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11571 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11573 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11576 if ((bd->resize_mode == RESIZE_TL) ||
11577 (bd->resize_mode == RESIZE_T) ||
11578 (bd->resize_mode == RESIZE_TR))
11580 if ((bd->moveinfo.down.button >= 1) &&
11581 (bd->moveinfo.down.button <= 3))
11582 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11583 (bd->mouse.current.my - bd->moveinfo.down.my);
11585 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11587 else if ((bd->resize_mode == RESIZE_BL) ||
11588 (bd->resize_mode == RESIZE_B) ||
11589 (bd->resize_mode == RESIZE_BR))
11591 if ((bd->moveinfo.down.button >= 1) &&
11592 (bd->moveinfo.down.button <= 3))
11593 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11594 (bd->mouse.current.my - bd->moveinfo.down.my);
11596 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11602 if ((bd->resize_mode == RESIZE_TL) ||
11603 (bd->resize_mode == RESIZE_L) ||
11604 (bd->resize_mode == RESIZE_BL))
11606 if ((bd->resize_mode == RESIZE_TL) ||
11607 (bd->resize_mode == RESIZE_T) ||
11608 (bd->resize_mode == RESIZE_TR))
11611 skiplist = eina_list_append(skiplist, bd);
11612 e_resist_container_border_position(bd->zone->container, skiplist,
11613 bd->x, bd->y, bd->w, bd->h,
11615 &new_x, &new_y, &new_w, &new_h);
11616 eina_list_free(skiplist);
11620 e_border_resize_limit(bd, &new_w, &new_h);
11621 if ((bd->resize_mode == RESIZE_TL) ||
11622 (bd->resize_mode == RESIZE_L) ||
11623 (bd->resize_mode == RESIZE_BL))
11624 new_x += (w - new_w);
11625 if ((bd->resize_mode == RESIZE_TL) ||
11626 (bd->resize_mode == RESIZE_T) ||
11627 (bd->resize_mode == RESIZE_TR))
11628 new_y += (h - new_h);
11630 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11634 _e_border_shade_animator(void *data)
11636 E_Border *bd = data;
11638 double dur = bd->client.h / e_config->border_shade_speed;
11640 dt = ecore_loop_time_get() - bd->shade.start;
11643 if (val < 0.0) val = 0.0;
11644 else if (val > 1.0) val = 1.0;
11646 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11649 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11650 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11652 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11655 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11656 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11658 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11661 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11662 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11664 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11667 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11668 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11670 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11673 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11674 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11676 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11679 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11680 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11682 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11685 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11686 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11688 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11691 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11692 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11694 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11697 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11698 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11703 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11704 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11707 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11708 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11709 else if (bd->shade.val > .999)
11710 bd->shade.val = 1.0;
11712 if (bd->shade.dir == E_DIRECTION_UP)
11713 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11714 else if (bd->shade.dir == E_DIRECTION_DOWN)
11716 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11717 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11718 bd->changes.pos = 1;
11720 else if (bd->shade.dir == E_DIRECTION_LEFT)
11721 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11722 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11724 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11725 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11726 bd->changes.pos = 1;
11729 if ((bd->shaped) || (bd->client.shaped))
11731 bd->need_shape_merge = 1;
11732 bd->need_shape_export = 1;
11734 if (bd->shaped_input)
11736 bd->need_shape_merge = 1;
11738 bd->changes.size = 1;
11744 E_Event_Border_Resize *ev;
11747 bd->shaded = !(bd->shaded);
11748 bd->changes.size = 1;
11749 bd->changes.shaded = 1;
11750 bd->changes.shading = 1;
11752 bd->shade.anim = NULL;
11755 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11757 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11758 edje_object_message_signal_process(bd->bg_object);
11759 e_border_frame_recalc(bd);
11761 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11762 ev = E_NEW(E_Event_Border_Resize, 1);
11764 e_object_ref(E_OBJECT(bd));
11765 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11766 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11767 return ECORE_CALLBACK_CANCEL;
11769 return ECORE_CALLBACK_RENEW;
11773 _e_border_event_border_resize_free(void *data __UNUSED__,
11776 E_Event_Border_Resize *e;
11779 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11780 e_object_unref(E_OBJECT(e->border));
11785 _e_border_event_border_move_free(void *data __UNUSED__,
11788 E_Event_Border_Move *e;
11791 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11792 e_object_unref(E_OBJECT(e->border));
11797 _e_border_event_border_add_free(void *data __UNUSED__,
11800 E_Event_Border_Add *e;
11803 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11804 e_object_unref(E_OBJECT(e->border));
11809 _e_border_event_border_remove_free(void *data __UNUSED__,
11812 E_Event_Border_Remove *e;
11815 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11816 e_object_unref(E_OBJECT(e->border));
11821 _e_border_event_border_show_free(void *data __UNUSED__,
11824 E_Event_Border_Show *e;
11827 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11828 e_object_unref(E_OBJECT(e->border));
11833 _e_border_event_border_hide_free(void *data __UNUSED__,
11836 E_Event_Border_Hide *e;
11839 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11840 e_object_unref(E_OBJECT(e->border));
11845 _e_border_event_border_iconify_free(void *data __UNUSED__,
11848 E_Event_Border_Iconify *e;
11851 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11852 e_object_unref(E_OBJECT(e->border));
11857 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11860 E_Event_Border_Uniconify *e;
11863 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11864 e_object_unref(E_OBJECT(e->border));
11869 _e_border_event_border_stick_free(void *data __UNUSED__,
11872 E_Event_Border_Stick *e;
11875 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11876 e_object_unref(E_OBJECT(e->border));
11881 _e_border_event_border_unstick_free(void *data __UNUSED__,
11884 E_Event_Border_Unstick *e;
11887 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11888 e_object_unref(E_OBJECT(e->border));
11893 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11896 E_Event_Border_Zone_Set *e;
11899 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11900 e_object_unref(E_OBJECT(e->border));
11901 e_object_unref(E_OBJECT(e->zone));
11906 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11909 E_Event_Border_Desk_Set *e;
11912 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11913 e_object_unref(E_OBJECT(e->border));
11914 e_object_unref(E_OBJECT(e->desk));
11919 _e_border_event_border_stack_free(void *data __UNUSED__,
11922 E_Event_Border_Stack *e;
11925 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
11926 e_object_unref(E_OBJECT(e->border));
11929 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
11930 e_object_unref(E_OBJECT(e->stack));
11936 _e_border_event_border_icon_change_free(void *data __UNUSED__,
11939 E_Event_Border_Icon_Change *e;
11942 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
11943 e_object_unref(E_OBJECT(e->border));
11948 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
11951 E_Event_Border_Urgent_Change *e;
11954 e_object_unref(E_OBJECT(e->border));
11959 _e_border_event_border_focus_in_free(void *data __UNUSED__,
11962 E_Event_Border_Focus_In *e;
11965 e_object_unref(E_OBJECT(e->border));
11970 _e_border_event_border_focus_out_free(void *data __UNUSED__,
11973 E_Event_Border_Focus_Out *e;
11976 e_object_unref(E_OBJECT(e->border));
11981 _e_border_event_border_property_free(void *data __UNUSED__,
11984 E_Event_Border_Property *e;
11987 e_object_unref(E_OBJECT(e->border));
11992 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
11995 E_Event_Border_Fullscreen *e;
11998 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
11999 e_object_unref(E_OBJECT(e->border));
12004 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
12007 E_Event_Border_Unfullscreen *e;
12010 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
12011 e_object_unref(E_OBJECT(e->border));
12015 #ifdef _F_ZONE_WINDOW_ROTATION_
12017 _e_border_event_border_rotation_change_begin_free(void *data __UNUSED__,
12020 E_Event_Border_Rotation_Change_Begin *e;
12022 e_object_unref(E_OBJECT(e->border));
12027 _e_border_event_border_rotation_change_cancel_free(void *data __UNUSED__,
12030 E_Event_Border_Rotation_Change_Cancel *e;
12032 e_object_unref(E_OBJECT(e->border));
12037 _e_border_event_border_rotation_change_end_free(void *data __UNUSED__,
12040 E_Event_Border_Rotation_Change_End *e;
12042 e_object_unref(E_OBJECT(e->border));
12047 _e_border_event_border_rotation_change_begin_send(E_Border *bd)
12049 E_Event_Border_Rotation_Change_Begin *ev = NULL;
12050 ev = E_NEW(E_Event_Border_Rotation_Change_End, 1);
12054 e_object_ref(E_OBJECT(bd));
12055 ecore_event_add(E_EVENT_BORDER_ROTATION_CHANGE_BEGIN,
12057 _e_border_event_border_rotation_change_begin_free,
12064 _e_border_zone_update(E_Border *bd)
12070 /* still within old zone - leave it there */
12071 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12072 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
12073 #if _F_BORDER_CLIP_TO_ZONE_
12075 _e_border_shape_input_clip_to_zone(bd);
12080 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12081 /* find a new zone */
12082 con = bd->zone->container;
12083 EINA_LIST_FOREACH(con->zones, l, zone)
12085 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
12086 zone->x, zone->y, zone->w, zone->h))
12088 e_border_zone_set(bd, zone);
12089 #if _F_BORDER_CLIP_TO_ZONE_
12090 _e_border_shape_input_clip_to_zone(bd);
12091 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
12098 _e_border_resize_begin(E_Border *bd)
12102 if (!bd->lock_user_stacking)
12104 if (e_config->border_raise_on_mouse_action)
12105 e_border_raise(bd);
12107 if ((bd->shaded) || (bd->shading) ||
12108 (bd->fullscreen) || (bd->lock_user_size))
12111 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12112 ret = e_grabinput_get(bd->win, 0, bd->win);
12114 ret = e_grabinput_get(bd->win, 0, 0);
12116 if (grabbed && !ret)
12122 if (bd->client.netwm.sync.request)
12124 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12125 bd->client.netwm.sync.serial = 1;
12126 bd->client.netwm.sync.wait = 0;
12127 bd->client.netwm.sync.send_time = ecore_loop_time_get();
12130 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
12137 _e_border_resize_end(E_Border *bd)
12141 e_grabinput_release(bd->win, bd->win);
12144 if (bd->client.netwm.sync.alarm)
12146 E_Border_Pending_Move_Resize *pnd;
12148 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12149 bd->client.netwm.sync.alarm = 0;
12150 /* resize to last geometry if sync alarm for it was not yet handled */
12151 if (bd->pending_move_resize)
12154 bd->changes.pos = 1;
12155 bd->changes.size = 1;
12156 _e_border_client_move_resize_send(bd);
12159 EINA_LIST_FREE(bd->pending_move_resize, pnd)
12163 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
12167 /* If this border was maximized, we need to unset Maximized state or
12168 * on restart, E still thinks it's maximized */
12169 if (bd->maximized != E_MAXIMIZE_NONE)
12170 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
12171 bd->maximized & E_MAXIMIZE_NONE);
12176 _e_border_resize_update(E_Border *bd)
12178 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
12182 _e_border_move_begin(E_Border *bd)
12185 if (!bd->lock_user_stacking)
12187 if (e_config->border_raise_on_mouse_action)
12188 e_border_raise(bd);
12190 if ((bd->fullscreen) || (bd->lock_user_location))
12193 if (bd->client.icccm.accepts_focus || bd->client.icccm.take_focus)
12194 ret = e_grabinput_get(bd->win, 0, bd->win);
12196 ret = e_grabinput_get(bd->win, 0, 0);
12198 if (grabbed && !ret)
12204 if (bd->client.netwm.sync.request)
12206 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
12207 bd->client.netwm.sync.serial = 0;
12208 bd->client.netwm.sync.wait = 0;
12209 bd->client.netwm.sync.time = ecore_loop_time_get();
12212 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
12219 _e_border_move_end(E_Border *bd)
12223 e_grabinput_release(bd->win, bd->win);
12227 if (bd->client.netwm.sync.alarm)
12229 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
12230 bd->client.netwm.sync.alarm = 0;
12233 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
12240 _e_border_move_update(E_Border *bd)
12242 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
12246 _e_border_cb_ping_poller(void *data)
12256 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
12257 if (bd->kill_timer)
12259 ecore_timer_del(bd->kill_timer);
12260 bd->kill_timer = NULL;
12266 /* if time between last ping and now is greater
12267 * than half the ping interval... */
12268 if ((ecore_loop_time_get() - bd->ping) >
12269 ((e_config->ping_clients_interval *
12270 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
12275 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
12276 /* FIXME: if below dialog is up - hide it now */
12278 if (bd->delete_requested)
12280 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
12281 e_border_act_kill_begin(bd);
12285 bd->ping_poller = NULL;
12287 return ECORE_CALLBACK_CANCEL;
12291 _e_border_cb_kill_timer(void *data)
12296 // dont wait until it's hung -
12299 if (bd->client.netwm.pid > 1)
12300 kill(bd->client.netwm.pid, SIGKILL);
12302 bd->kill_timer = NULL;
12303 return ECORE_CALLBACK_CANCEL;
12307 _e_border_pointer_resize_begin(E_Border *bd)
12309 switch (bd->resize_mode)
12312 e_pointer_type_push(bd->pointer, bd, "resize_tl");
12316 e_pointer_type_push(bd->pointer, bd, "resize_t");
12320 e_pointer_type_push(bd->pointer, bd, "resize_tr");
12324 e_pointer_type_push(bd->pointer, bd, "resize_r");
12328 e_pointer_type_push(bd->pointer, bd, "resize_br");
12332 e_pointer_type_push(bd->pointer, bd, "resize_b");
12336 e_pointer_type_push(bd->pointer, bd, "resize_bl");
12340 e_pointer_type_push(bd->pointer, bd, "resize_l");
12346 _e_border_pointer_resize_end(E_Border *bd)
12348 switch (bd->resize_mode)
12351 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
12355 e_pointer_type_pop(bd->pointer, bd, "resize_t");
12359 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
12363 e_pointer_type_pop(bd->pointer, bd, "resize_r");
12367 e_pointer_type_pop(bd->pointer, bd, "resize_br");
12371 e_pointer_type_pop(bd->pointer, bd, "resize_b");
12375 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
12379 e_pointer_type_pop(bd->pointer, bd, "resize_l");
12385 _e_border_pointer_move_begin(E_Border *bd)
12387 e_pointer_type_push(bd->pointer, bd, "move");
12391 _e_border_pointer_move_end(E_Border *bd)
12393 e_pointer_type_pop(bd->pointer, bd, "move");
12396 static Eina_List *_e_border_hooks = NULL;
12397 static int _e_border_hooks_delete = 0;
12398 static int _e_border_hooks_walking = 0;
12401 _e_border_hooks_clean(void)
12406 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
12410 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
12417 _e_border_hook_call(E_Border_Hook_Point hookpoint,
12423 _e_border_hooks_walking++;
12424 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
12426 if (bh->delete_me) continue;
12427 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
12429 _e_border_hooks_walking--;
12430 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
12431 _e_border_hooks_clean();
12434 EAPI E_Border_Hook *
12435 e_border_hook_add(E_Border_Hook_Point hookpoint,
12436 void (*func)(void *data,
12442 bh = E_NEW(E_Border_Hook, 1);
12443 if (!bh) return NULL;
12444 bh->hookpoint = hookpoint;
12447 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
12452 e_border_hook_del(E_Border_Hook *bh)
12455 if (_e_border_hooks_walking == 0)
12457 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
12461 _e_border_hooks_delete++;
12465 e_border_focus_track_freeze(void)
12467 focus_track_frozen++;
12471 e_border_focus_track_thaw(void)
12473 focus_track_frozen--;
12477 e_border_under_pointer_get(E_Desk *desk,
12480 E_Border *bd = NULL, *cbd;
12484 /* We need to ensure that we can get the container window for the
12485 * zone of either the given desk or the desk of the excluded
12486 * window, so return if neither is given */
12488 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
12490 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
12494 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
12496 if (!cbd) continue;
12497 /* If a border was specified which should be excluded from the list
12498 * (because it will be closed shortly for example), skip */
12499 if ((exclude) && (cbd == exclude)) continue;
12500 if ((desk) && (cbd->desk != desk)) continue;
12501 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
12503 /* If the layer is higher, the position of the window is higher
12504 * (always on top vs always below) */
12505 if (!bd || (cbd->layer > bd->layer))
12515 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
12522 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
12523 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
12524 (y - warp_y) > 5 || (y - warp_y) < -5)
12526 /* User moved the mouse, so stop warping */
12531 /* We just use the same warp speed as configured
12532 * for the windowlist */
12533 spd = e_config->winlist_warp_speed;
12536 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12537 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12538 if (warp_x == x && warp_y == y)
12540 warp_x = warp_to_x;
12541 warp_y = warp_to_y;
12545 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12546 return ECORE_CALLBACK_RENEW;
12549 ecore_timer_del(warp_timer);
12551 return ECORE_CALLBACK_CANCEL;
12555 e_border_pointer_warp_to_center(E_Border *bd)
12559 /* Do not slide pointer when disabled (probably breaks focus
12560 * on sloppy/mouse focus but requested by users). */
12561 if (!e_config->pointer_slide) return 0;
12562 /* Only warp the pointer if it is not already in the area of
12563 * the given border */
12564 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12565 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12566 (y >= bd->y) && (y <= (bd->y + bd->h)))
12569 warp_to_x = bd->x + (bd->w / 2);
12570 if (warp_to_x < (bd->zone->x + 1))
12571 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12572 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12573 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12575 warp_to_y = bd->y + (bd->h / 2);
12576 if (warp_to_y < (bd->zone->y + 1))
12577 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12578 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12579 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12582 warp_to_win = bd->zone->container->win;
12583 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12585 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12590 e_border_comp_hidden_set(E_Border *bd,
12596 E_OBJECT_CHECK(bd);
12597 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12599 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12602 ecore_x_window_hide(tmp->win);
12604 ecore_x_window_show(tmp->win);
12607 if (bd->comp_hidden == hidden) return;
12609 bd->comp_hidden = hidden;
12611 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12613 ecore_x_composite_window_events_disable(bd->win);
12614 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12618 _e_border_shape_input_rectangle_set(bd);
12619 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12624 e_border_tmp_input_hidden_push(E_Border *bd)
12629 E_OBJECT_CHECK(bd);
12630 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12632 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12633 e_border_tmp_input_hidden_push(tmp);
12635 bd->tmp_input_hidden++;
12636 if (bd->tmp_input_hidden != 1) return;
12638 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12640 ecore_x_composite_window_events_disable(bd->win);
12641 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12645 _e_border_shape_input_rectangle_set(bd);
12646 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12651 e_border_tmp_input_hidden_pop(E_Border *bd)
12656 E_OBJECT_CHECK(bd);
12657 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12659 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12660 e_border_tmp_input_hidden_pop(tmp);
12662 bd->tmp_input_hidden--;
12663 if (bd->tmp_input_hidden != 0) return;
12665 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12667 ecore_x_composite_window_events_disable(bd->win);
12668 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12672 _e_border_shape_input_rectangle_set(bd);
12673 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12678 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12680 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12682 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12683 ((bd->parent->focused) &&
12684 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12689 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12690 e_desk_show(bd->desk);
12692 if (!bd->lock_user_iconify)
12693 e_border_uniconify(bd);
12695 if ((!bd->iconic) && (!bd->sticky))
12696 e_desk_show(bd->desk);
12697 if (!bd->lock_user_stacking) e_border_raise(bd);
12698 if (!bd->lock_focus_out)
12700 /* XXX ooffice does send this request for
12701 config dialogs when the main window gets focus.
12702 causing the pointer to jump back and forth. */
12703 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12704 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12705 ecore_x_pointer_warp(bd->zone->container->win,
12706 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12707 e_border_focus_set(bd, 1, 1);
12711 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/