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(void *data,
155 static Eina_Bool _e_border_rotation_change_prepare_timeout(void *data);
156 static void _e_border_rotation_change_request(E_Zone *zone);
157 static Eina_Bool _e_border_rotation_change_done_timeout(void *data);
158 static void _e_border_rotation_change_done(void);
159 static Eina_Bool _e_border_rotation_geom_get(E_Border *bd,
167 static Eina_Bool _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd);
168 static void _e_border_rotation_list_remove(E_Border *bd);
169 static Eina_Bool _e_border_rotation_check(E_Border *bd);
170 static Eina_Bool _e_border_rotation_zone_check(E_Zone *zone);
171 static Eina_Bool _e_border_rotation_border_check(E_Border *bd, int ang);
172 static Eina_Bool _e_border_rotation_zone_vkbd_check(E_Zone *zone);
173 static Eina_Bool _e_border_rotation_vkbd_transient_for_check(E_Border *bd);
174 static Eina_Bool _e_border_rotation_transient_for_check(E_Border *bd, int ang);
175 static Eina_Bool _e_border_cb_window_configure(void *data,
178 static Eina_Bool _e_border_vkbd_show_prepare_timeout(void *data);
179 static Eina_Bool _e_border_vkbd_hide_prepare_timeout(void *data);
180 static void _e_border_vkbd_show(E_Border *bd);
181 static void _e_border_vkbd_hide(E_Border *bd);
183 static void _e_border_move_resize_internal(E_Border *bd,
188 Eina_Bool without_border,
191 static void _e_border_eval(E_Border *bd);
192 static void _e_border_eval0(E_Border *bd);
193 static void _e_border_container_layout_hook(E_Container *con);
195 static void _e_border_moveinfo_gather(E_Border *bd,
197 static void _e_border_resize_handle(E_Border *bd);
199 static Eina_Bool _e_border_shade_animator(void *data);
201 static void _e_border_event_border_add_free(void *data,
203 static void _e_border_event_border_remove_free(void *data,
205 static void _e_border_event_border_zone_set_free(void *data,
207 static void _e_border_event_border_desk_set_free(void *data,
209 static void _e_border_event_border_stack_free(void *data,
211 static void _e_border_event_border_icon_change_free(void *data,
213 static void _e_border_event_border_urgent_change_free(void *data,
215 static void _e_border_event_border_focus_in_free(void *data,
217 static void _e_border_event_border_focus_out_free(void *data,
219 static void _e_border_event_border_resize_free(void *data,
221 static void _e_border_event_border_move_free(void *data,
223 static void _e_border_event_border_show_free(void *data,
225 static void _e_border_event_border_hide_free(void *data,
227 static void _e_border_event_border_iconify_free(void *data,
229 static void _e_border_event_border_uniconify_free(void *data,
231 static void _e_border_event_border_stick_free(void *data,
233 static void _e_border_event_border_unstick_free(void *data,
235 static void _e_border_event_border_property_free(void *data,
237 static void _e_border_event_border_fullscreen_free(void *data,
239 static void _e_border_event_border_unfullscreen_free(void *data,
241 #ifdef _F_ZONE_WINDOW_ROTATION_
242 static void _e_border_event_border_rotation_free(void *data,
246 static void _e_border_zone_update(E_Border *bd);
248 static int _e_border_resize_begin(E_Border *bd);
249 static int _e_border_resize_end(E_Border *bd);
250 static void _e_border_resize_update(E_Border *bd);
252 static int _e_border_move_begin(E_Border *bd);
253 static int _e_border_move_end(E_Border *bd);
254 static void _e_border_move_update(E_Border *bd);
256 static Eina_Bool _e_border_cb_ping_poller(void *data);
257 static Eina_Bool _e_border_cb_kill_timer(void *data);
259 static void _e_border_pointer_resize_begin(E_Border *bd);
260 static void _e_border_pointer_resize_end(E_Border *bd);
261 static void _e_border_pointer_move_begin(E_Border *bd);
262 static void _e_border_pointer_move_end(E_Border *bd);
264 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
267 static void _e_border_client_move_resize_send(E_Border *bd);
269 static void _e_border_frame_replace(E_Border *bd,
272 static void _e_border_shape_input_rectangle_set(E_Border* bd);
273 static void _e_border_show(E_Border *bd);
274 static void _e_border_hide(E_Border *bd);
277 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
278 static void _e_border_latest_stacked_focus (E_Border* bd);
279 static void _e_border_check_stack (E_Border *bd);
280 static void _e_border_focus_top_stack_set (E_Border* bd);
282 #if _F_BORDER_CLIP_TO_ZONE_
283 static void _e_border_shape_input_clip_to_zone(E_Border *bd);
284 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
285 /* local subsystem globals */
286 static Eina_List *handlers = NULL;
287 static Eina_List *borders = NULL;
288 static Eina_Hash *borders_hash = NULL;
289 static E_Border *focused = NULL;
290 static E_Border *focusing = NULL;
291 static Eina_List *focus_next = NULL;
292 static Ecore_X_Time focus_time = 0;
294 static E_Border *bdresize = NULL;
295 static E_Border *bdmove = NULL;
296 static E_Drag *drag_border = NULL;
298 static int grabbed = 0;
300 static Eina_List *focus_stack = NULL;
301 static Eina_List *raise_stack = NULL;
303 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
304 static int screen_size_index = -1;
306 static int focus_track_frozen = 0;
308 static int warp_to = 0;
309 static int warp_to_x = 0;
310 static int warp_to_y = 0;
311 static int warp_x = 0;
312 static int warp_y = 0;
313 static Ecore_X_Window warp_to_win;
314 static Ecore_Timer *warp_timer = NULL;
316 #ifdef _F_ZONE_WINDOW_ROTATION_
317 typedef struct _E_Border_Rotation E_Border_Rotation;
318 typedef struct _E_Border_Rotation_Info E_Border_Rotation_Info;
320 struct _E_Border_Rotation
324 Eina_Bool wait_prepare_done;
325 Ecore_Timer *prepare_timer;
326 Ecore_Timer *done_timer;
328 Ecore_X_Window vkbd_ctrl_win;
330 E_Border *vkbd_prediction;
332 /* vkbd show/hide preprare */
333 Eina_Bool vkbd_show_prepare_done;
334 Ecore_Timer *vkbd_show_prepare_timer;
335 Ecore_Timer *vkbd_show_timer;
337 Eina_Bool vkbd_hide_prepare_done;
338 Ecore_Timer *vkbd_hide_prepare_timer;
339 Ecore_Timer *vkbd_hide_timer;
345 struct _E_Border_Rotation_Info
350 Eina_Bool win_resize;
353 static E_Border_Rotation rot =
373 EAPI int E_EVENT_BORDER_ADD = 0;
374 EAPI int E_EVENT_BORDER_REMOVE = 0;
375 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
376 EAPI int E_EVENT_BORDER_DESK_SET = 0;
377 EAPI int E_EVENT_BORDER_RESIZE = 0;
378 EAPI int E_EVENT_BORDER_MOVE = 0;
379 EAPI int E_EVENT_BORDER_SHOW = 0;
380 EAPI int E_EVENT_BORDER_HIDE = 0;
381 EAPI int E_EVENT_BORDER_ICONIFY = 0;
382 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
383 EAPI int E_EVENT_BORDER_STICK = 0;
384 EAPI int E_EVENT_BORDER_UNSTICK = 0;
385 EAPI int E_EVENT_BORDER_STACK = 0;
386 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
387 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
388 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
389 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
390 EAPI int E_EVENT_BORDER_PROPERTY = 0;
391 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
392 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
393 #ifdef _F_ZONE_WINDOW_ROTATION_
394 EAPI int E_EVENT_BORDER_ROTATION = 0;
397 #define GRAV_SET(bd, grav) \
398 ecore_x_window_gravity_set(bd->bg_win, grav); \
399 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
400 ecore_x_window_gravity_set(bd->client.win, grav);
403 _e_border_sub_borders_new(E_Border *bd)
405 Eina_List *list = NULL, *l;
409 EINA_LIST_FOREACH(bd->transients, l, child)
411 if (!eina_list_data_find(list, child))
412 list = eina_list_append(list, child);
414 bl = e_container_border_list_first(bd->zone->container);
415 while ((child = e_container_border_list_next(bl)))
417 if (e_object_is_del(E_OBJECT(child))) continue;
418 if (child == bd) continue;
420 if ((bd->client.icccm.client_leader) &&
421 (child->client.icccm.client_leader ==
422 bd->client.icccm.client_leader))
424 printf("bd %s in group with %s\n",
425 e_border_name_get(child),
426 e_border_name_get(bd));
427 if (!eina_list_data_find(list, child))
428 list = eina_list_append(list, child);
432 e_container_border_list_free(bl);
436 /* externally accessible functions */
440 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
441 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
442 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
443 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
444 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
445 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
446 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
447 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
448 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
449 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
450 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
451 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
452 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
453 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
454 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
455 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
456 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
457 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
458 #ifdef _F_ZONE_WINDOW_ROTATION_
459 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_border_cb_window_configure, NULL));
462 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
464 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
465 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
466 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
467 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
468 #ifdef _F_USE_DESK_WINDOW_PROFILE_
469 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_DESK_WINDOW_PROFILE_CHANGE, _e_border_cb_desk_window_profile_change, NULL));
471 #ifdef _F_ZONE_WINDOW_ROTATION_
472 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_ZONE_ROTATION_CHANGE, _e_border_cb_zone_rotation_change, NULL));
475 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
477 E_EVENT_BORDER_ADD = ecore_event_type_new();
478 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
479 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
480 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
481 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
482 E_EVENT_BORDER_MOVE = ecore_event_type_new();
483 E_EVENT_BORDER_SHOW = ecore_event_type_new();
484 E_EVENT_BORDER_HIDE = ecore_event_type_new();
485 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
486 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
487 E_EVENT_BORDER_STICK = ecore_event_type_new();
488 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
489 E_EVENT_BORDER_STACK = ecore_event_type_new();
490 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
491 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
492 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
493 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
494 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
495 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
496 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
497 #ifdef _F_ZONE_WINDOW_ROTATION_
498 E_EVENT_BORDER_ROTATION = ecore_event_type_new();
507 e_border_shutdown(void)
509 E_FREE_LIST(handlers, ecore_event_handler_del);
511 if (borders_hash) eina_hash_free(borders_hash);
513 e_int_border_menu_hooks_clear();
519 e_border_new(E_Container *con,
525 Ecore_X_Window_Attributes *att;
526 unsigned int managed, desk[2];
529 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
530 if (!bd) return NULL;
531 ecore_x_window_shadow_tree_flush();
532 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
536 /* FIXME: ewww - round trip */
537 bd->client.argb = ecore_x_window_argb_get(win);
539 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
542 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
543 ecore_x_window_shape_events_select(bd->win, 1);
545 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
546 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
548 bd->bg_ecore_evas = e_canvas_new(bd->win,
549 0, 0, bd->w, bd->h, 1, 0,
551 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
552 e_canvas_add(bd->bg_ecore_evas);
553 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
554 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
555 ecore_x_window_shape_events_select(bd->bg_win, 1);
556 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
557 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
559 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
561 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
562 ecore_x_window_container_manage(bd->client.shell_win);
563 if (!internal) ecore_x_window_client_manage(win);
564 /* FIXME: Round trip. XCB */
565 /* fetch needed to avoid grabbing the server as window may vanish */
566 att = &bd->client.initial_attributes;
567 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
569 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
570 e_canvas_del(bd->bg_ecore_evas);
571 ecore_evas_free(bd->bg_ecore_evas);
572 ecore_x_window_free(bd->client.shell_win);
573 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
574 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
575 ecore_x_window_free(bd->win);
580 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
581 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
583 /* FIXME: if first_map is 1 then we should ignore the first hide event
584 * or ensure the window is already hidden and events flushed before we
585 * create a border for it */
588 // printf("##- FIRST MAP\n");
593 // needed to be 1 for internal windw and on restart.
594 // bd->ignore_first_unmap = 2;
597 bd->client.win = win;
598 bd->zone = e_zone_current_get(con);
600 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
602 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
603 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
604 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
605 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
606 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
607 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
609 bd->client.icccm.title = NULL;
610 bd->client.icccm.name = NULL;
611 bd->client.icccm.class = NULL;
612 bd->client.icccm.icon_name = NULL;
613 bd->client.icccm.machine = NULL;
614 bd->client.icccm.min_w = 1;
615 bd->client.icccm.min_h = 1;
616 bd->client.icccm.max_w = 32767;
617 bd->client.icccm.max_h = 32767;
618 bd->client.icccm.base_w = 0;
619 bd->client.icccm.base_h = 0;
620 bd->client.icccm.step_w = -1;
621 bd->client.icccm.step_h = -1;
622 bd->client.icccm.min_aspect = 0.0;
623 bd->client.icccm.max_aspect = 0.0;
624 bd->client.icccm.accepts_focus = 1;
626 bd->client.netwm.pid = 0;
627 bd->client.netwm.name = NULL;
628 bd->client.netwm.icon_name = NULL;
629 bd->client.netwm.desktop = 0;
630 bd->client.netwm.state.modal = 0;
631 bd->client.netwm.state.sticky = 0;
632 bd->client.netwm.state.shaded = 0;
633 bd->client.netwm.state.hidden = 0;
634 bd->client.netwm.state.maximized_v = 0;
635 bd->client.netwm.state.maximized_h = 0;
636 bd->client.netwm.state.skip_taskbar = 0;
637 bd->client.netwm.state.skip_pager = 0;
638 bd->client.netwm.state.fullscreen = 0;
639 bd->client.netwm.state.stacking = E_STACKING_NONE;
640 bd->client.netwm.action.move = 0;
641 bd->client.netwm.action.resize = 0;
642 bd->client.netwm.action.minimize = 0;
643 bd->client.netwm.action.shade = 0;
644 bd->client.netwm.action.stick = 0;
645 bd->client.netwm.action.maximized_h = 0;
646 bd->client.netwm.action.maximized_v = 0;
647 bd->client.netwm.action.fullscreen = 0;
648 bd->client.netwm.action.change_desktop = 0;
649 bd->client.netwm.action.close = 0;
650 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
656 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
657 bd->client.icccm.fetch.command = 1;
660 Eina_Bool video_parent = EINA_FALSE;
661 Eina_Bool video_position = EINA_FALSE;
664 for (i = 0; i < at_num; i++)
666 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
667 bd->client.icccm.fetch.title = 1;
668 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
669 bd->client.icccm.fetch.name_class = 1;
670 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
671 bd->client.icccm.fetch.icon_name = 1;
672 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
673 bd->client.icccm.fetch.machine = 1;
674 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
675 bd->client.icccm.fetch.hints = 1;
676 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
677 bd->client.icccm.fetch.size_pos_hints = 1;
678 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
679 bd->client.icccm.fetch.protocol = 1;
680 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
681 bd->client.mwm.fetch.hints = 1;
682 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
684 bd->client.icccm.fetch.transient_for = 1;
685 bd->client.netwm.fetch.type = 1;
687 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
688 bd->client.icccm.fetch.client_leader = 1;
689 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
690 bd->client.icccm.fetch.window_role = 1;
691 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
692 bd->client.icccm.fetch.state = 1;
694 /* netwm, loop again, netwm will ignore some icccm, so we
695 * have to be sure that netwm is checked after */
696 for (i = 0; i < at_num; i++)
698 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
701 bd->client.icccm.fetch.title = 0;
702 bd->client.netwm.fetch.name = 1;
704 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
707 bd->client.icccm.fetch.icon_name = 0;
708 bd->client.netwm.fetch.icon_name = 1;
710 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
712 bd->client.netwm.fetch.icon = 1;
714 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
716 bd->client.netwm.fetch.user_time = 1;
718 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
720 DBG("ECORE_X_ATOM_NET_WM_STRUT");
721 bd->client.netwm.fetch.strut = 1;
723 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
725 DBG("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL");
726 bd->client.netwm.fetch.strut = 1;
728 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
731 bd->client.mwm.fetch.hints = 0;
733 bd->client.netwm.fetch.type = 1;
735 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
737 bd->client.netwm.fetch.state = 1;
740 /* other misc atoms */
741 for (i = 0; i < at_num; i++)
743 /* loop to check for own atoms */
744 if (atoms[i] == E_ATOM_WINDOW_STATE)
746 bd->client.e.fetch.state = 1;
748 /* loop to check for qtopia atoms */
749 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
750 bd->client.qtopia.fetch.soft_menu = 1;
751 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
752 bd->client.qtopia.fetch.soft_menus = 1;
753 /* loop to check for vkbd atoms */
754 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
755 bd->client.vkbd.fetch.state = 1;
756 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
757 bd->client.vkbd.fetch.vkbd = 1;
758 /* loop to check for illume atoms */
759 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
760 bd->client.illume.conformant.fetch.conformant = 1;
761 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
762 bd->client.illume.quickpanel.fetch.state = 1;
763 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
764 bd->client.illume.quickpanel.fetch.quickpanel = 1;
765 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
766 bd->client.illume.quickpanel.fetch.priority.major = 1;
767 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
768 bd->client.illume.quickpanel.fetch.priority.minor = 1;
769 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
770 bd->client.illume.quickpanel.fetch.zone = 1;
771 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
772 bd->client.illume.drag.fetch.locked = 1;
773 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
774 bd->client.illume.drag.fetch.drag = 1;
775 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
776 bd->client.illume.win_state.fetch.state = 1;
777 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
778 video_parent = EINA_TRUE;
779 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
780 video_position = EINA_TRUE;
781 #ifdef _F_USE_DESK_WINDOW_PROFILE_
782 /* loop to check for window profile list atom */
783 else if (atoms[i] == ECORE_X_ATOM_E_PROFILE_LIST)
784 bd->client.e.fetch.profile_list = 1;
786 #ifdef _F_ZONE_WINDOW_ROTATION_
787 /* loop to check for wm rotation */
788 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
790 if (e_config->wm_win_rotation)
791 bd->client.e.fetch.rot.support = 1;
793 else if ((atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
794 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
795 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
796 (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
798 if (e_config->wm_win_rotation)
799 bd->client.e.fetch.rot.geom_hint = 1;
801 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
803 if (e_config->wm_win_rotation)
804 bd->client.e.fetch.rot.app_set = 1;
806 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
808 if (e_config->wm_win_rotation)
809 bd->client.e.fetch.rot.preferred_rot = 1;
811 else if (atoms[i] == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
813 if (e_config->wm_win_rotation)
814 bd->client.e.fetch.rot.available_rots = 1;
817 #ifdef _F_DEICONIFY_APPROVE_
818 else if (atoms[i] == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
820 bd->client.e.state.deiconify_approve.support = 1;
824 if (video_position && video_parent)
826 bd->client.e.state.video = 1;
827 bd->client.e.fetch.video_parent = 1;
828 bd->client.e.fetch.video_position = 1;
829 ecore_x_window_lower(bd->win);
830 ecore_x_composite_window_events_disable(bd->win);
831 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
832 fprintf(stderr, "We found a video window \\o/ %x\n", win);
837 bd->client.border.changed = 1;
839 bd->client.w = att->w;
840 bd->client.h = att->h;
842 bd->w = bd->client.w;
843 bd->h = bd->client.h;
845 bd->resize_mode = RESIZE_NONE;
847 bd->saved.layer = bd->layer;
848 bd->changes.icon = 1;
849 bd->changes.size = 1;
850 bd->changes.shape = 1;
851 bd->changes.shape_input = 1;
853 bd->offer_resistance = 1;
855 /* just to friggin make java happy - we're DELAYING the reparent until
858 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
859 bd->need_reparent = 1;
861 ecore_x_window_border_width_set(win, 0);
862 ecore_x_window_show(bd->event_win);
863 ecore_x_window_show(bd->client.shell_win);
864 bd->shape = e_container_shape_add(con);
869 #ifdef _F_ZONE_WINDOW_ROTATION_
870 bd->client.e.state.rot.preferred_rot = -1;
873 // bd->zone = e_zone_current_get(con);
874 bd->desk = e_desk_current_get(bd->zone);
875 e_container_border_add(bd);
876 borders = eina_list_append(borders, bd);
877 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
881 WRN("EEEEK! 2 borders with same client window id in them! very bad!\n"
882 "optimisations failing due to bizarre client behavior. will\n"
884 "bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x",
885 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
888 ELBF(ELBT_BD, 0, bd->client.win,
889 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
890 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
892 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
893 printf("optimisations failing due to bizarre client behavior. will\n");
894 printf("work around.\n");
895 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
896 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
899 ELBF(ELBT_BD, 0, bd->client.win,
900 "ERR! 2 borders with same client win id in them! bd:%p ref:%i deleted:%i",
901 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted);
904 #ifdef _F_ZONE_WINDOW_ROTATION_
905 if ((rot.vkbd) && (rot.vkbd == bd2))
907 ELB(ELBT_BD, "UNSET VKBD", rot.vkbd->client.win);
908 ELBF(ELBT_BD, 1, rot.vkbd->client.win, "VKBD HIDE PREPARE_DONE:%d",
909 rot.vkbd_hide_prepare_done);
911 if (rot.vkbd_hide_prepare_timer)
913 ecore_timer_del(rot.vkbd_hide_prepare_timer);
914 rot.vkbd_hide_prepare_timer = NULL;
916 e_object_unref(E_OBJECT(bd2));
919 _e_border_vkbd_hide(rot.vkbd);
921 if (rot.vkbd_ctrl_win)
923 ELB(ELBT_BD, "SET KBD_OFF", 0);
924 ecore_x_e_virtual_keyboard_state_set
925 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
927 rot.vkbd_hide_prepare_done = EINA_FALSE;
929 if (rot.vkbd_hide_timer)
930 ecore_timer_del(rot.vkbd_hide_timer);
931 rot.vkbd_hide_timer = NULL;
933 rot.vkbd_show_prepare_done = EINA_FALSE;
934 if (rot.vkbd_show_prepare_timer)
935 ecore_timer_del(rot.vkbd_show_prepare_timer);
936 rot.vkbd_show_prepare_timer = NULL;
937 if (rot.vkbd_show_timer)
938 ecore_timer_del(rot.vkbd_show_timer);
939 rot.vkbd_show_timer = NULL;
944 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
945 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
946 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
948 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
949 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
950 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
952 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
953 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
954 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
956 unsigned int zgeom[4];
958 zgeom[0] = bd->zone->x;
959 zgeom[1] = bd->zone->y;
960 zgeom[2] = bd->zone->w;
961 zgeom[3] = bd->zone->h;
962 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
964 e_desk_xy_get(bd->desk, &deskx, &desky);
967 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
968 #ifdef _F_USE_DESK_WINDOW_PROFILE_
969 if (strcmp(bd->desk->window_profile,
970 e_config->desktop_default_window_profile) != 0)
972 ecore_x_e_window_profile_set(bd->client.win,
973 bd->desk->window_profile);
977 focus_stack = eina_list_append(focus_stack, bd);
979 bd->pointer = e_pointer_window_new(bd->win, 0);
984 e_border_res_change_geometry_save(E_Border *bd)
987 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
989 if (bd->pre_res_change.valid) return;
990 bd->pre_res_change.valid = 1;
991 bd->pre_res_change.x = bd->x;
992 bd->pre_res_change.y = bd->y;
993 bd->pre_res_change.w = bd->w;
994 bd->pre_res_change.h = bd->h;
995 bd->pre_res_change.saved.x = bd->saved.x;
996 bd->pre_res_change.saved.y = bd->saved.y;
997 bd->pre_res_change.saved.w = bd->saved.w;
998 bd->pre_res_change.saved.h = bd->saved.h;
1002 e_border_res_change_geometry_restore(E_Border *bd)
1006 unsigned char valid : 1;
1015 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1016 if (!bd->pre_res_change.valid) return;
1017 if (bd->new_client) return;
1019 ecore_x_window_shadow_tree_flush();
1020 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
1024 e_border_unfullscreen(bd);
1025 e_border_fullscreen(bd, e_config->fullscreen_policy);
1027 else if (bd->maximized != E_MAXIMIZE_NONE)
1031 max = bd->maximized;
1032 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
1033 e_border_maximize(bd, max);
1037 int x, y, w, h, zx, zy, zw, zh;
1039 bd->saved.x = bd->pre_res_change.saved.x;
1040 bd->saved.y = bd->pre_res_change.saved.y;
1041 bd->saved.w = bd->pre_res_change.saved.w;
1042 bd->saved.h = bd->pre_res_change.saved.h;
1044 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1046 if (bd->saved.w > zw)
1048 if ((bd->saved.x + bd->saved.w) > (zx + zw))
1049 bd->saved.x = zx + zw - bd->saved.w;
1051 if (bd->saved.h > zh)
1053 if ((bd->saved.y + bd->saved.h) > (zy + zh))
1054 bd->saved.y = zy + zh - bd->saved.h;
1056 x = bd->pre_res_change.x;
1057 y = bd->pre_res_change.y;
1058 w = bd->pre_res_change.w;
1059 h = bd->pre_res_change.h;
1064 if ((x + w) > (zx + zw))
1066 if ((y + h) > (zy + zh))
1068 e_border_move_resize(bd, x, y, w, h);
1070 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
1074 e_border_zone_set(E_Border *bd,
1077 E_Event_Border_Zone_Set *ev;
1080 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1081 E_OBJECT_CHECK(zone);
1082 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
1084 if (bd->zone == zone) return;
1086 /* if the window does not lie in the new zone, move it so that it does */
1087 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1090 /* first guess -- get offset from old zone, and apply to new zone */
1091 x = zone->x + (bd->x - bd->zone->x);
1092 y = zone->y + (bd->y - bd->zone->y);
1094 /* keep window from hanging off bottom and left */
1095 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
1096 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
1098 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
1099 if (x < zone->x) x = zone->x;
1100 if (y < zone->y) y = zone->y;
1102 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
1104 /* still not in zone at all, so just move it to closest edge */
1105 if (x < zone->x) x = zone->x;
1106 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
1107 if (y < zone->y) y = zone->y;
1108 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
1110 e_border_move(bd, x, y);
1115 if (bd->desk->zone != bd->zone)
1116 e_border_desk_set(bd, e_desk_current_get(bd->zone));
1118 ev = E_NEW(E_Event_Border_Zone_Set, 1);
1120 e_object_ref(E_OBJECT(bd));
1121 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
1123 e_object_ref(E_OBJECT(zone));
1125 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
1127 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
1128 // XXXXXXXXXXXXXXXXXXXXXXXXX
1129 // XXX ZZZZZZZZZZZZZZZZZZZzz
1130 // need to adjust this if zone pos/size changes
1132 unsigned int zgeom[4];
1134 zgeom[0] = bd->zone->x;
1135 zgeom[1] = bd->zone->y;
1136 zgeom[2] = bd->zone->w;
1137 zgeom[3] = bd->zone->h;
1138 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE_GEOMETRY, zgeom, 4);
1140 e_remember_update(bd);
1144 e_border_desk_set(E_Border *bd,
1147 E_Event_Border_Desk_Set *ev;
1151 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1152 E_OBJECT_CHECK(desk);
1153 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
1154 if (bd->desk == desk) return;
1155 ecore_x_window_shadow_tree_flush();
1158 bd->desk->fullscreen_borders--;
1159 desk->fullscreen_borders++;
1161 old_desk = bd->desk;
1163 e_border_zone_set(bd, desk->zone);
1165 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
1166 e_hints_window_desktop_set(bd);
1168 ev = E_NEW(E_Event_Border_Desk_Set, 1);
1170 e_object_ref(E_OBJECT(bd));
1171 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
1172 ev->desk = old_desk;
1173 e_object_ref(E_OBJECT(old_desk));
1174 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
1176 if (bd->ignore_first_unmap != 1)
1178 if ((bd->desk->visible) || (bd->sticky))
1181 e_border_hide(bd, 1);
1184 if (e_config->transient.desktop)
1188 Eina_List *list = _e_border_sub_borders_new(bd);
1190 EINA_LIST_FOREACH(list, l, child)
1192 e_border_desk_set(child, bd->desk);
1194 eina_list_free(list);
1196 e_remember_update(bd);
1199 #ifdef _F_ZONE_WINDOW_ROTATION_
1201 _e_border_vkbd_state_check(E_Border *bd,
1204 Eina_Bool res = EINA_TRUE;
1205 if (!e_config->wm_win_rotation) return EINA_FALSE;
1206 if ((rot.vkbd) && (rot.vkbd == bd))
1210 if ((rot.vkbd_hide_prepare_done) ||
1211 (rot.vkbd_hide_prepare_timer))
1216 if ((rot.vkbd_show_prepare_done) ||
1217 (rot.vkbd_show_prepare_timer))
1225 _e_border_vkbd_show_timeout(void *data)
1227 E_Border *bd = data;
1228 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1229 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1231 if (_e_border_vkbd_state_check(bd, EINA_TRUE))
1233 if (rot.vkbd_ctrl_win)
1235 ELB(ELBT_BD, "SET KBD_ON", 0);
1236 ecore_x_e_virtual_keyboard_state_set
1237 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_ON);
1242 rot.vkbd_show_prepare_done = EINA_FALSE;
1244 if (rot.vkbd_show_prepare_timer)
1245 ecore_timer_del(rot.vkbd_show_prepare_timer);
1246 rot.vkbd_show_prepare_timer = NULL;
1248 if (rot.vkbd_show_timer)
1249 ecore_timer_del(rot.vkbd_show_timer);
1250 rot.vkbd_show_timer = NULL;
1252 return ECORE_CALLBACK_CANCEL;
1256 _e_border_vkbd_hide_timeout(void *data)
1258 E_Border *bd = data;
1259 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1260 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1262 if (_e_border_vkbd_state_check(bd, EINA_FALSE))
1264 if (rot.vkbd_ctrl_win)
1266 ELB(ELBT_BD, "SET KBD_OFF", 0);
1267 ecore_x_e_virtual_keyboard_state_set
1268 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
1271 e_object_unref(E_OBJECT(bd));
1274 rot.vkbd_hide_prepare_done = EINA_FALSE;
1276 if (rot.vkbd_hide_prepare_timer)
1277 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1278 rot.vkbd_hide_prepare_timer = NULL;
1280 if (rot.vkbd_hide_timer)
1281 ecore_timer_del(rot.vkbd_hide_timer);
1282 rot.vkbd_hide_timer = NULL;
1284 return ECORE_CALLBACK_CANCEL;
1288 _e_border_vkbd_show(E_Border *bd)
1290 if (!e_config->wm_win_rotation) return;
1291 rot.vkbd_show_prepare_done = EINA_TRUE;
1292 if (rot.vkbd_show_prepare_timer)
1293 ecore_timer_del(rot.vkbd_show_prepare_timer);
1294 rot.vkbd_show_prepare_timer = NULL;
1295 if (rot.vkbd_show_timer)
1296 ecore_timer_del(rot.vkbd_show_timer);
1297 rot.vkbd_show_timer = NULL;
1298 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1301 rot.vkbd_show_timer = ecore_timer_add(0.1f, _e_border_vkbd_show_timeout, bd);
1306 _e_border_vkbd_hide(E_Border *bd)
1308 if (!e_config->wm_win_rotation) return;
1309 rot.vkbd_hide_prepare_done = EINA_TRUE;
1310 if (rot.vkbd_hide_prepare_timer)
1311 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1312 rot.vkbd_hide_prepare_timer = NULL;
1313 if (rot.vkbd_hide_timer)
1314 ecore_timer_del(rot.vkbd_hide_timer);
1315 rot.vkbd_hide_timer = NULL;
1316 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1318 e_border_hide(bd, 0);
1319 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1324 _e_border_vkbd_show_prepare_timeout(void *data)
1326 E_Border *bd = data;
1327 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1328 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
1330 ELB(ELBT_BD, "TIMEOUT KBD_SHOW_PREPARE", bd->client.win);
1331 _e_border_vkbd_show(bd);
1333 return ECORE_CALLBACK_CANCEL;
1337 _e_border_vkbd_hide_prepare_timeout(void *data)
1339 E_Border *bd = data;
1340 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
1341 if ((bd) && ((E_OBJECT(bd)->type) == (E_BORDER_TYPE)))
1343 ELB(ELBT_BD, "TIMEOUT KBD_HIDE_PREPARE", bd->client.win);
1344 _e_border_vkbd_hide(bd);
1346 return ECORE_CALLBACK_CANCEL;
1351 e_border_show(E_Border *bd)
1353 E_Event_Border_Show *ev;
1354 unsigned int visible;
1357 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1358 if (bd->visible) return;
1359 #ifdef _F_ZONE_WINDOW_ROTATION_
1360 if ((e_config->wm_win_rotation) &&
1361 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1363 (!rot.vkbd_show_prepare_done))
1365 ELB(ELBT_BD, "SEND KBD_ON_PREPARE", bd->client.win);
1366 ecore_x_e_virtual_keyboard_on_prepare_request_send(rot.vkbd_ctrl_win);
1367 if (rot.vkbd_show_prepare_timer)
1368 ecore_timer_del(rot.vkbd_show_prepare_timer);
1369 rot.vkbd_show_prepare_timer = ecore_timer_add(1.5f,
1370 _e_border_vkbd_show_prepare_timeout,
1374 ELB(ELBT_BD, "SHOW", bd->client.win);
1376 ecore_x_window_shadow_tree_flush();
1377 e_container_shape_show(bd->shape);
1378 if (!bd->need_reparent)
1379 ecore_x_window_show(bd->client.win);
1380 e_hints_window_visible_set(bd);
1383 bd->changes.visible = 1;
1386 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1387 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1389 ev = E_NEW(E_Event_Border_Show, 1);
1391 e_object_ref(E_OBJECT(bd));
1392 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
1393 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
1395 #ifdef _F_ZONE_WINDOW_ROTATION_
1396 if ((e_config->wm_win_rotation) &&
1397 ((bd->client.e.state.rot.support) ||
1398 (bd->client.e.state.rot.app_set)))
1400 ELB(ELBT_ROT, "CHECK", bd->client.win);
1401 _e_border_rotation_check(bd);
1407 e_border_hide(E_Border *bd,
1410 unsigned int visible;
1413 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1415 #ifdef _F_ZONE_WINDOW_ROTATION_
1416 if ((e_config->wm_win_rotation) &&
1417 (rot.vkbd_ctrl_win) && (rot.vkbd) &&
1419 (!rot.vkbd_hide_prepare_done) &&
1422 Eina_Bool need_prepare = EINA_TRUE;
1423 E_Border *child = NULL;
1426 if (e_object_is_del(E_OBJECT(bd->parent)))
1427 need_prepare = EINA_FALSE;
1430 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
1431 if (bd->parent->modal == bd)
1433 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
1434 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
1435 bd->parent->lock_close = 0;
1436 bd->parent->saved.event_mask = 0;
1437 bd->parent->modal = NULL;
1443 need_prepare = EINA_FALSE;
1445 EINA_LIST_FREE(bd->transients, child)
1447 child->parent = NULL;
1450 ELBF(ELBT_BD, 0, bd->client.win, "SEND KBD_OFF_PREPARE:%d", need_prepare);
1454 e_object_ref(E_OBJECT(bd));
1455 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1456 if (rot.vkbd_hide_prepare_timer)
1457 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1458 rot.vkbd_hide_prepare_timer = ecore_timer_add(1.5f,
1459 _e_border_vkbd_hide_prepare_timeout,
1465 e_object_ref(E_OBJECT(bd));
1467 /* In order to clear conformant area properly, WM should send keyboard off prepare request event */
1468 ecore_x_e_virtual_keyboard_off_prepare_request_send(rot.vkbd_ctrl_win);
1470 /* cleanup code from _e_border_vkbd_hide() */
1471 rot.vkbd_hide_prepare_done = EINA_TRUE;
1472 if (rot.vkbd_hide_prepare_timer)
1473 ecore_timer_del(rot.vkbd_hide_prepare_timer);
1474 rot.vkbd_hide_prepare_timer = NULL;
1475 if (rot.vkbd_hide_timer)
1476 ecore_timer_del(rot.vkbd_hide_timer);
1477 rot.vkbd_hide_timer = ecore_timer_add(0.03f, _e_border_vkbd_hide_timeout, bd);
1480 ELBF(ELBT_BD, 0, bd->client.win, "HIDE visible:%d", bd->visible);
1482 if (!bd->visible) goto send_event;
1483 ecore_x_window_shadow_tree_flush();
1485 _e_border_move_end(bd);
1486 if (bd->resize_mode != RESIZE_NONE)
1488 _e_border_pointer_resize_end(bd);
1489 bd->resize_mode = RESIZE_NONE;
1490 _e_border_resize_end(bd);
1493 e_container_shape_hide(bd->shape);
1494 if (!bd->iconic) e_hints_window_hidden_set(bd);
1497 bd->changes.visible = 1;
1499 if (!bd->need_reparent)
1503 e_border_focus_set(bd, 0, 1);
1511 con = e_container_current_get(e_manager_current_get());
1512 zone = e_zone_current_get(con);
1513 desk = e_desk_current_get(zone);
1516 (bd->parent->desk == desk) && (bd->parent->modal == bd))
1517 e_border_focus_set(bd->parent, 1, 1);
1518 else if (e_config->focus_revert_on_hide_or_close)
1520 /* When using pointer focus, the border under the
1521 * pointer (if any) gets focused, in sloppy/click
1522 * focus the last focused window on the current
1523 * desk gets focus */
1524 if (e_config->focus_policy == E_FOCUS_MOUSE)
1526 pbd = e_border_under_pointer_get(desk, bd);
1528 e_border_focus_set(pbd, 1, 1);
1530 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1531 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
1532 (e_config->focus_policy == E_FOCUS_CLICK))
1533 _e_border_latest_stacked_focus(bd);
1537 e_desk_last_focused_focus(desk);
1547 /* Make sure that this border isn't deleted */
1548 bd->await_hide_event++;
1550 if (!e_manager_comp_evas_get(bd->zone->container->manager))
1551 ecore_x_window_hide(bd->client.win);
1556 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
1558 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1565 E_Event_Border_Hide *ev;
1567 ev = E_NEW(E_Event_Border_Hide, 1);
1569 e_object_ref(E_OBJECT(bd));
1570 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1571 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1576 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1580 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1581 setpriority(PRIO_PROCESS, pid, newpri);
1582 // shouldnt need to do this as default ionice class is "none" (0), and
1583 // this inherits io priority FROM nice level
1584 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1585 // IOPRIO_PRIO_VALUE(2, 5));
1589 char *file, buf[PATH_MAX];
1593 // yes - this is /proc specific... so this may not work on some
1594 // os's - works on linux. too bad for others.
1595 files = ecore_file_ls("/proc");
1596 EINA_LIST_FREE(files, file)
1598 if (isdigit(file[0]))
1600 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1601 f = fopen(buf, "r");
1606 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1612 _pri_adj(pid2, set, adj, EINA_TRUE,
1613 adj_children, do_children);
1615 _pri_adj(pid2, set, adj, use_adj,
1616 adj_children, do_children);
1628 _e_border_pri_raise(E_Border *bd)
1630 if (bd->client.netwm.pid <= 0) return;
1631 if (bd->client.netwm.pid == getpid()) return;
1632 _pri_adj(bd->client.netwm.pid,
1633 e_config->priority - 1, -1, EINA_FALSE,
1634 // EINA_TRUE, EINA_TRUE);
1635 EINA_TRUE, EINA_FALSE);
1636 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1637 // bd->client.netwm.pid, e_border_name_get(bd));
1641 _e_border_pri_norm(E_Border *bd)
1643 if (bd->client.netwm.pid <= 0) return;
1644 if (bd->client.netwm.pid == getpid()) return;
1645 _pri_adj(bd->client.netwm.pid,
1646 e_config->priority, 1, EINA_FALSE,
1647 // EINA_TRUE, EINA_TRUE);
1648 EINA_TRUE, EINA_FALSE);
1649 // printf("WIN: pid %i, title %s (NORMAL)\n",
1650 // bd->client.netwm.pid, e_border_name_get(bd));
1654 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1657 Ecore_Evas *bg_ecore_evas;
1663 bg_ecore_evas = bd->bg_ecore_evas;
1665 /* unregister old frame window */
1666 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1667 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1669 e_focus_setdown(bd);
1670 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1671 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
1673 if (bd->icon_object)
1674 evas_object_del(bd->icon_object);
1676 evas_object_del(bd->bg_object);
1677 e_canvas_del(bg_ecore_evas);
1678 ecore_evas_free(bg_ecore_evas);
1681 e_object_del(E_OBJECT(bd->pointer));
1683 /* create new frame */
1685 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1686 bd->x, bd->y, bd->w, bd->h);
1689 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1690 bd->x, bd->y, bd->w, bd->h);
1691 ecore_x_window_shape_events_select(bd->win, 1);
1694 ecore_x_window_configure(bd->win,
1695 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1696 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1698 win, ECORE_X_WINDOW_STACK_BELOW);
1700 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1701 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
1704 bd->bg_ecore_evas = e_canvas_new(bd->win,
1705 0, 0, bd->w, bd->h, 1, 0,
1708 e_canvas_add(bd->bg_ecore_evas);
1709 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1711 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1712 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1713 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1715 ecore_x_window_shape_events_select(bd->bg_win, 1);
1717 /* move client with shell win over to new frame */
1718 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1719 bd->client_inset.l, bd->client_inset.t);
1721 bd->pointer = e_pointer_window_new(bd->win, 0);
1723 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1724 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1731 ecore_evas_show(bd->bg_ecore_evas);
1732 ecore_x_window_show(bd->win);
1734 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1735 ecore_x_window_show(tmp->win);
1738 bd->bg_object = edje_object_add(bd->bg_evas);
1739 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1740 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1742 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1744 /* cleanup old frame */
1745 ecore_x_window_free(win);
1749 _e_border_client_move_resize_send(E_Border *bd)
1751 if (bd->internal_ecore_evas)
1752 ecore_evas_managed_move(bd->internal_ecore_evas,
1753 bd->x + bd->fx.x + bd->client_inset.l,
1754 bd->y + bd->fx.y + bd->client_inset.t);
1756 ecore_x_icccm_move_resize_send(bd->client.win,
1757 bd->x + bd->fx.x + bd->client_inset.l,
1758 bd->y + bd->fx.y + bd->client_inset.t,
1764 _e_border_pending_move_resize_add(E_Border *bd,
1771 Eina_Bool without_border,
1772 unsigned int serial)
1774 E_Border_Pending_Move_Resize *pnd;
1776 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1778 pnd->resize = resize;
1780 pnd->without_border = without_border;
1785 pnd->serial = serial;
1786 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1790 _e_border_move_internal(E_Border *bd,
1793 Eina_Bool without_border)
1795 E_Event_Border_Move *ev;
1798 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1800 ecore_x_window_shadow_tree_flush();
1803 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1809 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1811 if (e_config->allow_manip)
1814 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1819 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1824 else if (e_config->allow_manip)
1832 x -= bd->client_inset.l;
1833 y -= bd->client_inset.t;
1835 if (bd->move_intercept_cb)
1838 px = bd->x, py = bd->y;
1839 bd->move_intercept_cb(bd, x, y);
1840 if ((bd->x == px) && (bd->y == py)) return;
1842 else if ((x == bd->x) && (y == bd->y)) return;
1843 bd->pre_res_change.valid = 0;
1847 bd->changes.pos = 1;
1849 if (bd->client.netwm.sync.request)
1851 bd->client.netwm.sync.wait++;
1852 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1855 _e_border_client_move_resize_send(bd);
1856 _e_border_move_update(bd);
1857 ev = E_NEW(E_Event_Border_Move, 1);
1859 e_object_ref(E_OBJECT(bd));
1860 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1861 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1862 _e_border_zone_update(bd);
1866 * Move window to coordinates that already account border decorations.
1868 * This call will consider given position already accounts border
1869 * decorations, so it will not be considered later. This will just
1870 * work properly with borders that have being evaluated and border
1871 * decorations are known (border->client_inset).
1873 * @parm x horizontal position to place window.
1874 * @parm y vertical position to place window.
1876 * @see e_border_move_without_border()
1879 e_border_move(E_Border *bd,
1886 _e_border_move_internal(bd, x, y, 0);
1891 * Set a callback which will be called just prior to updating the
1892 * move coordinates for a border
1895 e_border_move_intercept_cb_set(E_Border *bd, E_Border_Move_Intercept_Cb cb)
1897 bd->move_intercept_cb = cb;
1901 * Move window to coordinates that do not account border decorations yet.
1903 * This call will consider given position does not account border
1904 * decoration, so these values (border->client_inset) will be
1905 * accounted automatically. This is specially useful when it is a new
1906 * client and has not be evaluated yet, in this case
1907 * border->client_inset will be zeroed and no information is known. It
1908 * will mark pending requests so border will be accounted on
1909 * evalutation phase.
1911 * @parm x horizontal position to place window.
1912 * @parm y vertical position to place window.
1914 * @see e_border_move()
1917 e_border_move_without_border(E_Border *bd,
1924 _e_border_move_internal(bd, x, y, 1);
1928 e_border_center(E_Border *bd)
1932 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1934 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1935 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1939 e_border_center_pos_get(E_Border *bd,
1945 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1947 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1948 if (x) *x = zx + (zw - bd->w) / 2;
1949 if (y) *y = zy + (zh - bd->h) / 2;
1953 e_border_fx_offset(E_Border *bd,
1958 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1960 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
1964 bd->changes.pos = 1;
1967 if (bd->moving) _e_border_move_update(bd);
1971 _e_border_move_resize_internal(E_Border *bd,
1976 Eina_Bool without_border,
1979 E_Event_Border_Move *mev;
1980 E_Event_Border_Resize *rev;
1983 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1985 ecore_x_window_shadow_tree_flush();
1989 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
1995 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1997 if (e_config->allow_manip)
2000 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2006 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2013 if (e_config->allow_manip)
2021 x -= bd->client_inset.l;
2022 y -= bd->client_inset.t;
2023 w += (bd->client_inset.l + bd->client_inset.r);
2024 h += (bd->client_inset.t + bd->client_inset.b);
2027 if ((!move || ((x == bd->x) && (y == bd->y))) &&
2028 (w == bd->w) && (h == bd->h))
2031 bd->pre_res_change.valid = 0;
2034 bd->changes.pos = 1;
2040 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
2041 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
2043 if ((bd->shaped) || (bd->client.shaped))
2045 bd->need_shape_merge = 1;
2046 bd->need_shape_export = 1;
2048 if (bd->shaped_input)
2050 bd->need_shape_merge = 1;
2053 if (bd->internal_ecore_evas)
2056 bd->changes.size = 1;
2060 if (bdresize && bd->client.netwm.sync.request)
2062 bd->client.netwm.sync.wait++;
2063 /* Don't use x and y as supplied to this function, as it is called with 0, 0
2064 * when no move is intended. The border geometry is set above anyways.
2066 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
2067 bd->client.netwm.sync.serial);
2068 ecore_x_netwm_sync_request_send(bd->client.win,
2069 bd->client.netwm.sync.serial++);
2074 bd->changes.size = 1;
2078 _e_border_client_move_resize_send(bd);
2080 _e_border_resize_update(bd);
2083 mev = E_NEW(E_Event_Border_Move, 1);
2085 e_object_ref(E_OBJECT(bd));
2086 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
2087 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
2090 rev = E_NEW(E_Event_Border_Resize, 1);
2092 e_object_ref(E_OBJECT(bd));
2093 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2094 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2095 _e_border_zone_update(bd);
2099 * Move and resize window to values that already account border decorations.
2101 * This call will consider given values already accounts border
2102 * decorations, so it will not be considered later. This will just
2103 * work properly with borders that have being evaluated and border
2104 * decorations are known (border->client_inset).
2106 * @parm x horizontal position to place window.
2107 * @parm y vertical position to place window.
2108 * @parm w horizontal window size.
2109 * @parm h vertical window size.
2111 * @see e_border_move_resize_without_border()
2114 e_border_move_resize(E_Border *bd,
2123 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2127 * Move and resize window to values that do not account border decorations yet.
2129 * This call will consider given values already accounts border
2130 * decorations, so it will not be considered later. This will just
2131 * work properly with borders that have being evaluated and border
2132 * decorations are known (border->client_inset).
2134 * @parm x horizontal position to place window.
2135 * @parm y vertical position to place window.
2136 * @parm w horizontal window size.
2137 * @parm h vertical window size.
2139 * @see e_border_move_resize()
2142 e_border_move_resize_without_border(E_Border *bd,
2151 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
2155 * Resize window to values that already account border decorations.
2157 * This call will consider given size already accounts border
2158 * decorations, so it will not be considered later. This will just
2159 * work properly with borders that have being evaluated and border
2160 * decorations are known (border->client_inset).
2162 * @parm w horizontal window size.
2163 * @parm h vertical window size.
2165 * @see e_border_resize_without_border()
2168 e_border_resize(E_Border *bd,
2175 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
2179 * Resize window to values that do not account border decorations yet.
2181 * This call will consider given size does not account border
2182 * decoration, so these values (border->client_inset) will be
2183 * accounted automatically. This is specially useful when it is a new
2184 * client and has not be evaluated yet, in this case
2185 * border->client_inset will be zeroed and no information is known. It
2186 * will mark pending requests so border will be accounted on
2187 * evalutation phase.
2189 * @parm w horizontal window size.
2190 * @parm h vertical window size.
2192 * @see e_border_resize()
2195 e_border_resize_without_border(E_Border *bd,
2202 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
2206 e_border_layer_set(E_Border *bd,
2212 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2214 ecore_x_window_shadow_tree_flush();
2216 oldraise = e_config->transient.raise;
2220 bd->saved.layer = layer;
2224 if (e_config->transient.layer)
2228 Eina_List *list = _e_border_sub_borders_new(bd);
2230 /* We need to set raise to one, else the child wont
2231 * follow to the new layer. It should be like this,
2232 * even if the user usually doesn't want to raise
2235 e_config->transient.raise = 1;
2236 EINA_LIST_FOREACH(list, l, child)
2238 e_border_layer_set(child, layer);
2242 e_config->transient.raise = oldraise;
2246 e_border_raise(E_Border *bd)
2248 E_Event_Border_Stack *ev;
2249 E_Border *last = NULL, *child;
2253 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2255 ecore_x_window_shadow_tree_flush();
2257 if (e_config->transient.raise)
2259 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2260 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2263 Eina_List *list = _e_border_sub_borders_new(bd);
2265 EINA_LIST_REVERSE_FOREACH(list, l, child)
2267 /* Don't stack iconic transients. If the user wants these shown,
2268 * thats another option.
2273 e_border_stack_below(child, last);
2278 /* First raise the border to find out which border we will end up above */
2279 above = e_container_border_raise(child);
2283 /* We ended up above a border, now we must stack this border to
2284 * generate the stacking event, and to check if this transient
2285 * has other transients etc.
2287 e_border_stack_above(child, above);
2291 /* If we didn't end up above any border, we are on the bottom! */
2292 e_border_lower(child);
2298 eina_list_free(list);
2299 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2303 EINA_LIST_FOREACH(bd->transients, l, child)
2305 /* Don't stack iconic transients. If the user wants these shown,
2306 * thats another option.
2310 child->layer = bd->layer;
2311 if (!last) last = child;
2312 e_border_raise (child);
2319 ev = E_NEW(E_Event_Border_Stack, 1);
2321 e_object_ref(E_OBJECT(bd));
2325 e_container_border_stack_below(bd, last);
2327 e_object_ref(E_OBJECT(last));
2328 ev->type = E_STACKING_BELOW;
2334 /* If we don't have any children, raise this border */
2335 above = e_container_border_raise(bd);
2336 e_border_raise_latest_set(bd);
2339 /* We ended up above a border */
2341 e_object_ref(E_OBJECT(above));
2342 ev->type = E_STACKING_ABOVE;
2346 /* No border to raise above, same as a lower! */
2348 ev->type = E_STACKING_ABOVE;
2352 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2353 e_remember_update(bd);
2357 e_border_lower(E_Border *bd)
2359 E_Event_Border_Stack *ev;
2360 E_Border *last = NULL, *child;
2364 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2366 ecore_x_window_shadow_tree_flush();
2368 if (e_config->transient.lower)
2370 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2371 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
2374 Eina_List *list = _e_border_sub_borders_new(bd);
2376 EINA_LIST_REVERSE_FOREACH(list, l, child)
2378 /* Don't stack iconic transients. If the user wants these shown,
2379 * thats another option.
2384 e_border_stack_below(child, last);
2389 /* First lower the border to find out which border we will end up below */
2390 below = e_container_border_lower(child);
2394 /* We ended up below a border, now we must stack this border to
2395 * generate the stacking event, and to check if this transient
2396 * has other transients etc.
2398 e_border_stack_below(child, below);
2402 /* If we didn't end up below any border, we are on top! */
2403 e_border_raise(child);
2409 eina_list_free(list);
2411 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
2415 EINA_LIST_FOREACH(bd->transients, l, child)
2417 /* Don't stack iconic transients. If the user wants these shown,
2418 * thats another option.
2422 child->layer = bd->layer;
2423 e_border_lower (child);
2431 ev = E_NEW(E_Event_Border_Stack, 1);
2433 e_object_ref(E_OBJECT(bd));
2437 e_container_border_stack_below(bd, last);
2439 e_object_ref(E_OBJECT(last));
2440 ev->type = E_STACKING_BELOW;
2446 /* If we don't have any children, lower this border */
2447 below = e_container_border_lower(bd);
2450 /* We ended up below a border */
2452 e_object_ref(E_OBJECT(below));
2453 ev->type = E_STACKING_BELOW;
2457 /* No border to hide under, same as a raise! */
2459 ev->type = E_STACKING_BELOW;
2463 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2464 e_remember_update(bd);
2468 e_border_stack_above(E_Border *bd,
2471 /* TODO: Should stack above allow the border to change level */
2472 E_Event_Border_Stack *ev;
2473 E_Border *last = NULL, *child;
2477 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2479 ecore_x_window_shadow_tree_flush();
2481 if (e_config->transient.raise)
2483 Eina_List *list = _e_border_sub_borders_new(bd);
2485 EINA_LIST_REVERSE_FOREACH(list, l, child)
2487 /* Don't stack iconic transients. If the user wants these shown,
2488 * thats another option.
2493 e_border_stack_below(child, last);
2495 e_border_stack_above(child, above);
2499 eina_list_free(list);
2502 ev = E_NEW(E_Event_Border_Stack, 1);
2504 e_object_ref(E_OBJECT(bd));
2508 e_container_border_stack_below(bd, last);
2510 e_object_ref(E_OBJECT(last));
2511 ev->type = E_STACKING_BELOW;
2515 e_container_border_stack_above(bd, above);
2517 e_object_ref(E_OBJECT(above));
2518 ev->type = E_STACKING_ABOVE;
2521 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2522 e_remember_update(bd);
2526 e_border_stack_below(E_Border *bd,
2529 /* TODO: Should stack below allow the border to change level */
2530 E_Event_Border_Stack *ev;
2531 E_Border *last = NULL, *child;
2535 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2537 ecore_x_window_shadow_tree_flush();
2539 if (e_config->transient.lower)
2541 Eina_List *list = _e_border_sub_borders_new(bd);
2543 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
2545 /* Don't stack iconic transients. If the user wants these shown,
2546 * thats another option.
2551 e_border_stack_below(child, last);
2553 e_border_stack_below(child, below);
2557 eina_list_free(list);
2560 ev = E_NEW(E_Event_Border_Stack, 1);
2562 e_object_ref(E_OBJECT(bd));
2566 e_container_border_stack_below(bd, last);
2568 e_object_ref(E_OBJECT(last));
2569 ev->type = E_STACKING_BELOW;
2573 e_container_border_stack_below(bd, below);
2575 e_object_ref(E_OBJECT(below));
2576 ev->type = E_STACKING_BELOW;
2579 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
2580 e_remember_update(bd);
2584 e_border_focus_latest_set(E_Border *bd)
2586 focus_stack = eina_list_remove(focus_stack, bd);
2587 focus_stack = eina_list_prepend(focus_stack, bd);
2591 e_border_raise_latest_set(E_Border *bd)
2593 raise_stack = eina_list_remove(raise_stack, bd);
2594 raise_stack = eina_list_prepend(raise_stack, bd);
2598 * Sets the focus to the given border if necessary
2599 * There are 3 cases of different focus_policy-configurations:
2601 * - E_FOCUS_CLICK: just set the focus, the most simple one
2603 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2604 * warp the pointer to the window. If this fails (because
2605 * the pointer is already in the window), just set the focus.
2607 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2608 * last window which was focused, if the mouse is on the
2609 * desktop. So, we need to look if there is another window
2610 * under the pointer and warp to pointer to the right
2611 * one if so (also, we set the focus afterwards). In case
2612 * there is no window under pointer, the pointer is on the
2613 * desktop and so we just set the focus.
2616 * This function is to be called when setting the focus was not
2617 * explicitly triggered by the user (by moving the mouse or
2618 * clicking for example), but implicitly (by closing a window,
2619 * the last focused window should get focus).
2623 e_border_focus_set_with_pointer(E_Border *bd)
2625 #ifdef PRINT_LOTS_OF_DEBUG
2626 E_PRINT_BORDER_INFO(bd);
2628 /* note: this is here as it seems there are enough apps that do not even
2629 * expect us to emulate a look of focus but not actually set x input
2630 * focus as we do - so simply abort any focuse set on such windows */
2631 /* be strict about accepting focus hint */
2632 if ((!bd->client.icccm.accepts_focus) &&
2633 (!bd->client.icccm.take_focus)) return;
2634 if (bd->lock_focus_out) return;
2636 e_border_focus_set(bd, 1, 1);
2638 if (e_config->focus_policy == E_FOCUS_CLICK) return;
2639 if (!bd->visible) return;
2641 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2643 if (!e_border_under_pointer_get(bd->desk, bd))
2645 e_border_pointer_warp_to_center(bd);
2650 e_border_pointer_warp_to_center(bd);
2655 e_border_focus_set(E_Border *bd,
2659 E_Border *bd_unfocus = NULL;
2660 Eina_Bool focus_changed = EINA_FALSE;
2663 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2664 /* note: this is here as it seems there are enough apps that do not even
2665 * expect us to emulate a look of focus but not actually set x input
2666 * focus as we do - so simply abort any focuse set on such windows */
2667 /* be strict about accepting focus hint */
2668 if ((!bd->client.icccm.accepts_focus) &&
2669 (!bd->client.icccm.take_focus))
2671 if ((set) && (focus) && (bd->lock_focus_out)) return;
2673 /* dont focus an iconified window. that's silly! */
2678 e_border_uniconify(bd);
2679 if (!focus_track_frozen)
2680 e_border_focus_latest_set(bd);
2683 else if (!bd->visible)
2687 /* FIXME: hack for deskflip animation:
2688 * dont update focus when sliding previous desk */
2689 else if ((!bd->sticky) &&
2690 (bd->desk != e_desk_current_get(bd->desk->zone)))
2696 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2698 e_border_focus_set(bd->modal, focus, set);
2701 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2703 e_border_focus_set(bd->leader->modal, focus, set);
2711 if (bd->visible && bd->changes.visible)
2716 else if ((!bd->focused) ||
2717 (focus_next && (bd != eina_list_data_get(focus_next))))
2721 if ((l = eina_list_data_find_list(focus_next, bd)))
2722 focus_next = eina_list_promote_list(focus_next, l);
2724 focus_next = eina_list_prepend(focus_next, bd);
2726 if ((bd->client.icccm.take_focus) &&
2727 (bd->client.icccm.accepts_focus))
2729 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
2730 /* TODO what if the client didn't take focus ? */
2732 else if (!bd->client.icccm.accepts_focus)
2734 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
2736 else if (!bd->client.icccm.take_focus)
2738 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
2739 /* e_border_focus_set(bd, 1, 0); */
2749 if (focused) bd_unfocus = focused;
2750 if (focusing == bd) focusing = NULL;
2755 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2757 if ((bd2->fullscreen) &&
2759 (bd2->zone == bd->zone) &&
2760 ((bd2->desk == bd->desk) ||
2761 (bd2->sticky) || (bd->sticky)))
2763 Eina_Bool unfocus_is_parent = EINA_FALSE;
2764 E_Border *bd_parent;
2766 bd_parent = bd->parent;
2769 if (bd_parent == bd2)
2771 unfocus_is_parent = EINA_TRUE;
2774 bd_parent = bd->parent;
2776 if ((!unfocus_is_parent) &&
2777 (!e_config->allow_above_fullscreen))
2779 e_border_iconify(bd2);
2784 focus_changed = EINA_TRUE;
2790 focus_next = eina_list_remove(focus_next, bd);
2791 if (bd == focusing) focusing = NULL;
2793 if ((bd->focused) &&
2794 ((bd->desk == e_desk_current_get(bd->zone)) || (bd->sticky)))
2796 Eina_Bool wasfocused = EINA_FALSE;
2799 /* should always be the case. anyway */
2803 wasfocused = EINA_TRUE;
2806 if ((set) && (!focus_next) && (!focusing))
2808 e_grabinput_focus(bd->zone->container->bg_win,
2809 E_FOCUS_METHOD_PASSIVE);
2811 if ((bd->fullscreen) && (wasfocused))
2813 Eina_Bool have_vis_child = EINA_FALSE;
2817 EINA_LIST_FOREACH(e_border_client_list(), l, bd2)
2820 (bd2->zone == bd->zone) &&
2821 ((bd2->desk == bd->desk) ||
2822 (bd2->sticky) || (bd->sticky)))
2824 if (bd2->parent == bd)
2826 have_vis_child = EINA_TRUE;
2831 if ((!have_vis_child) &&
2832 (!e_config->allow_above_fullscreen))
2833 e_border_iconify(bd);
2839 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2840 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2842 E_Event_Border_Focus_Out *ev;
2844 bd_unfocus->focused = 0;
2845 e_focus_event_focus_out(bd_unfocus);
2847 if (bd_unfocus->raise_timer)
2848 ecore_timer_del(bd_unfocus->raise_timer);
2849 bd_unfocus->raise_timer = NULL;
2851 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2852 if (bd_unfocus->icon_object)
2853 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2855 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2856 ev->border = bd_unfocus;
2857 e_object_ref(E_OBJECT(bd_unfocus));
2859 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2860 _e_border_event_border_focus_out_free, NULL);
2861 if ((bd_unfocus->fullscreen) &&
2862 (bd != bd_unfocus) &&
2863 (bd->zone == bd_unfocus->zone) &&
2864 ((bd->desk == bd_unfocus->desk) ||
2865 (bd->sticky) || (bd_unfocus->sticky)))
2867 Eina_Bool unfocus_is_parent = EINA_FALSE;
2868 E_Border *bd_parent;
2870 bd_parent = bd->parent;
2873 if (bd_parent == bd_unfocus)
2875 unfocus_is_parent = EINA_TRUE;
2878 bd_parent = bd->parent;
2880 if ((!unfocus_is_parent) && (!e_config->allow_above_fullscreen))
2882 e_border_iconify(bd_unfocus);
2889 E_Event_Border_Focus_In *ev;
2891 e_focus_event_focus_in(bd);
2893 if (!focus_track_frozen)
2894 e_border_focus_latest_set(bd);
2896 e_hints_active_window_set(bd->zone->container->manager, bd);
2898 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2899 if (bd->icon_object)
2900 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2902 ev = E_NEW(E_Event_Border_Focus_In, 1);
2904 e_object_ref(E_OBJECT(bd));
2906 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2907 _e_border_event_border_focus_in_free, NULL);
2912 e_border_shade(E_Border *bd,
2915 E_Event_Border_Resize *ev;
2920 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2921 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2922 ((bd->maximized) && (!e_config->allow_manip))) return;
2923 if ((bd->client.border.name) &&
2924 (!strcmp("borderless", bd->client.border.name))) return;
2926 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2927 ecore_x_window_hide(tmp->win);
2929 ecore_x_window_shadow_tree_flush();
2931 bd->shade.x = bd->x;
2932 bd->shade.y = bd->y;
2933 bd->shade.dir = dir;
2935 e_hints_window_shaded_set(bd, 1);
2936 e_hints_window_shade_direction_set(bd, dir);
2938 if (e_config->border_shade_animate)
2940 bd->shade.start = ecore_loop_time_get();
2942 bd->changes.shading = 1;
2945 if (bd->shade.dir == E_DIRECTION_UP ||
2946 bd->shade.dir == E_DIRECTION_LEFT)
2947 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2949 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2951 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2952 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
2956 if (bd->shade.dir == E_DIRECTION_UP)
2958 bd->h = bd->client_inset.t + bd->client_inset.b;
2960 else if (bd->shade.dir == E_DIRECTION_DOWN)
2962 bd->h = bd->client_inset.t + bd->client_inset.b;
2963 bd->y = bd->y + bd->client.h;
2964 bd->changes.pos = 1;
2966 else if (bd->shade.dir == E_DIRECTION_LEFT)
2968 bd->w = bd->client_inset.l + bd->client_inset.r;
2970 else if (bd->shade.dir == E_DIRECTION_RIGHT)
2972 bd->w = bd->client_inset.l + bd->client_inset.r;
2973 bd->x = bd->x + bd->client.w;
2974 bd->changes.pos = 1;
2977 if ((bd->shaped) || (bd->client.shaped))
2979 bd->need_shape_merge = 1;
2980 bd->need_shape_export = 1;
2982 if (bd->shaped_input)
2984 bd->need_shape_merge = 1;
2987 bd->changes.size = 1;
2989 bd->changes.shaded = 1;
2991 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
2992 e_border_frame_recalc(bd);
2993 ev = E_NEW(E_Event_Border_Resize, 1);
2995 /* The resize is added in the animator when animation complete */
2996 /* For non-animated, we add it immediately with the new size */
2997 e_object_ref(E_OBJECT(bd));
2998 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2999 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3002 e_remember_update(bd);
3006 e_border_unshade(E_Border *bd,
3009 E_Event_Border_Resize *ev;
3014 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3015 if ((!bd->shaded) || (bd->shading))
3018 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3019 ecore_x_window_show(tmp->win);
3021 ecore_x_window_shadow_tree_flush();
3023 bd->shade.dir = dir;
3025 e_hints_window_shaded_set(bd, 0);
3026 e_hints_window_shade_direction_set(bd, dir);
3028 if (bd->shade.dir == E_DIRECTION_UP ||
3029 bd->shade.dir == E_DIRECTION_LEFT)
3031 bd->shade.x = bd->x;
3032 bd->shade.y = bd->y;
3036 bd->shade.x = bd->x - bd->client.w;
3037 bd->shade.y = bd->y - bd->client.h;
3039 if (e_config->border_shade_animate)
3041 bd->shade.start = ecore_loop_time_get();
3043 bd->changes.shading = 1;
3046 if (bd->shade.dir == E_DIRECTION_UP)
3048 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3049 ecore_x_window_move_resize(bd->client.win, 0,
3050 bd->h - (bd->client_inset.t + bd->client_inset.b) -
3052 bd->client.w, bd->client.h);
3054 else if (bd->shade.dir == E_DIRECTION_LEFT)
3056 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
3057 ecore_x_window_move_resize(bd->client.win,
3058 bd->w - (bd->client_inset.l + bd->client_inset.r) -
3060 0, bd->client.w, bd->client.h);
3063 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
3065 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
3066 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
3070 if (bd->shade.dir == E_DIRECTION_UP)
3072 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3074 else if (bd->shade.dir == E_DIRECTION_DOWN)
3076 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
3077 bd->y = bd->y - bd->client.h;
3078 bd->changes.pos = 1;
3080 else if (bd->shade.dir == E_DIRECTION_LEFT)
3082 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3084 else if (bd->shade.dir == E_DIRECTION_RIGHT)
3086 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
3087 bd->x = bd->x - bd->client.w;
3088 bd->changes.pos = 1;
3090 if ((bd->shaped) || (bd->client.shaped))
3092 bd->need_shape_merge = 1;
3093 bd->need_shape_export = 1;
3095 if (bd->shaped_input)
3097 bd->need_shape_merge = 1;
3100 bd->changes.size = 1;
3102 bd->changes.shaded = 1;
3104 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
3105 e_border_frame_recalc(bd);
3106 ev = E_NEW(E_Event_Border_Resize, 1);
3108 /* The resize is added in the animator when animation complete */
3109 /* For non-animated, we add it immediately with the new size */
3110 e_object_ref(E_OBJECT(bd));
3111 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
3112 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
3115 e_remember_update(bd);
3119 _e_border_client_inset_calc(E_Border *bd)
3122 Evas_Coord cx, cy, cw, ch;
3126 evas_object_resize(bd->bg_object, 1000, 1000);
3127 edje_object_message_signal_process(bd->bg_object);
3128 edje_object_calc_force(bd->bg_object);
3129 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3130 bd->client_inset.l = cx;
3131 bd->client_inset.r = 1000 - (cx + cw);
3132 bd->client_inset.t = cy;
3133 bd->client_inset.b = 1000 - (cy + ch);
3137 bd->client_inset.l = 0;
3138 bd->client_inset.r = 0;
3139 bd->client_inset.t = 0;
3140 bd->client_inset.b = 0;
3143 ecore_x_netwm_frame_size_set(bd->client.win,
3144 bd->client_inset.l, bd->client_inset.r,
3145 bd->client_inset.t, bd->client_inset.b);
3146 ecore_x_e_frame_size_set(bd->client.win,
3147 bd->client_inset.l, bd->client_inset.r,
3148 bd->client_inset.t, bd->client_inset.b);
3152 _e_border_maximize(E_Border *bd, E_Maximize max)
3154 int x1, yy1, x2, y2;
3157 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3161 zx = zy = zw = zh = 0;
3163 switch (max & E_MAXIMIZE_TYPE)
3165 case E_MAXIMIZE_NONE:
3169 case E_MAXIMIZE_FULLSCREEN:
3175 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
3176 _e_border_client_inset_calc(bd);
3178 e_border_resize_limit(bd, &w, &h);
3179 /* center x-direction */
3180 x1 = bd->zone->x + (bd->zone->w - w) / 2;
3181 /* center y-direction */
3182 yy1 = bd->zone->y + (bd->zone->h - h) / 2;
3184 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3185 cy = bd->zone->y + (bd->zone->h / 2);
3188 switch (max & E_MAXIMIZE_DIRECTION)
3190 case E_MAXIMIZE_BOTH:
3191 e_border_move_resize(bd, x1, yy1, w, h);
3194 case E_MAXIMIZE_VERTICAL:
3195 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3198 case E_MAXIMIZE_HORIZONTAL:
3199 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3202 case E_MAXIMIZE_LEFT:
3203 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3206 case E_MAXIMIZE_RIGHT:
3207 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3209 #ifdef _F_USE_BOTTOM_TOP_MAXIMIZE
3210 case E_MAXIMIZE_TOP:
3211 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w, h / 2);
3213 case E_MAXIMIZE_BOTTOM:
3214 e_border_move_resize(bd, bd->zone->x, cy, w, h / 2);
3220 case E_MAXIMIZE_SMART:
3221 case E_MAXIMIZE_EXPAND:
3223 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
3235 if (bd->x < zx) // window left not useful coordinates
3237 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
3238 x1 = zx + zw - bd->w;
3239 else // window normal position
3242 if (bd->y < zy) // window top not useful coordinates
3244 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
3245 yy1 = zy + zh - bd->h;
3246 else // window normal position
3249 switch (max & E_MAXIMIZE_DIRECTION)
3251 case E_MAXIMIZE_BOTH:
3252 e_border_move_resize(bd, zx, zy, zw, zh);
3255 case E_MAXIMIZE_VERTICAL:
3256 e_border_move_resize(bd, x1, zy, w, zh);
3259 case E_MAXIMIZE_HORIZONTAL:
3260 e_border_move_resize(bd, zx, yy1, zw, h);
3263 case E_MAXIMIZE_LEFT:
3264 e_border_move_resize(bd, zx, zy, zw / 2, zh);
3267 case E_MAXIMIZE_RIGHT:
3268 e_border_move_resize(bd, zx + zw / 2, zy, zw / 2, zh);
3272 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
3275 case E_MAXIMIZE_FILL:
3278 x2 = bd->zone->x + bd->zone->w;
3279 y2 = bd->zone->y + bd->zone->h;
3281 /* walk through all shelves */
3282 e_maximize_border_shelf_fill(bd, &x1, &yy1, &x2, &y2, max);
3284 /* walk through all windows */
3285 e_maximize_border_border_fill(bd, &x1, &yy1, &x2, &y2, max);
3291 e_border_resize_limit(bd, &w, &h);
3292 /* center x-direction */
3293 x1 = x1 + (pw - w) / 2;
3294 /* center y-direction */
3295 yy1 = yy1 + (ph - h) / 2;
3297 switch (max & E_MAXIMIZE_DIRECTION)
3299 case E_MAXIMIZE_BOTH:
3300 e_border_move_resize(bd, x1, yy1, w, h);
3303 case E_MAXIMIZE_VERTICAL:
3304 e_border_move_resize(bd, bd->x, yy1, bd->w, h);
3307 case E_MAXIMIZE_HORIZONTAL:
3308 e_border_move_resize(bd, x1, bd->y, w, bd->h);
3311 case E_MAXIMIZE_LEFT:
3312 e_border_move_resize(bd, bd->zone->x, bd->zone->y, w / 2, h);
3315 case E_MAXIMIZE_RIGHT:
3316 e_border_move_resize(bd, x1, bd->zone->y, w / 2, h);
3324 e_border_maximize(E_Border *bd,
3328 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3330 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
3332 if ((bd->shaded) || (bd->shading)) return;
3333 ecore_x_window_shadow_tree_flush();
3335 e_border_unfullscreen(bd);
3336 /* Only allow changes in vertical/ horizontal maximization */
3337 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
3338 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
3341 bd->need_maximize = 1;
3342 bd->maximized &= ~E_MAXIMIZE_TYPE;
3343 bd->maximized |= max;
3347 bd->pre_res_change.valid = 0;
3348 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
3350 /* Horizontal hasn't been set */
3351 bd->saved.x = bd->x - bd->zone->x;
3352 bd->saved.w = bd->w;
3354 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
3356 /* Vertical hasn't been set */
3357 bd->saved.y = bd->y - bd->zone->y;
3358 bd->saved.h = bd->h;
3361 bd->saved.zone = bd->zone->num;
3362 e_hints_window_size_set(bd);
3366 _e_border_maximize(bd, max);
3369 /* Remove previous type */
3370 bd->maximized &= ~E_MAXIMIZE_TYPE;
3371 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
3372 bd->maximized |= max;
3374 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3375 bd->maximized & E_MAXIMIZE_VERTICAL);
3376 e_remember_update(bd);
3380 e_border_unmaximize(E_Border *bd,
3384 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3385 if (!(max & E_MAXIMIZE_DIRECTION))
3387 CRI("BUG: Unmaximize call without direction!");
3391 if ((bd->shaded) || (bd->shading)) return;
3392 ecore_x_window_shadow_tree_flush();
3393 /* Remove directions not used */
3394 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
3395 /* Can only remove existing maximization directions */
3397 if (bd->maximized & E_MAXIMIZE_TYPE)
3399 bd->pre_res_change.valid = 0;
3400 bd->need_maximize = 0;
3402 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
3406 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
3407 _e_border_client_inset_calc(bd);
3410 bd->maximized = E_MAXIMIZE_NONE;
3411 _e_border_move_resize_internal(bd,
3412 bd->zone->x + bd->saved.x,
3413 bd->zone->y + bd->saved.y,
3414 bd->saved.w, bd->saved.h, 0, 1);
3415 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
3416 e_hints_window_size_unset(bd);
3427 if (max & E_MAXIMIZE_VERTICAL)
3429 /* Remove vertical */
3431 y = bd->saved.y + bd->zone->y;
3432 bd->saved.h = bd->saved.y = 0;
3433 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
3434 bd->maximized &= ~E_MAXIMIZE_LEFT;
3435 bd->maximized &= ~E_MAXIMIZE_RIGHT;
3437 if (max & E_MAXIMIZE_HORIZONTAL)
3439 /* Remove horizontal */
3441 x = bd->saved.x + bd->zone->x;
3442 bd->saved.w = bd->saved.x = 0;
3443 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
3446 e_border_resize_limit(bd, &w, &h);
3448 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
3450 bd->maximized = E_MAXIMIZE_NONE;
3451 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3452 e_hints_window_size_unset(bd);
3453 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
3457 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
3458 e_hints_window_size_set(bd);
3461 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
3462 bd->maximized & E_MAXIMIZE_VERTICAL);
3464 e_remember_update(bd);
3468 e_border_fullscreen(E_Border *bd,
3469 E_Fullscreen policy)
3471 E_Event_Border_Fullscreen *ev;
3474 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3476 if ((bd->shaded) || (bd->shading)) return;
3477 ecore_x_window_shadow_tree_flush();
3480 bd->need_fullscreen = 1;
3483 if (!bd->fullscreen)
3485 bd->pre_res_change.valid = 0;
3487 bd->saved.x = bd->x - bd->zone->x;
3488 bd->saved.y = bd->y - bd->zone->y;
3489 bd->saved.w = bd->client.w;
3490 bd->saved.h = bd->client.h;
3491 bd->saved.maximized = bd->maximized;
3492 bd->saved.zone = bd->zone->num;
3495 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
3496 e_hints_window_size_set(bd);
3498 bd->client_inset.l = 0;
3499 bd->client_inset.r = 0;
3500 bd->client_inset.t = 0;
3501 bd->client_inset.b = 0;
3503 bd->desk->fullscreen_borders++;
3505 /* e_zone_fullscreen_set(bd->zone, 1); */
3506 bd->saved.layer = bd->layer;
3507 if (!e_config->allow_above_fullscreen)
3508 e_border_layer_set(bd, 250);
3510 if ((eina_list_count(bd->zone->container->zones) > 1) ||
3511 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
3513 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3515 else if (policy == E_FULLSCREEN_ZOOM)
3517 Ecore_X_Randr_Screen_Size_MM *sizes;
3518 int num_sizes, i, best_size_index = 0;
3520 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
3522 &screen_size.height,
3524 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
3528 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
3529 int best_dist = INT_MAX, dist;
3531 for (i = 0; i < num_sizes; i++)
3533 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
3535 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
3536 if (dist < best_dist)
3538 best_size.width = sizes[i].width;
3539 best_size.height = sizes[i].height;
3541 best_size_index = i;
3545 if (((best_size.width != -1) && (best_size.height != -1)) &&
3546 ((best_size.width != screen_size.width) ||
3547 (best_size.height != screen_size.height)))
3549 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3551 screen_size_index = best_size_index;
3552 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
3556 screen_size.width = -1;
3557 screen_size.height = -1;
3558 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
3563 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
3567 e_hints_window_fullscreen_set(bd, 1);
3568 e_hints_window_size_unset(bd);
3569 bd->client.border.changed = 1;
3572 bd->fullscreen_policy = policy;
3574 ev = E_NEW(E_Event_Border_Fullscreen, 1);
3576 e_object_ref(E_OBJECT(bd));
3577 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
3578 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
3580 e_remember_update(bd);
3584 e_border_unfullscreen(E_Border *bd)
3586 E_Event_Border_Unfullscreen *ev;
3589 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3590 if ((bd->shaded) || (bd->shading)) return;
3591 ecore_x_window_shadow_tree_flush();
3594 bd->pre_res_change.valid = 0;
3596 bd->need_fullscreen = 0;
3597 bd->desk->fullscreen_borders--;
3599 if ((screen_size.width != -1) && (screen_size.height != -1))
3601 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
3603 screen_size.width = -1;
3604 screen_size.height = -1;
3606 e_border_move_resize(bd,
3607 bd->saved.x + bd->zone->x,
3608 bd->saved.y + bd->zone->y,
3609 bd->saved.w, bd->saved.h);
3611 if (bd->saved.maximized)
3612 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
3613 bd->saved.maximized);
3615 e_border_layer_set(bd, bd->saved.layer);
3617 e_hints_window_fullscreen_set(bd, 0);
3618 bd->client.border.changed = 1;
3621 bd->fullscreen_policy = 0;
3623 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
3625 e_object_ref(E_OBJECT(bd));
3626 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
3627 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
3629 e_remember_update(bd);
3633 e_border_iconify(E_Border *bd)
3635 E_Event_Border_Iconify *ev;
3636 unsigned int iconic;
3639 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3640 if (bd->shading) return;
3641 ecore_x_window_shadow_tree_flush();
3645 e_border_hide(bd, 1);
3646 if (bd->fullscreen) bd->desk->fullscreen_borders--;
3647 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
3650 e_hints_window_iconic_set(bd);
3651 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3653 ev = E_NEW(E_Event_Border_Iconify, 1);
3655 e_object_ref(E_OBJECT(bd));
3656 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
3657 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
3659 if (e_config->transient.iconify)
3663 Eina_List *list = _e_border_sub_borders_new(bd);
3665 EINA_LIST_FOREACH(list, l, child)
3667 e_border_iconify(child);
3669 eina_list_free(list);
3671 e_remember_update(bd);
3674 #ifdef _F_DEICONIFY_APPROVE_
3676 _e_border_uniconify_timeout(void *data)
3681 if (!e_object_is_del(E_OBJECT(bd)))
3683 bd->client.e.state.deiconify_approve.render_done = 1;
3684 e_border_uniconify(bd);
3685 bd->client.e.state.deiconify_approve.wait_timer = NULL;
3688 return ECORE_CALLBACK_CANCEL;
3693 e_border_uniconify(E_Border *bd)
3696 E_Event_Border_Uniconify *ev;
3697 unsigned int iconic;
3700 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3702 #ifdef _F_DEICONIFY_APPROVE_
3703 if (e_config->deiconify_approve)
3705 if (bd->client.e.state.deiconify_approve.support)
3707 if (bd->client.e.state.deiconify_approve.wait_timer) return;
3708 if (bd->client.e.state.deiconify_approve.render_done == 0)
3710 ecore_x_client_message32_send(bd->client.win,
3711 ECORE_X_ATOM_E_DEICONIFY_APPROVE,
3712 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE,
3713 bd->client.win, 0, 0, 0, 0);
3714 bd->client.e.state.deiconify_approve.wait_timer = ecore_timer_add(e_config->deiconify_timeout, _e_border_uniconify_timeout, bd);
3719 bd->client.e.state.deiconify_approve.render_done = 0;
3723 #if _F_ZONE_WINDOW_ROTATION_
3724 if (!bd->client.win)
3726 ELB(ELBT_DFT, "ERR! obj is already deleted", bd->client.win);
3731 if (bd->shading) return;
3732 ecore_x_window_shadow_tree_flush();
3737 if (bd->fullscreen) bd->desk->fullscreen_borders++;
3738 desk = e_desk_current_get(bd->desk->zone);
3739 #ifdef _F_USE_EXTENDED_ICONIFY_
3740 if (e_manager_comp_evas_get(bd->zone->container->manager))
3742 if (bd->await_hide_event > 0)
3743 bd->await_hide_event--;
3746 e_border_desk_set(bd, desk);
3748 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
3751 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
3753 ev = E_NEW(E_Event_Border_Uniconify, 1);
3755 e_object_ref(E_OBJECT(bd));
3756 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
3757 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
3759 if (e_config->transient.iconify)
3763 Eina_List *list = _e_border_sub_borders_new(bd);
3765 EINA_LIST_FOREACH(list, l, child)
3767 e_border_uniconify(child);
3769 eina_list_free(list);
3771 e_remember_update(bd);
3775 e_border_stick(E_Border *bd)
3777 E_Event_Border_Stick *ev;
3780 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3781 if (bd->sticky) return;
3783 e_hints_window_sticky_set(bd, 1);
3786 if (e_config->transient.desktop)
3790 Eina_List *list = _e_border_sub_borders_new(bd);
3792 EINA_LIST_FOREACH(list, l, child)
3795 e_hints_window_sticky_set(child, 1);
3796 e_border_show(child);
3798 eina_list_free(list);
3801 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
3802 ev = E_NEW(E_Event_Border_Stick, 1);
3804 e_object_ref(E_OBJECT(bd));
3805 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
3806 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
3807 e_remember_update(bd);
3811 e_border_unstick(E_Border *bd)
3813 E_Event_Border_Unstick *ev;
3816 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3817 /* Set the desk before we unstick the border */
3818 if (!bd->sticky) return;
3820 e_hints_window_sticky_set(bd, 0);
3822 if (e_config->transient.desktop)
3826 Eina_List *list = _e_border_sub_borders_new(bd);
3828 EINA_LIST_FOREACH(list, l, child)
3831 e_hints_window_sticky_set(child, 0);
3833 eina_list_free(list);
3836 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
3837 ev = E_NEW(E_Event_Border_Unstick, 1);
3839 e_object_ref(E_OBJECT(bd));
3840 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
3841 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
3843 e_border_desk_set(bd, e_desk_current_get(bd->zone));
3844 e_remember_update(bd);
3848 e_border_pinned_set(E_Border *bd,
3856 bd->borderless = set;
3857 bd->user_skip_winlist = set;
3861 stacking = E_STACKING_BELOW;
3866 stacking = E_STACKING_NONE;
3869 e_border_layer_set(bd, layer);
3870 e_hints_window_stacking_set(bd, stacking);
3872 bd->client.border.changed = 1;
3878 e_border_find_by_client_window(Ecore_X_Window win)
3882 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3883 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3884 (bd->client.win == win))
3890 e_border_find_all_by_client_window(Ecore_X_Window win)
3894 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3895 if ((bd) && (bd->client.win == win))
3901 e_border_find_by_frame_window(Ecore_X_Window win)
3905 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3906 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3907 (bd->bg_win == win))
3913 e_border_find_by_window(Ecore_X_Window win)
3917 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3918 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3925 e_border_find_by_alarm(Ecore_X_Sync_Alarm al)
3930 EINA_LIST_FOREACH(borders, l, bd)
3932 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3933 (bd->client.netwm.sync.alarm == al))
3940 e_border_focused_get(void)
3946 _e_border_shape_input_rectangle_set(E_Border* bd)
3950 if ((bd->visible) && (bd->shaped_input))
3952 Ecore_X_Rectangle rects[4];
3953 Ecore_X_Window twin, twin2;
3956 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
3957 0, 0, bd->w, bd->h);
3960 rects[0].width = bd->w;
3961 rects[0].height = bd->client_inset.t;
3963 rects[1].y = bd->client_inset.t;
3964 rects[1].width = bd->client_inset.l;
3965 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3966 rects[2].x = bd->w - bd->client_inset.r;
3967 rects[2].y = bd->client_inset.t;
3968 rects[2].width = bd->client_inset.r;
3969 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3971 rects[3].y = bd->h - bd->client_inset.b;
3972 rects[3].width = bd->w;
3973 rects[3].height = bd->client_inset.b;
3974 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
3976 twin2 = ecore_x_window_override_new
3977 (bd->zone->container->scratch_win, 0, 0,
3978 bd->w - bd->client_inset.l - bd->client_inset.r,
3979 bd->h - bd->client_inset.t - bd->client_inset.b);
3982 if ((bd->shading) || (bd->shaded))
3984 if (bd->shade.dir == E_DIRECTION_UP)
3985 y = bd->h - bd->client_inset.t - bd->client_inset.b -
3987 else if (bd->shade.dir == E_DIRECTION_LEFT)
3988 x = bd->w - bd->client_inset.l - bd->client_inset.r -
3991 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
3993 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
3994 bd->w - bd->client_inset.l - bd->client_inset.r,
3995 bd->h - bd->client_inset.t - bd->client_inset.b);
3996 ecore_x_window_shape_input_window_add_xy(twin, twin2,
3998 bd->client_inset.t);
3999 ecore_x_window_shape_input_window_set(bd->win, twin);
4000 ecore_x_window_free(twin2);
4001 ecore_x_window_free(twin);
4005 if (bd->visible) // not shaped input
4007 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4008 ecore_x_composite_window_events_enable(bd->win);
4010 ecore_x_composite_window_events_disable(bd->win);
4014 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4015 ecore_x_composite_window_events_enable(bd->win);
4017 ecore_x_composite_window_events_disable(bd->win);
4023 e_border_idler_before(void)
4032 EINA_LIST_FOREACH(e_manager_list(), ml, man)
4034 EINA_LIST_FOREACH(man->containers, cl, con)
4039 // pass 1 - eval0. fetch properties on new or on change and
4040 // call hooks to decide what to do - maybe move/resize
4041 bl = e_container_border_list_last(con);
4042 while ((bd = e_container_border_list_prev(bl)))
4044 if (bd->changed) _e_border_eval0(bd);
4046 e_container_border_list_free(bl);
4048 // layout hook - this is where a hook gets to figure out what to
4050 _e_border_container_layout_hook(con);
4052 // pass 2 - show windows needing show
4053 bl = e_container_border_list_last(con);
4054 while ((bd = e_container_border_list_prev(bl)))
4056 if ((bd->changes.visible) && (bd->visible) &&
4057 (!bd->new_client) && (!bd->changes.pos) &&
4058 (!bd->changes.size))
4061 bd->changes.visible = 0;
4064 e_container_border_list_free(bl);
4066 // pass 3 - hide windows needing hide and eval (main eval)
4067 bl = e_container_border_list_first(con);
4068 while ((bd = e_container_border_list_next(bl)))
4070 if (e_object_is_del(E_OBJECT(bd))) continue;
4072 if ((bd->changes.visible) && (!bd->visible))
4075 bd->changes.visible = 0;
4078 if (bd->changed) _e_border_eval(bd);
4080 if ((bd->changes.visible) && (bd->visible))
4083 bd->changes.visible = 0;
4086 e_container_border_list_free(bl);
4092 E_Border *bd = NULL, *bd2;
4094 EINA_LIST_FREE(focus_next, bd2)
4095 if ((!bd) && (bd2->visible)) bd = bd2;
4099 /* TODO revert focus when lost here ? */
4105 /* already focused. but anyway dont be so strict, this
4106 fcks up illume setting focus on internal windows */
4111 focus_time = ecore_x_current_time_get();
4115 if ((bd->client.icccm.take_focus) &&
4116 (bd->client.icccm.accepts_focus))
4118 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
4119 /* TODO what if the client didn't take focus ? */
4121 else if (!bd->client.icccm.accepts_focus)
4123 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
4125 else if (!bd->client.icccm.take_focus)
4127 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
4128 /* e_border_focus_set(bd, 1, 0); */
4132 #ifdef _F_ZONE_WINDOW_ROTATION_
4133 if ((e_config->wm_win_rotation) &&
4136 Ecore_X_Event_Client_Message *msg = NULL;
4138 EINA_LIST_FREE(rot.msgs, msg)
4140 t = msg->message_type;
4141 if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE)
4143 if ((rot.vkbd_ctrl_win) &&
4144 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4147 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE", rot.vkbd_ctrl_win);
4148 if (rot.vkbd_show_prepare_timer)
4149 _e_border_vkbd_show(rot.vkbd);
4151 ELB(ELBT_BD, "GET KBD_ON_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4154 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE)
4156 if ((rot.vkbd_ctrl_win) &&
4157 ((Ecore_X_Window)msg->data.l[0] == rot.vkbd_ctrl_win) &&
4160 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE", rot.vkbd_ctrl_win);
4161 if (rot.vkbd_hide_prepare_timer)
4163 _e_border_vkbd_hide(rot.vkbd);
4164 rot.vkbd_hide_prepare_timer = NULL;
4165 e_object_unref(E_OBJECT(rot.vkbd));
4168 ELB(ELBT_BD, "GET KBD_OFF_PREPARE_DONE but skip", rot.vkbd_ctrl_win);
4171 else if (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW)
4173 rot.vkbd_ctrl_win = msg->data.l[0];
4174 ELB(ELBT_BD, "SET KBD_CONTROL_WIN", rot.vkbd_ctrl_win);
4176 else if (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE)
4178 if ((rot.vkbd_ctrl_win) &&
4179 (rot.vkbd_ctrl_win == (Ecore_X_Window)msg->data.l[0]))
4181 ELB(ELBT_ROT, "GET ROT_PREPARE_DONE", rot.vkbd_ctrl_win);
4182 E_Manager *m = e_manager_current_get();
4183 E_Zone *zone = NULL;
4184 if (m) zone = e_util_zone_current_get(m);
4185 if ((zone) && (rot.wait_prepare_done))
4187 if (_e_border_rotation_list_add(zone, EINA_FALSE))
4188 _e_border_rotation_change_request(zone);
4191 if (rot.prepare_timer)
4192 ecore_timer_del(rot.prepare_timer);
4193 rot.prepare_timer = NULL;
4194 rot.wait_prepare_done = EINA_FALSE;
4202 rot.fetch = EINA_FALSE;
4208 e_border_client_list(void)
4210 /* FIXME: This should be a somewhat ordered list */
4214 static Ecore_X_Window action_input_win = 0;
4215 static E_Border *action_border = NULL;
4216 static Ecore_Event_Handler *action_handler_key = NULL;
4217 static Ecore_Event_Handler *action_handler_mouse = NULL;
4218 static Ecore_Timer *action_timer = NULL;
4219 static Ecore_X_Rectangle action_orig;
4222 _e_border_show(E_Border *bd)
4227 ecore_evas_show(bd->bg_ecore_evas);
4235 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
4237 _e_border_shape_input_rectangle_set(bd);
4239 // ecore_x_composite_window_events_enable(bd->win);
4240 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
4243 ecore_x_window_show(bd->win);
4245 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4246 ecore_x_window_show(tmp->win);
4250 _e_border_hide(E_Border *bd)
4255 if (!e_manager_comp_evas_get(bd->zone->container->manager))
4257 ecore_x_window_hide(bd->win);
4258 ecore_evas_hide(bd->bg_ecore_evas);
4260 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4261 ecore_x_window_hide(tmp->win);
4265 ecore_x_composite_window_events_disable(bd->win);
4266 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
4271 _e_border_action_input_win_del(void)
4273 if (!action_input_win)
4276 e_grabinput_release(action_input_win, action_input_win);
4277 ecore_x_window_free(action_input_win);
4278 action_input_win = 0;
4283 _e_border_action_input_win_new(E_Border *bd)
4285 if (!action_input_win)
4287 Ecore_X_Window parent = bd->zone->container->win;
4288 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
4289 if (!action_input_win)
4293 ecore_x_window_show(action_input_win);
4294 if (e_grabinput_get(action_input_win, 0, action_input_win))
4297 _e_border_action_input_win_del();
4302 _e_border_action_finish(void)
4304 _e_border_action_input_win_del();
4308 ecore_timer_del(action_timer);
4309 action_timer = NULL;
4312 if (action_handler_key)
4314 ecore_event_handler_del(action_handler_key);
4315 action_handler_key = NULL;
4318 if (action_handler_mouse)
4320 ecore_event_handler_del(action_handler_mouse);
4321 action_handler_mouse = NULL;
4324 action_border = NULL;
4328 _e_border_action_init(E_Border *bd)
4330 action_orig.x = bd->x;
4331 action_orig.y = bd->y;
4332 action_orig.width = bd->w;
4333 action_orig.height = bd->h;
4339 _e_border_action_restore_orig(E_Border *bd)
4341 if (action_border != bd)
4344 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
4348 _e_border_key_down_modifier_apply(int modifier,
4351 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
4353 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
4366 _e_border_action_move_timeout(void *data __UNUSED__)
4368 _e_border_move_end(action_border);
4369 _e_border_action_finish();
4370 return ECORE_CALLBACK_CANCEL;
4374 _e_border_action_move_timeout_add(void)
4377 ecore_timer_del(action_timer);
4378 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
4382 _e_border_move_key_down(void *data __UNUSED__,
4383 int type __UNUSED__,
4386 Ecore_Event_Key *ev = event;
4389 if (ev->event_window != action_input_win)
4390 return ECORE_CALLBACK_PASS_ON;
4393 fputs("ERROR: no action_border!\n", stderr);
4397 x = action_border->x;
4398 y = action_border->y;
4400 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4401 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4402 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4403 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
4404 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4405 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4406 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4407 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
4408 else if (strcmp(ev->key, "Return") == 0)
4410 else if (strcmp(ev->key, "Escape") == 0)
4412 _e_border_action_restore_orig(action_border);
4415 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4416 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4419 e_border_move(action_border, x, y);
4420 _e_border_action_move_timeout_add();
4422 return ECORE_CALLBACK_PASS_ON;
4425 _e_border_move_end(action_border);
4426 _e_border_action_finish();
4427 return ECORE_CALLBACK_DONE;
4431 _e_border_move_mouse_down(void *data __UNUSED__,
4432 int type __UNUSED__,
4435 Ecore_Event_Mouse_Button *ev = event;
4437 if (ev->event_window != action_input_win)
4438 return ECORE_CALLBACK_PASS_ON;
4441 fputs("ERROR: no action_border!\n", stderr);
4443 _e_border_move_end(action_border);
4444 _e_border_action_finish();
4445 return ECORE_CALLBACK_DONE;
4449 e_border_act_move_keyboard(E_Border *bd)
4454 if (!_e_border_move_begin(bd))
4457 if (!_e_border_action_input_win_new(bd))
4459 _e_border_move_end(bd);
4463 _e_border_action_init(bd);
4464 _e_border_action_move_timeout_add();
4465 _e_border_move_update(bd);
4467 if (action_handler_key)
4468 ecore_event_handler_del(action_handler_key);
4469 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
4471 if (action_handler_mouse)
4472 ecore_event_handler_del(action_handler_mouse);
4473 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
4477 _e_border_action_resize_timeout(void *data __UNUSED__)
4479 _e_border_resize_end(action_border);
4480 _e_border_action_finish();
4481 return ECORE_CALLBACK_CANCEL;
4485 _e_border_action_resize_timeout_add(void)
4488 ecore_timer_del(action_timer);
4489 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
4493 _e_border_resize_key_down(void *data __UNUSED__,
4494 int type __UNUSED__,
4497 Ecore_Event_Key *ev = event;
4500 if (ev->event_window != action_input_win)
4501 return ECORE_CALLBACK_PASS_ON;
4504 fputs("ERROR: no action_border!\n", stderr);
4508 w = action_border->w;
4509 h = action_border->h;
4511 dx = e_config->border_keyboard.resize.dx;
4512 if (dx < action_border->client.icccm.step_w)
4513 dx = action_border->client.icccm.step_w;
4514 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
4515 if (dx < action_border->client.icccm.step_w)
4516 dx = action_border->client.icccm.step_w;
4518 dy = e_config->border_keyboard.resize.dy;
4519 if (dy < action_border->client.icccm.step_h)
4520 dy = action_border->client.icccm.step_h;
4521 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
4522 if (dy < action_border->client.icccm.step_h)
4523 dy = action_border->client.icccm.step_h;
4525 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
4527 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
4529 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
4531 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
4533 else if (strcmp(ev->key, "Return") == 0)
4535 else if (strcmp(ev->key, "Escape") == 0)
4537 _e_border_action_restore_orig(action_border);
4540 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
4541 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
4544 e_border_resize_limit(action_border, &w, &h);
4545 e_border_resize(action_border, w, h);
4546 _e_border_action_resize_timeout_add();
4548 return ECORE_CALLBACK_PASS_ON;
4551 _e_border_resize_end(action_border);
4552 _e_border_action_finish();
4553 return ECORE_CALLBACK_DONE;
4557 _e_border_resize_mouse_down(void *data __UNUSED__,
4558 int type __UNUSED__,
4561 Ecore_Event_Mouse_Button *ev = event;
4563 if (ev->event_window != action_input_win)
4564 return ECORE_CALLBACK_PASS_ON;
4567 fputs("ERROR: no action_border!\n", stderr);
4569 _e_border_resize_end(action_border);
4570 _e_border_action_finish();
4571 return ECORE_CALLBACK_DONE;
4575 e_border_act_resize_keyboard(E_Border *bd)
4580 if (!_e_border_resize_begin(bd))
4583 if (!_e_border_action_input_win_new(bd))
4585 _e_border_resize_end(bd);
4589 _e_border_action_init(bd);
4590 _e_border_action_resize_timeout_add();
4591 _e_border_resize_update(bd);
4593 if (action_handler_key)
4594 ecore_event_handler_del(action_handler_key);
4595 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
4597 if (action_handler_mouse)
4598 ecore_event_handler_del(action_handler_mouse);
4599 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
4603 e_border_act_move_begin(E_Border *bd,
4604 Ecore_Event_Mouse_Button *ev)
4607 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4608 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4609 if (!_e_border_move_begin(bd))
4612 e_zone_edge_disable();
4614 _e_border_pointer_move_begin(bd);
4619 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4620 _e_border_moveinfo_gather(bd, source);
4625 e_border_act_move_end(E_Border *bd,
4626 Ecore_Event_Mouse_Button *ev __UNUSED__)
4629 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4630 if (!bd->moving) return;
4632 _e_border_pointer_move_end(bd);
4633 e_zone_edge_enable();
4634 _e_border_move_end(bd);
4635 e_zone_flip_coords_handle(bd->zone, -1, -1);
4639 e_border_act_resize_begin(E_Border *bd,
4640 Ecore_Event_Mouse_Button *ev)
4643 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4644 if (bd->lock_user_size) return;
4645 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4646 if (!_e_border_resize_begin(bd))
4648 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
4650 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4652 bd->resize_mode = RESIZE_TL;
4653 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
4657 bd->resize_mode = RESIZE_BL;
4658 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
4663 if (bd->mouse.current.my < (bd->y + bd->h / 2))
4665 bd->resize_mode = RESIZE_TR;
4666 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
4670 bd->resize_mode = RESIZE_BR;
4671 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
4674 _e_border_pointer_resize_begin(bd);
4679 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
4680 _e_border_moveinfo_gather(bd, source);
4685 e_border_act_resize_end(E_Border *bd,
4686 Ecore_Event_Mouse_Button *ev __UNUSED__)
4689 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4690 if (bd->resize_mode != RESIZE_NONE)
4692 _e_border_pointer_resize_end(bd);
4693 bd->resize_mode = RESIZE_NONE;
4694 _e_border_resize_end(bd);
4695 bd->changes.reset_gravity = 1;
4701 e_border_act_menu_begin(E_Border *bd,
4702 Ecore_Event_Mouse_Button *ev,
4706 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4709 e_int_border_menu_show(bd,
4710 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
4711 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
4718 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
4719 e_int_border_menu_show(bd, x, y, key, 0);
4724 e_border_act_close_begin(E_Border *bd)
4727 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4728 if (bd->lock_close) return;
4729 if (bd->client.icccm.delete_request)
4731 bd->delete_requested = 1;
4732 ecore_x_window_delete_request_send(bd->client.win);
4733 if (bd->client.netwm.ping)
4736 else if (e_config->kill_if_close_not_possible)
4738 e_border_act_kill_begin(bd);
4743 e_border_act_kill_begin(E_Border *bd)
4746 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4747 if (bd->internal) return;
4748 if (bd->lock_close) return;
4749 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
4751 kill(bd->client.netwm.pid, SIGINT);
4752 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
4753 _e_border_cb_kill_timer, bd);
4757 if (!bd->internal) ecore_x_kill(bd->client.win);
4762 e_border_icon_add(E_Border *bd,
4767 E_OBJECT_CHECK_RETURN(bd, NULL);
4768 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
4773 if (!bd->internal_icon)
4775 o = e_icon_add(evas);
4776 e_util_icon_theme_set(o, "enlightenment");
4780 if (!bd->internal_icon_key)
4784 ext = strrchr(bd->internal_icon, '.');
4785 if ((ext) && ((!strcmp(ext, ".edj"))))
4787 o = edje_object_add(evas);
4788 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
4789 e_util_icon_theme_set(o, "enlightenment");
4793 o = e_icon_add(evas);
4794 e_icon_file_set(o, bd->internal_icon);
4798 o = e_icon_add(evas);
4799 if (!e_util_icon_theme_set(o, bd->internal_icon))
4800 e_util_icon_theme_set(o, "enlightenment");
4805 o = edje_object_add(evas);
4806 edje_object_file_set(o, bd->internal_icon,
4807 bd->internal_icon_key);
4812 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
4814 if (bd->client.netwm.icons)
4816 o = e_icon_add(evas);
4817 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4818 bd->client.netwm.icons[0].width,
4819 bd->client.netwm.icons[0].height);
4820 e_icon_alpha_set(o, 1);
4826 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
4828 o = e_icon_add(evas);
4831 e_icon_fdo_icon_set(o, bd->desktop->icon);
4835 else if (bd->client.netwm.icons)
4837 o = e_icon_add(evas);
4838 e_icon_data_set(o, bd->client.netwm.icons[0].data,
4839 bd->client.netwm.icons[0].width,
4840 bd->client.netwm.icons[0].height);
4841 e_icon_alpha_set(o, 1);
4846 o = e_icon_add(evas);
4847 e_util_icon_theme_set(o, "unknown");
4852 e_border_button_bindings_ungrab_all(void)
4857 EINA_LIST_FOREACH(borders, l, bd)
4859 e_focus_setdown(bd);
4860 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4861 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
4866 e_border_button_bindings_grab_all(void)
4871 EINA_LIST_FOREACH(borders, l, bd)
4873 e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
4874 e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, bd->win);
4880 e_border_focus_stack_get(void)
4886 e_border_raise_stack_get(void)
4892 e_border_lost_windows_get(E_Zone *zone)
4894 Eina_List *list = NULL, *l;
4896 int loss_overlap = 5;
4898 E_OBJECT_CHECK_RETURN(zone, NULL);
4899 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
4900 EINA_LIST_FOREACH(borders, l, bd)
4905 if ((bd->zone != zone) ||
4906 (bd->zone->container != zone->container))
4909 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
4910 bd->zone->y + loss_overlap,
4911 bd->zone->w - (2 * loss_overlap),
4912 bd->zone->h - (2 * loss_overlap),
4913 bd->x, bd->y, bd->w, bd->h))
4915 list = eina_list_append(list, bd);
4917 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
4918 bd->zone->w, bd->zone->h,
4919 bd->x, bd->y, bd->w, bd->h)) &&
4922 Ecore_X_Rectangle *rect;
4925 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
4931 for (i = 0; i < num; i++)
4933 if (E_INTERSECTS(bd->zone->x + loss_overlap,
4934 bd->zone->y + loss_overlap,
4935 bd->zone->w - (2 * loss_overlap),
4936 bd->zone->h - (2 * loss_overlap),
4937 rect[i].x, rect[i].y,
4938 (int)rect[i].width, (int)rect[i].height))
4946 list = eina_list_append(list, bd);
4954 e_border_ping(E_Border *bd)
4957 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4958 if (!e_config->ping_clients) return;
4960 ecore_x_netwm_ping_send(bd->client.win);
4961 bd->ping = ecore_loop_time_get();
4962 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
4963 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
4964 e_config->ping_clients_interval,
4965 _e_border_cb_ping_poller, bd);
4969 e_border_move_cancel(void)
4973 if (bdmove->cur_mouse_action)
4978 e_object_ref(E_OBJECT(bd));
4979 if (bd->cur_mouse_action->func.end_mouse)
4980 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
4981 else if (bd->cur_mouse_action->func.end)
4982 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
4983 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4984 bd->cur_mouse_action = NULL;
4985 e_object_unref(E_OBJECT(bd));
4988 _e_border_move_end(bdmove);
4993 e_border_resize_cancel(void)
4997 if (bdresize->cur_mouse_action)
5002 e_object_ref(E_OBJECT(bd));
5003 if (bd->cur_mouse_action->func.end_mouse)
5004 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
5005 else if (bd->cur_mouse_action->func.end)
5006 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5007 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5008 bd->cur_mouse_action = NULL;
5009 e_object_unref(E_OBJECT(bd));
5013 bdresize->resize_mode = RESIZE_NONE;
5014 _e_border_resize_end(bdresize);
5020 e_border_frame_recalc(E_Border *bd)
5022 if (!bd->bg_object) return;
5024 bd->w -= (bd->client_inset.l + bd->client_inset.r);
5025 bd->h -= (bd->client_inset.t + bd->client_inset.b);
5027 _e_border_client_inset_calc(bd);
5029 bd->w += (bd->client_inset.l + bd->client_inset.r);
5030 bd->h += (bd->client_inset.t + bd->client_inset.b);
5033 bd->changes.size = 1;
5034 if ((bd->shaped) || (bd->client.shaped))
5036 bd->need_shape_merge = 1;
5037 bd->need_shape_export = 1;
5039 if (bd->shaped_input)
5041 bd->need_shape_merge = 1;
5043 _e_border_client_move_resize_send(bd);
5047 e_border_immortal_windows_get(void)
5049 Eina_List *list = NULL, *l;
5052 EINA_LIST_FOREACH(borders, l, bd)
5055 list = eina_list_append(list, bd);
5061 e_border_name_get(const E_Border *bd)
5063 E_OBJECT_CHECK_RETURN(bd, "");
5064 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
5065 if (bd->client.netwm.name)
5066 return bd->client.netwm.name;
5067 else if (bd->client.icccm.title)
5068 return bd->client.icccm.title;
5073 e_border_signal_move_begin(E_Border *bd,
5075 const char *src __UNUSED__)
5078 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5080 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5081 if (!_e_border_move_begin(bd)) return;
5083 _e_border_pointer_move_begin(bd);
5084 e_zone_edge_disable();
5085 _e_border_moveinfo_gather(bd, sig);
5086 if (bd->cur_mouse_action)
5088 if ((!bd->cur_mouse_action->func.end_mouse) &&
5089 (!bd->cur_mouse_action->func.end))
5090 bd->cur_mouse_action = NULL;
5092 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5094 bd->cur_mouse_action = e_action_find("window_move");
5095 if (bd->cur_mouse_action)
5096 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5100 e_border_signal_move_end(E_Border *bd,
5101 const char *sig __UNUSED__,
5102 const char *src __UNUSED__)
5105 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5106 if (!bd->moving) return;
5108 _e_border_pointer_move_end(bd);
5109 e_zone_edge_enable();
5110 _e_border_move_end(bd);
5111 e_zone_flip_coords_handle(bd->zone, -1, -1);
5115 e_border_resizing_get(E_Border *bd)
5117 E_OBJECT_CHECK_RETURN(bd, 0);
5118 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
5119 if (bd->resize_mode == RESIZE_NONE) return 0;
5124 e_border_signal_resize_begin(E_Border *bd,
5127 const char *src __UNUSED__)
5129 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
5130 int resize_mode = RESIZE_BR;
5133 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5135 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
5136 if (!_e_border_resize_begin(bd))
5138 if (!strcmp(dir, "tl"))
5140 resize_mode = RESIZE_TL;
5141 grav = ECORE_X_GRAVITY_SE;
5143 else if (!strcmp(dir, "t"))
5145 resize_mode = RESIZE_T;
5146 grav = ECORE_X_GRAVITY_S;
5148 else if (!strcmp(dir, "tr"))
5150 resize_mode = RESIZE_TR;
5151 grav = ECORE_X_GRAVITY_SW;
5153 else if (!strcmp(dir, "r"))
5155 resize_mode = RESIZE_R;
5156 grav = ECORE_X_GRAVITY_W;
5158 else if (!strcmp(dir, "br"))
5160 resize_mode = RESIZE_BR;
5161 grav = ECORE_X_GRAVITY_NW;
5163 else if (!strcmp(dir, "b"))
5165 resize_mode = RESIZE_B;
5166 grav = ECORE_X_GRAVITY_N;
5168 else if (!strcmp(dir, "bl"))
5170 resize_mode = RESIZE_BL;
5171 grav = ECORE_X_GRAVITY_NE;
5173 else if (!strcmp(dir, "l"))
5175 resize_mode = RESIZE_L;
5176 grav = ECORE_X_GRAVITY_E;
5178 bd->resize_mode = resize_mode;
5179 _e_border_pointer_resize_begin(bd);
5180 _e_border_moveinfo_gather(bd, sig);
5182 if (bd->cur_mouse_action)
5184 if ((!bd->cur_mouse_action->func.end_mouse) &&
5185 (!bd->cur_mouse_action->func.end))
5186 bd->cur_mouse_action = NULL;
5188 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5190 bd->cur_mouse_action = e_action_find("window_resize");
5191 if (bd->cur_mouse_action)
5192 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5196 e_border_signal_resize_end(E_Border *bd,
5197 const char *dir __UNUSED__,
5198 const char *sig __UNUSED__,
5199 const char *src __UNUSED__)
5202 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5203 if (bd->resize_mode == RESIZE_NONE) return;
5204 _e_border_resize_handle(bd);
5205 _e_border_pointer_resize_end(bd);
5206 bd->resize_mode = RESIZE_NONE;
5207 _e_border_resize_end(bd);
5208 bd->changes.reset_gravity = 1;
5213 e_border_resize_limit(E_Border *bd,
5220 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
5221 *w -= bd->client_inset.l + bd->client_inset.r;
5222 *h -= bd->client_inset.t + bd->client_inset.b;
5225 if ((bd->client.icccm.base_w >= 0) &&
5226 (bd->client.icccm.base_h >= 0))
5230 tw = *w - bd->client.icccm.base_w;
5231 th = *h - bd->client.icccm.base_h;
5234 a = (double)(tw) / (double)(th);
5235 if ((bd->client.icccm.min_aspect != 0.0) &&
5236 (a < bd->client.icccm.min_aspect))
5238 th = tw / bd->client.icccm.max_aspect;
5239 *h = th + bd->client.icccm.base_h;
5241 else if ((bd->client.icccm.max_aspect != 0.0) &&
5242 (a > bd->client.icccm.max_aspect))
5244 tw = th * bd->client.icccm.max_aspect;
5245 *w = tw + bd->client.icccm.base_w;
5250 a = (double)*w / (double)*h;
5251 if ((bd->client.icccm.min_aspect != 0.0) &&
5252 (a < bd->client.icccm.min_aspect))
5253 *h = *w / bd->client.icccm.min_aspect;
5254 else if ((bd->client.icccm.max_aspect != 0.0) &&
5255 (a > bd->client.icccm.max_aspect))
5256 *w = *h * bd->client.icccm.max_aspect;
5258 if (bd->client.icccm.step_w > 0)
5260 if (bd->client.icccm.base_w >= 0)
5261 *w = bd->client.icccm.base_w +
5262 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
5263 bd->client.icccm.step_w);
5265 *w = bd->client.icccm.min_w +
5266 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
5267 bd->client.icccm.step_w);
5269 if (bd->client.icccm.step_h > 0)
5271 if (bd->client.icccm.base_h >= 0)
5272 *h = bd->client.icccm.base_h +
5273 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
5274 bd->client.icccm.step_h);
5276 *h = bd->client.icccm.min_h +
5277 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
5278 bd->client.icccm.step_h);
5284 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
5285 else if (*w < bd->client.icccm.min_w)
5286 *w = bd->client.icccm.min_w;
5287 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
5288 else if (*h < bd->client.icccm.min_h)
5289 *h = bd->client.icccm.min_h;
5291 *w += bd->client_inset.l + bd->client_inset.r;
5292 *h += bd->client_inset.t + bd->client_inset.b;
5295 /* local subsystem functions */
5297 _e_border_free(E_Border *bd)
5299 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5302 if (bd->client.e.state.video_parent && bd->client.e.state.video_parent_border)
5304 bd->client.e.state.video_parent_border->client.e.state.video_child =
5306 (bd->client.e.state.video_parent_border->client.e.state.video_child,
5309 if (bd->client.e.state.video_child)
5313 EINA_LIST_FREE(bd->client.e.state.video_child, tmp)
5315 tmp->client.e.state.video_parent_border = NULL;
5320 efreet_desktop_free(bd->desktop);
5325 ecore_idle_enterer_del(bd->post_job);
5326 bd->post_job = NULL;
5330 e_object_del(E_OBJECT(bd->pointer));
5334 _e_border_resize_end(bd);
5336 _e_border_move_end(bd);
5337 /* TODO: Other states to end before dying? */
5339 if (bd->cur_mouse_action)
5341 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5342 bd->cur_mouse_action = NULL;
5345 E_FREE(bd->shape_rects);
5346 bd->shape_rects_num = 0;
5348 if (bd->dangling_ref_check)
5350 ecore_timer_del(bd->dangling_ref_check);
5351 bd->dangling_ref_check = NULL;
5356 ecore_timer_del(bd->kill_timer);
5357 bd->kill_timer = NULL;
5359 if (bd->ping_poller)
5361 ecore_poller_del(bd->ping_poller);
5362 bd->ping_poller = NULL;
5364 E_FREE_LIST(bd->pending_move_resize, free);
5366 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
5367 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5369 if (bd->border_locks_dialog)
5371 e_object_del(E_OBJECT(bd->border_locks_dialog));
5372 bd->border_locks_dialog = NULL;
5374 if (bd->border_remember_dialog)
5376 e_object_del(E_OBJECT(bd->border_remember_dialog));
5377 bd->border_remember_dialog = NULL;
5379 if (bd->border_border_dialog)
5381 e_object_del(E_OBJECT(bd->border_border_dialog));
5382 bd->border_border_dialog = NULL;
5384 if (bd->border_prop_dialog)
5386 e_object_del(E_OBJECT(bd->border_prop_dialog));
5387 bd->border_prop_dialog = NULL;
5390 e_int_border_menu_del(bd);
5395 focus_next = eina_list_remove(focus_next, bd);
5397 if ((focused == bd) ||
5398 (e_grabinput_last_focus_win_get() == bd->client.win))
5400 if ((!focus_next) && (!focusing))
5402 e_grabinput_focus(bd->zone->container->bg_win,
5403 E_FOCUS_METHOD_PASSIVE);
5404 e_hints_active_window_set(bd->zone->container->manager, NULL);
5409 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
5415 bd->remember = NULL;
5416 e_remember_unuse(rem);
5418 if (!bd->already_unparented)
5420 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
5421 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
5422 ecore_x_window_save_set_del(bd->client.win);
5423 bd->already_unparented = 1;
5425 if (bd->group) eina_list_free(bd->group);
5426 if (bd->transients) eina_list_free(bd->transients);
5427 if (bd->stick_desks) eina_list_free(bd->stick_desks);
5428 if (bd->client.netwm.icons)
5431 for (i = 0; i < bd->client.netwm.num_icons; i++)
5432 free(bd->client.netwm.icons[i].data);
5433 free(bd->client.netwm.icons);
5435 if (bd->client.netwm.extra_types)
5436 free(bd->client.netwm.extra_types);
5437 if (bd->client.border.name)
5438 eina_stringshare_del(bd->client.border.name);
5440 eina_stringshare_del(bd->bordername);
5441 if (bd->client.icccm.name)
5442 eina_stringshare_del(bd->client.icccm.name);
5443 if (bd->client.icccm.class)
5445 if (!strcmp(bd->client.icccm.class, "Vmplayer"))
5446 e_bindings_mapping_change_enable(EINA_TRUE);
5447 eina_stringshare_del(bd->client.icccm.class);
5449 if (bd->client.icccm.title)
5450 eina_stringshare_del(bd->client.icccm.title);
5451 if (bd->client.icccm.icon_name)
5452 eina_stringshare_del(bd->client.icccm.icon_name);
5453 if (bd->client.icccm.machine)
5454 eina_stringshare_del(bd->client.icccm.machine);
5455 if (bd->client.icccm.window_role)
5456 eina_stringshare_del(bd->client.icccm.window_role);
5458 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
5462 for (i = 0; i < bd->client.icccm.command.argc; i++)
5463 free(bd->client.icccm.command.argv[i]);
5464 free(bd->client.icccm.command.argv);
5466 if (bd->client.netwm.name)
5467 eina_stringshare_del(bd->client.netwm.name);
5468 if (bd->client.netwm.icon_name)
5469 eina_stringshare_del(bd->client.netwm.icon_name);
5470 e_object_del(E_OBJECT(bd->shape));
5471 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
5472 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
5473 if (bd->icon_object) evas_object_del(bd->icon_object);
5474 #ifdef _F_USE_DESK_WINDOW_PROFILE_
5475 EINA_LIST_FREE(bd->client.e.state.profiles, str)
5477 if (str) eina_stringshare_del(str);
5479 bd->client.e.state.profiles = NULL;
5480 if (bd->client.e.state.profile)
5481 eina_stringshare_del(bd->client.e.state.profile);
5482 bd->client.e.state.profile = NULL;
5484 #ifdef _F_ZONE_WINDOW_ROTATION_
5485 if (e_config->wm_win_rotation)
5487 bd->client.e.fetch.rot.app_set = 0;
5488 bd->client.e.state.rot.preferred_rot = -1;
5490 if (bd->client.e.state.rot.available_rots)
5491 E_FREE(bd->client.e.state.rot.available_rots);
5493 _e_border_rotation_list_remove(bd);
5494 if ((rot.vkbd) && (rot.vkbd == bd))
5496 ELB(ELBT_BD, "UNSET VKBD", bd->client.win);
5498 if (rot.vkbd_ctrl_win)
5500 ELB(ELBT_BD, "SET KBD_OFF", 0);
5501 ecore_x_e_virtual_keyboard_state_set
5502 (rot.vkbd_ctrl_win, ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF);
5505 rot.vkbd_hide_prepare_done = EINA_FALSE;
5506 if (rot.vkbd_hide_prepare_timer)
5507 ecore_timer_del(rot.vkbd_hide_prepare_timer);
5508 rot.vkbd_hide_prepare_timer = NULL;
5509 if (rot.vkbd_hide_timer)
5510 ecore_timer_del(rot.vkbd_hide_timer);
5511 rot.vkbd_hide_timer = NULL;
5513 rot.vkbd_show_prepare_done = EINA_FALSE;
5514 if (rot.vkbd_show_prepare_timer)
5515 ecore_timer_del(rot.vkbd_show_prepare_timer);
5516 rot.vkbd_show_prepare_timer = NULL;
5517 if (rot.vkbd_show_timer)
5518 ecore_timer_del(rot.vkbd_show_timer);
5519 rot.vkbd_show_timer = NULL;
5521 else if ((rot.vkbd_prediction) &&
5522 (rot.vkbd_prediction == bd))
5523 rot.vkbd_prediction = NULL;
5526 evas_object_del(bd->bg_object);
5527 e_canvas_del(bd->bg_ecore_evas);
5528 ecore_evas_free(bd->bg_ecore_evas);
5529 ecore_x_window_free(bd->client.shell_win);
5530 e_focus_setdown(bd);
5531 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5532 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_WINDOW, bd->win);
5533 ecore_x_window_free(bd->win);
5535 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
5536 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
5537 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
5538 borders = eina_list_remove(borders, bd);
5539 focus_stack = eina_list_remove(focus_stack, bd);
5540 raise_stack = eina_list_remove(raise_stack, bd);
5542 e_container_border_remove(bd);
5548 _e_border_del_dangling_ref_check(void *data)
5554 printf("EEK EEK border still around 1 second after being deleted!\n");
5555 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
5556 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
5557 bd->client.icccm.name, bd->client.icccm.class);
5558 // e_object_breadcrumb_debug(E_OBJECT(bd));
5565 _e_border_del(E_Border *bd)
5567 E_Event_Border_Remove *ev;
5570 #ifdef _F_BORDER_HOOK_PATCH_
5571 _e_border_hook_call(E_BORDER_HOOK_DEL_BORDER, bd);
5582 focus_next = eina_list_remove(focus_next, bd);
5584 if (bd->fullscreen) bd->desk->fullscreen_borders--;
5586 if ((drag_border) && (drag_border->data == bd))
5588 e_object_del(E_OBJECT(drag_border));
5591 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
5593 if (bd->border_locks_dialog)
5595 e_object_del(E_OBJECT(bd->border_locks_dialog));
5596 bd->border_locks_dialog = NULL;
5598 if (bd->border_remember_dialog)
5600 e_object_del(E_OBJECT(bd->border_remember_dialog));
5601 bd->border_remember_dialog = NULL;
5603 if (bd->border_border_dialog)
5605 e_object_del(E_OBJECT(bd->border_border_dialog));
5606 bd->border_border_dialog = NULL;
5608 if (bd->border_prop_dialog)
5610 e_object_del(E_OBJECT(bd->border_prop_dialog));
5611 bd->border_prop_dialog = NULL;
5614 e_int_border_menu_del(bd);
5616 if (bd->raise_timer)
5618 ecore_timer_del(bd->raise_timer);
5619 bd->raise_timer = NULL;
5621 if (!bd->already_unparented)
5623 ecore_x_window_reparent(bd->client.win,
5624 bd->zone->container->manager->root,
5625 bd->x + bd->client_inset.l,
5626 bd->y + bd->client_inset.t);
5627 ecore_x_window_save_set_del(bd->client.win);
5628 bd->already_unparented = 1;
5629 // bd->client.win = 0;
5631 bd->already_unparented = 1;
5633 if ((!bd->new_client) && (!stopping))
5635 ev = E_NEW(E_Event_Border_Remove, 1);
5637 e_object_ref(E_OBJECT(bd));
5638 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
5639 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
5642 #ifdef _F_DEICONIFY_APPROVE_
5643 if (bd->client.e.state.deiconify_approve.wait_timer)
5645 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
5646 bd->client.e.state.deiconify_approve.wait_timer = NULL;
5652 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
5653 if (bd->parent->modal == bd)
5655 ecore_x_event_mask_unset(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
5656 ecore_x_event_mask_set(bd->parent->client.win, bd->parent->saved.event_mask);
5657 bd->parent->lock_close = 0;
5658 bd->parent->saved.event_mask = 0;
5659 bd->parent->modal = NULL;
5663 EINA_LIST_FREE(bd->transients, child)
5665 child->parent = NULL;
5670 bd->leader->group = eina_list_remove(bd->leader->group, bd);
5671 if (bd->leader->modal == bd)
5672 bd->leader->modal = NULL;
5675 EINA_LIST_FREE(bd->group, child)
5677 child->leader = NULL;
5681 #ifdef PRINT_LOTS_OF_DEBUG
5683 _e_border_print(E_Border *bd,
5692 "\tBorderless: %s\n",
5693 bd, bd->client.icccm.name, bd->client.icccm.title,
5694 bd->borderless ? "TRUE" : "FALSE");
5700 _e_border_cb_window_show_request(void *data __UNUSED__,
5701 int ev_type __UNUSED__,
5705 Ecore_X_Event_Window_Show_Request *e;
5708 bd = e_border_find_by_client_window(e->win);
5709 if (!bd) return ECORE_CALLBACK_PASS_ON;
5712 if (!bd->lock_client_iconify)
5713 e_border_uniconify(bd);
5717 /* FIXME: make border "urgent" for a bit - it wants attention */
5718 /* e_border_show(bd); */
5719 if (!bd->lock_client_stacking)
5722 return ECORE_CALLBACK_PASS_ON;
5726 _e_border_cb_window_destroy(void *data __UNUSED__,
5727 int ev_type __UNUSED__,
5731 Ecore_X_Event_Window_Destroy *e;
5734 bd = e_border_find_by_client_window(e->win);
5735 if (!bd) return ECORE_CALLBACK_PASS_ON;
5736 e_border_hide(bd, 0);
5737 e_object_del(E_OBJECT(bd));
5738 return ECORE_CALLBACK_PASS_ON;
5742 _e_border_cb_window_hide(void *data __UNUSED__,
5743 int ev_type __UNUSED__,
5746 E_Border *bd = NULL;
5747 Ecore_X_Event_Window_Hide *e;
5750 // printf("HIDE: %x, event %x send: %i\n", e->win, e->event_win, e->send_event);
5751 // not interested in hide events from windows other than the window in question
5752 if (e->win != e->event_win)
5754 bd = e_border_find_by_client_window(e->win);
5755 if (!bd) return ECORE_CALLBACK_PASS_ON;
5756 if (!e->send_event) return ECORE_CALLBACK_PASS_ON;
5760 (bd->zone->container->manager->root == e->event_win)))
5761 return ECORE_CALLBACK_PASS_ON;
5764 if (!bd) bd = e_border_find_by_client_window(e->win);
5765 // printf(" bd = %p\n", bd);
5766 if (!bd) return ECORE_CALLBACK_PASS_ON;
5767 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
5768 if (bd->ignore_first_unmap > 0)
5770 bd->ignore_first_unmap--;
5771 return ECORE_CALLBACK_PASS_ON;
5773 /* Don't delete hidden or iconified windows */
5774 #ifdef _F_USE_EXTENDED_ICONIFY_
5775 if (bd->await_hide_event > 0)
5777 if ((bd->iconic) || (bd->await_hide_event > 0))
5780 // printf(" Don't delete hidden or iconified windows\n");
5781 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
5782 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
5783 if (bd->await_hide_event > 0)
5785 bd->await_hide_event--;
5789 // printf(" hide really\n");
5790 /* Only hide the border if it is visible */
5791 if (bd->visible) e_border_hide(bd, 1);
5796 // printf(" hide2\n");
5797 #ifdef _F_USE_EXTENDED_ICONIFY_
5804 e_border_hide(bd, 0);
5805 e_object_del(E_OBJECT(bd));
5807 return ECORE_CALLBACK_PASS_ON;
5811 _e_border_cb_window_reparent(void *data __UNUSED__,
5812 int ev_type __UNUSED__,
5813 void *ev __UNUSED__)
5817 Ecore_X_Event_Window_Reparent *e;
5820 bd = e_border_find_by_client_window(e->win);
5822 if (e->parent == bd->client.shell_win) return 1;
5823 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
5827 e_border_hide(bd, 0);
5828 e_object_del(E_OBJECT(bd));
5830 return ECORE_CALLBACK_PASS_ON;
5834 _e_border_cb_window_configure_request(void *data __UNUSED__,
5835 int ev_type __UNUSED__,
5839 Ecore_X_Event_Window_Configure_Request *e;
5842 bd = e_border_find_by_client_window(e->win);
5845 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
5846 if (!e_util_container_window_find(e->win))
5847 ecore_x_window_configure(e->win, e->value_mask,
5848 e->x, e->y, e->w, e->h, e->border,
5849 e->abovewin, e->detail);
5850 return ECORE_CALLBACK_PASS_ON;
5853 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
5854 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
5860 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
5862 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
5864 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
5865 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
5871 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
5872 w = e->w + bd->client_inset.l + bd->client_inset.r;
5873 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
5874 h = e->h + bd->client_inset.t + bd->client_inset.b;
5875 if ((!bd->lock_client_location) && (!bd->lock_client_size))
5877 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5879 bd->saved.x = x - bd->zone->x;
5880 bd->saved.y = y - bd->zone->y;
5885 e_border_move_resize(bd, x, y, w, h);
5887 else if (!bd->lock_client_location)
5889 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5891 bd->saved.x = x - bd->zone->x;
5892 bd->saved.y = y - bd->zone->y;
5895 e_border_move(bd, x, y);
5897 else if (!bd->lock_client_size)
5899 if ((bd->shaded) || (bd->shading))
5905 if ((bd->shade.dir == E_DIRECTION_UP) ||
5906 (bd->shade.dir == E_DIRECTION_DOWN))
5908 e_border_resize(bd, w, bd->h);
5913 e_border_resize(bd, bd->w, h);
5919 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5925 e_border_resize(bd, w, h);
5931 if (!bd->lock_client_location)
5933 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
5935 bd->saved.x = x - bd->zone->x;
5936 bd->saved.y = y - bd->zone->y;
5939 e_border_move(bd, x, y);
5943 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
5944 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
5950 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
5951 w = e->w + bd->client_inset.l + bd->client_inset.r;
5952 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
5953 h = e->h + bd->client_inset.t + bd->client_inset.b;
5954 #ifdef _F_ZONE_WINDOW_ROTATION_
5955 if (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE)
5957 if (!bd->lock_client_size)
5959 if ((bd->shaded) || (bd->shading))
5965 if ((bd->shade.dir == E_DIRECTION_UP) ||
5966 (bd->shade.dir == E_DIRECTION_DOWN))
5968 e_border_resize(bd, w, bd->h);
5973 e_border_resize(bd, bd->w, h);
5979 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
5984 zx = zy = zw = zh = 0;
5987 * This code does resize and move a window on a
5988 * X configure request into an useful geometry.
5989 * This is really useful for size jumping file dialogs.
5994 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
5996 if (e_config->geometry_auto_resize_limit == 1)
6005 e_border_resize(bd, w, h);
6007 if (e_config->geometry_auto_move == 1)
6009 /* z{x,y,w,h} are only set here; FIXME! */
6012 // move window horizontal if resize to not useful geometry
6013 if (bd->x + bd->w > zx + zw)
6014 rx = zx + zw - bd->w;
6015 else if (bd->x < zx)
6018 // move window vertical if resize to not useful geometry
6019 if (bd->y + bd->h > zy + zh)
6020 ry = zy + zh - bd->h;
6021 else if (bd->y < zy)
6024 e_border_move(bd, rx, ry);
6030 if (!bd->lock_client_stacking)
6032 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
6033 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
6037 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6039 obd = e_border_find_by_client_window(e->abovewin);
6042 e_border_stack_above(bd, obd);
6046 ecore_x_window_configure(bd->win,
6047 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6048 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6050 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
6051 /* FIXME: need to rebuiuld border list from current stacking */
6054 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6056 obd = e_border_find_by_client_window(e->abovewin);
6059 e_border_stack_below(bd, obd);
6063 ecore_x_window_configure(bd->win,
6064 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
6065 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
6067 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
6068 /* FIXME: need to rebuiuld border list from current stacking */
6071 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6075 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6079 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6084 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
6086 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6090 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6094 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
6098 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
6102 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
6109 /* FIXME: need to send synthetic stacking event too as well as move/resize */
6110 _e_border_client_move_resize_send(bd);
6111 return ECORE_CALLBACK_PASS_ON;
6115 _e_border_cb_window_resize_request(void *data __UNUSED__,
6116 int ev_type __UNUSED__,
6120 Ecore_X_Event_Window_Resize_Request *e;
6123 bd = e_border_find_by_client_window(e->win);
6126 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6127 ecore_x_window_resize(e->win, e->w, e->h);
6128 return ECORE_CALLBACK_PASS_ON;
6133 w = e->w + bd->client_inset.l + bd->client_inset.r;
6134 h = e->h + bd->client_inset.t + bd->client_inset.b;
6135 if ((bd->shaded) || (bd->shading))
6141 if ((bd->shade.dir == E_DIRECTION_UP) ||
6142 (bd->shade.dir == E_DIRECTION_DOWN))
6144 e_border_resize(bd, w, bd->h);
6149 e_border_resize(bd, bd->w, h);
6154 e_border_resize(bd, w, h);
6157 _e_border_client_move_resize_send(bd);
6158 return ECORE_CALLBACK_PASS_ON;
6162 _e_border_cb_window_gravity(void *data __UNUSED__,
6163 int ev_type __UNUSED__,
6164 void *ev __UNUSED__)
6167 // Ecore_X_Event_Window_Gravity *e;
6170 // bd = e_border_find_by_client_window(e->win);
6171 // if (!bd) return 1;
6176 _e_border_cb_window_stack_request(void *data __UNUSED__,
6177 int ev_type __UNUSED__,
6181 Ecore_X_Event_Window_Stack_Request *e;
6184 bd = e_border_find_by_client_window(e->win);
6187 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
6188 if (!e_util_container_window_find(e->win))
6190 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6191 ecore_x_window_raise(e->win);
6192 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6193 ecore_x_window_lower(e->win);
6195 return ECORE_CALLBACK_PASS_ON;
6197 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
6199 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
6201 return ECORE_CALLBACK_PASS_ON;
6205 _e_border_cb_window_property(void *data __UNUSED__,
6206 int ev_type __UNUSED__,
6210 Ecore_X_Event_Window_Property *e;
6213 bd = e_border_find_by_client_window(e->win);
6214 if (!bd) return ECORE_CALLBACK_PASS_ON;
6215 if (e->atom == ECORE_X_ATOM_WM_NAME)
6217 if ((!bd->client.netwm.name) &&
6218 (!bd->client.netwm.fetch.name))
6220 bd->client.icccm.fetch.title = 1;
6224 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
6226 bd->client.netwm.fetch.name = 1;
6229 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
6231 bd->client.icccm.fetch.name_class = 1;
6234 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
6236 if ((!bd->client.netwm.icon_name) &&
6237 (!bd->client.netwm.fetch.icon_name))
6239 bd->client.icccm.fetch.icon_name = 1;
6243 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
6245 bd->client.netwm.fetch.icon_name = 1;
6248 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
6250 bd->client.icccm.fetch.machine = 1;
6253 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
6255 bd->client.icccm.fetch.protocol = 1;
6258 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
6260 bd->client.icccm.fetch.hints = 1;
6263 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
6265 bd->client.icccm.fetch.size_pos_hints = 1;
6268 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
6271 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
6272 (!bd->client.netwm.fetch.type))
6275 bd->client.mwm.fetch.hints = 1;
6281 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
6283 bd->client.icccm.fetch.transient_for = 1;
6286 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
6288 bd->client.icccm.fetch.client_leader = 1;
6291 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
6293 bd->client.icccm.fetch.window_role = 1;
6296 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
6298 bd->client.netwm.fetch.icon = 1;
6301 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
6303 bd->client.qtopia.fetch.soft_menu = 1;
6306 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
6308 bd->client.qtopia.fetch.soft_menus = 1;
6311 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
6313 bd->client.vkbd.fetch.state = 1;
6316 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
6318 bd->client.vkbd.fetch.vkbd = 1;
6321 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
6323 bd->client.illume.conformant.fetch.conformant = 1;
6326 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
6328 bd->client.illume.quickpanel.fetch.state = 1;
6331 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
6333 bd->client.illume.quickpanel.fetch.quickpanel = 1;
6336 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
6338 bd->client.illume.quickpanel.fetch.priority.major = 1;
6341 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
6343 bd->client.illume.quickpanel.fetch.priority.minor = 1;
6346 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
6348 bd->client.illume.quickpanel.fetch.zone = 1;
6351 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
6353 bd->client.illume.drag.fetch.locked = 1;
6356 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
6358 bd->client.illume.drag.fetch.drag = 1;
6361 else if (e->atom == ECORE_X_ATOM_E_ILLUME_WINDOW_STATE)
6363 bd->client.illume.win_state.fetch.state = 1;
6367 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
6369 bd->client.netwm.fetch.user_time = 1;
6372 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
6374 bd->client.netwm.fetch.strut = 1;
6377 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
6379 bd->client.netwm.fetch.strut = 1;
6383 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
6385 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
6387 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
6389 bd->client.e.fetch.video_position = 1;
6392 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
6394 bd->client.e.fetch.video_parent = 1;
6397 else if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
6399 bd->client.netwm.fetch.state = 1;
6402 #ifdef _F_USE_DESK_WINDOW_PROFILE_
6403 else if (e->atom == ECORE_X_ATOM_E_PROFILE_LIST)
6405 bd->client.e.fetch.profile_list = 1;
6409 #ifdef _F_ZONE_WINDOW_ROTATION_
6410 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED)
6412 if (e_config->wm_win_rotation)
6414 bd->client.e.fetch.rot.support = 1;
6418 else if ((e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_0_GEOMETRY) ||
6419 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_90_GEOMETRY) ||
6420 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_180_GEOMETRY) ||
6421 (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_270_GEOMETRY))
6423 if (e_config->wm_win_rotation)
6425 bd->client.e.fetch.rot.geom_hint = 1;
6429 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_APP_SUPPORTED)
6431 if (e_config->wm_win_rotation)
6433 bd->client.e.fetch.rot.app_set = 1;
6437 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_PREFERRED_ROTATION)
6439 if (e_config->wm_win_rotation)
6441 bd->client.e.fetch.rot.preferred_rot = 1;
6445 else if (e->atom == ECORE_X_ATOM_E_WINDOW_ROTATION_AVAILABLE_LIST)
6447 if (e_config->wm_win_rotation)
6449 bd->client.e.fetch.rot.available_rots = 1;
6455 return ECORE_CALLBACK_PASS_ON;
6459 _e_border_cb_window_colormap(void *data __UNUSED__,
6460 int ev_type __UNUSED__,
6464 Ecore_X_Event_Window_Colormap *e;
6467 bd = e_border_find_by_client_window(e->win);
6468 if (!bd) return ECORE_CALLBACK_PASS_ON;
6469 return ECORE_CALLBACK_PASS_ON;
6473 _e_border_cb_window_shape(void *data __UNUSED__,
6474 int ev_type __UNUSED__,
6478 Ecore_X_Event_Window_Shape *e;
6481 bd = e_border_find_by_client_window(e->win);
6483 if (e->type == ECORE_X_SHAPE_INPUT)
6487 bd->need_shape_merge = 1;
6488 // YYY bd->shaped_input = 1;
6489 bd->changes.shape_input = 1;
6493 return ECORE_CALLBACK_PASS_ON;
6498 bd->changes.shape = 1;
6500 return ECORE_CALLBACK_PASS_ON;
6502 bd = e_border_find_by_window(e->win);
6505 bd->need_shape_export = 1;
6507 return ECORE_CALLBACK_PASS_ON;
6509 bd = e_border_find_by_frame_window(e->win);
6512 bd->need_shape_merge = 1;
6514 return ECORE_CALLBACK_PASS_ON;
6516 return ECORE_CALLBACK_PASS_ON;
6520 _e_border_cb_window_focus_in(void *data __UNUSED__,
6521 int ev_type __UNUSED__,
6525 Ecore_X_Event_Window_Focus_In *e;
6528 bd = e_border_find_by_client_window(e->win);
6529 if (!bd) return ECORE_CALLBACK_PASS_ON;
6530 #ifdef INOUTDEBUG_FOCUS
6535 const char *modes[] = {
6537 "MODE_WHILE_GRABBED",
6541 const char *details[] = {
6545 "DETAIL_NON_LINEAR",
6546 "DETAIL_NON_LINEAR_VIRTUAL",
6548 "DETAIL_POINTER_ROOT",
6549 "DETAIL_DETAIL_NONE"
6553 ct[strlen(ct) - 1] = 0;
6554 DBG("FF ->IN %i 0x%x %s md=%s dt=%s\n",
6559 details[e->detail]);
6561 DBG("%s cb focus in %d %d\n",
6562 e_border_name_get(bd),
6563 bd->client.icccm.accepts_focus,
6564 bd->client.icccm.take_focus);
6567 _e_border_pri_raise(bd);
6568 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6570 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6572 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6574 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
6577 /* ignore focus in from !take_focus windows, we just gave it em */
6578 /* if (!bd->client.icccm.take_focus)
6579 * return ECORE_CALLBACK_PASS_ON; */
6581 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
6582 if (e->time >= focus_time)
6583 e_border_focus_set(bd, 1, 0);
6584 return ECORE_CALLBACK_PASS_ON;
6588 _e_border_cb_window_focus_out(void *data __UNUSED__,
6589 int ev_type __UNUSED__,
6593 Ecore_X_Event_Window_Focus_Out *e;
6596 bd = e_border_find_by_client_window(e->win);
6597 if (!bd) return ECORE_CALLBACK_PASS_ON;
6598 #ifdef INOUTDEBUG_FOCUS
6603 const char *modes[] = {
6605 "MODE_WHILE_GRABBED",
6609 const char *details[] = {
6613 "DETAIL_NON_LINEAR",
6614 "DETAIL_NON_LINEAR_VIRTUAL",
6616 "DETAIL_POINTER_ROOT",
6617 "DETAIL_DETAIL_NONE"
6621 ct[strlen(ct) - 1] = 0;
6622 DBG("FF <-OUT %i 0x%x %s md=%s dt=%s",
6627 details[e->detail]);
6629 DBG("%s cb focus out %d %d",
6630 e_border_name_get(bd),
6631 bd->client.icccm.accepts_focus,
6632 bd->client.icccm.take_focus);
6635 _e_border_pri_norm(bd);
6636 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
6638 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6639 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
6640 return ECORE_CALLBACK_PASS_ON;
6641 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6642 return ECORE_CALLBACK_PASS_ON;
6644 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
6646 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
6647 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6648 return ECORE_CALLBACK_PASS_ON;
6649 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
6650 return ECORE_CALLBACK_PASS_ON;
6651 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
6652 return ECORE_CALLBACK_PASS_ON;
6653 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
6654 return ECORE_CALLBACK_PASS_ON;
6656 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
6658 /* for firefox/thunderbird (xul) menu walking */
6659 /* NB: why did i disable this before? */
6660 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
6661 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
6662 return ECORE_CALLBACK_PASS_ON;
6664 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
6666 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
6667 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
6668 return ECORE_CALLBACK_PASS_ON;
6670 e_border_focus_set(bd, 0, 0);
6671 return ECORE_CALLBACK_PASS_ON;
6674 #if _F_BORDER_CLIP_TO_ZONE_
6676 _e_border_shape_input_clip_to_zone(E_Border *bd)
6678 /* if (!(e_config->window_out_of_vscreen_limits_partly)) return; */
6682 if (!(E_CONTAINS(bd->zone->x, bd->zone->y,
6683 bd->zone->w, bd->zone->h,
6684 bd->x, bd->y, bd->w, bd->h)))
6687 x = bd->x; y = bd->y; w = bd->w; h = bd->h;
6688 E_RECTS_CLIP_TO_RECT(x, y, w, h,
6689 bd->zone->x, bd->zone->y,
6690 bd->zone->w, bd->zone->h);
6693 ecore_x_window_shape_input_rectangle_set(bd->bg_win, x, y, w, h);
6694 ecore_x_window_shape_input_rectangle_set(bd->win, x, y, w, h);
6698 ecore_x_window_shape_input_rectangle_set(bd->bg_win, 0, 0, bd->w, bd->h);
6699 ecore_x_window_shape_input_rectangle_set(bd->win, 0, 0, bd->w, bd->h);
6702 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
6705 _e_border_cb_client_message(void *data __UNUSED__,
6706 int ev_type __UNUSED__,
6709 Ecore_X_Event_Client_Message *e;
6713 #ifdef _F_DEICONIFY_APPROVE_
6714 if (e->message_type == ECORE_X_ATOM_E_DEICONIFY_APPROVE)
6716 if (!e_config->deiconify_approve) return ECORE_CALLBACK_PASS_ON;
6718 bd = e_border_find_by_client_window(e->win);
6721 if (bd->client.e.state.deiconify_approve.support)
6723 if (e->data.l[1] != 1) return ECORE_CALLBACK_PASS_ON;
6724 if (bd->client.e.state.deiconify_approve.wait_timer)
6726 ecore_timer_del(bd->client.e.state.deiconify_approve.wait_timer);
6727 bd->client.e.state.deiconify_approve.wait_timer = NULL;
6729 bd->client.e.state.deiconify_approve.render_done = 1;
6730 e_border_uniconify(bd);
6733 return ECORE_CALLBACK_PASS_ON;
6737 #ifdef _F_ZONE_WINDOW_ROTATION_
6738 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
6740 bd = e_border_find_by_client_window(e->win);
6743 if (e_config->wm_win_rotation)
6745 Ecore_X_Event_Client_Message *msg = NULL;
6746 Ecore_X_Atom t = e->message_type;
6747 if ((t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_ON_PREPARE_DONE) ||
6748 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_OFF_PREPARE_DONE) ||
6749 (t == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_CONTROL_WINDOW) ||
6750 (t == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_PREPARE_DONE))
6752 msg = E_NEW(Ecore_X_Event_Client_Message, 1);
6753 if (!msg) return ECORE_CALLBACK_PASS_ON;
6756 msg->message_type = e->message_type;
6757 msg->data.l[0] = e->data.l[0];
6758 msg->data.l[1] = e->data.l[1];
6759 msg->data.l[2] = e->data.l[2];
6760 msg->data.l[3] = e->data.l[3];
6761 msg->data.l[4] = e->data.l[4];
6762 rot.msgs = eina_list_append(rot.msgs, msg);
6764 rot.fetch = EINA_TRUE;
6767 return ECORE_CALLBACK_PASS_ON;
6770 if (e->message_type == ECORE_X_ATOM_E_WINDOW_ROTATION_CHANGE_DONE)
6772 ELBF(ELBT_ROT, 0, e->data.l[0], "GET ROT_DONE a%d %dx%d zone_a:%d",
6773 e->data.l[1], e->data.l[2], e->data.l[3], bd->zone->rot.curr);
6775 if (e_config->wm_win_rotation)
6777 if ((int)e->data.l[1] == bd->client.e.state.rot.curr)
6778 _e_border_rotation_list_remove(bd);
6782 return ECORE_CALLBACK_PASS_ON;
6786 _e_border_cb_window_state_request(void *data __UNUSED__,
6787 int ev_type __UNUSED__,
6791 Ecore_X_Event_Window_State_Request *e;
6795 bd = e_border_find_by_client_window(e->win);
6796 if (!bd) return ECORE_CALLBACK_PASS_ON;
6798 for (i = 0; i < 2; i++)
6799 e_hints_window_state_update(bd, e->state[i], e->action);
6801 return ECORE_CALLBACK_PASS_ON;
6805 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
6806 int ev_type __UNUSED__,
6810 Ecore_X_Event_Window_Move_Resize_Request *e;
6813 bd = e_border_find_by_client_window(e->win);
6814 if (!bd) return ECORE_CALLBACK_PASS_ON;
6816 if ((bd->shaded) || (bd->shading) ||
6817 (bd->fullscreen) || (bd->moving) ||
6818 (bd->resize_mode != RESIZE_NONE))
6819 return ECORE_CALLBACK_PASS_ON;
6821 if ((e->button >= 1) && (e->button <= 3))
6823 bd->mouse.last_down[e->button - 1].mx = e->x;
6824 bd->mouse.last_down[e->button - 1].my = e->y;
6825 bd->mouse.last_down[e->button - 1].x = bd->x;
6826 bd->mouse.last_down[e->button - 1].y = bd->y;
6827 bd->mouse.last_down[e->button - 1].w = bd->w;
6828 bd->mouse.last_down[e->button - 1].h = bd->h;
6832 bd->moveinfo.down.x = bd->x;
6833 bd->moveinfo.down.y = bd->y;
6834 bd->moveinfo.down.w = bd->w;
6835 bd->moveinfo.down.h = bd->h;
6837 bd->mouse.current.mx = e->x;
6838 bd->mouse.current.my = e->y;
6839 bd->moveinfo.down.button = e->button;
6840 bd->moveinfo.down.mx = e->x;
6841 bd->moveinfo.down.my = e->y;
6844 if (!bd->lock_user_stacking)
6847 if (e->direction == MOVE)
6849 bd->cur_mouse_action = e_action_find("window_move");
6850 if (bd->cur_mouse_action)
6852 if ((!bd->cur_mouse_action->func.end_mouse) &&
6853 (!bd->cur_mouse_action->func.end))
6854 bd->cur_mouse_action = NULL;
6855 if (bd->cur_mouse_action)
6857 e_object_ref(E_OBJECT(bd->cur_mouse_action));
6858 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
6861 return ECORE_CALLBACK_PASS_ON;
6864 if (!_e_border_resize_begin(bd))
6865 return ECORE_CALLBACK_PASS_ON;
6867 switch (e->direction)
6870 bd->resize_mode = RESIZE_TL;
6871 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
6875 bd->resize_mode = RESIZE_T;
6876 GRAV_SET(bd, ECORE_X_GRAVITY_S);
6880 bd->resize_mode = RESIZE_TR;
6881 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
6885 bd->resize_mode = RESIZE_R;
6886 GRAV_SET(bd, ECORE_X_GRAVITY_W);
6890 bd->resize_mode = RESIZE_BR;
6891 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
6895 bd->resize_mode = RESIZE_B;
6896 GRAV_SET(bd, ECORE_X_GRAVITY_N);
6900 bd->resize_mode = RESIZE_BL;
6901 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
6905 bd->resize_mode = RESIZE_L;
6906 GRAV_SET(bd, ECORE_X_GRAVITY_E);
6910 return ECORE_CALLBACK_PASS_ON;
6913 bd->cur_mouse_action = e_action_find("window_resize");
6914 if (bd->cur_mouse_action)
6916 if ((!bd->cur_mouse_action->func.end_mouse) &&
6917 (!bd->cur_mouse_action->func.end))
6918 bd->cur_mouse_action = NULL;
6920 if (bd->cur_mouse_action)
6921 e_object_ref(E_OBJECT(bd->cur_mouse_action));
6923 return ECORE_CALLBACK_PASS_ON;
6927 _e_border_cb_desktop_change(void *data __UNUSED__,
6928 int ev_type __UNUSED__,
6932 Ecore_X_Event_Desktop_Change *e;
6935 bd = e_border_find_by_client_window(e->win);
6938 if (e->desk == 0xffffffff)
6940 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
6944 desk = e_desk_at_pos_get(bd->zone, e->desk);
6946 e_border_desk_set(bd, desk);
6951 ecore_x_netwm_desktop_set(e->win, e->desk);
6953 return ECORE_CALLBACK_PASS_ON;
6957 _e_border_cb_sync_alarm(void *data __UNUSED__,
6958 int ev_type __UNUSED__,
6962 Ecore_X_Event_Sync_Alarm *e;
6963 unsigned int serial;
6966 bd = e_border_find_by_alarm(e->alarm);
6967 if (!bd) return ECORE_CALLBACK_PASS_ON;
6969 if (bd->client.netwm.sync.wait)
6970 bd->client.netwm.sync.wait--;
6972 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
6974 E_Border_Pending_Move_Resize *pnd = NULL;
6976 /* skip pending for which we didn't get a reply */
6977 while (bd->pending_move_resize)
6979 pnd = bd->pending_move_resize->data;
6980 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
6982 if (serial == pnd->serial)
6994 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
6995 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
7000 bd->changes.size = 1;
7001 bd->changes.pos = 1;
7004 evas_render(bd->bg_evas);
7006 ecore_x_pointer_xy_get(e_manager_current_get()->root,
7007 &bd->mouse.current.mx,
7008 &bd->mouse.current.my);
7010 bd->client.netwm.sync.send_time = ecore_loop_time_get();
7011 _e_border_resize_handle(bd);
7013 return ECORE_CALLBACK_PASS_ON;
7017 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
7018 int ev_type __UNUSED__,
7019 void *ev __UNUSED__)
7024 /* mark all borders for desktop/icon updates */
7025 EINA_LIST_FOREACH(borders, l, bd)
7029 efreet_desktop_free(bd->desktop);
7032 bd->changes.icon = 1;
7036 e_init_status_set(_("Desktop files scan done"));
7039 return ECORE_CALLBACK_PASS_ON;
7043 _e_border_cb_config_icon_theme(void *data __UNUSED__,
7044 int ev_type __UNUSED__,
7045 void *ev __UNUSED__)
7050 /* mark all borders for desktop/icon updates */
7051 EINA_LIST_FOREACH(borders, l, bd)
7053 bd->changes.icon = 1;
7056 return ECORE_CALLBACK_PASS_ON;
7060 _e_border_cb_pointer_warp(void *data __UNUSED__,
7061 int ev_type __UNUSED__,
7064 E_Event_Pointer_Warp *e;
7067 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
7068 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
7069 return ECORE_CALLBACK_PASS_ON;
7073 _e_border_cb_signal_bind(void *data,
7074 Evas_Object *obj __UNUSED__,
7075 const char *emission,
7081 if (e_dnd_active()) return;
7082 e_bindings_signal_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd),
7087 _e_border_cb_mouse_in(void *data,
7088 int type __UNUSED__,
7091 Ecore_X_Event_Mouse_In *ev;
7096 #ifdef INOUTDEBUG_MOUSE
7101 const char *modes[] = {
7103 "MODE_WHILE_GRABBED",
7107 const char *details[] = {
7111 "DETAIL_NON_LINEAR",
7112 "DETAIL_NON_LINEAR_VIRTUAL",
7114 "DETAIL_POINTER_ROOT",
7115 "DETAIL_DETAIL_NONE"
7119 ct[strlen(ct) - 1] = 0;
7120 DBG("@@ ->IN 0x%x 0x%x %s md=%s dt=%s",
7121 ev->win, ev->event_win,
7124 details[ev->detail]);
7127 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7128 if (ev->event_win == bd->win)
7130 e_focus_event_mouse_in(bd);
7133 if ((ev->win != bd->win) &&
7134 (ev->win != bd->event_win) &&
7135 (ev->event_win != bd->win) &&
7136 (ev->event_win != bd->event_win))
7137 return ECORE_CALLBACK_PASS_ON;
7139 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7141 bd->mouse.current.mx = ev->root.x;
7142 bd->mouse.current.my = ev->root.y;
7143 if (!bd->bg_evas_in)
7145 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
7146 bd->bg_evas_in = EINA_TRUE;
7148 return ECORE_CALLBACK_PASS_ON;
7152 _e_border_cb_mouse_out(void *data,
7153 int type __UNUSED__,
7156 Ecore_X_Event_Mouse_Out *ev;
7161 #ifdef INOUTDEBUG_MOUSE
7166 const char *modes[] = {
7168 "MODE_WHILE_GRABBED",
7172 const char *details[] = {
7176 "DETAIL_NON_LINEAR",
7177 "DETAIL_NON_LINEAR_VIRTUAL",
7179 "DETAIL_POINTER_ROOT",
7180 "DETAIL_DETAIL_NONE"
7184 ct[strlen(ct) - 1] = 0;
7185 DBG("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s",
7186 ev->win, ev->event_win,
7189 details[ev->detail]);
7192 if (grabbed) return ECORE_CALLBACK_PASS_ON;
7193 if (ev->event_win == bd->win)
7196 return ECORE_CALLBACK_PASS_ON;
7197 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
7198 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7199 return ECORE_CALLBACK_PASS_ON;
7200 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7201 return ECORE_CALLBACK_PASS_ON;
7202 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
7203 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
7204 return ECORE_CALLBACK_PASS_ON;
7205 e_focus_event_mouse_out(bd);
7208 if ((ev->win != bd->win) &&
7209 (ev->win != bd->event_win) &&
7210 (ev->event_win != bd->win) &&
7211 (ev->event_win != bd->event_win))
7212 return ECORE_CALLBACK_PASS_ON;
7214 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7216 bd->mouse.current.mx = ev->root.x;
7217 bd->mouse.current.my = ev->root.y;
7220 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
7221 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
7222 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
7224 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
7225 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
7226 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
7227 bd->bg_evas_in = EINA_FALSE;
7230 return ECORE_CALLBACK_PASS_ON;
7234 _e_border_cb_mouse_wheel(void *data,
7235 int type __UNUSED__,
7238 Ecore_Event_Mouse_Wheel *ev;
7243 if ((ev->event_window == bd->win) ||
7244 (ev->event_window == bd->event_win))
7246 bd->mouse.current.mx = ev->root.x;
7247 bd->mouse.current.my = ev->root.y;
7248 if (!bd->cur_mouse_action)
7249 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_WINDOW,
7252 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
7253 return ECORE_CALLBACK_PASS_ON;
7257 _e_border_cb_mouse_down(void *data,
7258 int type __UNUSED__,
7261 Ecore_Event_Mouse_Button *ev;
7266 if ((ev->event_window == bd->win) ||
7267 (ev->event_window == bd->event_win))
7269 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7271 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7272 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7273 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7274 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7275 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7276 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7280 bd->moveinfo.down.x = bd->x + bd->fx.x;
7281 bd->moveinfo.down.y = bd->y + bd->fx.y;
7282 bd->moveinfo.down.w = bd->w;
7283 bd->moveinfo.down.h = bd->h;
7285 bd->mouse.current.mx = ev->root.x;
7286 bd->mouse.current.my = ev->root.y;
7287 if (!bd->cur_mouse_action)
7289 bd->cur_mouse_action =
7290 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_WINDOW,
7292 if (bd->cur_mouse_action)
7294 if ((!bd->cur_mouse_action->func.end_mouse) &&
7295 (!bd->cur_mouse_action->func.end))
7296 bd->cur_mouse_action = NULL;
7297 if (bd->cur_mouse_action)
7298 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7301 e_focus_event_mouse_down(bd);
7303 if (ev->window != ev->event_window)
7307 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
7311 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7313 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
7314 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
7315 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
7316 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
7317 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
7318 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
7322 bd->moveinfo.down.x = bd->x + bd->fx.x;
7323 bd->moveinfo.down.y = bd->y + bd->fx.y;
7324 bd->moveinfo.down.w = bd->w;
7325 bd->moveinfo.down.h = bd->h;
7327 bd->mouse.current.mx = ev->root.x;
7328 bd->mouse.current.my = ev->root.y;
7333 else if (bd->resize_mode != RESIZE_NONE)
7339 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
7341 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
7342 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
7343 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
7345 return ECORE_CALLBACK_PASS_ON;
7349 _e_border_cb_mouse_up(void *data,
7350 int type __UNUSED__,
7353 Ecore_Event_Mouse_Button *ev;
7358 if ((ev->event_window == bd->win) ||
7359 (ev->event_window == bd->event_win))
7361 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7363 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7364 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7365 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7366 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7368 bd->mouse.current.mx = ev->root.x;
7369 bd->mouse.current.my = ev->root.y;
7370 /* also we dont pass the same params that went in - then again that */
7371 /* should be ok as we are just ending the action if it has an end */
7372 if (bd->cur_mouse_action)
7374 if (bd->cur_mouse_action->func.end_mouse)
7375 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
7376 else if (bd->cur_mouse_action->func.end)
7377 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
7378 e_object_unref(E_OBJECT(bd->cur_mouse_action));
7379 bd->cur_mouse_action = NULL;
7383 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_WINDOW, E_OBJECT(bd), ev))
7384 e_focus_event_mouse_up(bd);
7387 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
7388 if ((ev->buttons >= 1) && (ev->buttons <= 3))
7390 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
7391 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
7392 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
7393 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
7395 bd->mouse.current.mx = ev->root.x;
7396 bd->mouse.current.my = ev->root.y;
7400 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
7401 return ECORE_CALLBACK_PASS_ON;
7405 _e_border_stay_within_container(E_Border *bd, int x, int y, int *new_x, int *new_y)
7407 #ifdef _F_BORDER_CLIP_TO_ZONE_
7408 int new_x_max, new_y_max;
7409 int new_x_min, new_y_min;
7410 int margin_x, margin_y;
7412 margin_x = bd->w - 100;
7413 margin_y = bd->h - 100;
7415 new_x_max = bd->zone->x + bd->zone->w - bd->w + margin_x;
7416 new_x_min = bd->zone->x - margin_x;
7417 new_y_max = bd->zone->y + bd->zone->h - bd->h + margin_y;
7418 new_y_min = bd->zone->y - margin_y;
7420 if (x >= new_x_max) *new_x = new_x_max;
7421 else if (x <= new_x_min) *new_x = new_x_min;
7423 if (y >= new_y_max) *new_y = new_y_max;
7424 else if (y <= new_y_min) *new_y = new_y_min;
7429 _e_border_cb_mouse_move(void *data,
7430 int type __UNUSED__,
7433 Ecore_Event_Mouse_Move *ev;
7438 if ((ev->window != bd->event_win) &&
7439 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
7440 bd->mouse.current.mx = ev->root.x;
7441 bd->mouse.current.my = ev->root.y;
7444 int x, y, new_x, new_y;
7446 Eina_List *skiplist = NULL;
7448 // FIXME: remove? sync what for when only moving?
7449 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
7450 bd->client.netwm.sync.wait = 0;
7451 if ((bd->client.netwm.sync.request) &&
7452 (bd->client.netwm.sync.alarm) &&
7453 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
7455 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
7457 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
7458 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7459 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
7460 (bd->mouse.current.my - bd->moveinfo.down.my);
7464 x = bd->moveinfo.down.x +
7465 (bd->mouse.current.mx - bd->moveinfo.down.mx);
7466 y = bd->moveinfo.down.y +
7467 (bd->mouse.current.my - bd->moveinfo.down.my);
7472 #ifdef _F_USE_RESIST_MAGNETIC_EFFECT_
7473 skiplist = eina_list_append(skiplist, bd);
7474 e_resist_container_border_position(bd->zone->container, skiplist,
7475 bd->x, bd->y, bd->w, bd->h,
7477 &new_x, &new_y, &new_w, &new_h);
7478 eina_list_free(skiplist);
7480 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7482 /* if (e_config->window_out_of_vscreen_limits_partly) */
7484 _e_border_stay_within_container(bd, x, y, &new_x, &new_y);
7487 skiplist = eina_list_append(skiplist, bd);
7488 e_resist_container_border_position(bd->zone->container, skiplist,
7489 bd->x, bd->y, bd->w, bd->h,
7491 &new_x, &new_y, &new_w, &new_h);
7492 eina_list_free(skiplist);
7495 bd->shelf_fix.x = 0;
7496 bd->shelf_fix.y = 0;
7497 bd->shelf_fix.modified = 0;
7498 e_border_move(bd, new_x, new_y);
7499 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
7501 else if (bd->resize_mode != RESIZE_NONE)
7503 if ((bd->client.netwm.sync.request) &&
7504 (bd->client.netwm.sync.alarm))
7506 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
7508 E_Border_Pending_Move_Resize *pnd;
7510 if (bd->pending_move_resize)
7512 bd->changes.pos = 1;
7513 bd->changes.size = 1;
7515 _e_border_client_move_resize_send(bd);
7517 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7520 bd->client.netwm.sync.wait = 0;
7522 /* sync.wait is incremented when resize_handle sends
7523 * sync-request and decremented by sync-alarm cb. so
7524 * we resize here either on initial resize, timeout or
7525 * when no new resize-request was added by sync-alarm cb.
7527 if (!bd->client.netwm.sync.wait)
7528 _e_border_resize_handle(bd);
7531 _e_border_resize_handle(bd);
7537 if ((bd->drag.x == -1) && (bd->drag.y == -1))
7539 bd->drag.x = ev->root.x;
7540 bd->drag.y = ev->root.y;
7546 dx = bd->drag.x - ev->root.x;
7547 dy = bd->drag.y - ev->root.y;
7548 if (((dx * dx) + (dy * dy)) >
7549 (e_config->drag_resist * e_config->drag_resist))
7552 if (bd->icon_object)
7554 Evas_Object *o = NULL;
7555 Evas_Coord x, y, w, h;
7556 const char *drag_types[] = { "enlightenment/border" };
7558 e_object_ref(E_OBJECT(bd));
7559 evas_object_geometry_get(bd->icon_object,
7561 drag_border = e_drag_new(bd->zone->container,
7562 bd->x + bd->fx.x + x,
7563 bd->y + bd->fx.y + y,
7564 drag_types, 1, bd, -1,
7566 _e_border_cb_drag_finished);
7567 o = e_border_icon_add(bd, drag_border->evas);
7570 /* FIXME: fallback icon for drag */
7571 o = evas_object_rectangle_add(drag_border->evas);
7572 evas_object_color_set(o, 255, 255, 255, 255);
7574 e_drag_object_set(drag_border, o);
7576 e_drag_resize(drag_border, w, h);
7577 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
7583 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
7585 return ECORE_CALLBACK_PASS_ON;
7589 _e_border_cb_grab_replay(void *data __UNUSED__,
7593 Ecore_Event_Mouse_Button *ev;
7595 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
7597 if ((e_config->pass_click_on)
7598 || (e_config->always_click_to_raise) // this works even if not on click-to-focus
7599 || (e_config->always_click_to_focus) // this works even if not on click-to-focus
7604 bd = e_border_find_by_window(ev->event_window);
7607 if (bd->cur_mouse_action)
7608 return ECORE_CALLBACK_DONE;
7609 if (ev->event_window == bd->win)
7611 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_WINDOW,
7612 E_OBJECT(bd), ev, NULL))
7613 return ECORE_CALLBACK_PASS_ON;
7617 return ECORE_CALLBACK_DONE;
7621 _e_border_cb_drag_finished(E_Drag *drag,
7622 int dropped __UNUSED__)
7627 e_object_unref(E_OBJECT(bd));
7631 #ifdef _F_USE_DESK_WINDOW_PROFILE_
7633 _e_border_cb_desk_window_profile_change(void *data __UNUSED__,
7634 int ev_type __UNUSED__,
7637 E_Event_Desk_Window_Profile_Change *e;
7642 EINA_LIST_FOREACH(borders, l, bd)
7644 if ((bd) && (!e_object_is_del(E_OBJECT(bd))))
7646 bd->client.e.fetch.profile_list = 1;
7650 return ECORE_CALLBACK_PASS_ON;
7654 #ifdef _F_ZONE_WINDOW_ROTATION_
7656 _e_border_cb_zone_rotation_change(void *data __UNUSED__,
7657 int ev_type __UNUSED__,
7660 E_Event_Zone_Rotation_Change *e = ev;
7661 Eina_Bool res = EINA_FALSE;
7663 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
7664 if ((!e) || (!e->zone)) return ECORE_CALLBACK_PASS_ON;
7666 res = _e_border_rotation_zone_check(e->zone);
7667 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: result:%d (%d)", res, e->zone->rot.curr);
7670 e_manager_comp_screen_lock(e_manager_current_get());
7671 res = _e_border_rotation_zone_vkbd_check(e->zone);
7672 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd result:%d (%d)", res, e->zone->rot.curr);
7675 res = _e_border_rotation_transient_for_check(rot.vkbd,
7677 ELBF(ELBT_ROT, 0, e->zone->id, "ZONE ROT CHECK: vkbd transient_for result:%d (%d)", res, e->zone->rot.curr);
7682 if (rot.prepare_timer)
7683 ecore_timer_del(rot.prepare_timer);
7684 rot.prepare_timer = NULL;
7687 ecore_timer_del(rot.done_timer);
7688 rot.done_timer = NULL;
7690 ELB(ELBT_ROT, "SEND ROT_CHANGE_PREPARE", rot.vkbd_ctrl_win);
7691 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
7694 rot.prepare_timer = ecore_timer_add(4.0f,
7695 _e_border_rotation_change_prepare_timeout,
7697 rot.wait_prepare_done = EINA_TRUE;
7701 _e_border_rotation_list_add(e->zone, EINA_TRUE);
7702 _e_border_rotation_change_request(e->zone);
7707 /* there is no border which supports window manager rotation */
7708 e_zone_rotation_update_cancel(e->zone);
7710 return ECORE_CALLBACK_PASS_ON;
7714 _e_border_rotation_change_prepare_timeout(void *data)
7716 E_Zone *zone = data;
7717 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
7719 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE_PREPARE", 0);
7721 if ((rot.wait_prepare_done) &&
7723 (_e_border_rotation_list_add(zone, EINA_FALSE)))
7725 _e_border_rotation_change_request(zone);
7729 if (rot.prepare_timer)
7730 ecore_timer_del(rot.prepare_timer);
7731 rot.prepare_timer = NULL;
7732 rot.wait_prepare_done = EINA_FALSE;
7734 return ECORE_CALLBACK_CANCEL;
7738 _e_border_rotation_change_request(E_Zone *zone __UNUSED__)
7740 Eina_List *l = NULL;
7741 E_Border_Rotation_Info *info = NULL;
7743 if (!e_config->wm_win_rotation) return;
7744 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
7745 rot.prepare_timer = NULL;
7746 rot.wait_prepare_done = EINA_FALSE;
7748 EINA_LIST_FOREACH(rot.list, l, info)
7750 ELBF(ELBT_ROT, 1, info->bd->client.win,
7751 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
7752 info->ang, info->win_resize, info->w, info->h);
7754 ecore_x_e_window_rotation_change_prepare_send
7755 (info->bd->client.win, info->ang,
7756 info->win_resize, info->w, info->h);
7758 if (!info->bd->client.e.state.rot.pending_change_request)
7760 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
7761 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
7767 ecore_timer_del(rot.done_timer);
7768 rot.done_timer = ecore_timer_add(4.0f,
7769 _e_border_rotation_change_done_timeout,
7774 _e_border_rotation_list_remove(E_Border *bd)
7776 Eina_List *l = NULL;
7777 E_Border_Rotation_Info *info = NULL;
7778 if (!e_config->wm_win_rotation) return;
7780 EINA_LIST_FOREACH(rot.list, l, info)
7784 rot.list = eina_list_remove(rot.list, info);
7789 if (bd->client.e.state.rot.wait_for_done)
7791 bd->client.e.state.rot.wait_for_done = 0;
7792 if (eina_list_count(rot.list) == 0)
7794 _e_border_rotation_change_done();
7800 _e_border_rotation_change_done_timeout(void *data __UNUSED__)
7802 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_CANCEL;
7803 ELB(ELBT_ROT, "TIMEOUT ROT_CHANGE", 0);
7804 _e_border_rotation_change_done();
7805 return ECORE_CALLBACK_CANCEL;
7809 _e_border_rotation_change_done(void)
7811 E_Manager *m = NULL;
7812 E_Border_Rotation_Info *info = NULL;
7814 if (!e_config->wm_win_rotation) return;
7816 if (rot.prepare_timer)
7817 ecore_timer_del(rot.prepare_timer);
7818 rot.prepare_timer = NULL;
7820 rot.wait_prepare_done = EINA_FALSE;
7823 ecore_timer_del(rot.done_timer);
7824 rot.done_timer = NULL;
7826 EINA_LIST_FREE(rot.list, info)
7830 info->bd->client.e.state.rot.wait_for_done = 0;
7831 ELB(ELBT_ROT, "TIMEOUT ROT_DONE", info->bd->client.win);
7838 m = e_manager_current_get();
7839 e_manager_comp_screen_unlock(m);
7840 e_zone_rotation_update_done(e_util_zone_current_get(m));
7844 _prev_angle_get(Ecore_X_Window win)
7846 int ret, count = 0, ang = -1;
7847 unsigned char* data = NULL;
7849 ret = ecore_x_window_prop_property_get
7850 (win, ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
7851 ECORE_X_ATOM_CARDINAL, 32, &data, &count);
7853 if ((ret) && (data) && (count))
7854 ang = ((int *)data)[0];
7855 if (data) free(data);
7859 /* get proper rotation value using preferred rotation and list of available rotations */
7861 _e_border_rotation_get(E_Border *bd,
7866 Eina_Bool found = EINA_FALSE;
7868 if (!e_config->wm_win_rotation) return ang;
7869 if (!bd->client.e.state.rot.app_set) return ang;
7871 if (bd->client.e.state.rot.preferred_rot != -1)
7873 ang = bd->client.e.state.rot.preferred_rot;
7874 ELBF(ELBT_ROT, 0, bd->client.win, "ang:%d base_ang:%d", ang, base_ang);
7876 else if ((bd->client.e.state.rot.available_rots) &&
7877 (bd->client.e.state.rot.count))
7879 for (i = 0; i < bd->client.e.state.rot.count; i++)
7881 if (bd->client.e.state.rot.available_rots[i] == base_ang)
7889 /* do nothing. this window wants to maintain current state.
7890 * for example, window's available_rots: 0, 90, 270,
7891 * current zone rotation request: 180. the WM does nothing
7896 if (bd->client.e.state.rot.curr != -1)
7897 ang = bd->client.e.state.rot.curr;
7899 ang = bd->client.e.state.rot.available_rots[0];
7904 /* In this case, border doesn't have a list of
7905 * available rotations, thus WM should request
7906 * rotation with '0' degree to the application.
7914 #define REGION_EQUAL_TO_ZONE(a, z) \
7915 ((((a)->x) == ((z)->x)) && \
7916 (((a)->y) == ((z)->y)) && \
7917 (((a)->w) == ((z)->w)) && \
7918 (((a)->h) == ((z)->h)))
7921 _e_border_rotation_check(E_Border *bd)
7923 E_Zone *zone = bd->zone;
7924 int x, y, w, h, ang = 0;
7925 int diff = 0, _ang = 0;
7926 Eina_Bool resize = EINA_TRUE;
7927 Eina_Bool hint = EINA_FALSE;
7928 Eina_Bool move = EINA_TRUE;
7930 if (!e_config->wm_win_rotation) return EINA_FALSE;
7932 ELB(ELBT_ROT, "CHECK ROT", bd->client.win);
7934 ang = zone->rot.curr;
7936 if (((rot.vkbd) && (rot.vkbd == bd)) ||
7937 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
7939 ELBF(ELBT_ROT, 1, bd->client.win,
7940 "%s->parent:0x%08x (support:%d app_set:%d ang:%d)",
7941 (rot.vkbd == bd) ? "vkbd" : "prediction",
7942 bd->parent ? bd->parent->client.win : 0,
7943 bd->parent ? bd->parent->client.e.state.rot.support : -1,
7944 bd->parent ? bd->parent->client.e.state.rot.app_set : -1,
7945 bd->parent ? bd->parent->client.e.state.rot.curr : -1);
7949 ang = bd->parent->client.e.state.rot.curr;
7950 if ((!bd->parent->client.e.state.rot.support) &&
7951 (!bd->parent->client.e.state.rot.app_set))
7958 if ((!bd->client.e.state.rot.app_set) &&
7959 (!bd->client.e.state.rot.support))
7961 /* hack for magnifier and keyboard popup */
7962 if ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER) ||
7963 (bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP))
7965 ELB(ELBT_BD, "MAG", bd->client.win);
7967 if ((rot.vkbd) && (rot.vkbd->visible))
7968 ang = rot.vkbd->client.e.state.rot.curr;
7969 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
7972 ELBF(ELBT_ROT, 1, bd->client.win, "MAG %d,%d %dx%d m:%d", x, y, w, h, move);
7973 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
7979 if (bd->client.e.state.rot.app_set)
7981 /* utility type window should be rotated according to
7982 * rotation of the transient_for window.
7985 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UTILITY))
7987 ang = bd->parent->client.e.state.rot.curr;
7988 if ((!bd->parent->client.e.state.rot.support) &&
7989 (!bd->parent->client.e.state.rot.app_set))
7991 /* if transient_for window doesn't support rotation feature,
7992 * then this window should't be rotated.
7993 * TODO: need to check whether window supports '0' degree or not.
7996 ELBF(ELBT_ROT, 0, bd->client.win,
7997 "GET ROT ang:%d Transient_For:0x%08x Not support rot",
7998 ang, bd->parent->client.win);
8002 ang = _e_border_rotation_get(bd->parent, ang);
8003 ELBF(ELBT_ROT, 0, bd->client.win,
8004 "GET ROT ang:%d Transient_For:0x%08x",
8005 ang, bd->parent->client.win);
8010 ang = _e_border_rotation_get(bd, ang);
8011 ELBF(ELBT_ROT, 0, bd->client.win, "GET ROT ang:%d bd->parent:0x%08x type:%d",
8012 ang, bd->parent ? bd->parent->client.win : 0,
8013 bd->client.netwm.type);
8017 hint = _e_border_rotation_geom_get(bd, zone, ang, &x, &y, &w, &h, &move);
8019 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8021 /* need to check previous rotation angle, this may be because
8022 * the window was unmapped with non-0 rotation degree.
8023 * and now, the window wants to show on the 0 degree zone,
8024 * thus the wm should request to rotate the window to 0 degree.
8028 _ang = _prev_angle_get(bd->client.win);
8030 bd->client.e.state.rot.curr = _ang;
8031 ELBF(ELBT_ROT, 1, bd->client.win, "prev_ang:%d", _ang);
8034 if (bd->client.e.state.rot.curr != ang)
8036 Eina_Bool is_screen_locked = EINA_FALSE;
8038 if ((rot.vkbd != bd) && (rot.vkbd_prediction != bd) &&
8039 /* check whether virtual keyboard is visible on the zone */
8040 (_e_border_rotation_zone_vkbd_check(bd->zone)) &&
8041 /* check whether virtual keyboard belongs to this border (transient_for) */
8042 (_e_border_rotation_vkbd_transient_for_check(bd)) &&
8043 /* check rotation of the virtual keyboard */
8044 (((rot.vkbd) && (rot.vkbd->client.e.state.rot.curr != ang)) ||
8045 ((rot.vkbd_prediction) && (rot.vkbd_prediction->client.e.state.rot.curr != ang))) &&
8046 (!rot.wait_prepare_done))
8048 ELB(ELBT_ROT, "DO VKBD ROT", bd->client.win);
8049 e_manager_comp_screen_lock(e_manager_current_get());
8050 is_screen_locked = EINA_TRUE;
8052 if (rot.prepare_timer) ecore_timer_del(rot.prepare_timer);
8053 rot.prepare_timer = NULL;
8055 if (rot.done_timer) ecore_timer_del(rot.done_timer);
8056 rot.done_timer = NULL;
8058 ELB(ELBT_ROT, "send rot_change_prepare", rot.vkbd_ctrl_win);
8059 ecore_x_e_window_rotation_change_prepare_send(rot.vkbd_ctrl_win,
8062 rot.prepare_timer = ecore_timer_add(4.0f,
8063 _e_border_rotation_change_prepare_timeout,
8065 rot.wait_prepare_done = EINA_TRUE;
8068 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8069 bd->client.e.state.rot.curr = ang;
8070 bd->client.e.state.rot.wait_for_done = 1;
8072 diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
8073 if ((diff == 180) || (diff == -180))
8074 resize = EINA_FALSE;
8076 /* Check if it has size hint, full size or not, and needs to resize.
8077 * Under the below condition, replace width value with height.
8079 if ((!hint) && (!REGION_EQUAL_TO_ZONE(bd, bd->zone)) && (resize))
8081 x = bd->x; y = bd->y;
8082 w = bd->w; h = bd->h;
8085 resize = EINA_FALSE;
8091 _e_border_move_resize_internal(bd, x, y, w, h,
8092 EINA_TRUE, EINA_FALSE);
8097 if (bd->client.e.state.rot.app_set) resize = EINA_FALSE;
8099 E_Border_Rotation_Info *info = NULL;
8100 info = E_NEW(E_Border_Rotation_Info, 1);
8103 if (!is_screen_locked)
8104 e_manager_comp_screen_lock(e_manager_current_get());
8108 info->x = x; info->y = y;
8109 info->w = w; info->h = h;
8110 info->win_resize = resize;
8111 rot.list = eina_list_append(rot.list, info);
8113 if (info->win_resize)
8114 bd->client.e.state.rot.pending_change_request = 1;
8116 ELBF(ELBT_ROT, 1, info->bd->client.win,
8117 "SEND ROT_CHANGE_PREPARE a%d res%d %dx%d",
8118 info->ang, info->win_resize, info->w, info->h);
8120 ecore_x_e_window_rotation_change_prepare_send
8121 (info->bd->client.win, info->ang,
8122 info->win_resize, info->w, info->h);
8124 if (!info->bd->client.e.state.rot.pending_change_request)
8126 ELBF(ELBT_ROT, 1, 0, "SEND ROT_CHANGE_REQUEST");
8127 ecore_x_e_window_rotation_change_request_send(info->bd->client.win,
8132 ecore_timer_del(rot.done_timer);
8133 rot.done_timer = ecore_timer_add(4.0f,
8134 _e_border_rotation_change_done_timeout,
8142 _e_border_rotation_zone_check(E_Zone *zone)
8144 Eina_Bool wait = EINA_FALSE;
8145 E_Border_List *l = NULL;
8146 E_Border *bd = NULL;
8148 if (!e_config->wm_win_rotation) return EINA_FALSE;
8150 l = e_container_border_list_last(zone->container);
8151 if (!l) return EINA_FALSE;
8152 while ((bd = e_container_border_list_prev(l)))
8154 if ((!bd) || (e_object_is_del(E_OBJECT(bd))) ||
8155 (!bd->visible) || (bd->zone != zone) ||
8156 (!E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8157 bd->x, bd->y, bd->w, bd->h))) continue;
8159 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8160 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)) ||
8161 ((REGION_EQUAL_TO_ZONE(bd, zone)) &&
8162 (bd->client.e.state.rot.preferred_rot != -1))) continue;
8164 if (_e_border_rotation_border_check(bd, zone->rot.curr))
8170 if (l) e_container_border_list_free(l);
8175 // check if border is rotatable in ang.
8177 _e_border_rotation_border_check(E_Border *bd, int ang)
8179 Eina_Bool wait = EINA_FALSE;
8181 if (!bd) return wait;
8183 if (((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8184 /* basically WM allows only fullscreen window to rotate */
8185 ((REGION_EQUAL_TO_ZONE(bd, bd->zone)) ||
8186 /* we don't like this kind of code.
8187 * it means that the WM also allows non-fullscreen window to rotate if it sets geom hint.
8188 * such as large editable window.
8190 ((bd->client.vkbd.win_type == E_VIRTUAL_KEYBOARD_WINDOW_TYPE_NONE) && (bd->client.e.state.rot.geom_hint)) ||
8191 /* and floating mode window is also rotatable */
8192 (bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) &&
8193 (bd->client.e.state.rot.preferred_rot == -1))
8197 if (bd->client.e.state.rot.app_set)
8199 if (bd->client.e.state.rot.available_rots &&
8200 bd->client.e.state.rot.count)
8202 Eina_Bool found = EINA_FALSE;
8203 for (i = 0; i < bd->client.e.state.rot.count; i++)
8205 if (bd->client.e.state.rot.available_rots[i] == ang)
8210 if ((found) && (ang != bd->client.e.state.rot.curr))
8216 ELB(ELBT_ROT, "ROT CANCEL for preferred rot", bd->client.win);
8223 ELB(ELBT_ROT, "DO ROT", 0);
8231 /* check whether virtual keyboard is visible on the zone */
8233 _e_border_rotation_zone_vkbd_check(E_Zone *zone)
8235 if (!e_config->wm_win_rotation) return EINA_FALSE;
8237 if ((rot.vkbd_ctrl_win) &&
8239 (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8240 (rot.vkbd->visible) &&
8241 (rot.vkbd->zone == zone) &&
8242 (E_INTERSECTS(zone->x, zone->y,
8244 rot.vkbd->x, rot.vkbd->y,
8245 rot.vkbd->w, rot.vkbd->h)))
8252 /* check whether border is parent of the virtual keyboard */
8254 _e_border_rotation_vkbd_transient_for_check(E_Border *bd)
8256 if (!e_config->wm_win_rotation) return EINA_FALSE;
8258 if (rot.vkbd_ctrl_win)
8260 if ((rot.vkbd) && (!e_object_is_del(E_OBJECT(rot.vkbd))) &&
8263 if (rot.vkbd->parent == bd)
8267 if ((rot.vkbd_prediction) && (!e_object_is_del(E_OBJECT(rot.vkbd_prediction))) &&
8268 (rot.vkbd_prediction != bd))
8270 if (rot.vkbd_prediction == bd)
8278 // check if bd's parent is rotatable.
8280 _e_border_rotation_transient_for_check(E_Border *bd, int ang)
8282 Eina_Bool ret = EINA_FALSE;
8284 if (!e_config->wm_win_rotation) return EINA_FALSE;
8285 if (!bd) return EINA_FALSE;
8287 if (!bd->parent) ret = EINA_TRUE;
8290 if (_e_border_rotation_border_check(bd->parent, ang))
8298 _e_border_rotation_list_add(E_Zone *zone, Eina_Bool without_vkbd)
8300 Eina_Bool wait = EINA_FALSE;
8301 E_Border_List *l = NULL;
8302 Eina_List *nl = NULL;
8303 E_Border *bd = NULL;
8304 E_Border_Rotation_Info *info = NULL;
8306 if (!e_config->wm_win_rotation) return EINA_FALSE;
8308 l = e_container_border_list_last(zone->container);
8309 if (!l) return EINA_FALSE;
8310 while ((bd = e_container_border_list_prev(l)))
8312 if ((!bd) || (e_object_is_del(E_OBJECT(bd)))) continue;
8314 if ((without_vkbd) &&
8315 (((rot.vkbd) && (rot.vkbd == bd)) ||
8316 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))) continue;
8318 if ((bd->visible) &&
8319 ((bd->client.e.state.rot.support) || (bd->client.e.state.rot.app_set)) &&
8320 (bd->zone == zone) &&
8321 (E_INTERSECTS(zone->x, zone->y, zone->w, zone->h,
8322 bd->x, bd->y, bd->w, bd->h)))
8324 // check if this window is available to be rotate.
8325 if ((bd->client.e.state.rot.app_set) &&
8326 (bd->client.e.state.rot.preferred_rot != -1)) continue;
8328 /* check list of available rotations */
8329 int ang = zone->rot.curr;
8330 if (bd->client.e.state.rot.app_set)
8332 ang = _e_border_rotation_get(bd, ang);
8333 ELBF(ELBT_ROT, 0, bd->client.win, "returned ang:%d", ang);
8336 /* skip same angle */
8337 if (bd->client.e.state.rot.curr == ang)
8339 ELBF(ELBT_ROT, 0, bd->client.win, "SKIP ang:%d", ang);
8344 ELBF(ELBT_ROT, 0, bd->client.win, "ADD ROT_LIST curr:%d != ang:%d",
8345 bd->client.e.state.rot.curr, ang);
8348 bd->client.e.state.rot.prev = bd->client.e.state.rot.curr;
8349 bd->client.e.state.rot.curr = ang;
8350 bd->client.e.state.rot.wait_for_done = 1;
8352 info = E_NEW(E_Border_Rotation_Info, 1);
8357 info->x = bd->x; info->y = bd->y;
8358 info->w = bd->w; info->h = bd->h;
8359 info->win_resize = EINA_FALSE;
8360 nl = eina_list_append(nl, info);
8363 if (REGION_EQUAL_TO_ZONE(bd, zone))
8365 wait = EINA_TRUE; // for the maximized window
8369 int diff = bd->client.e.state.rot.curr - bd->client.e.state.rot.prev;
8371 Eina_Bool resize = EINA_TRUE;
8372 if ((diff == 180) || (diff == -180))
8373 resize = EINA_FALSE;
8375 Eina_Bool move = EINA_TRUE;
8376 Eina_Bool hint = EINA_FALSE;
8377 hint = _e_border_rotation_geom_get(bd, zone, zone->rot.curr, &x, &y, &w, &h, &move);
8379 _e_border_move_resize_internal(bd, x, y, w, h, EINA_TRUE, move);
8382 x = bd->x; y = bd->y;
8383 w = bd->w; h = bd->h;
8387 resize = EINA_FALSE;
8390 // swap width and height and resize border
8394 _e_border_move_resize_internal(bd, x, y, w, h,
8395 EINA_TRUE, EINA_TRUE);
8402 info->x = x; info->y = y;
8403 info->w = w; info->h = h;
8404 info->win_resize = resize;
8408 bd->client.e.state.rot.pending_change_request = 1;
8415 if (l) e_container_border_list_free(l);
8419 // clear previous list
8420 EINA_LIST_FREE(rot.list, info)
8431 _e_border_cb_window_configure(void *data __UNUSED__,
8432 int ev_type __UNUSED__,
8435 Ecore_X_Event_Window_Configure *e = ev;
8436 if (!e) return ECORE_CALLBACK_PASS_ON;
8437 if (!e_config->wm_win_rotation) return ECORE_CALLBACK_PASS_ON;
8439 E_Border *bd = e_border_find_by_client_window(e->win);
8440 if (!bd) return ECORE_CALLBACK_PASS_ON;
8442 if (bd->client.e.state.rot.pending_change_request)
8444 if ((e->w == bd->w) && (e->h == bd->h))
8446 ELBF(ELBT_ROT, 0, bd->client.win,
8447 "SEND ROT_CHANGE_REQUEST a%d %dx%d",
8448 bd->client.e.state.rot.curr,
8451 bd->client.e.state.rot.pending_change_request = 0;
8453 ecore_x_e_window_rotation_change_request_send(bd->client.win,
8454 bd->client.e.state.rot.curr);
8457 return ECORE_CALLBACK_PASS_ON;
8461 _e_border_rotation_geom_get(E_Border *bd,
8470 if (!e_config->wm_win_rotation) return EINA_FALSE;
8472 Eina_Bool res = EINA_FALSE;
8473 Eina_Bool _move = EINA_TRUE;
8483 if (move) *move = EINA_TRUE;
8485 if (bd->client.e.state.rot.geom_hint)
8490 _w = bd->client.e.state.rot.geom[0].w;
8491 _h = bd->client.e.state.rot.geom[0].h;
8492 if (_w == 0) _w = bd->w;
8493 if (_h == 0) _h = bd->h;
8494 _x = 0; _y = zone->h - _h;
8497 _w = bd->client.e.state.rot.geom[1].w;
8498 _h = bd->client.e.state.rot.geom[1].h;
8499 if (_w == 0) _w = bd->w;
8500 if (_h == 0) _h = bd->h;
8501 _x = zone->w - _w; _y = 0;
8504 _w = bd->client.e.state.rot.geom[2].w;
8505 _h = bd->client.e.state.rot.geom[2].h;
8506 if (_w == 0) _w = bd->w;
8507 if (_h == 0) _h = bd->h;
8511 _w = bd->client.e.state.rot.geom[3].w;
8512 _h = bd->client.e.state.rot.geom[3].h;
8513 if (_w == 0) _w = bd->w;
8514 if (_h == 0) _h = bd->h;
8524 if (!((rot.vkbd) && (rot.vkbd == bd)))
8528 if (move) *move = EINA_FALSE;
8536 _x = 0; _y = 0; _w = 0; _h = 0;
8541 if (move) _move = *move;
8543 ELBF(ELBT_ROT, 1, bd->client.win,
8544 "GET SIZE_HINT[%d] %d,%d %dx%d move:%d",
8545 ang, _x, _y, _w, _h, _move);
8553 _e_border_post_move_resize_job(void *data)
8557 bd = (E_Border *)data;
8563 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
8564 ecore_x_window_move(tmp->win,
8566 bd->client_inset.l +
8568 tmp->client.e.state.video_position.x,
8570 bd->client_inset.t +
8572 tmp->client.e.state.video_position.y);
8574 if (bd->client.e.state.video)
8578 parent = bd->client.e.state.video_parent_border;
8579 ecore_x_window_move(bd->win,
8581 parent->client_inset.l +
8583 bd->client.e.state.video_position.x,
8585 parent->client_inset.t +
8587 bd->client.e.state.video_position.y);
8589 else if ((bd->post_move) && (bd->post_resize))
8591 ecore_x_window_move_resize(bd->win,
8596 else if (bd->post_move)
8598 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
8600 else if (bd->post_resize)
8602 ecore_x_window_resize(bd->win, bd->w, bd->h);
8605 if (bd->client.e.state.video)
8607 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
8609 bd->client.e.state.video_parent_border->x +
8610 bd->client.e.state.video_parent_border->client_inset.l +
8611 bd->client.e.state.video_parent_border->fx.x +
8612 bd->client.e.state.video_position.x,
8613 bd->client.e.state.video_parent_border->y +
8614 bd->client.e.state.video_parent_border->client_inset.t +
8615 bd->client.e.state.video_parent_border->fx.y +
8616 bd->client.e.state.video_position.y,
8624 bd->post_job = NULL;
8630 bd->post_resize = 0;
8631 bd->post_job = NULL;
8632 return ECORE_CALLBACK_CANCEL;
8636 _e_border_container_layout_hook(E_Container *con)
8638 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
8642 _e_border_eval0(E_Border *bd)
8644 int change_urgent = 0;
8646 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8647 Eina_Bool need_desk_set = EINA_FALSE;
8649 #ifdef _F_ZONE_WINDOW_ROTATION_
8650 Eina_Bool need_rotation_set = EINA_FALSE;
8652 if ((e_config->wm_win_rotation) &&
8653 (bd->client.icccm.fetch.transient_for))
8655 if (((rot.vkbd) && (rot.vkbd == bd)) ||
8656 ((rot.vkbd_prediction) && (rot.vkbd_prediction == bd)))
8658 need_rotation_set = EINA_TRUE;
8659 ELB(ELBT_BD, "UPDATE TRANSIENT_FOR", bd->client.win);
8664 if (e_object_is_del(E_OBJECT(bd)))
8666 CRI("_e_border_eval(%p) with deleted border!\n", bd);
8671 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
8673 bd->changes.border = 0;
8675 /* fetch any info queued to be fetched */
8676 if (bd->client.netwm.fetch.state)
8678 e_hints_window_state_get(bd);
8679 bd->client.netwm.fetch.state = 0;
8682 if (bd->client.icccm.fetch.client_leader)
8684 /* TODO: What do to if the client leader isn't mapped yet? */
8685 E_Border *bd_leader = NULL;
8687 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
8688 if (bd->client.icccm.client_leader)
8689 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
8692 if (bd->leader != bd_leader)
8694 bd->leader->group = eina_list_remove(bd->leader->group, bd);
8695 if (bd->leader->modal == bd) bd->leader->modal = NULL;
8701 /* If this border is the leader of the group, don't register itself */
8702 if ((bd_leader) && (bd_leader != bd))
8704 bd_leader->group = eina_list_append(bd_leader->group, bd);
8705 bd->leader = bd_leader;
8706 /* Only set the window modal to the leader it there is no parent */
8707 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
8708 ((!bd->parent) || (bd->parent->modal != bd)))
8710 bd->leader->modal = bd;
8711 if (bd->leader->focused)
8712 e_border_focus_set(bd, 1, 1);
8718 EINA_LIST_FOREACH(bd->leader->group, l, child)
8720 if ((child != bd) && (child->focused))
8721 e_border_focus_set(bd, 1, 1);
8726 bd->client.icccm.fetch.client_leader = 0;
8729 if (bd->client.icccm.fetch.title)
8731 char *title = ecore_x_icccm_title_get(bd->client.win);
8732 eina_stringshare_replace(&bd->client.icccm.title, title);
8733 if (title) free(title);
8736 edje_object_part_text_set(bd->bg_object, "e.text.title",
8737 bd->client.icccm.title);
8738 bd->client.icccm.fetch.title = 0;
8741 if (bd->client.netwm.fetch.name)
8744 ecore_x_netwm_name_get(bd->client.win, &name);
8745 eina_stringshare_replace(&bd->client.netwm.name, name);
8746 if (name) free(name);
8749 edje_object_part_text_set(bd->bg_object, "e.text.title",
8750 bd->client.netwm.name);
8751 bd->client.netwm.fetch.name = 0;
8754 if (bd->client.icccm.fetch.name_class)
8756 const char *pname, *pclass;
8757 char *nname, *nclass;
8759 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
8760 pname = bd->client.icccm.name;
8761 pclass = bd->client.icccm.class;
8762 bd->client.icccm.name = eina_stringshare_add(nname);
8763 bd->client.icccm.class = eina_stringshare_add(nclass);
8764 if (bd->client.icccm.class && (!strcmp(bd->client.icccm.class, "Vmplayer")))
8765 e_bindings_mapping_change_enable(EINA_FALSE);
8766 #ifdef _F_ZONE_WINDOW_ROTATION_
8767 if (e_config->wm_win_rotation)
8769 if ((bd->client.icccm.name) && (bd->client.icccm.class))
8771 if ((!strcmp(bd->client.icccm.name, "Virtual Keyboard")) &&
8772 (!strcmp(bd->client.icccm.class, "ISF")))
8774 ELB(ELBT_BD, "SET VKBD", bd->client.win);
8775 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_KEYPAD;
8778 else if ((!strcmp(bd->client.icccm.name, "Prediction Window")) &&
8779 (!strcmp(bd->client.icccm.class, "ISF")))
8781 ELB(ELBT_BD, "SET PREDICTION", bd->client.win);
8782 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_PREDICTION;
8783 rot.vkbd_prediction = bd;
8785 else if ((!strcmp(bd->client.icccm.name, "Key Magnifier")) &&
8786 (!strcmp(bd->client.icccm.class, "ISF")))
8788 ELB(ELBT_BD, "SET MAGNIFIER", bd->client.win);
8789 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_MAGNIFIER;
8791 else if ((!strcmp(bd->client.icccm.name, "ISF Popup")) &&
8792 (!strcmp(bd->client.icccm.class, "ISF")))
8794 ELB(ELBT_BD, "SET VKBD_POPUP", bd->client.win);
8795 bd->client.vkbd.win_type = E_VIRTUAL_KEYBOARD_WINDOW_TYPE_POPUP;
8800 if (nname) free(nname);
8801 if (nclass) free(nclass);
8803 if (!((bd->client.icccm.name == pname) &&
8804 (bd->client.icccm.class == pclass)))
8805 bd->changes.icon = 1;
8807 if (pname) eina_stringshare_del(pname);
8808 if (pclass) eina_stringshare_del(pclass);
8809 bd->client.icccm.fetch.name_class = 0;
8810 bd->changes.icon = 1;
8813 if (bd->client.icccm.fetch.state)
8815 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
8816 bd->client.icccm.fetch.state = 0;
8819 if (bd->client.e.fetch.state)
8821 e_hints_window_e_state_get(bd);
8822 bd->client.e.fetch.state = 0;
8825 #ifdef _F_USE_DESK_WINDOW_PROFILE_
8826 if (bd->client.e.fetch.profile_list)
8828 const char **profiles = NULL;
8832 if (bd->client.e.state.profile)
8833 eina_stringshare_del(bd->client.e.state.profile);
8834 EINA_LIST_FREE(bd->client.e.state.profiles, str)
8836 if (str) eina_stringshare_del(str);
8838 bd->client.e.state.profile = NULL;
8839 bd->client.e.state.profiles = NULL;
8840 bd->client.e.state.profile_list = 0;
8842 if (ecore_x_e_window_profile_list_get(bd->client.win,
8845 bd->client.e.state.profile_list = 1;
8846 for (i = 0; i < num; i++)
8848 str = eina_stringshare_add(profiles[i]);
8849 bd->client.e.state.profiles = eina_list_append(bd->client.e.state.profiles, str);
8852 /* We should set desk to contain given border after creating E_BORDER_ADD event.
8853 * If not, e will have an E_BORDER_SHOW event before E_BORDER_ADD event.
8855 need_desk_set = EINA_TRUE;
8859 if (strcmp(bd->desk->window_profile,
8860 e_config->desktop_default_window_profile) != 0)
8862 ecore_x_e_window_profile_set(bd->client.win,
8863 bd->desk->window_profile);
8870 bd->client.e.fetch.profile_list = 0;
8873 #ifdef _F_ZONE_WINDOW_ROTATION_
8874 if ((e_config->wm_win_rotation) &&
8875 (bd->client.e.fetch.rot.support))
8878 unsigned int support = 0;
8880 ret = ecore_x_window_prop_card32_get
8882 ECORE_X_ATOM_E_WINDOW_ROTATION_SUPPORTED,
8885 bd->client.e.state.rot.support = 0;
8886 if ((ret == 1) && (support == 1))
8887 bd->client.e.state.rot.support = 1;
8889 if (bd->client.e.state.rot.support)
8890 need_rotation_set = EINA_TRUE;
8892 bd->client.e.fetch.rot.support = 0;
8894 if ((e_config->wm_win_rotation) &&
8895 (bd->client.e.fetch.rot.geom_hint))
8897 Eina_Rectangle r[4];
8899 bd->client.e.state.rot.geom_hint = 0;
8900 for (i = 0; i < 4; i++)
8902 r[i].x = bd->client.e.state.rot.geom[i].x;
8903 r[i].y = bd->client.e.state.rot.geom[i].y;
8904 r[i].w = bd->client.e.state.rot.geom[i].w;
8905 r[i].h = bd->client.e.state.rot.geom[i].h;
8907 bd->client.e.state.rot.geom[i].x = 0;
8908 bd->client.e.state.rot.geom[i].y = 0;
8909 bd->client.e.state.rot.geom[i].w = 0;
8910 bd->client.e.state.rot.geom[i].h = 0;
8913 for (i = 0; i < 4; i++)
8915 x = 0; y = 0; w = 0; h = 0;
8916 if (ecore_x_e_window_rotation_geometry_get(bd->client.win, i*90, &x, &y, &w, &h))
8918 bd->client.e.state.rot.geom_hint = 1;
8919 bd->client.e.state.rot.geom[i].x = x;
8920 bd->client.e.state.rot.geom[i].y = y;
8921 bd->client.e.state.rot.geom[i].w = w;
8922 bd->client.e.state.rot.geom[i].h = h;
8924 if (!((r[i].x == x) && (r[i].y == y) &&
8925 (r[i].w == w) && (r[i].h == h)))
8927 need_rotation_set = EINA_TRUE;
8931 bd->client.e.fetch.rot.geom_hint = 0;
8933 if ((e_config->wm_win_rotation) &&
8934 (bd->client.e.fetch.rot.app_set))
8936 ELB(ELBT_ROT, "Fetch ROT_APP_SET", bd->client.win);
8937 unsigned char _prev_app_set = bd->client.e.state.rot.app_set;
8938 bd->client.e.state.rot.app_set = ecore_x_e_window_rotation_app_get(bd->client.win);
8940 if (_prev_app_set != bd->client.e.state.rot.app_set)
8941 need_rotation_set = EINA_TRUE;
8943 bd->client.e.fetch.rot.app_set = 0;
8945 if ((e_config->wm_win_rotation) &&
8946 (bd->client.e.fetch.rot.preferred_rot))
8948 int r = 0, _prev_preferred_rot;
8949 _prev_preferred_rot = bd->client.e.state.rot.preferred_rot;
8950 bd->client.e.state.rot.preferred_rot = -1;
8951 if (ecore_x_e_window_rotation_preferred_rotation_get(bd->client.win, &r))
8953 bd->client.e.state.rot.preferred_rot = r;
8954 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch PREFERRED_ROT:%d", r);
8958 ELB(ELBT_ROT, "Fetch PREFERRED_ROT Del..", bd->client.win);
8961 if (_prev_preferred_rot != bd->client.e.state.rot.preferred_rot)
8962 need_rotation_set = EINA_TRUE;
8964 bd->client.e.fetch.rot.preferred_rot = 0;
8966 if ((e_config->wm_win_rotation) &&
8967 (bd->client.e.fetch.rot.available_rots))
8969 Eina_Bool res, diff = EINA_FALSE;
8971 unsigned int count = 0, i = 0;
8972 int _prev_rots[4] = { -1, };
8974 if (bd->client.e.state.rot.available_rots)
8977 bd->client.e.state.rot.available_rots,
8978 (sizeof(int) * bd->client.e.state.rot.count));
8980 E_FREE(bd->client.e.state.rot.available_rots);
8983 bd->client.e.state.rot.count = 0;
8985 res = ecore_x_e_window_rotation_available_rotations_get(bd->client.win,
8987 if ((res) && (count > 0) && (rots))
8989 bd->client.e.state.rot.available_rots = rots;
8990 bd->client.e.state.rot.count = count;
8992 for (i = 0; i < count; i++)
8994 ELBF(ELBT_ROT, 0, bd->client.win, "Fetch AVAILABLE_ROTS[%d]:%d", i, rots[i]);
8995 if ((!diff) && (_prev_rots[i] != rots[i]))
8997 ELBF(ELBT_ROT, 0, bd->client.win, "count:%d i:%d _prev:%d != rot:%d",
8998 count, i, _prev_rots[i], rots[i]);
9005 ELB(ELBT_ROT, "Fetch AVAILABLE_ROTS Del..", bd->client.win);
9009 if (diff) need_rotation_set = EINA_TRUE;
9010 bd->client.e.fetch.rot.available_rots = 0;
9013 if (bd->client.netwm.fetch.type)
9015 e_hints_window_type_get(bd);
9016 if ((!bd->lock_border) || (!bd->client.border.name))
9017 bd->client.border.changed = 1;
9019 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
9021 if (!bd->client.netwm.state.skip_pager)
9023 bd->client.netwm.state.skip_pager = 1;
9024 bd->client.netwm.update.state = 1;
9026 if (!bd->client.netwm.state.skip_taskbar)
9028 bd->client.netwm.state.skip_taskbar = 1;
9029 bd->client.netwm.update.state = 1;
9032 bd->client.netwm.fetch.type = 0;
9034 if (bd->client.icccm.fetch.machine)
9036 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
9038 if ((!machine) && (bd->client.icccm.client_leader))
9039 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
9041 eina_stringshare_replace(&bd->client.icccm.machine, machine);
9042 if (machine) free(machine);
9044 bd->client.icccm.fetch.machine = 0;
9047 if (bd->client.icccm.fetch.command)
9049 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
9053 for (i = 0; i < bd->client.icccm.command.argc; i++)
9054 free(bd->client.icccm.command.argv[i]);
9055 free(bd->client.icccm.command.argv);
9057 bd->client.icccm.command.argc = 0;
9058 bd->client.icccm.command.argv = NULL;
9059 ecore_x_icccm_command_get(bd->client.win,
9060 &(bd->client.icccm.command.argc),
9061 &(bd->client.icccm.command.argv));
9062 if ((bd->client.icccm.client_leader) &&
9063 (!bd->client.icccm.command.argv))
9064 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
9065 &(bd->client.icccm.command.argc),
9066 &(bd->client.icccm.command.argv));
9067 bd->client.icccm.fetch.command = 0;
9070 if (bd->client.icccm.fetch.hints)
9072 Eina_Bool accepts_focus, is_urgent;
9074 accepts_focus = EINA_TRUE;
9075 is_urgent = EINA_FALSE;
9076 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
9077 if (ecore_x_icccm_hints_get(bd->client.win,
9079 &bd->client.icccm.initial_state,
9080 &bd->client.icccm.icon_pixmap,
9081 &bd->client.icccm.icon_mask,
9082 &bd->client.icccm.icon_window,
9083 &bd->client.icccm.window_group,
9086 bd->client.icccm.accepts_focus = accepts_focus;
9087 if ((bd->client.icccm.urgent != is_urgent) && ((!bd->focused) || (!is_urgent)))
9089 bd->client.icccm.urgent = is_urgent;
9091 /* If this is a new window, set the state as requested. */
9092 if ((bd->new_client) &&
9093 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
9095 e_border_iconify(bd);
9096 e_border_hide(bd, 1);
9099 bd->client.icccm.fetch.hints = 0;
9102 if (bd->client.icccm.fetch.size_pos_hints)
9104 Eina_Bool request_pos;
9106 request_pos = EINA_FALSE;
9107 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
9109 &bd->client.icccm.gravity,
9110 &bd->client.icccm.min_w,
9111 &bd->client.icccm.min_h,
9112 &bd->client.icccm.max_w,
9113 &bd->client.icccm.max_h,
9114 &bd->client.icccm.base_w,
9115 &bd->client.icccm.base_h,
9116 &bd->client.icccm.step_w,
9117 &bd->client.icccm.step_h,
9118 &bd->client.icccm.min_aspect,
9119 &bd->client.icccm.max_aspect))
9121 bd->client.icccm.request_pos = request_pos;
9126 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
9127 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
9128 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
9129 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
9130 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
9131 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
9132 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
9133 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
9134 // if doing a resize, fix it up
9135 if (bd->resize_mode != RESIZE_NONE)
9137 int x, y, w, h, new_w, new_h;
9145 e_border_resize_limit(bd, &new_w, &new_h);
9146 if ((bd->resize_mode == RESIZE_TL) ||
9147 (bd->resize_mode == RESIZE_L) ||
9148 (bd->resize_mode == RESIZE_BL))
9150 if ((bd->resize_mode == RESIZE_TL) ||
9151 (bd->resize_mode == RESIZE_T) ||
9152 (bd->resize_mode == RESIZE_TR))
9154 e_border_move_resize(bd, x, y, new_w, new_h);
9156 bd->client.icccm.fetch.size_pos_hints = 0;
9159 if (bd->client.icccm.fetch.protocol)
9162 Ecore_X_WM_Protocol *proto;
9164 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
9167 for (i = 0; i < num; i++)
9169 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
9170 bd->client.icccm.delete_request = 1;
9171 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
9172 bd->client.icccm.take_focus = 1;
9173 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
9174 bd->client.netwm.ping = 1;
9175 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
9177 bd->client.netwm.sync.request = 1;
9178 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
9179 &bd->client.netwm.sync.counter))
9180 bd->client.netwm.sync.request = 0;
9185 if (bd->client.netwm.ping)
9189 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
9190 bd->ping_poller = NULL;
9192 bd->client.icccm.fetch.protocol = 0;
9194 if (bd->client.icccm.fetch.transient_for)
9196 /* TODO: What do to if the transient for isn't mapped yet? */
9197 E_Border *bd_parent = NULL;
9199 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
9200 if (bd->client.icccm.transient_for)
9201 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
9202 /* If we already have a parent, remove it */
9205 if (bd_parent != bd->parent)
9207 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
9208 if (bd->parent->modal == bd) bd->parent->modal = NULL;
9214 if ((bd_parent) && (bd_parent != bd) &&
9215 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
9217 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
9218 bd->parent = bd_parent;
9222 e_border_layer_set(bd, bd->parent->layer);
9223 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9225 Ecore_X_Window_Attributes attr;
9226 bd->parent->modal = bd;
9227 ecore_x_window_attributes_get(bd->parent->client.win, &attr);
9228 bd->parent->saved.event_mask = attr.event_mask.mine;
9229 bd->parent->lock_close = 1;
9230 ecore_x_event_mask_unset(bd->parent->client.win, attr.event_mask.mine);
9231 ecore_x_event_mask_set(bd->parent->client.win, ECORE_X_EVENT_MASK_WINDOW_DAMAGE | ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
9234 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
9235 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
9238 bd->client.icccm.fetch.transient_for = 0;
9241 if (bd->client.icccm.fetch.window_role)
9243 char *role = ecore_x_icccm_window_role_get(bd->client.win);
9244 eina_stringshare_replace(&bd->client.icccm.window_role, role);
9245 if (role) free(role);
9247 bd->client.icccm.fetch.window_role = 0;
9250 if (bd->client.icccm.fetch.icon_name)
9252 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
9253 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
9254 if (icon_name) free(icon_name);
9256 bd->client.icccm.fetch.icon_name = 0;
9259 if (bd->client.netwm.fetch.icon_name)
9262 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
9263 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
9264 if (icon_name) free(icon_name);
9266 bd->client.netwm.fetch.icon_name = 0;
9269 if (bd->client.netwm.fetch.icon)
9272 if (bd->client.netwm.icons)
9274 for (i = 0; i < bd->client.netwm.num_icons; i++)
9276 free(bd->client.netwm.icons[i].data);
9277 bd->client.netwm.icons[i].data = NULL;
9279 free(bd->client.netwm.icons);
9281 bd->client.netwm.icons = NULL;
9282 bd->client.netwm.num_icons = 0;
9283 if (ecore_x_netwm_icons_get(bd->client.win,
9284 &bd->client.netwm.icons,
9285 &bd->client.netwm.num_icons))
9287 // unless the rest of e17 uses border icons OTHER than icon #0
9288 // then free the rest that we don't need anymore.
9289 for (i = 1; i < bd->client.netwm.num_icons; i++)
9291 free(bd->client.netwm.icons[i].data);
9292 bd->client.netwm.icons[i].data = NULL;
9294 bd->client.netwm.num_icons = 1;
9295 bd->changes.icon = 1;
9297 bd->client.netwm.fetch.icon = 0;
9299 if (bd->client.netwm.fetch.user_time)
9301 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
9302 bd->client.netwm.fetch.user_time = 0;
9304 if (bd->client.netwm.fetch.strut)
9306 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
9307 &bd->client.netwm.strut.left,
9308 &bd->client.netwm.strut.right,
9309 &bd->client.netwm.strut.top,
9310 &bd->client.netwm.strut.bottom,
9311 &bd->client.netwm.strut.left_start_y,
9312 &bd->client.netwm.strut.left_end_y,
9313 &bd->client.netwm.strut.right_start_y,
9314 &bd->client.netwm.strut.right_end_y,
9315 &bd->client.netwm.strut.top_start_x,
9316 &bd->client.netwm.strut.top_end_x,
9317 &bd->client.netwm.strut.bottom_start_x,
9318 &bd->client.netwm.strut.bottom_end_x))
9320 ecore_x_netwm_strut_get(bd->client.win,
9321 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
9322 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
9324 bd->client.netwm.strut.left_start_y = 0;
9325 bd->client.netwm.strut.left_end_y = 0;
9326 bd->client.netwm.strut.right_start_y = 0;
9327 bd->client.netwm.strut.right_end_y = 0;
9328 bd->client.netwm.strut.top_start_x = 0;
9329 bd->client.netwm.strut.top_end_x = 0;
9330 bd->client.netwm.strut.bottom_start_x = 0;
9331 bd->client.netwm.strut.bottom_end_x = 0;
9333 bd->client.netwm.fetch.strut = 0;
9335 if (bd->client.qtopia.fetch.soft_menu)
9337 e_hints_window_qtopia_soft_menu_get(bd);
9338 bd->client.qtopia.fetch.soft_menu = 0;
9341 if (bd->client.qtopia.fetch.soft_menus)
9343 e_hints_window_qtopia_soft_menus_get(bd);
9344 bd->client.qtopia.fetch.soft_menus = 0;
9347 if (bd->client.vkbd.fetch.state)
9349 e_hints_window_virtual_keyboard_state_get(bd);
9350 bd->client.vkbd.fetch.state = 0;
9353 if (bd->client.vkbd.fetch.vkbd)
9355 e_hints_window_virtual_keyboard_get(bd);
9356 bd->client.vkbd.fetch.vkbd = 0;
9359 if (bd->client.illume.conformant.fetch.conformant)
9361 bd->client.illume.conformant.conformant =
9362 ecore_x_e_illume_conformant_get(bd->client.win);
9363 bd->client.illume.conformant.fetch.conformant = 0;
9365 if (bd->client.illume.quickpanel.fetch.state)
9367 bd->client.illume.quickpanel.state =
9368 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
9369 bd->client.illume.quickpanel.fetch.state = 0;
9371 if (bd->client.illume.quickpanel.fetch.quickpanel)
9373 bd->client.illume.quickpanel.quickpanel =
9374 ecore_x_e_illume_quickpanel_get(bd->client.win);
9375 bd->client.illume.quickpanel.fetch.quickpanel = 0;
9377 if (bd->client.illume.quickpanel.fetch.priority.major)
9379 bd->client.illume.quickpanel.priority.major =
9380 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
9381 bd->client.illume.quickpanel.fetch.priority.major = 0;
9383 if (bd->client.illume.quickpanel.fetch.priority.minor)
9385 bd->client.illume.quickpanel.priority.minor =
9386 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
9387 bd->client.illume.quickpanel.fetch.priority.minor = 0;
9389 if (bd->client.illume.quickpanel.fetch.zone)
9391 bd->client.illume.quickpanel.zone =
9392 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
9393 bd->client.illume.quickpanel.fetch.zone = 0;
9395 if (bd->client.illume.drag.fetch.drag)
9397 bd->client.illume.drag.drag =
9398 ecore_x_e_illume_drag_get(bd->client.win);
9399 bd->client.illume.drag.fetch.drag = 0;
9401 if (bd->client.illume.drag.fetch.locked)
9403 bd->client.illume.drag.locked =
9404 ecore_x_e_illume_drag_locked_get(bd->client.win);
9405 bd->client.illume.drag.fetch.locked = 0;
9407 if (bd->client.illume.win_state.fetch.state)
9409 bd->client.illume.win_state.state =
9410 ecore_x_e_illume_window_state_get(bd->client.win);
9411 bd->client.illume.win_state.fetch.state = 0;
9413 if (bd->changes.shape)
9415 Ecore_X_Rectangle *rects;
9418 bd->changes.shape = 0;
9419 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
9424 /* This doesn't fix the race, but makes it smaller. we detect
9425 * this and if cw and ch != client w/h then mark this as needing
9426 * a shape change again to fixup next event loop.
9428 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9429 if ((cw != bd->client.w) || (ch != bd->client.h))
9430 bd->changes.shape = 1;
9432 (rects[0].x == 0) &&
9433 (rects[0].y == 0) &&
9434 ((int)rects[0].width == cw) &&
9435 ((int)rects[0].height == ch))
9437 if (bd->client.shaped)
9439 bd->client.shaped = 0;
9440 if (!bd->bordername)
9441 bd->client.border.changed = 1;
9446 if (!bd->client.shaped)
9448 bd->client.shaped = 1;
9449 if (!bd->bordername)
9450 bd->client.border.changed = 1;
9457 // FIXME: no rects i think can mean... totally empty window
9458 bd->client.shaped = 0;
9459 if (!bd->bordername)
9460 bd->client.border.changed = 1;
9462 bd->need_shape_merge = 1;
9464 if (bd->changes.shape_input)
9466 Ecore_X_Rectangle *rects;
9469 bd->changes.shape_input = 0;
9470 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
9475 /* This doesn't fix the race, but makes it smaller. we detect
9476 * this and if cw and ch != client w/h then mark this as needing
9477 * a shape change again to fixup next event loop.
9479 ecore_x_window_size_get(bd->client.win, &cw, &ch);
9480 if ((cw != bd->client.w) || (ch != bd->client.h))
9481 bd->changes.shape_input = 1;
9483 (rects[0].x == 0) &&
9484 (rects[0].y == 0) &&
9485 ((int)rects[0].width == cw) &&
9486 ((int)rects[0].height == ch))
9488 if (bd->shaped_input)
9490 bd->shaped_input = 0;
9491 if (!bd->bordername)
9492 bd->client.border.changed = 1;
9497 if (!bd->shaped_input)
9499 bd->shaped_input = 1;
9500 if (!bd->bordername)
9501 bd->client.border.changed = 1;
9508 bd->shaped_input = 1;
9509 if (!bd->bordername)
9510 bd->client.border.changed = 1;
9512 bd->need_shape_merge = 1;
9514 if (bd->client.mwm.fetch.hints)
9518 bd->client.mwm.exists =
9519 ecore_x_mwm_hints_get(bd->client.win,
9520 &bd->client.mwm.func,
9521 &bd->client.mwm.decor,
9522 &bd->client.mwm.input);
9523 pb = bd->client.mwm.borderless;
9524 bd->client.mwm.borderless = 0;
9525 if (bd->client.mwm.exists)
9527 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
9528 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
9529 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
9530 bd->client.mwm.borderless = 1;
9532 if (bd->client.mwm.borderless != pb)
9534 if ((!bd->lock_border) || (!bd->client.border.name))
9535 bd->client.border.changed = 1;
9537 bd->client.mwm.fetch.hints = 0;
9540 if (bd->client.e.fetch.video_parent)
9542 /* unlinking child/parent */
9543 if (bd->client.e.state.video_parent_border != NULL)
9545 bd->client.e.state.video_parent_border->client.e.state.video_child =
9547 (bd->client.e.state.video_parent_border->client.e.state.video_child,
9551 ecore_x_window_prop_card32_get(bd->client.win,
9552 ECORE_X_ATOM_E_VIDEO_PARENT,
9553 &bd->client.e.state.video_parent,
9556 /* linking child/parent */
9557 if (bd->client.e.state.video_parent != 0)
9562 EINA_LIST_FOREACH(borders, l, tmp)
9563 if (tmp->client.win == bd->client.e.state.video_parent)
9565 /* fprintf(stderr, "child added to parent \\o/\n"); */
9566 bd->client.e.state.video_parent_border = tmp;
9567 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
9569 if (bd->desk != tmp->desk)
9570 e_border_desk_set(bd, tmp->desk);
9575 /* fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border); */
9577 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
9580 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
9584 ecore_x_window_prop_card32_get(bd->client.win,
9585 ECORE_X_ATOM_E_VIDEO_POSITION,
9588 bd->client.e.state.video_position.x = xy[0];
9589 bd->client.e.state.video_position.y = xy[1];
9590 bd->client.e.state.video_position.updated = 1;
9591 bd->client.e.fetch.video_position = 0;
9592 bd->x = bd->client.e.state.video_position.x;
9593 bd->y = bd->client.e.state.video_position.y;
9595 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
9597 if (bd->client.netwm.update.state)
9599 e_hints_window_state_set(bd);
9600 /* Some stats might change the border, like modal */
9601 if (((!bd->lock_border) || (!bd->client.border.name)) &&
9602 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
9604 bd->client.border.changed = 1;
9608 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9610 bd->parent->modal = bd;
9611 if (bd->parent->focused)
9612 e_border_focus_set(bd, 1, 1);
9615 else if (bd->leader)
9617 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
9619 bd->leader->modal = bd;
9620 if (bd->leader->focused)
9621 e_border_focus_set(bd, 1, 1);
9627 EINA_LIST_FOREACH(bd->leader->group, l, child)
9629 if ((child != bd) && (child->focused))
9630 e_border_focus_set(bd, 1, 1);
9635 bd->client.netwm.update.state = 0;
9640 E_Event_Border_Add *ev;
9641 E_Exec_Instance *inst;
9643 ev = E_NEW(E_Event_Border_Add, 1);
9645 e_object_ref(E_OBJECT(bd));
9646 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
9647 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
9649 if ((!bd->lock_border) || (!bd->client.border.name))
9650 bd->client.border.changed = 1;
9655 if ((ecore_x_netwm_startup_id_get(bd->client.win, &str) && (str)) ||
9656 ((bd->client.icccm.client_leader > 0) &&
9657 ecore_x_netwm_startup_id_get(bd->client.icccm.client_leader, &str) && (str))
9660 if (!strncmp(str, "E_START|", 8))
9665 if (id > 0) bd->client.netwm.startup_id = id;
9670 /* It's ok not to have fetch flag, should only be set on startup
9671 * * and not changed. */
9672 if (!ecore_x_netwm_pid_get(bd->client.win, &bd->client.netwm.pid))
9674 if (bd->client.icccm.client_leader)
9676 if (!ecore_x_netwm_pid_get(bd->client.icccm.client_leader, &bd->client.netwm.pid))
9677 bd->client.netwm.pid = -1;
9680 bd->client.netwm.pid = -1;
9685 inst = e_exec_startup_id_pid_instance_find(bd->client.netwm.startup_id,
9686 bd->client.netwm.pid);
9687 if ((inst) && (inst->used == 0))
9693 zone = e_container_zone_number_get(bd->zone->container,
9695 if (zone) e_border_zone_set(bd, zone);
9696 desk = e_desk_at_xy_get(bd->zone, inst->desk_x,
9698 if (desk) e_border_desk_set(bd, desk);
9699 e_exec_instance_found(inst);
9702 if (e_config->window_grouping) // FIXME: We may want to make the border "urgent" so that the user knows it appeared.
9704 E_Border *bdl = NULL;
9709 if (bd->leader) bdl = bd->leader;
9716 bl = e_container_border_list_first(bd->zone->container);
9717 while ((child = e_container_border_list_next(bl)))
9719 if (child == bd) continue;
9720 if (e_object_is_del(E_OBJECT(child))) continue;
9721 if ((bd->client.icccm.client_leader) &&
9722 (child->client.icccm.client_leader ==
9723 bd->client.icccm.client_leader))
9729 e_container_border_list_free(bl);
9734 e_border_zone_set(bd, bdl->zone);
9736 e_border_desk_set(bd, bdl->desk);
9744 #ifdef _F_USE_DESK_WINDOW_PROFILE_
9747 E_Container *con = bd->zone->container;
9748 E_Desk *desk = NULL;
9751 EINA_LIST_FOREACH(bd->client.e.state.profiles, l, str)
9753 desk = e_container_desk_window_profile_get(con, str);
9756 if (bd->desk != desk)
9758 bd->client.e.state.profile = eina_stringshare_add(str);
9759 if (bd->zone != desk->zone)
9760 e_border_zone_set(bd, desk->zone);
9761 e_border_desk_set(bd, desk);
9768 #ifdef _F_ZONE_WINDOW_ROTATION_
9769 if ((e_config->wm_win_rotation) &&
9770 (need_rotation_set))
9772 ELB(ELBT_ROT, "NEED ROT", bd->client.win);
9773 _e_border_rotation_check(bd);
9777 /* PRE_POST_FETCH calls e_remember apply for new client */
9778 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
9779 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
9780 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
9782 if (bd->need_reparent)
9785 ecore_x_window_save_set_add(bd->client.win);
9786 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
9789 if ((bd->new_client) && (bd->internal) &&
9790 (bd->internal_ecore_evas))
9791 ecore_evas_show(bd->internal_ecore_evas);
9792 ecore_x_window_show(bd->client.win);
9794 bd->need_reparent = 0;
9797 if ((bd->client.border.changed) && (!bd->shaded) &&
9798 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
9800 const char *bordername;
9803 bordername = "borderless";
9804 else if (bd->bordername)
9805 bordername = bd->bordername;
9806 else if ((bd->client.mwm.borderless) || (bd->borderless))
9807 bordername = "borderless";
9808 else if (((bd->client.icccm.transient_for != 0) ||
9809 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
9810 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
9811 (bd->client.icccm.min_h == bd->client.icccm.max_h))
9812 bordername = "noresize_dialog";
9813 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
9814 (bd->client.icccm.min_h == bd->client.icccm.max_h))
9815 bordername = "noresize";
9816 else if (bd->client.shaped)
9817 bordername = "shaped";
9818 else if ((!bd->client.icccm.accepts_focus) &&
9819 (!bd->client.icccm.take_focus))
9820 bordername = "nofocus";
9821 else if (bd->client.icccm.urgent)
9822 bordername = "urgent";
9823 else if ((bd->client.icccm.transient_for != 0) ||
9824 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
9825 bordername = "dialog";
9826 else if (bd->client.netwm.state.modal)
9827 bordername = "modal";
9828 else if ((bd->client.netwm.state.skip_taskbar) ||
9829 (bd->client.netwm.state.skip_pager))
9830 bordername = "skipped";
9831 else if ((bd->internal) && (bd->client.icccm.class) &&
9832 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
9833 bordername = "internal_fileman";
9835 bordername = e_config->theme_default_border_style;
9836 if (!bordername) bordername = "default";
9838 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
9844 bd->changes.border = 1;
9845 eina_stringshare_replace(&bd->client.border.name, bordername);
9849 bd->w -= (bd->client_inset.l + bd->client_inset.r);
9850 bd->h -= (bd->client_inset.t + bd->client_inset.b);
9851 bd->changes.size = 1;
9852 evas_object_del(bd->bg_object);
9854 o = edje_object_add(bd->bg_evas);
9855 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
9856 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
9857 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
9859 if (bd->client.border.name != e_config->theme_default_border_style)
9861 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", e_config->theme_default_border_style);
9862 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
9866 ok = e_theme_edje_object_set(o, "base/theme/borders",
9867 "e/widgets/border/default/border");
9870 /* Reset default border style to default */
9871 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
9872 e_config_save_queue();
9880 const char *shape_option, *argb_option;
9885 if ((e_config->use_composite) && (!bd->client.argb))
9887 argb_option = edje_object_data_get(o, "argb");
9888 if ((argb_option) && (!strcmp(argb_option, "1")))
9891 if (use_argb != bd->argb)
9892 _e_border_frame_replace(bd, use_argb);
9899 shape_option = edje_object_data_get(o, "shaped");
9900 if ((shape_option) && (!strcmp(shape_option, "1")))
9904 if (bd->client.netwm.name)
9905 edje_object_part_text_set(o, "e.text.title",
9906 bd->client.netwm.name);
9907 else if (bd->client.icccm.title)
9908 edje_object_part_text_set(o, "e.text.title",
9909 bd->client.icccm.title);
9914 bd->bg_object = NULL;
9917 _e_border_client_inset_calc(bd);
9919 bd->w += (bd->client_inset.l + bd->client_inset.r);
9920 bd->h += (bd->client_inset.t + bd->client_inset.b);
9921 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
9922 bd->changes.size = 1;
9923 /* really needed ? */
9924 ecore_x_window_move(bd->client.shell_win,
9926 bd->client_inset.t);
9928 if (bd->maximized != E_MAXIMIZE_NONE)
9930 E_Maximize maximized = bd->maximized;
9932 /* to force possible resizes */
9933 bd->maximized = E_MAXIMIZE_NONE;
9935 _e_border_maximize(bd, maximized);
9937 /* restore maximized state */
9938 bd->maximized = maximized;
9940 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
9941 bd->maximized & E_MAXIMIZE_VERTICAL);
9945 edje_object_signal_callback_add(bd->bg_object, "*", "*",
9946 _e_border_cb_signal_bind, bd);
9949 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
9950 if (bd->icon_object)
9951 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
9954 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
9956 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
9958 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
9959 // FIXME: in eval -do differently
9960 // edje_object_message_signal_process(bd->bg_object);
9961 // e_border_frame_recalc(bd);
9963 evas_object_move(bd->bg_object, 0, 0);
9964 evas_object_resize(bd->bg_object, bd->w, bd->h);
9965 evas_object_show(bd->bg_object);
9968 bd->client.border.changed = 0;
9970 if (bd->icon_object)
9974 evas_object_show(bd->icon_object);
9975 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
9978 evas_object_hide(bd->icon_object);
9982 if (rem_change) e_remember_update(bd);
9986 E_Event_Border_Urgent_Change *ev;
9988 if (bd->client.icccm.urgent)
9989 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
9991 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
9993 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
9995 e_object_ref(E_OBJECT(bd));
9996 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
9997 _e_border_event_border_urgent_change_free, NULL);
10000 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
10003 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10005 _e_border_latest_stacked_focus_check_set(E_Border *bd)
10007 E_Border* temp_bd = NULL;
10008 E_Border* top_focusable_bd = NULL;
10009 Eina_Bool is_fully_obscured = EINA_FALSE;
10010 Ecore_X_XRegion *visible_region = NULL;
10011 Ecore_X_XRegion *win_region = NULL;
10012 Ecore_X_Rectangle visible_rect, win_rect;
10015 // set the entire visible region as a root geometry
10016 visible_rect.x = bd->zone->x;
10017 visible_rect.y = bd->zone->y;
10018 visible_rect.width = bd->zone->w;
10019 visible_rect.height = bd->zone->h;
10021 visible_region = ecore_x_xregion_new();
10022 if (!visible_region) return;
10024 ecore_x_xregion_union_rect(visible_region, visible_region, &visible_rect);
10026 bl = e_container_border_list_last(bd->zone->container);
10027 while ((temp_bd = e_container_border_list_prev(bl)))
10029 if (temp_bd == bd) break;
10031 if (temp_bd == focused) continue;
10032 if ((temp_bd->x >= bd->zone->w) || (temp_bd->y >= bd->zone->h)) continue;
10033 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10034 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10035 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10036 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10037 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10038 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10039 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10040 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10042 if (!top_focusable_bd)
10044 top_focusable_bd = temp_bd;
10047 win_rect.x = temp_bd->x;
10048 win_rect.y = temp_bd->y;
10049 win_rect.width = temp_bd->w;
10050 win_rect.height = temp_bd->h;
10052 // if it stick out or is bigger than the entire visible region,
10053 // clip it by the entire visible's geometry.
10054 E_RECTS_CLIP_TO_RECT(win_rect.x, win_rect.y,
10055 win_rect.width, win_rect.height,
10056 visible_rect.x, visible_rect.y,
10057 (int)(visible_rect.width), (int)(visible_rect.height));
10059 if (ecore_x_xregion_rect_contain(visible_region, &win_rect))
10061 win_region = ecore_x_xregion_new();
10064 ecore_x_xregion_union_rect(win_region, win_region, &win_rect);
10065 ecore_x_xregion_subtract(visible_region, visible_region, win_region);
10066 ecore_x_xregion_free(win_region);
10069 if (ecore_x_xregion_is_empty(visible_region))
10071 is_fully_obscured = EINA_TRUE;
10079 if (is_fully_obscured == EINA_TRUE)
10081 e_border_focus_set(top_focusable_bd, 1, 1);
10085 e_border_focus_set(bd, 1, 1);
10088 if (visible_region) ecore_x_xregion_free(visible_region);
10089 e_container_border_list_free(bl);
10093 _e_border_latest_stacked_focus(E_Border *bd)
10096 int root_w, root_h;
10098 root_w = bd->zone->w;
10099 root_h = bd->zone->h;
10102 EINA_LIST_FOREACH(focus_stack, l, temp_bd)
10104 if (bd == temp_bd) continue;
10105 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10106 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10108 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10109 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10110 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10111 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10112 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10113 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10114 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10116 _e_border_latest_stacked_focus_check_set(temp_bd);
10123 _e_border_check_stack (E_Border *bd)
10125 E_Border* temp_bd = NULL;
10126 E_Border* top_bd = NULL;
10127 int passed_focus = 0;
10129 int root_w = bd->zone->w;
10130 int root_h = bd->zone->h;
10133 bl = e_container_border_list_last(bd->zone->container);
10134 while ((temp_bd = e_container_border_list_prev(bl)))
10136 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10137 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10138 if ((temp_bd != bd) &&
10139 (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING)) continue;
10141 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10142 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10143 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10144 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10145 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10146 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10147 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10153 e_border_focus_set_with_pointer(bd);
10160 e_border_focus_set_with_pointer(top_bd);
10169 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
10171 if (!bd->lock_focus_out)
10173 e_border_focus_latest_set(bd);
10185 if (temp_bd == focused)
10191 e_container_border_list_free(bl);
10195 _e_border_focus_top_stack_set(E_Border* bd)
10198 int root_w, root_h;
10200 root_w = bd->zone->w;
10201 root_h = bd->zone->h;
10204 bl = e_container_border_list_last(bd->zone->container);
10205 while ((temp_bd = e_container_border_list_prev(bl)))
10207 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
10208 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
10209 if (temp_bd->client.illume.win_state.state == ECORE_X_ILLUME_WINDOW_STATE_FLOATING) continue;
10211 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
10212 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
10213 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
10214 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
10215 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
10216 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
10217 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
10219 if (!temp_bd->focused)
10221 /* this border is the top of the latest stack */
10222 e_border_focus_set (temp_bd, 1, 1);
10227 e_container_border_list_free(bl);
10232 _e_border_eval(E_Border *bd)
10234 E_Event_Border_Property *event;
10235 E_Border_Pending_Move_Resize *pnd;
10236 int rem_change = 0;
10237 int send_event = 1;
10239 if (e_object_is_del(E_OBJECT(bd)))
10241 CRI("_e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
10246 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
10248 if (bd->new_client)
10250 int zx = 0, zy = 0, zw = 0, zh = 0;
10253 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
10256 * Limit maximum size of windows to useful geometry
10258 // TODO: temoporary limited maximize algorithm
10270 if ((rw != bd->w) || (rh != bd->h))
10274 e_border_resize (bd, bd->w, bd->h);
10280 bd->x -= bd->client_inset.l;
10281 bd->y -= bd->client_inset.t;
10282 bd->changes.pos = 1;
10285 else if ((!bd->placed) && (bd->client.icccm.request_pos))
10288 Ecore_X_Window_Attributes *att;
10291 att = &bd->client.initial_attributes;
10292 bw = att->border * 2;
10293 switch (bd->client.icccm.gravity)
10295 case ECORE_X_GRAVITY_N:
10296 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10300 case ECORE_X_GRAVITY_NE:
10301 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10305 case ECORE_X_GRAVITY_E:
10306 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10307 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10310 case ECORE_X_GRAVITY_SE:
10311 bd->x = (att->x - (bw)) - (bd->client_inset.l);
10312 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10315 case ECORE_X_GRAVITY_S:
10316 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10317 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10320 case ECORE_X_GRAVITY_SW:
10322 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10325 case ECORE_X_GRAVITY_W:
10327 bd->y = (att->y - (bw)) - (bd->client_inset.t);
10330 case ECORE_X_GRAVITY_CENTER:
10331 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
10332 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
10335 case ECORE_X_GRAVITY_NW:
10342 * This ensures that windows that like to open with a x/y
10343 * position smaller than returned by e_zone_useful_geometry_get()
10344 * are moved to useful positions.
10347 if (e_config->geometry_auto_move)
10355 if (bd->x + bd->w > zx + zw)
10356 bd->x = zx + zw - bd->w;
10358 if (bd->y + bd->h > zy + zh)
10359 bd->y = zy + zh - bd->h;
10362 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
10364 bd->changes.pos = 1;
10370 bd->changes.pos = 1;
10376 /* FIXME: special placement for dialogs etc. etc. etc goes
10378 /* FIXME: what if parent is not on this desktop - or zone? */
10379 if ((bd->parent) && (bd->parent->visible))
10381 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
10382 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
10383 bd->changes.pos = 1;
10387 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
10389 /* TODO: Place in center of group */
10392 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10394 bd->x = zx + ((zw - bd->w) / 2);
10395 bd->y = zy + ((zh - bd->h) / 2);
10396 bd->changes.pos = 1;
10402 Eina_List *skiplist = NULL;
10406 new_x = zx + (rand() % (zw - bd->w));
10410 new_y = zy + (rand() % (zh - bd->h));
10414 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
10416 skiplist = eina_list_append(skiplist, bd);
10418 e_place_desk_region_smart(bd->desk, skiplist,
10419 bd->x, bd->y, bd->w, bd->h,
10422 e_place_zone_region_smart(bd->zone, skiplist,
10423 bd->x, bd->y, bd->w, bd->h,
10425 eina_list_free(skiplist);
10427 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
10429 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
10434 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
10435 bd->client_inset.t, &new_x, &new_y);
10439 bd->changes.pos = 1;
10442 EINA_LIST_FREE(bd->pending_move_resize, pnd)
10444 if ((!bd->lock_client_location) && (pnd->move))
10448 bd->changes.pos = 1;
10450 if (pnd->without_border)
10452 bd->x -= bd->client_inset.l;
10453 bd->y -= bd->client_inset.t;
10456 if ((!bd->lock_client_size) && (pnd->resize))
10458 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
10459 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
10460 bd->client.w = pnd->w;
10461 bd->client.h = pnd->h;
10462 bd->changes.size = 1;
10468 /* Recreate state */
10469 e_hints_window_init(bd);
10470 if ((bd->client.e.state.centered) &&
10471 ((!bd->remember) ||
10472 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
10474 bd->x = zx + (zw - bd->w) / 2;
10475 bd->y = zy + (zh - bd->h) / 2;
10476 bd->changes.pos = 1;
10480 _e_border_client_move_resize_send(bd);
10482 /* if the explicit geometry request asks for the app to be
10483 * in another zone - well move it there */
10487 zone = e_container_zone_at_point_get(bd->zone->container,
10488 bd->x + (bd->w / 2),
10489 bd->y + (bd->h / 2));
10491 zone = e_container_zone_at_point_get(bd->zone->container,
10495 zone = e_container_zone_at_point_get(bd->zone->container,
10499 zone = e_container_zone_at_point_get(bd->zone->container,
10501 bd->y + bd->h - 1);
10503 zone = e_container_zone_at_point_get(bd->zone->container,
10505 bd->y + bd->h - 1);
10506 if ((zone) && (zone != bd->zone))
10507 e_border_zone_set(bd, zone);
10511 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
10513 /* effect changes to the window border itself */
10514 if ((bd->changes.shading))
10516 /* show at start of unshade (but don't hide until end of shade) */
10518 ecore_x_window_raise(bd->client.shell_win);
10519 bd->changes.shading = 0;
10522 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
10525 ecore_x_window_lower(bd->client.shell_win);
10527 ecore_x_window_raise(bd->client.shell_win);
10528 bd->changes.shaded = 0;
10531 else if ((bd->changes.shaded) && (bd->changes.pos))
10534 ecore_x_window_lower(bd->client.shell_win);
10536 ecore_x_window_raise(bd->client.shell_win);
10537 bd->changes.size = 1;
10538 bd->changes.shaded = 0;
10541 else if ((bd->changes.shaded) && (bd->changes.size))
10544 ecore_x_window_lower(bd->client.shell_win);
10546 ecore_x_window_raise(bd->client.shell_win);
10547 bd->changes.shaded = 0;
10550 else if (bd->changes.shaded)
10553 ecore_x_window_lower(bd->client.shell_win);
10555 ecore_x_window_raise(bd->client.shell_win);
10556 bd->changes.size = 1;
10557 bd->changes.shaded = 0;
10561 if (bd->changes.size)
10563 int x = 0, y = 0, xx = 0, yy = 0;
10565 if ((bd->shaded) && (!bd->shading))
10567 evas_obscured_clear(bd->bg_evas);
10571 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
10572 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
10574 evas_obscured_clear(bd->bg_evas);
10575 evas_obscured_rectangle_add(bd->bg_evas,
10576 bd->client_inset.l, bd->client_inset.t, xx, yy);
10580 if (bd->shade.dir == E_DIRECTION_UP)
10582 y = yy - bd->client.h;
10584 else if (bd->shade.dir == E_DIRECTION_LEFT)
10586 x = xx - bd->client.w;
10591 if (bd->client.e.state.video)
10593 if (bd->client.e.state.video_position.updated)
10595 ecore_x_window_move(bd->win,
10596 bd->client.e.state.video_parent_border->x +
10597 bd->client.e.state.video_parent_border->client_inset.l +
10598 bd->client.e.state.video_parent_border->fx.x +
10599 bd->client.e.state.video_position.x,
10600 bd->client.e.state.video_parent_border->y +
10601 bd->client.e.state.video_parent_border->client_inset.t +
10602 bd->client.e.state.video_parent_border->fx.y +
10603 bd->client.e.state.video_position.y);
10604 bd->client.e.state.video_position.updated = 0;
10607 else if (!bd->changes.pos)
10609 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10610 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10611 bd->post_resize = 1;
10618 ecore_x_window_move_resize(bd->win,
10623 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
10624 ecore_x_window_move(tmp->win,
10625 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
10626 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
10629 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
10631 if ((!bd->shaded) || (bd->shading))
10632 ecore_x_window_move_resize(bd->client.shell_win,
10633 bd->client_inset.l, bd->client_inset.t, xx, yy);
10635 if (bd->internal_ecore_evas)
10636 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
10637 else if (!bd->client.e.state.video)
10638 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
10640 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
10641 evas_object_resize(bd->bg_object, bd->w, bd->h);
10642 e_container_shape_resize(bd->shape, bd->w, bd->h);
10643 if (bd->changes.pos)
10644 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10646 _e_border_client_move_resize_send(bd);
10648 bd->changes.pos = 0;
10649 bd->changes.size = 0;
10652 else if (bd->changes.pos)
10654 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
10655 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
10658 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
10660 _e_border_client_move_resize_send(bd);
10662 bd->changes.pos = 0;
10666 if (bd->changes.reset_gravity)
10668 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
10669 bd->changes.reset_gravity = 0;
10673 if (bd->need_shape_merge)
10675 _e_border_shape_input_rectangle_set(bd);
10676 if ((bd->shaped) || (bd->client.shaped))
10678 Ecore_X_Window twin, twin2;
10681 twin = ecore_x_window_override_new
10682 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
10684 ecore_x_window_shape_window_set(twin, bd->bg_win);
10687 Ecore_X_Rectangle rects[4];
10691 rects[0].width = bd->w;
10692 rects[0].height = bd->client_inset.t;
10694 rects[1].y = bd->client_inset.t;
10695 rects[1].width = bd->client_inset.l;
10696 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
10697 rects[2].x = bd->w - bd->client_inset.r;
10698 rects[2].y = bd->client_inset.t;
10699 rects[2].width = bd->client_inset.r;
10700 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
10702 rects[3].y = bd->h - bd->client_inset.b;
10703 rects[3].width = bd->w;
10704 rects[3].height = bd->client_inset.b;
10705 ecore_x_window_shape_rectangles_set(twin, rects, 4);
10707 twin2 = ecore_x_window_override_new
10708 (bd->zone->container->scratch_win, 0, 0,
10709 bd->w - bd->client_inset.l - bd->client_inset.r,
10710 bd->h - bd->client_inset.t - bd->client_inset.b);
10713 if ((bd->shading) || (bd->shaded))
10715 if (bd->shade.dir == E_DIRECTION_UP)
10716 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
10717 else if (bd->shade.dir == E_DIRECTION_LEFT)
10718 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
10720 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
10722 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
10723 bd->w - bd->client_inset.l - bd->client_inset.r,
10724 bd->h - bd->client_inset.t - bd->client_inset.b);
10725 ecore_x_window_shape_window_add_xy(twin, twin2,
10726 bd->client_inset.l,
10727 bd->client_inset.t);
10728 ecore_x_window_free(twin2);
10729 ecore_x_window_shape_window_set(bd->win, twin);
10730 ecore_x_window_free(twin);
10733 ecore_x_window_shape_mask_set(bd->win, 0);
10734 // bd->need_shape_export = 1;
10735 bd->need_shape_merge = 0;
10738 if (bd->need_shape_export)
10740 Ecore_X_Rectangle *rects, *orects;
10743 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
10749 if ((num == bd->shape_rects_num) && (bd->shape_rects))
10753 orects = bd->shape_rects;
10755 for (i = 0; i < num; i++)
10757 if (rects[i].x < 0)
10759 rects[i].width -= rects[i].x;
10762 if ((rects[i].x + (int)rects[i].width) > bd->w)
10763 rects[i].width = rects[i].width - rects[i].x;
10764 if (rects[i].y < 0)
10766 rects[i].height -= rects[i].y;
10769 if ((rects[i].y + (int)rects[i].height) > bd->h)
10770 rects[i].height = rects[i].height - rects[i].y;
10772 if ((orects[i].x != rects[i].x) ||
10773 (orects[i].y != rects[i].y) ||
10774 (orects[i].width != rects[i].width) ||
10775 (orects[i].height != rects[i].height))
10784 if (bd->client.shaped)
10785 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
10787 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
10788 E_FREE(bd->shape_rects);
10789 bd->shape_rects = rects;
10790 bd->shape_rects_num = num;
10791 e_container_shape_rects_set(bd->shape, rects, num);
10798 E_FREE(bd->shape_rects);
10799 bd->shape_rects = NULL;
10800 bd->shape_rects_num = 0;
10801 e_container_shape_rects_set(bd->shape, NULL, 0);
10803 bd->need_shape_export = 0;
10806 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
10810 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
10811 if ((!bd->placed) && (!bd->re_manage) &&
10812 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
10813 (!((bd->client.icccm.transient_for != 0) ||
10814 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
10815 (!bdmove) && (!bdresize))
10817 /* Set this window into moving state */
10819 bd->cur_mouse_action = e_action_find("window_move");
10820 if (bd->cur_mouse_action)
10822 if ((!bd->cur_mouse_action->func.end_mouse) &&
10823 (!bd->cur_mouse_action->func.end))
10824 bd->cur_mouse_action = NULL;
10825 if (bd->cur_mouse_action)
10827 bd->x = x - (bd->w >> 1);
10828 bd->y = y - (bd->client_inset.t >> 1);
10830 bd->changes.pos = 1;
10832 _e_border_client_move_resize_send(bd);
10837 _e_border_show(bd);
10839 if (bd->cur_mouse_action)
10841 bd->moveinfo.down.x = bd->x + bd->fx.x;
10842 bd->moveinfo.down.y = bd->y + bd->fx.y;
10843 bd->moveinfo.down.w = bd->w;
10844 bd->moveinfo.down.h = bd->h;
10845 bd->mouse.current.mx = x;
10846 bd->mouse.current.my = y;
10847 bd->moveinfo.down.button = 0;
10848 bd->moveinfo.down.mx = x;
10849 bd->moveinfo.down.my = y;
10852 e_object_ref(E_OBJECT(bd->cur_mouse_action));
10853 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
10854 if (e_config->border_raise_on_mouse_action)
10855 e_border_raise(bd);
10856 e_border_focus_set(bd, 1, 1);
10858 bd->changes.visible = 0;
10862 if (bd->changes.icon)
10866 efreet_desktop_free(bd->desktop);
10867 bd->desktop = NULL;
10869 if (bd->icon_object)
10871 evas_object_del(bd->icon_object);
10872 bd->icon_object = NULL;
10874 if (bd->remember && bd->remember->prop.desktop_file)
10876 const char *desktop = bd->remember->prop.desktop_file;
10878 bd->desktop = efreet_desktop_get(desktop);
10880 bd->desktop = efreet_util_desktop_name_find(desktop);
10884 if ((bd->client.icccm.name) && (bd->client.icccm.class))
10885 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
10886 bd->client.icccm.class);
10890 /* libreoffice and maybe others match window class
10891 with .desktop file name */
10892 if (bd->client.icccm.class)
10895 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
10896 bd->desktop = efreet_util_desktop_file_id_find(buf);
10901 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
10902 bd->client.netwm.pid);
10903 if (bd->desktop) efreet_desktop_ref(bd->desktop);
10905 if (!bd->desktop && bd->client.icccm.name)
10907 /* this works for most cases as fallback. useful when app is
10908 run from a shell */
10909 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
10911 if (!bd->desktop && bd->client.icccm.transient_for)
10913 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
10914 if (bd2 && bd2->desktop)
10916 efreet_desktop_ref(bd2->desktop);
10917 bd->desktop = bd2->desktop;
10922 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
10923 bd->desktop->orig_path);
10926 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
10927 if ((bd->focused) && (bd->icon_object))
10928 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
10931 evas_object_show(bd->icon_object);
10932 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
10935 evas_object_hide(bd->icon_object);
10938 E_Event_Border_Icon_Change *ev;
10940 ev = E_NEW(E_Event_Border_Icon_Change, 1);
10942 e_object_ref(E_OBJECT(bd));
10943 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
10944 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
10945 _e_border_event_border_icon_change_free, NULL);
10947 bd->changes.icon = 0;
10950 bd->new_client = 0;
10952 bd->changes.stack = 0;
10953 bd->changes.prop = 0;
10955 if ((bd->take_focus) || (bd->want_focus))
10957 bd->take_focus = 0;
10958 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10959 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
10960 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
10963 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
10966 bd->want_focus = 0;
10967 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
10968 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
10969 _e_border_check_stack(bd);
10972 e_border_focus_set_with_pointer(bd);
10974 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
10976 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
10977 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
10978 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
10979 e_border_focused_get())))
10981 e_border_focus_set_with_pointer(bd);
10986 /* focus window by default when it is the only one on desk */
10987 E_Border *bd2 = NULL;
10989 EINA_LIST_FOREACH(focus_stack, l, bd2)
10991 if (bd == bd2) continue;
10992 if ((!bd2->iconic) && (bd2->visible) &&
10993 ((bd->desk == bd2->desk) || bd2->sticky))
10999 e_border_focus_set_with_pointer(bd);
11004 if (bd->need_maximize)
11007 max = bd->maximized;
11008 bd->maximized = E_MAXIMIZE_NONE;
11009 e_border_maximize(bd, max);
11010 bd->need_maximize = 0;
11013 if (bd->need_fullscreen)
11015 e_border_fullscreen(bd, e_config->fullscreen_policy);
11016 bd->need_fullscreen = 0;
11020 e_remember_update(bd);
11022 if (send_event) // FIXME: send only if a property changed - above need to
11023 { // check on that. for now - always send.
11024 event = E_NEW(E_Event_Border_Property, 1);
11025 event->border = bd;
11026 e_object_ref(E_OBJECT(bd));
11027 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
11029 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
11033 _e_border_moveinfo_gather(E_Border *bd,
11034 const char *source)
11036 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
11037 else if (e_util_glob_match(source, "mouse,*,2"))
11038 bd->moveinfo.down.button = 2;
11039 else if (e_util_glob_match(source, "mouse,*,3"))
11040 bd->moveinfo.down.button = 3;
11041 else bd->moveinfo.down.button = 0;
11042 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
11044 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
11045 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
11049 bd->moveinfo.down.mx = bd->mouse.current.mx;
11050 bd->moveinfo.down.my = bd->mouse.current.my;
11055 _e_border_resize_handle(E_Border *bd)
11058 int new_x, new_y, new_w, new_h;
11060 Eina_List *skiplist = NULL;
11067 if ((bd->resize_mode == RESIZE_TR) ||
11068 (bd->resize_mode == RESIZE_R) ||
11069 (bd->resize_mode == RESIZE_BR))
11071 if ((bd->moveinfo.down.button >= 1) &&
11072 (bd->moveinfo.down.button <= 3))
11073 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
11074 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11076 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
11078 else if ((bd->resize_mode == RESIZE_TL) ||
11079 (bd->resize_mode == RESIZE_L) ||
11080 (bd->resize_mode == RESIZE_BL))
11082 if ((bd->moveinfo.down.button >= 1) &&
11083 (bd->moveinfo.down.button <= 3))
11084 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
11085 (bd->mouse.current.mx - bd->moveinfo.down.mx);
11087 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
11090 if ((bd->resize_mode == RESIZE_TL) ||
11091 (bd->resize_mode == RESIZE_T) ||
11092 (bd->resize_mode == RESIZE_TR))
11094 if ((bd->moveinfo.down.button >= 1) &&
11095 (bd->moveinfo.down.button <= 3))
11096 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
11097 (bd->mouse.current.my - bd->moveinfo.down.my);
11099 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
11101 else if ((bd->resize_mode == RESIZE_BL) ||
11102 (bd->resize_mode == RESIZE_B) ||
11103 (bd->resize_mode == RESIZE_BR))
11105 if ((bd->moveinfo.down.button >= 1) &&
11106 (bd->moveinfo.down.button <= 3))
11107 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
11108 (bd->mouse.current.my - bd->moveinfo.down.my);
11110 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
11116 if ((bd->resize_mode == RESIZE_TL) ||
11117 (bd->resize_mode == RESIZE_L) ||
11118 (bd->resize_mode == RESIZE_BL))
11120 if ((bd->resize_mode == RESIZE_TL) ||
11121 (bd->resize_mode == RESIZE_T) ||
11122 (bd->resize_mode == RESIZE_TR))
11125 skiplist = eina_list_append(skiplist, bd);
11126 e_resist_container_border_position(bd->zone->container, skiplist,
11127 bd->x, bd->y, bd->w, bd->h,
11129 &new_x, &new_y, &new_w, &new_h);
11130 eina_list_free(skiplist);
11134 e_border_resize_limit(bd, &new_w, &new_h);
11135 if ((bd->resize_mode == RESIZE_TL) ||
11136 (bd->resize_mode == RESIZE_L) ||
11137 (bd->resize_mode == RESIZE_BL))
11138 new_x += (w - new_w);
11139 if ((bd->resize_mode == RESIZE_TL) ||
11140 (bd->resize_mode == RESIZE_T) ||
11141 (bd->resize_mode == RESIZE_TR))
11142 new_y += (h - new_h);
11144 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
11148 _e_border_shade_animator(void *data)
11150 E_Border *bd = data;
11152 double dur = bd->client.h / e_config->border_shade_speed;
11154 dt = ecore_loop_time_get() - bd->shade.start;
11157 if (val < 0.0) val = 0.0;
11158 else if (val > 1.0) val = 1.0;
11160 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
11163 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
11164 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11166 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
11169 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
11170 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11172 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
11175 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
11176 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11178 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
11181 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11182 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11184 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
11187 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
11188 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11190 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
11193 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
11194 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11196 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
11199 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
11200 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11202 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
11205 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
11206 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11208 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
11211 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
11212 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11217 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
11218 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
11221 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
11222 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
11223 else if (bd->shade.val > .999)
11224 bd->shade.val = 1.0;
11226 if (bd->shade.dir == E_DIRECTION_UP)
11227 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11228 else if (bd->shade.dir == E_DIRECTION_DOWN)
11230 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
11231 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
11232 bd->changes.pos = 1;
11234 else if (bd->shade.dir == E_DIRECTION_LEFT)
11235 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11236 else if (bd->shade.dir == E_DIRECTION_RIGHT)
11238 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
11239 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
11240 bd->changes.pos = 1;
11243 if ((bd->shaped) || (bd->client.shaped))
11245 bd->need_shape_merge = 1;
11246 bd->need_shape_export = 1;
11248 if (bd->shaped_input)
11250 bd->need_shape_merge = 1;
11252 bd->changes.size = 1;
11258 E_Event_Border_Resize *ev;
11261 bd->shaded = !(bd->shaded);
11262 bd->changes.size = 1;
11263 bd->changes.shaded = 1;
11264 bd->changes.shading = 1;
11266 bd->shade.anim = NULL;
11269 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
11271 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
11272 edje_object_message_signal_process(bd->bg_object);
11273 e_border_frame_recalc(bd);
11275 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
11276 ev = E_NEW(E_Event_Border_Resize, 1);
11278 e_object_ref(E_OBJECT(bd));
11279 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
11280 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
11281 return ECORE_CALLBACK_CANCEL;
11283 return ECORE_CALLBACK_RENEW;
11287 _e_border_event_border_resize_free(void *data __UNUSED__,
11290 E_Event_Border_Resize *e;
11293 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
11294 e_object_unref(E_OBJECT(e->border));
11299 _e_border_event_border_move_free(void *data __UNUSED__,
11302 E_Event_Border_Move *e;
11305 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
11306 e_object_unref(E_OBJECT(e->border));
11311 _e_border_event_border_add_free(void *data __UNUSED__,
11314 E_Event_Border_Add *e;
11317 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
11318 e_object_unref(E_OBJECT(e->border));
11323 _e_border_event_border_remove_free(void *data __UNUSED__,
11326 E_Event_Border_Remove *e;
11329 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
11330 e_object_unref(E_OBJECT(e->border));
11335 _e_border_event_border_show_free(void *data __UNUSED__,
11338 E_Event_Border_Show *e;
11341 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
11342 e_object_unref(E_OBJECT(e->border));
11347 _e_border_event_border_hide_free(void *data __UNUSED__,
11350 E_Event_Border_Hide *e;
11353 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
11354 e_object_unref(E_OBJECT(e->border));
11359 _e_border_event_border_iconify_free(void *data __UNUSED__,
11362 E_Event_Border_Iconify *e;
11365 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
11366 e_object_unref(E_OBJECT(e->border));
11371 _e_border_event_border_uniconify_free(void *data __UNUSED__,
11374 E_Event_Border_Uniconify *e;
11377 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
11378 e_object_unref(E_OBJECT(e->border));
11383 _e_border_event_border_stick_free(void *data __UNUSED__,
11386 E_Event_Border_Stick *e;
11389 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
11390 e_object_unref(E_OBJECT(e->border));
11395 _e_border_event_border_unstick_free(void *data __UNUSED__,
11398 E_Event_Border_Unstick *e;
11401 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
11402 e_object_unref(E_OBJECT(e->border));
11407 _e_border_event_border_zone_set_free(void *data __UNUSED__,
11410 E_Event_Border_Zone_Set *e;
11413 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
11414 e_object_unref(E_OBJECT(e->border));
11415 e_object_unref(E_OBJECT(e->zone));
11420 _e_border_event_border_desk_set_free(void *data __UNUSED__,
11423 E_Event_Border_Desk_Set *e;
11426 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
11427 e_object_unref(E_OBJECT(e->border));
11428 e_object_unref(E_OBJECT(e->desk));
11433 _e_border_event_border_stack_free(void *data __UNUSED__,
11436 E_Event_Border_Stack *e;
11439 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
11440 e_object_unref(E_OBJECT(e->border));
11443 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
11444 e_object_unref(E_OBJECT(e->stack));
11450 _e_border_event_border_icon_change_free(void *data __UNUSED__,
11453 E_Event_Border_Icon_Change *e;
11456 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
11457 e_object_unref(E_OBJECT(e->border));
11462 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
11465 E_Event_Border_Urgent_Change *e;
11468 e_object_unref(E_OBJECT(e->border));
11473 _e_border_event_border_focus_in_free(void *data __UNUSED__,
11476 E_Event_Border_Focus_In *e;
11479 e_object_unref(E_OBJECT(e->border));
11484 _e_border_event_border_focus_out_free(void *data __UNUSED__,
11487 E_Event_Border_Focus_Out *e;
11490 e_object_unref(E_OBJECT(e->border));
11495 _e_border_event_border_property_free(void *data __UNUSED__,
11498 E_Event_Border_Property *e;
11501 e_object_unref(E_OBJECT(e->border));
11506 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
11509 E_Event_Border_Fullscreen *e;
11512 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
11513 e_object_unref(E_OBJECT(e->border));
11518 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
11521 E_Event_Border_Unfullscreen *e;
11524 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
11525 e_object_unref(E_OBJECT(e->border));
11529 #ifdef _F_ZONE_WINDOW_ROTATION_
11531 _e_border_event_border_rotation_free(void *data __UNUSED__,
11534 E_Event_Border_Rotation *e;
11537 e_object_unref(E_OBJECT(e->border));
11543 _e_border_zone_update(E_Border *bd)
11549 /* still within old zone - leave it there */
11550 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11551 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
11552 #if _F_BORDER_CLIP_TO_ZONE_
11554 _e_border_shape_input_clip_to_zone(bd);
11559 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11560 /* find a new zone */
11561 con = bd->zone->container;
11562 EINA_LIST_FOREACH(con->zones, l, zone)
11564 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
11565 zone->x, zone->y, zone->w, zone->h))
11567 e_border_zone_set(bd, zone);
11568 #if _F_BORDER_CLIP_TO_ZONE_
11569 _e_border_shape_input_clip_to_zone(bd);
11570 #endif /* _F_BORDER_CLIP_TO_ZONE_ */
11577 _e_border_resize_begin(E_Border *bd)
11579 if (!bd->lock_user_stacking)
11581 if (e_config->border_raise_on_mouse_action)
11582 e_border_raise(bd);
11584 if ((bd->shaded) || (bd->shading) ||
11585 (bd->fullscreen) || (bd->lock_user_size))
11588 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
11594 if (bd->client.netwm.sync.request)
11596 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
11597 bd->client.netwm.sync.serial = 1;
11598 bd->client.netwm.sync.wait = 0;
11599 bd->client.netwm.sync.send_time = ecore_loop_time_get();
11602 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
11609 _e_border_resize_end(E_Border *bd)
11613 e_grabinput_release(bd->win, bd->win);
11616 if (bd->client.netwm.sync.alarm)
11618 E_Border_Pending_Move_Resize *pnd;
11620 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
11621 bd->client.netwm.sync.alarm = 0;
11622 /* resize to last geometry if sync alarm for it was not yet handled */
11623 if (bd->pending_move_resize)
11626 bd->changes.pos = 1;
11627 bd->changes.size = 1;
11628 _e_border_client_move_resize_send(bd);
11631 EINA_LIST_FREE(bd->pending_move_resize, pnd)
11635 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
11639 /* If this border was maximized, we need to unset Maximized state or
11640 * on restart, E still thinks it's maximized */
11641 if (bd->maximized != E_MAXIMIZE_NONE)
11642 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
11643 bd->maximized & E_MAXIMIZE_NONE);
11648 _e_border_resize_update(E_Border *bd)
11650 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
11654 _e_border_move_begin(E_Border *bd)
11656 if (!bd->lock_user_stacking)
11658 if (e_config->border_raise_on_mouse_action)
11659 e_border_raise(bd);
11661 if ((bd->fullscreen) || (bd->lock_user_location))
11664 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
11670 if (bd->client.netwm.sync.request)
11672 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
11673 bd->client.netwm.sync.serial = 0;
11674 bd->client.netwm.sync.wait = 0;
11675 bd->client.netwm.sync.time = ecore_loop_time_get();
11678 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
11685 _e_border_move_end(E_Border *bd)
11689 e_grabinput_release(bd->win, bd->win);
11693 if (bd->client.netwm.sync.alarm)
11695 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
11696 bd->client.netwm.sync.alarm = 0;
11699 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
11706 _e_border_move_update(E_Border *bd)
11708 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
11712 _e_border_cb_ping_poller(void *data)
11722 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
11723 if (bd->kill_timer)
11725 ecore_timer_del(bd->kill_timer);
11726 bd->kill_timer = NULL;
11732 /* if time between last ping and now is greater
11733 * than half the ping interval... */
11734 if ((ecore_loop_time_get() - bd->ping) >
11735 ((e_config->ping_clients_interval *
11736 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
11741 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
11742 /* FIXME: if below dialog is up - hide it now */
11744 if (bd->delete_requested)
11746 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
11747 e_border_act_kill_begin(bd);
11751 bd->ping_poller = NULL;
11753 return ECORE_CALLBACK_CANCEL;
11757 _e_border_cb_kill_timer(void *data)
11762 // dont wait until it's hung -
11765 if (bd->client.netwm.pid > 1)
11766 kill(bd->client.netwm.pid, SIGKILL);
11768 bd->kill_timer = NULL;
11769 return ECORE_CALLBACK_CANCEL;
11773 _e_border_pointer_resize_begin(E_Border *bd)
11775 switch (bd->resize_mode)
11778 e_pointer_type_push(bd->pointer, bd, "resize_tl");
11782 e_pointer_type_push(bd->pointer, bd, "resize_t");
11786 e_pointer_type_push(bd->pointer, bd, "resize_tr");
11790 e_pointer_type_push(bd->pointer, bd, "resize_r");
11794 e_pointer_type_push(bd->pointer, bd, "resize_br");
11798 e_pointer_type_push(bd->pointer, bd, "resize_b");
11802 e_pointer_type_push(bd->pointer, bd, "resize_bl");
11806 e_pointer_type_push(bd->pointer, bd, "resize_l");
11812 _e_border_pointer_resize_end(E_Border *bd)
11814 switch (bd->resize_mode)
11817 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
11821 e_pointer_type_pop(bd->pointer, bd, "resize_t");
11825 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
11829 e_pointer_type_pop(bd->pointer, bd, "resize_r");
11833 e_pointer_type_pop(bd->pointer, bd, "resize_br");
11837 e_pointer_type_pop(bd->pointer, bd, "resize_b");
11841 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
11845 e_pointer_type_pop(bd->pointer, bd, "resize_l");
11851 _e_border_pointer_move_begin(E_Border *bd)
11853 e_pointer_type_push(bd->pointer, bd, "move");
11857 _e_border_pointer_move_end(E_Border *bd)
11859 e_pointer_type_pop(bd->pointer, bd, "move");
11862 static Eina_List *_e_border_hooks = NULL;
11863 static int _e_border_hooks_delete = 0;
11864 static int _e_border_hooks_walking = 0;
11867 _e_border_hooks_clean(void)
11872 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
11876 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
11883 _e_border_hook_call(E_Border_Hook_Point hookpoint,
11889 _e_border_hooks_walking++;
11890 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
11892 if (bh->delete_me) continue;
11893 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
11895 _e_border_hooks_walking--;
11896 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
11897 _e_border_hooks_clean();
11900 EAPI E_Border_Hook *
11901 e_border_hook_add(E_Border_Hook_Point hookpoint,
11902 void (*func)(void *data,
11908 bh = E_NEW(E_Border_Hook, 1);
11909 if (!bh) return NULL;
11910 bh->hookpoint = hookpoint;
11913 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
11918 e_border_hook_del(E_Border_Hook *bh)
11921 if (_e_border_hooks_walking == 0)
11923 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
11927 _e_border_hooks_delete++;
11931 e_border_focus_track_freeze(void)
11933 focus_track_frozen++;
11937 e_border_focus_track_thaw(void)
11939 focus_track_frozen--;
11943 e_border_under_pointer_get(E_Desk *desk,
11946 E_Border *bd = NULL, *cbd;
11950 /* We need to ensure that we can get the container window for the
11951 * zone of either the given desk or the desk of the excluded
11952 * window, so return if neither is given */
11954 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
11956 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
11960 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
11962 if (!cbd) continue;
11963 /* If a border was specified which should be excluded from the list
11964 * (because it will be closed shortly for example), skip */
11965 if ((exclude) && (cbd == exclude)) continue;
11966 if ((desk) && (cbd->desk != desk)) continue;
11967 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
11969 /* If the layer is higher, the position of the window is higher
11970 * (always on top vs always below) */
11971 if (!bd || (cbd->layer > bd->layer))
11981 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
11988 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
11989 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
11990 (y - warp_y) > 5 || (y - warp_y) < -5)
11992 /* User moved the mouse, so stop warping */
11997 /* We just use the same warp speed as configured
11998 * for the windowlist */
11999 spd = e_config->winlist_warp_speed;
12002 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
12003 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
12004 if (warp_x == x && warp_y == y)
12006 warp_x = warp_to_x;
12007 warp_y = warp_to_y;
12011 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
12012 return ECORE_CALLBACK_RENEW;
12015 ecore_timer_del(warp_timer);
12017 return ECORE_CALLBACK_CANCEL;
12021 e_border_pointer_warp_to_center(E_Border *bd)
12025 /* Do not slide pointer when disabled (probably breaks focus
12026 * on sloppy/mouse focus but requested by users). */
12027 if (!e_config->pointer_slide) return 0;
12028 /* Only warp the pointer if it is not already in the area of
12029 * the given border */
12030 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
12031 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
12032 (y >= bd->y) && (y <= (bd->y + bd->h)))
12035 warp_to_x = bd->x + (bd->w / 2);
12036 if (warp_to_x < (bd->zone->x + 1))
12037 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
12038 else if (warp_to_x > (bd->zone->x + bd->zone->w))
12039 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
12041 warp_to_y = bd->y + (bd->h / 2);
12042 if (warp_to_y < (bd->zone->y + 1))
12043 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
12044 else if (warp_to_y > (bd->zone->y + bd->zone->h))
12045 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
12048 warp_to_win = bd->zone->container->win;
12049 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
12051 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
12056 e_border_comp_hidden_set(E_Border *bd,
12062 E_OBJECT_CHECK(bd);
12063 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12065 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12068 ecore_x_window_hide(tmp->win);
12070 ecore_x_window_show(tmp->win);
12073 if (bd->comp_hidden == hidden) return;
12075 bd->comp_hidden = hidden;
12077 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12079 ecore_x_composite_window_events_disable(bd->win);
12080 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12084 _e_border_shape_input_rectangle_set(bd);
12085 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12090 e_border_tmp_input_hidden_push(E_Border *bd)
12095 E_OBJECT_CHECK(bd);
12096 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12098 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12099 e_border_tmp_input_hidden_push(tmp);
12101 bd->tmp_input_hidden++;
12102 if (bd->tmp_input_hidden != 1) return;
12104 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12106 ecore_x_composite_window_events_disable(bd->win);
12107 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12111 _e_border_shape_input_rectangle_set(bd);
12112 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12117 e_border_tmp_input_hidden_pop(E_Border *bd)
12122 E_OBJECT_CHECK(bd);
12123 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
12125 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
12126 e_border_tmp_input_hidden_pop(tmp);
12128 bd->tmp_input_hidden--;
12129 if (bd->tmp_input_hidden != 0) return;
12131 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
12133 ecore_x_composite_window_events_disable(bd->win);
12134 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
12138 _e_border_shape_input_rectangle_set(bd);
12139 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
12144 e_border_activate(E_Border *bd, Eina_Bool just_do_it)
12146 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
12148 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
12149 ((bd->parent->focused) &&
12150 (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))) ||
12155 if (e_config->clientlist_warp_to_iconified_desktop == 1)
12156 e_desk_show(bd->desk);
12158 if (!bd->lock_user_iconify)
12159 e_border_uniconify(bd);
12161 if ((!bd->iconic) && (!bd->sticky))
12162 e_desk_show(bd->desk);
12163 if (!bd->lock_user_stacking) e_border_raise(bd);
12164 if (!bd->lock_focus_out)
12166 /* XXX ooffice does send this request for
12167 config dialogs when the main window gets focus.
12168 causing the pointer to jump back and forth. */
12169 if ((e_config->focus_policy != E_FOCUS_CLICK) &&
12170 !(bd->client.icccm.name && !strcmp(bd->client.icccm.name, "VCLSalFrame")))
12171 ecore_x_pointer_warp(bd->zone->container->win,
12172 bd->x + (bd->w / 2), bd->y + (bd->h / 2));
12173 e_border_focus_set(bd, 1, 1);
12177 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/