3 //#define INOUTDEBUG_MOUSE 1
4 //#define INOUTDEBUG_FOCUS 1
6 /* These are compatible with netwm */
16 #define RESIZE_NONE 11
18 /* local subsystem functions */
19 static void _e_border_free(E_Border *bd);
20 static void _e_border_del(E_Border *bd);
22 #ifdef PRINT_LOTS_OF_DEBUG
23 #define E_PRINT_BORDER_INFO(X) \
24 _e_border_print(X, __PRETTY_FUNC__)
26 static void _e_border_print(E_Border *bd,
30 /* FIXME: these likely belong in a separate icccm/client handler */
31 /* and the border needs to become a dumb object that just does what its */
33 static Eina_Bool _e_border_cb_window_show_request(void *data,
36 static Eina_Bool _e_border_cb_window_destroy(void *data,
39 static Eina_Bool _e_border_cb_window_hide(void *data,
42 static Eina_Bool _e_border_cb_window_reparent(void *data,
45 static Eina_Bool _e_border_cb_window_configure_request(void *data,
48 static Eina_Bool _e_border_cb_window_resize_request(void *data,
51 static Eina_Bool _e_border_cb_window_gravity(void *data,
54 static Eina_Bool _e_border_cb_window_stack_request(void *data,
57 static Eina_Bool _e_border_cb_window_property(void *data,
60 static Eina_Bool _e_border_cb_window_colormap(void *data,
63 static Eina_Bool _e_border_cb_window_shape(void *data,
66 static Eina_Bool _e_border_cb_window_focus_in(void *data,
69 static Eina_Bool _e_border_cb_window_focus_out(void *data,
72 static Eina_Bool _e_border_cb_client_message(void *data,
76 static Eina_Bool _e_border_cb_window_state_request(void *data,
79 static Eina_Bool _e_border_cb_window_move_resize_request(void *data,
82 static Eina_Bool _e_border_cb_desktop_change(void *data,
85 static Eina_Bool _e_border_cb_sync_alarm(void *data,
88 static Eina_Bool _e_border_cb_efreet_cache_update(void *data,
91 static Eina_Bool _e_border_cb_config_icon_theme(void *data,
95 static Eina_Bool _e_border_cb_pointer_warp(void *data,
98 static void _e_border_cb_signal_bind(void *data,
100 const char *emission,
102 static Eina_Bool _e_border_cb_mouse_in(void *data,
105 static Eina_Bool _e_border_cb_mouse_out(void *data,
108 static Eina_Bool _e_border_cb_mouse_wheel(void *data,
111 static Eina_Bool _e_border_cb_mouse_down(void *data,
114 static Eina_Bool _e_border_cb_mouse_up(void *data,
117 static Eina_Bool _e_border_cb_mouse_move(void *data,
120 static Eina_Bool _e_border_cb_grab_replay(void *data,
123 static void _e_border_cb_drag_finished(E_Drag *drag,
126 static void _e_border_eval(E_Border *bd);
127 static void _e_border_eval0(E_Border *bd);
128 static void _e_border_container_layout_hook(E_Container *con);
130 static void _e_border_moveinfo_gather(E_Border *bd,
132 static void _e_border_resize_handle(E_Border *bd);
134 static Eina_Bool _e_border_shade_animator(void *data);
136 static void _e_border_event_border_add_free(void *data,
138 static void _e_border_event_border_remove_free(void *data,
140 static void _e_border_event_border_zone_set_free(void *data,
142 static void _e_border_event_border_desk_set_free(void *data,
144 static void _e_border_event_border_stack_free(void *data,
146 static void _e_border_event_border_icon_change_free(void *data,
148 static void _e_border_event_border_urgent_change_free(void *data,
150 static void _e_border_event_border_focus_in_free(void *data,
152 static void _e_border_event_border_focus_out_free(void *data,
154 static void _e_border_event_border_resize_free(void *data,
156 static void _e_border_event_border_move_free(void *data,
158 static void _e_border_event_border_show_free(void *data,
160 static void _e_border_event_border_hide_free(void *data,
162 static void _e_border_event_border_iconify_free(void *data,
164 static void _e_border_event_border_uniconify_free(void *data,
166 static void _e_border_event_border_stick_free(void *data,
168 static void _e_border_event_border_unstick_free(void *data,
170 static void _e_border_event_border_property_free(void *data,
172 static void _e_border_event_border_fullscreen_free(void *data,
174 static void _e_border_event_border_unfullscreen_free(void *data,
177 static void _e_border_zone_update(E_Border *bd);
179 static int _e_border_resize_begin(E_Border *bd);
180 static int _e_border_resize_end(E_Border *bd);
181 static void _e_border_resize_update(E_Border *bd);
183 static int _e_border_move_begin(E_Border *bd);
184 static int _e_border_move_end(E_Border *bd);
185 static void _e_border_move_update(E_Border *bd);
187 static Eina_Bool _e_border_cb_ping_poller(void *data);
188 static Eina_Bool _e_border_cb_kill_timer(void *data);
190 static void _e_border_pointer_resize_begin(E_Border *bd);
191 static void _e_border_pointer_resize_end(E_Border *bd);
192 static void _e_border_pointer_move_begin(E_Border *bd);
193 static void _e_border_pointer_move_end(E_Border *bd);
195 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
198 static void _e_border_client_move_resize_send(E_Border *bd);
200 static void _e_border_frame_replace(E_Border *bd,
203 static void _e_border_shape_input_rectangle_set(E_Border* bd);
204 static void _e_border_show(E_Border *bd);
205 static void _e_border_hide(E_Border *bd);
208 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
209 static void _e_border_latest_stacked_focus (E_Border* bd);
210 static void _e_border_check_stack (E_Border *bd);
211 static void _e_border_focus_top_stack_set (E_Border* bd);
214 /* local subsystem globals */
215 static Eina_List *handlers = NULL;
216 static Eina_List *borders = NULL;
217 static Eina_Hash *borders_hash = NULL;
218 static E_Border *focused = NULL;
219 static Eina_List *focus_next = NULL;
220 static Ecore_X_Time focus_time = 0;
222 static E_Border *resize = NULL;
223 static E_Border *move = NULL;
224 static E_Drag *drag_border = NULL;
226 static int grabbed = 0;
228 static Eina_List *focus_stack = NULL;
229 static Eina_List *raise_stack = NULL;
231 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
232 static int screen_size_index = -1;
234 static int focus_track_frozen = 0;
236 static int warp_to = 0;
237 static int warp_to_x = 0;
238 static int warp_to_y = 0;
239 static int warp_x = 0;
240 static int warp_y = 0;
241 static Ecore_X_Window warp_to_win;
242 static Ecore_Timer *warp_timer = NULL;
244 EAPI int E_EVENT_BORDER_ADD = 0;
245 EAPI int E_EVENT_BORDER_REMOVE = 0;
246 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
247 EAPI int E_EVENT_BORDER_DESK_SET = 0;
248 EAPI int E_EVENT_BORDER_RESIZE = 0;
249 EAPI int E_EVENT_BORDER_MOVE = 0;
250 EAPI int E_EVENT_BORDER_SHOW = 0;
251 EAPI int E_EVENT_BORDER_HIDE = 0;
252 EAPI int E_EVENT_BORDER_ICONIFY = 0;
253 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
254 EAPI int E_EVENT_BORDER_STICK = 0;
255 EAPI int E_EVENT_BORDER_UNSTICK = 0;
256 EAPI int E_EVENT_BORDER_STACK = 0;
257 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
258 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
259 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
260 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
261 EAPI int E_EVENT_BORDER_PROPERTY = 0;
262 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
263 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
265 #define GRAV_SET(bd, grav) \
266 ecore_x_window_gravity_set(bd->bg_win, grav); \
267 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
268 ecore_x_window_gravity_set(bd->client.win, grav);
270 /* externally accessible functions */
274 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
275 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
276 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
277 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
278 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
279 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
280 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
281 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
282 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
283 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
284 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
285 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
286 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
287 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
288 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
289 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
290 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
291 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
293 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
295 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
296 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
297 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
298 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
300 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
302 E_EVENT_BORDER_ADD = ecore_event_type_new();
303 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
304 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
305 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
306 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
307 E_EVENT_BORDER_MOVE = ecore_event_type_new();
308 E_EVENT_BORDER_SHOW = ecore_event_type_new();
309 E_EVENT_BORDER_HIDE = ecore_event_type_new();
310 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
311 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
312 E_EVENT_BORDER_STICK = ecore_event_type_new();
313 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
314 E_EVENT_BORDER_STACK = ecore_event_type_new();
315 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
316 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
317 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
318 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
319 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
320 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
321 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
329 e_border_shutdown(void)
331 E_FREE_LIST(handlers, ecore_event_handler_del);
333 if (borders_hash) eina_hash_free(borders_hash);
340 e_border_new(E_Container *con,
346 Ecore_X_Window_Attributes *att;
347 unsigned int managed, desk[2];
350 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
351 if (!bd) return NULL;
352 ecore_x_window_shadow_tree_flush();
353 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
357 /* FIXME: ewww - round trip */
358 bd->client.argb = ecore_x_window_argb_get(win);
360 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
363 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
364 ecore_x_window_shape_events_select(bd->win, 1);
366 e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
367 e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
369 bd->bg_ecore_evas = e_canvas_new(e_config->evas_engine_borders, bd->win,
370 0, 0, bd->w, bd->h, 1, 0,
372 e_canvas_add(bd->bg_ecore_evas);
373 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
374 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
375 ecore_x_window_shape_events_select(bd->bg_win, 1);
376 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
377 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
379 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
381 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
382 ecore_x_window_container_manage(bd->client.shell_win);
383 if (!internal) ecore_x_window_client_manage(win);
384 /* FIXME: Round trip. XCB */
385 /* fetch needed to avoid grabbing the server as window may vanish */
386 att = &bd->client.initial_attributes;
387 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
389 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
390 e_canvas_del(bd->bg_ecore_evas);
391 ecore_evas_free(bd->bg_ecore_evas);
392 ecore_x_window_free(bd->client.shell_win);
393 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
394 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
395 ecore_x_window_free(bd->win);
400 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
401 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
403 /* FIXME: if first_map is 1 then we should ignore the first hide event
404 * or ensure the window is already hidden and events flushed before we
405 * create a border for it */
408 // printf("##- FIRST MAP\n");
413 // needed to be 1 for internal windw and on restart.
414 // bd->ignore_first_unmap = 2;
417 bd->client.win = win;
418 bd->zone = e_zone_current_get(con);
420 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
422 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
423 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
424 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
425 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
426 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
427 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
429 bd->client.icccm.title = NULL;
430 bd->client.icccm.name = NULL;
431 bd->client.icccm.class = NULL;
432 bd->client.icccm.icon_name = NULL;
433 bd->client.icccm.machine = NULL;
434 bd->client.icccm.min_w = 1;
435 bd->client.icccm.min_h = 1;
436 bd->client.icccm.max_w = 32767;
437 bd->client.icccm.max_h = 32767;
438 bd->client.icccm.base_w = 0;
439 bd->client.icccm.base_h = 0;
440 bd->client.icccm.step_w = -1;
441 bd->client.icccm.step_h = -1;
442 bd->client.icccm.min_aspect = 0.0;
443 bd->client.icccm.max_aspect = 0.0;
444 bd->client.icccm.accepts_focus = 1;
446 bd->client.netwm.pid = 0;
447 bd->client.netwm.name = NULL;
448 bd->client.netwm.icon_name = NULL;
449 bd->client.netwm.desktop = 0;
450 bd->client.netwm.state.modal = 0;
451 bd->client.netwm.state.sticky = 0;
452 bd->client.netwm.state.shaded = 0;
453 bd->client.netwm.state.hidden = 0;
454 bd->client.netwm.state.maximized_v = 0;
455 bd->client.netwm.state.maximized_h = 0;
456 bd->client.netwm.state.skip_taskbar = 0;
457 bd->client.netwm.state.skip_pager = 0;
458 bd->client.netwm.state.fullscreen = 0;
459 bd->client.netwm.state.stacking = E_STACKING_NONE;
460 bd->client.netwm.action.move = 0;
461 bd->client.netwm.action.resize = 0;
462 bd->client.netwm.action.minimize = 0;
463 bd->client.netwm.action.shade = 0;
464 bd->client.netwm.action.stick = 0;
465 bd->client.netwm.action.maximized_h = 0;
466 bd->client.netwm.action.maximized_v = 0;
467 bd->client.netwm.action.fullscreen = 0;
468 bd->client.netwm.action.change_desktop = 0;
469 bd->client.netwm.action.close = 0;
470 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
476 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
477 bd->client.icccm.fetch.command = 1;
481 for (i = 0; i < at_num; i++)
483 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
484 bd->client.icccm.fetch.title = 1;
485 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
486 bd->client.icccm.fetch.name_class = 1;
487 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
488 bd->client.icccm.fetch.icon_name = 1;
489 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
490 bd->client.icccm.fetch.machine = 1;
491 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
492 bd->client.icccm.fetch.hints = 1;
493 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
494 bd->client.icccm.fetch.size_pos_hints = 1;
495 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
496 bd->client.icccm.fetch.protocol = 1;
497 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
498 bd->client.mwm.fetch.hints = 1;
499 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
501 bd->client.icccm.fetch.transient_for = 1;
502 bd->client.netwm.fetch.type = 1;
504 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
505 bd->client.icccm.fetch.client_leader = 1;
506 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
507 bd->client.icccm.fetch.window_role = 1;
508 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
509 bd->client.icccm.fetch.state = 1;
511 /* netwm, loop again, netwm will ignore some icccm, so we
512 * have to be sure that netwm is checked after */
513 for (i = 0; i < at_num; i++)
515 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
518 bd->client.icccm.fetch.title = 0;
519 bd->client.netwm.fetch.name = 1;
521 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
524 bd->client.icccm.fetch.icon_name = 0;
525 bd->client.netwm.fetch.icon_name = 1;
527 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
529 bd->client.netwm.fetch.icon = 1;
531 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
533 bd->client.netwm.fetch.user_time = 1;
535 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
537 printf("ECORE_X_ATOM_NET_WM_STRUT\n");
538 bd->client.netwm.fetch.strut = 1;
540 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
542 printf("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL\n");
543 bd->client.netwm.fetch.strut = 1;
545 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
548 bd->client.mwm.fetch.hints = 0;
550 bd->client.netwm.fetch.type = 1;
552 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
554 bd->client.netwm.fetch.state = 1;
557 /* other misc atoms */
558 for (i = 0; i < at_num; i++)
560 /* loop to check for own atoms */
561 if (atoms[i] == E_ATOM_WINDOW_STATE)
563 bd->client.e.fetch.state = 1;
565 /* loop to check for qtopia atoms */
566 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
567 bd->client.qtopia.fetch.soft_menu = 1;
568 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
569 bd->client.qtopia.fetch.soft_menus = 1;
570 /* loop to check for vkbd atoms */
571 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
572 bd->client.vkbd.fetch.state = 1;
573 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
574 bd->client.vkbd.fetch.vkbd = 1;
575 /* loop to check for illume atoms */
576 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
577 bd->client.illume.conformant.fetch.conformant = 1;
578 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
579 bd->client.illume.quickpanel.fetch.state = 1;
580 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
581 bd->client.illume.quickpanel.fetch.quickpanel = 1;
582 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
583 bd->client.illume.quickpanel.fetch.priority.major = 1;
584 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
585 bd->client.illume.quickpanel.fetch.priority.minor = 1;
586 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
587 bd->client.illume.quickpanel.fetch.zone = 1;
588 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
589 bd->client.illume.drag.fetch.locked = 1;
590 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
591 bd->client.illume.drag.fetch.drag = 1;
596 bd->client.border.changed = 1;
598 bd->client.w = att->w;
599 bd->client.h = att->h;
601 bd->w = bd->client.w;
602 bd->h = bd->client.h;
604 bd->resize_mode = RESIZE_NONE;
606 bd->saved.layer = bd->layer;
607 bd->changes.icon = 1;
608 bd->changes.size = 1;
609 bd->changes.shape = 1;
610 bd->changes.shape_input = 1;
612 bd->offer_resistance = 1;
614 /* just to friggin make java happy - we're DELAYING the reparent until
617 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
618 bd->need_reparent = 1;
620 ecore_x_window_border_width_set(win, 0);
621 ecore_x_window_show(bd->event_win);
622 ecore_x_window_show(bd->client.shell_win);
623 bd->shape = e_container_shape_add(con);
629 // bd->zone = e_zone_current_get(con);
630 bd->desk = e_desk_current_get(bd->zone);
631 e_container_border_add(bd);
632 borders = eina_list_append(borders, bd);
633 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
636 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
637 printf("optimisations failing due to bizarre client behavior. will\n");
638 printf("work around.\n");
639 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
640 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
642 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
643 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
644 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
646 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
647 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
648 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
650 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
651 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
652 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
653 e_desk_xy_get(bd->desk, &deskx, &desky);
656 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
658 focus_stack = eina_list_append(focus_stack, bd);
660 bd->pointer = e_pointer_window_new(bd->win, 0);
665 e_border_res_change_geometry_save(E_Border *bd)
668 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
670 if (bd->pre_res_change.valid) return;
671 bd->pre_res_change.valid = 1;
672 bd->pre_res_change.x = bd->x;
673 bd->pre_res_change.y = bd->y;
674 bd->pre_res_change.w = bd->w;
675 bd->pre_res_change.h = bd->h;
676 bd->pre_res_change.saved.x = bd->saved.x;
677 bd->pre_res_change.saved.y = bd->saved.y;
678 bd->pre_res_change.saved.w = bd->saved.w;
679 bd->pre_res_change.saved.h = bd->saved.h;
683 e_border_res_change_geometry_restore(E_Border *bd)
687 unsigned char valid : 1;
696 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
697 if (!bd->pre_res_change.valid) return;
698 if (bd->new_client) return;
700 ecore_x_window_shadow_tree_flush();
701 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
705 e_border_unfullscreen(bd);
706 e_border_fullscreen(bd, e_config->fullscreen_policy);
708 else if (bd->maximized != E_MAXIMIZE_NONE)
713 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
714 e_border_maximize(bd, max);
718 int x, y, w, h, zx, zy, zw, zh;
720 bd->saved.x = bd->pre_res_change.saved.x;
721 bd->saved.y = bd->pre_res_change.saved.y;
722 bd->saved.w = bd->pre_res_change.saved.w;
723 bd->saved.h = bd->pre_res_change.saved.h;
725 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
727 if (bd->saved.w > zw)
729 if ((bd->saved.x + bd->saved.w) > (zx + zw))
730 bd->saved.x = zx + zw - bd->saved.w;
732 if (bd->saved.h > zh)
734 if ((bd->saved.y + bd->saved.h) > (zy + zh))
735 bd->saved.y = zy + zh - bd->saved.h;
737 x = bd->pre_res_change.x;
738 y = bd->pre_res_change.y;
739 w = bd->pre_res_change.w;
740 h = bd->pre_res_change.h;
745 if ((x + w) > (zx + zw))
747 if ((y + h) > (zy + zh))
749 e_border_move_resize(bd, x, y, w, h);
751 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
755 e_border_zone_set(E_Border *bd,
758 E_Event_Border_Zone_Set *ev;
761 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
762 E_OBJECT_CHECK(zone);
763 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
765 if (bd->zone == zone) return;
767 /* if the window does not lie in the new zone, move it so that it does */
768 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
771 /* first guess -- get offset from old zone, and apply to new zone */
772 x = zone->x + (bd->x - bd->zone->x);
773 y = zone->y + (bd->y - bd->zone->y);
775 /* keep window from hanging off bottom and left */
776 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
777 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
779 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
780 if (x < zone->x) x = zone->x;
781 if (y < zone->y) y = zone->y;
783 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
785 /* still not in zone at all, so just move it to closest edge */
786 if (x < zone->x) x = zone->x;
787 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
788 if (y < zone->y) y = zone->y;
789 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
791 e_border_move(bd, x, y);
796 if (bd->desk->zone != bd->zone)
797 e_border_desk_set(bd, e_desk_current_get(bd->zone));
799 ev = E_NEW(E_Event_Border_Zone_Set, 1);
801 e_object_ref(E_OBJECT(bd));
802 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
804 e_object_ref(E_OBJECT(zone));
806 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
808 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
809 e_remember_update(bd);
813 e_border_desk_set(E_Border *bd,
816 E_Event_Border_Desk_Set *ev;
820 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
821 E_OBJECT_CHECK(desk);
822 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
823 if (bd->desk == desk) return;
824 ecore_x_window_shadow_tree_flush();
827 bd->desk->fullscreen_borders--;
828 desk->fullscreen_borders++;
832 e_border_zone_set(bd, desk->zone);
834 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
835 e_hints_window_desktop_set(bd);
837 ev = E_NEW(E_Event_Border_Desk_Set, 1);
839 e_object_ref(E_OBJECT(bd));
840 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
842 e_object_ref(E_OBJECT(old_desk));
843 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
845 if (bd->ignore_first_unmap != 1)
847 if ((bd->desk->visible) || (bd->sticky))
850 e_border_hide(bd, 1);
853 if (e_config->transient.desktop)
857 EINA_LIST_FOREACH(bd->transients, l, child)
859 e_border_desk_set(child, bd->desk);
862 e_remember_update(bd);
866 e_border_show(E_Border *bd)
868 E_Event_Border_Show *ev;
869 unsigned int visible;
872 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
873 if (bd->visible) return;
874 ecore_x_window_shadow_tree_flush();
875 e_container_shape_show(bd->shape);
876 if (!bd->need_reparent)
877 ecore_x_window_show(bd->client.win);
878 e_hints_window_visible_set(bd);
880 bd->changes.visible = 1;
883 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
884 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
886 ev = E_NEW(E_Event_Border_Show, 1);
888 e_object_ref(E_OBJECT(bd));
889 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
890 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
894 e_border_hide(E_Border *bd,
897 unsigned int visible;
900 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
901 if (!bd->visible) return;
902 ecore_x_window_shadow_tree_flush();
904 _e_border_move_end(bd);
905 if (bd->resize_mode != RESIZE_NONE)
907 _e_border_pointer_resize_end(bd);
908 bd->resize_mode = RESIZE_NONE;
909 _e_border_resize_end(bd);
912 e_container_shape_hide(bd->shape);
913 if (!bd->iconic) e_hints_window_hidden_set(bd);
916 bd->changes.visible = 1;
918 if (!bd->need_reparent)
922 e_border_focus_set(bd, 0, 1);
930 con = e_container_current_get(e_manager_current_get());
931 zone = e_zone_current_get(con);
932 desk = e_desk_current_get(zone);
935 (bd->parent->desk == desk) && (bd->parent->modal == bd))
936 e_border_focus_set(bd->parent, 1, 1);
937 else if (e_config->focus_revert_on_hide_or_close)
939 /* When using pointer focus, the border under the
940 * pointer (if any) gets focused, in sloppy/click
941 * focus the last focused window on the current
943 if (e_config->focus_policy == E_FOCUS_MOUSE)
945 pbd = e_border_under_pointer_get(desk, bd);
947 e_border_focus_set(pbd, 1, 1);
949 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
950 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
951 (e_config->focus_policy == E_FOCUS_CLICK))
952 _e_border_latest_stacked_focus(bd);
955 e_desk_last_focused_focus(desk);
961 /* Make sure that this border isn't deleted */
962 bd->await_hide_event++;
966 if (!e_manager_comp_evas_get(bd->zone->container->manager))
967 ecore_x_window_hide(bd->client.win);
972 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
974 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
978 E_Event_Border_Hide *ev;
980 ev = E_NEW(E_Event_Border_Hide, 1);
982 e_object_ref(E_OBJECT(bd));
983 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
984 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
990 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
993 Ecore_Evas *bg_ecore_evas;
999 bg_ecore_evas = bd->bg_ecore_evas;
1001 /* unregister old frame window */
1002 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1003 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1005 e_focus_setdown(bd);
1006 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
1007 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
1009 if (bd->icon_object)
1010 evas_object_del(bd->icon_object);
1012 evas_object_del(bd->bg_object);
1013 e_canvas_del(bg_ecore_evas);
1014 ecore_evas_free(bg_ecore_evas);
1017 e_object_del(E_OBJECT(bd->pointer));
1019 /* create new frame */
1021 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1022 bd->x, bd->y, bd->w, bd->h);
1025 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1026 bd->x, bd->y, bd->w, bd->h);
1027 ecore_x_window_shape_events_select(bd->win, 1);
1030 ecore_x_window_configure(bd->win,
1031 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1032 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1034 win, ECORE_X_WINDOW_STACK_BELOW);
1036 e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
1037 e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
1040 bd->bg_ecore_evas = e_canvas_new(e_config->evas_engine_borders, bd->win,
1041 0, 0, bd->w, bd->h, 1, 0,
1044 e_canvas_add(bd->bg_ecore_evas);
1045 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1047 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1048 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1049 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1051 ecore_x_window_shape_events_select(bd->bg_win, 1);
1053 /* move client with shell win over to new frame */
1054 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1055 bd->client_inset.l, bd->client_inset.t);
1057 bd->pointer = e_pointer_window_new(bd->win, 0);
1059 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1060 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1064 ecore_evas_show(bd->bg_ecore_evas);
1065 ecore_x_window_show(bd->win);
1068 bd->bg_object = edje_object_add(bd->bg_evas);
1069 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1070 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1072 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1074 /* cleanup old frame */
1075 ecore_x_window_free(win);
1079 _e_border_client_move_resize_send(E_Border *bd)
1081 if (bd->internal_ecore_evas)
1082 ecore_evas_managed_move(bd->internal_ecore_evas,
1083 bd->x + bd->fx.x + bd->client_inset.l,
1084 bd->y + bd->fx.y + bd->client_inset.t);
1086 ecore_x_icccm_move_resize_send(bd->client.win,
1087 bd->x + bd->fx.x + bd->client_inset.l,
1088 bd->y + bd->fx.y + bd->client_inset.t,
1094 _e_border_pending_move_resize_add(E_Border *bd,
1101 Eina_Bool without_border,
1102 unsigned int serial)
1104 E_Border_Pending_Move_Resize *pnd;
1106 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1108 pnd->resize = resize;
1110 pnd->without_border = without_border;
1115 pnd->serial = serial;
1116 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1120 _e_border_move_internal(E_Border *bd,
1123 Eina_Bool without_border)
1125 E_Event_Border_Move *ev;
1128 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1130 ecore_x_window_shadow_tree_flush();
1133 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1139 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1141 if (e_config->allow_manip)
1144 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1149 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1155 if (e_config->allow_manip)
1163 x -= bd->client_inset.l;
1164 y -= bd->client_inset.t;
1167 if ((x == bd->x) && (y == bd->y)) return;
1168 bd->pre_res_change.valid = 0;
1172 bd->changes.pos = 1;
1174 if (bd->client.netwm.sync.request)
1176 bd->client.netwm.sync.wait++;
1177 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1180 _e_border_client_move_resize_send(bd);
1181 _e_border_move_update(bd);
1182 ev = E_NEW(E_Event_Border_Move, 1);
1184 e_object_ref(E_OBJECT(bd));
1185 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1186 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1187 _e_border_zone_update(bd);
1191 * Move window to coordinates that already account border decorations.
1193 * This call will consider given position already accounts border
1194 * decorations, so it will not be considered later. This will just
1195 * work properly with borders that have being evaluated and border
1196 * decorations are known (border->client_inset).
1198 * @parm x horizontal position to place window.
1199 * @parm y vertical position to place window.
1201 * @see e_border_move_without_border()
1204 e_border_move(E_Border *bd,
1211 _e_border_move_internal(bd, x, y, 0);
1215 * Move window to coordinates that do not account border decorations yet.
1217 * This call will consider given position does not account border
1218 * decoration, so these values (border->client_inset) will be
1219 * accounted automatically. This is specially useful when it is a new
1220 * client and has not be evaluated yet, in this case
1221 * border->client_inset will be zeroed and no information is known. It
1222 * will mark pending requests so border will be accounted on
1223 * evalutation phase.
1225 * @parm x horizontal position to place window.
1226 * @parm y vertical position to place window.
1228 * @see e_border_move()
1231 e_border_move_without_border(E_Border *bd,
1238 _e_border_move_internal(bd, x, y, 1);
1242 e_border_center(E_Border *bd)
1246 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1248 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1249 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1253 e_border_center_pos_get(E_Border *bd,
1259 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1261 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1262 if (x) *x = zx + (zw - bd->w) / 2;
1263 if (y) *y = zy + (zh - bd->h) / 2;
1267 e_border_fx_offset(E_Border *bd,
1272 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1274 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
1278 bd->changes.pos = 1;
1281 if (bd->moving) _e_border_move_update(bd);
1285 _e_border_move_resize_internal(E_Border *bd,
1290 Eina_Bool without_border,
1293 E_Event_Border_Move *mev;
1294 E_Event_Border_Resize *rev;
1297 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1299 ecore_x_window_shadow_tree_flush();
1303 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
1309 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1311 if (e_config->allow_manip)
1314 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1320 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1327 if (e_config->allow_manip)
1335 x -= bd->client_inset.l;
1336 y -= bd->client_inset.t;
1337 w += (bd->client_inset.l + bd->client_inset.r);
1338 h += (bd->client_inset.t + bd->client_inset.b);
1341 if ((!move || ((x == bd->x) && (y == bd->y))) &&
1342 (w == bd->w) && (h == bd->h))
1345 bd->pre_res_change.valid = 0;
1348 bd->changes.pos = 1;
1354 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
1355 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
1357 if ((bd->shaped) || (bd->client.shaped))
1359 bd->need_shape_merge = 1;
1360 bd->need_shape_export = 1;
1362 if (bd->shaped_input)
1364 bd->need_shape_merge = 1;
1367 if (bd->internal_ecore_evas)
1370 bd->changes.size = 1;
1374 if (resize && bd->client.netwm.sync.request)
1376 bd->client.netwm.sync.wait++;
1377 /* Don't use x and y as supplied to this function, as it is called with 0, 0
1378 * when no move is intended. The border geometry is set above anyways.
1380 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
1381 bd->client.netwm.sync.serial);
1382 ecore_x_netwm_sync_request_send(bd->client.win,
1383 bd->client.netwm.sync.serial++);
1388 bd->changes.size = 1;
1392 _e_border_client_move_resize_send(bd);
1394 _e_border_resize_update(bd);
1397 mev = E_NEW(E_Event_Border_Move, 1);
1399 e_object_ref(E_OBJECT(bd));
1400 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1401 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
1404 rev = E_NEW(E_Event_Border_Resize, 1);
1406 e_object_ref(E_OBJECT(bd));
1407 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
1408 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
1409 _e_border_zone_update(bd);
1413 * Move and resize window to values that already account border decorations.
1415 * This call will consider given values already accounts border
1416 * decorations, so it will not be considered later. This will just
1417 * work properly with borders that have being evaluated and border
1418 * decorations are known (border->client_inset).
1420 * @parm x horizontal position to place window.
1421 * @parm y vertical position to place window.
1422 * @parm w horizontal window size.
1423 * @parm h vertical window size.
1425 * @see e_border_move_resize_without_border()
1428 e_border_move_resize(E_Border *bd,
1437 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
1441 * Move and resize window to values that do not account border decorations yet.
1443 * This call will consider given values already accounts border
1444 * decorations, so it will not be considered later. This will just
1445 * work properly with borders that have being evaluated and border
1446 * decorations are known (border->client_inset).
1448 * @parm x horizontal position to place window.
1449 * @parm y vertical position to place window.
1450 * @parm w horizontal window size.
1451 * @parm h vertical window size.
1453 * @see e_border_move_resize()
1456 e_border_move_resize_without_border(E_Border *bd,
1465 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
1469 * Resize window to values that already account border decorations.
1471 * This call will consider given size already accounts border
1472 * decorations, so it will not be considered later. This will just
1473 * work properly with borders that have being evaluated and border
1474 * decorations are known (border->client_inset).
1476 * @parm w horizontal window size.
1477 * @parm h vertical window size.
1479 * @see e_border_resize_without_border()
1482 e_border_resize(E_Border *bd,
1489 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
1493 * Resize window to values that do not account border decorations yet.
1495 * This call will consider given size does not account border
1496 * decoration, so these values (border->client_inset) will be
1497 * accounted automatically. This is specially useful when it is a new
1498 * client and has not be evaluated yet, in this case
1499 * border->client_inset will be zeroed and no information is known. It
1500 * will mark pending requests so border will be accounted on
1501 * evalutation phase.
1503 * @parm w horizontal window size.
1504 * @parm h vertical window size.
1506 * @see e_border_resize()
1509 e_border_resize_without_border(E_Border *bd,
1516 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
1520 e_border_layer_set(E_Border *bd,
1526 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1528 ecore_x_window_shadow_tree_flush();
1530 raise = e_config->transient.raise;
1532 bd->saved.layer = bd->layer;
1534 if (e_config->transient.layer)
1539 /* We need to set raise to one, else the child wont
1540 * follow to the new layer. It should be like this,
1541 * even if the user usually doesn't want to raise
1544 e_config->transient.raise = 1;
1545 EINA_LIST_FOREACH(bd->transients, l, child)
1547 child->layer = layer;
1551 e_config->transient.raise = raise;
1555 e_border_raise(E_Border *bd)
1557 E_Event_Border_Stack *ev;
1558 E_Border *last = NULL, *child;
1562 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1564 ecore_x_window_shadow_tree_flush();
1566 if (e_config->transient.raise)
1568 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1569 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
1572 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1574 /* Don't stack iconic transients. If the user wants these shown,
1575 * thats another option.
1580 e_border_stack_below(child, last);
1585 /* First raise the border to find out which border we will end up above */
1586 above = e_container_border_raise(child);
1590 /* We ended up above a border, now we must stack this border to
1591 * generate the stacking event, and to check if this transient
1592 * has other transients etc.
1594 e_border_stack_above(child, above);
1598 /* If we didn't end up above any border, we are on the bottom! */
1599 e_border_lower(child);
1605 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1609 EINA_LIST_FOREACH(bd->transients, l, child)
1611 /* Don't stack iconic transients. If the user wants these shown,
1612 * thats another option.
1616 if (!last) last = child;
1617 e_border_raise (child);
1624 ev = E_NEW(E_Event_Border_Stack, 1);
1626 e_object_ref(E_OBJECT(bd));
1630 e_container_border_stack_below(bd, last);
1632 e_object_ref(E_OBJECT(last));
1633 ev->type = E_STACKING_BELOW;
1639 /* If we don't have any children, raise this border */
1640 above = e_container_border_raise(bd);
1641 e_border_raise_latest_set(bd);
1644 /* We ended up above a border */
1646 e_object_ref(E_OBJECT(above));
1647 ev->type = E_STACKING_ABOVE;
1651 /* No border to raise above, same as a lower! */
1653 ev->type = E_STACKING_ABOVE;
1657 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1658 e_remember_update(bd);
1662 e_border_lower(E_Border *bd)
1664 E_Event_Border_Stack *ev;
1665 E_Border *last = NULL, *child;
1669 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1671 ecore_x_window_shadow_tree_flush();
1673 if (e_config->transient.lower)
1675 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1676 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
1679 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1681 /* Don't stack iconic transients. If the user wants these shown,
1682 * thats another option.
1687 e_border_stack_below(child, last);
1692 /* First lower the border to find out which border we will end up below */
1693 below = e_container_border_lower(child);
1697 /* We ended up below a border, now we must stack this border to
1698 * generate the stacking event, and to check if this transient
1699 * has other transients etc.
1701 e_border_stack_below(child, below);
1705 /* If we didn't end up below any border, we are on top! */
1706 e_border_raise(child);
1712 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1716 EINA_LIST_FOREACH(bd->transients, l, child)
1718 /* Don't stack iconic transients. If the user wants these shown,
1719 * thats another option.
1723 e_border_lower (child);
1731 ev = E_NEW(E_Event_Border_Stack, 1);
1733 e_object_ref(E_OBJECT(bd));
1737 e_container_border_stack_below(bd, last);
1739 e_object_ref(E_OBJECT(last));
1740 ev->type = E_STACKING_BELOW;
1746 /* If we don't have any children, lower this border */
1747 below = e_container_border_lower(bd);
1750 /* We ended up below a border */
1752 e_object_ref(E_OBJECT(below));
1753 ev->type = E_STACKING_BELOW;
1757 /* No border to hide under, same as a raise! */
1759 ev->type = E_STACKING_BELOW;
1763 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1764 e_remember_update(bd);
1768 e_border_stack_above(E_Border *bd,
1771 /* TODO: Should stack above allow the border to change level */
1772 E_Event_Border_Stack *ev;
1773 E_Border *last = NULL, *child;
1777 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1779 ecore_x_window_shadow_tree_flush();
1781 if (e_config->transient.raise)
1783 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1785 /* Don't stack iconic transients. If the user wants these shown,
1786 * thats another option.
1791 e_border_stack_below(child, last);
1793 e_border_stack_above(child, above);
1799 ev = E_NEW(E_Event_Border_Stack, 1);
1801 e_object_ref(E_OBJECT(bd));
1805 e_container_border_stack_below(bd, last);
1807 e_object_ref(E_OBJECT(last));
1808 ev->type = E_STACKING_BELOW;
1812 e_container_border_stack_above(bd, above);
1814 e_object_ref(E_OBJECT(above));
1815 ev->type = E_STACKING_ABOVE;
1818 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1819 e_remember_update(bd);
1823 e_border_stack_below(E_Border *bd,
1826 /* TODO: Should stack below allow the border to change level */
1827 E_Event_Border_Stack *ev;
1828 E_Border *last = NULL, *child;
1832 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1834 ecore_x_window_shadow_tree_flush();
1836 if (e_config->transient.lower)
1838 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1840 /* Don't stack iconic transients. If the user wants these shown,
1841 * thats another option.
1846 e_border_stack_below(child, last);
1848 e_border_stack_below(child, below);
1854 ev = E_NEW(E_Event_Border_Stack, 1);
1856 e_object_ref(E_OBJECT(bd));
1860 e_container_border_stack_below(bd, last);
1862 e_object_ref(E_OBJECT(last));
1863 ev->type = E_STACKING_BELOW;
1867 e_container_border_stack_below(bd, below);
1869 e_object_ref(E_OBJECT(below));
1870 ev->type = E_STACKING_BELOW;
1873 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1874 e_remember_update(bd);
1878 e_border_focus_latest_set(E_Border *bd)
1880 focus_stack = eina_list_remove(focus_stack, bd);
1881 focus_stack = eina_list_prepend(focus_stack, bd);
1885 e_border_raise_latest_set(E_Border *bd)
1887 raise_stack = eina_list_remove(raise_stack, bd);
1888 raise_stack = eina_list_prepend(raise_stack, bd);
1892 * Sets the focus to the given border if necessary
1893 * There are 3 cases of different focus_policy-configurations:
1895 * - E_FOCUS_CLICK: just set the focus, the most simple one
1897 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
1898 * warp the pointer to the window. If this fails (because
1899 * the pointer is already in the window), just set the focus.
1901 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
1902 * last window which was focused, if the mouse is on the
1903 * desktop. So, we need to look if there is another window
1904 * under the pointer and warp to pointer to the right
1905 * one if so (also, we set the focus afterwards). In case
1906 * there is no window under pointer, the pointer is on the
1907 * desktop and so we just set the focus.
1910 * This function is to be called when setting the focus was not
1911 * explicitly triggered by the user (by moving the mouse or
1912 * clicking for example), but implicitly (by closing a window,
1913 * the last focused window should get focus).
1917 e_border_focus_set_with_pointer(E_Border *bd)
1919 #ifdef PRINT_LOTS_OF_DEBUG
1920 E_PRINT_BORDER_INFO(bd);
1922 /* note: this is here as it seems there are enough apps that do not even
1923 * expect us to emulate a look of focus but not actually set x input
1924 * focus as we do - so simply abort any focuse set on such windows */
1925 /* be strict about accepting focus hint */
1926 if ((!bd->client.icccm.accepts_focus) &&
1927 (!bd->client.icccm.take_focus)) return;
1928 if (bd->lock_focus_out) return;
1930 /* Try to grab the pointer to make sure it's not "in use" */
1932 * this causes problems as the grab can cause an in/out event (by grab) that
1933 * normally would be like a grab from a menu or something else and e gets into
1934 * a self-feeding loop. sorry - can't grab :(
1935 if (!ecore_x_pointer_grab(bd->zone->container->win))
1939 if (e_config->focus_policy == E_FOCUS_SLOPPY)
1941 if (e_border_under_pointer_get(bd->desk, bd))
1943 if (!e_border_pointer_warp_to_center(bd))
1945 e_border_focus_set(bd, 1, 1);
1950 e_border_focus_set(bd, 1, 1);
1953 else if (e_config->focus_policy == E_FOCUS_CLICK)
1955 e_border_focus_set(bd, 1, 1);
1958 if (!e_border_pointer_warp_to_center(bd))
1960 e_border_focus_set(bd, 1, 1);
1963 //ecore_x_pointer_ungrab();
1967 e_border_focus_set(E_Border *bd,
1971 E_Border *unfocus = NULL;
1974 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1975 /* note: this is here as it seems there are enough apps that do not even
1976 * expect us to emulate a look of focus but not actually set x input
1977 * focus as we do - so simply abort any focuse set on such windows */
1978 /* be strict about accepting focus hint */
1979 if ((!bd->client.icccm.accepts_focus) &&
1980 (!bd->client.icccm.take_focus))
1982 if ((set) && (focus) && (bd->lock_focus_out)) return;
1983 /* dont focus an iconified window. that's silly! */
1992 /* FIXME: hack for deskflip animation:
1993 * dont update focus when sliding previous desk */
1994 if ((!bd->sticky) && (bd->desk != e_desk_current_get(bd->desk->zone)))
1998 /* if !set and no other window is focused 'revert focus when lost' */
2001 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2003 e_border_focus_set(bd->modal, focus, set);
2006 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2008 e_border_focus_set(bd->leader->modal, focus, set);
2011 #ifdef INOUTDEBUG_FOCUS
2012 printf("%s focus set %d %d\n", e_border_name_get(bd), focus, set);
2015 if ((set) && (focus))
2017 if (bd->visible && bd->changes.visible)
2023 if ((!bd->focused) || (focus_next && (bd != eina_list_data_get(focus_next))))
2027 if ((l = eina_list_data_find_list(focus_next, bd)))
2028 focus_next = eina_list_promote_list(focus_next, l);
2030 focus_next = eina_list_prepend(focus_next, bd);
2034 else if ((focus) && (!bd->focused))
2036 E_Event_Border_Focus_In *ev;
2044 e_focus_event_focus_in(bd);
2045 e_border_focus_latest_set(bd);
2046 e_hints_active_window_set(bd->zone->container->manager, bd);
2048 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2049 if (bd->icon_object)
2050 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2052 ev = E_NEW(E_Event_Border_Focus_In, 1);
2054 e_object_ref(E_OBJECT(bd));
2056 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2057 _e_border_event_border_focus_in_free, NULL);
2059 else if ((!focus) && (bd->want_focus))
2061 if ((bd->visible) && (bd->changes.visible))
2068 else if ((!focus) && (bd->focused))
2072 /* should always be the case. anyway */
2077 e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE);
2081 (!e_object_is_del(E_OBJECT(unfocus)) &&
2082 (e_object_ref_get(E_OBJECT(unfocus)) > 0)))
2084 E_Event_Border_Focus_Out *ev;
2088 e_focus_event_focus_out(bd);
2090 if (bd->raise_timer)
2091 ecore_timer_del(bd->raise_timer);
2092 bd->raise_timer = NULL;
2094 edje_object_signal_emit(bd->bg_object, "e,state,unfocused", "e");
2095 if (bd->icon_object)
2096 edje_object_signal_emit(bd->icon_object, "e,state,unfocused", "e");
2098 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2100 e_object_ref(E_OBJECT(bd));
2102 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2103 _e_border_event_border_focus_out_free, NULL);
2108 e_border_shade(E_Border *bd,
2111 E_Event_Border_Resize *ev;
2114 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2115 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2116 ((bd->maximized) && (!e_config->allow_manip))) return;
2117 if ((bd->client.border.name) &&
2118 (!strcmp("borderless", bd->client.border.name))) return;
2120 ecore_x_window_shadow_tree_flush();
2122 bd->shade.x = bd->x;
2123 bd->shade.y = bd->y;
2124 bd->shade.dir = dir;
2126 e_hints_window_shaded_set(bd, 1);
2127 e_hints_window_shade_direction_set(bd, dir);
2129 if (e_config->border_shade_animate)
2131 bd->shade.start = ecore_loop_time_get();
2133 bd->changes.shading = 1;
2136 if (bd->shade.dir == E_DIRECTION_UP ||
2137 bd->shade.dir == E_DIRECTION_LEFT)
2138 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2140 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2142 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2143 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
2147 if (bd->shade.dir == E_DIRECTION_UP)
2149 bd->h = bd->client_inset.t + bd->client_inset.b;
2151 else if (bd->shade.dir == E_DIRECTION_DOWN)
2153 bd->h = bd->client_inset.t + bd->client_inset.b;
2154 bd->y = bd->y + bd->client.h;
2155 bd->changes.pos = 1;
2157 else if (bd->shade.dir == E_DIRECTION_LEFT)
2159 bd->w = bd->client_inset.l + bd->client_inset.r;
2161 else if (bd->shade.dir == E_DIRECTION_RIGHT)
2163 bd->w = bd->client_inset.l + bd->client_inset.r;
2164 bd->x = bd->x + bd->client.w;
2165 bd->changes.pos = 1;
2168 if ((bd->shaped) || (bd->client.shaped))
2170 bd->need_shape_merge = 1;
2171 bd->need_shape_export = 1;
2173 if (bd->shaped_input)
2175 bd->need_shape_merge = 1;
2178 bd->changes.size = 1;
2180 bd->changes.shaded = 1;
2182 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
2183 e_border_frame_recalc(bd);
2184 ev = E_NEW(E_Event_Border_Resize, 1);
2186 /* The resize is added in the animator when animation complete */
2187 /* For non-animated, we add it immediately with the new size */
2188 e_object_ref(E_OBJECT(bd));
2189 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2190 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
2193 e_remember_update(bd);
2197 e_border_unshade(E_Border *bd,
2200 E_Event_Border_Resize *ev;
2203 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2204 if ((!bd->shaded) || (bd->shading))
2207 ecore_x_window_shadow_tree_flush();
2209 bd->shade.dir = dir;
2211 e_hints_window_shaded_set(bd, 0);
2212 e_hints_window_shade_direction_set(bd, dir);
2214 if (bd->shade.dir == E_DIRECTION_UP ||
2215 bd->shade.dir == E_DIRECTION_LEFT)
2217 bd->shade.x = bd->x;
2218 bd->shade.y = bd->y;
2222 bd->shade.x = bd->x - bd->client.w;
2223 bd->shade.y = bd->y - bd->client.h;
2225 if (e_config->border_shade_animate)
2227 bd->shade.start = ecore_loop_time_get();
2229 bd->changes.shading = 1;
2232 if (bd->shade.dir == E_DIRECTION_UP)
2234 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2235 ecore_x_window_move_resize(bd->client.win, 0,
2236 bd->h - (bd->client_inset.t + bd->client_inset.b) -
2238 bd->client.w, bd->client.h);
2240 else if (bd->shade.dir == E_DIRECTION_LEFT)
2242 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2243 ecore_x_window_move_resize(bd->client.win,
2244 bd->w - (bd->client_inset.l + bd->client_inset.r) -
2246 0, bd->client.w, bd->client.h);
2249 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2251 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2252 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
2256 if (bd->shade.dir == E_DIRECTION_UP)
2258 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
2260 else if (bd->shade.dir == E_DIRECTION_DOWN)
2262 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
2263 bd->y = bd->y - bd->client.h;
2264 bd->changes.pos = 1;
2266 else if (bd->shade.dir == E_DIRECTION_LEFT)
2268 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
2270 else if (bd->shade.dir == E_DIRECTION_RIGHT)
2272 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
2273 bd->x = bd->x - bd->client.w;
2274 bd->changes.pos = 1;
2276 if ((bd->shaped) || (bd->client.shaped))
2278 bd->need_shape_merge = 1;
2279 bd->need_shape_export = 1;
2281 if (bd->shaped_input)
2283 bd->need_shape_merge = 1;
2286 bd->changes.size = 1;
2288 bd->changes.shaded = 1;
2290 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
2291 e_border_frame_recalc(bd);
2292 ev = E_NEW(E_Event_Border_Resize, 1);
2294 /* The resize is added in the animator when animation complete */
2295 /* For non-animated, we add it immediately with the new size */
2296 e_object_ref(E_OBJECT(bd));
2297 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2298 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
2301 e_remember_update(bd);
2305 e_border_maximize(E_Border *bd,
2309 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2311 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
2313 if ((bd->shaded) || (bd->shading)) return;
2314 ecore_x_window_shadow_tree_flush();
2316 e_border_unfullscreen(bd);
2317 /* Only allow changes in vertical/ horizontal maximization */
2318 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
2319 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
2322 bd->need_maximize = 1;
2323 bd->maximized &= ~E_MAXIMIZE_TYPE;
2324 bd->maximized |= max;
2333 zx = zy = zw = zh = 0;
2335 bd->pre_res_change.valid = 0;
2336 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
2338 /* Horizontal hasn't been set */
2339 bd->saved.x = bd->x - bd->zone->x;
2340 bd->saved.w = bd->w;
2342 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
2344 /* Vertical hasn't been set */
2345 bd->saved.y = bd->y - bd->zone->y;
2346 bd->saved.h = bd->h;
2348 bd->saved.zone = bd->zone->num;
2349 e_hints_window_size_set(bd);
2352 switch (max & E_MAXIMIZE_TYPE)
2354 case E_MAXIMIZE_NONE:
2356 max = E_MAXIMIZE_NONE;
2359 case E_MAXIMIZE_FULLSCREEN:
2365 Evas_Coord cx, cy, cw, ch;
2367 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
2369 evas_object_resize(bd->bg_object, w, h);
2370 edje_object_calc_force(bd->bg_object);
2371 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
2372 bd->client_inset.l = cx;
2373 bd->client_inset.r = w - (cx + cw);
2374 bd->client_inset.t = cy;
2375 bd->client_inset.b = h - (cy + ch);
2376 ecore_x_netwm_frame_size_set(bd->client.win,
2377 bd->client_inset.l, bd->client_inset.r,
2378 bd->client_inset.t, bd->client_inset.b);
2379 ecore_x_e_frame_size_set(bd->client.win,
2380 bd->client_inset.l, bd->client_inset.r,
2381 bd->client_inset.t, bd->client_inset.b);
2383 e_border_resize_limit(bd, &w, &h);
2384 /* center x-direction */
2385 x1 = bd->zone->x + (bd->zone->w - w) / 2;
2386 /* center y-direction */
2387 y1 = bd->zone->y + (bd->zone->h - h) / 2;
2389 if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
2390 e_border_move_resize(bd, x1, y1, w, h);
2391 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2392 e_border_move_resize(bd, bd->x, y1, bd->w, h);
2393 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2394 e_border_move_resize(bd, x1, bd->y, w, bd->h);
2397 case E_MAXIMIZE_SMART:
2398 case E_MAXIMIZE_EXPAND:
2400 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
2412 if (bd->x < zx) // window left not useful coordinates
2414 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
2415 x1 = zx + zw - bd->w;
2416 else // window normal position
2419 if (bd->y < zy) // window top not useful coordinates
2421 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
2422 y1 = zy + zh - bd->h;
2423 else // window normal position
2426 if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
2427 e_border_move_resize(bd, zx, zy, zw, zh);
2428 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2429 e_border_move_resize(bd, x1, zy, w, zh);
2430 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2431 e_border_move_resize(bd, zx, y1, zw, h);
2432 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
2435 case E_MAXIMIZE_FILL:
2438 x2 = bd->zone->x + bd->zone->w;
2439 y2 = bd->zone->y + bd->zone->h;
2441 /* walk through all shelves */
2442 e_maximize_border_shelf_fill(bd, &x1, &y1, &x2, &y2, max);
2444 /* walk through all windows */
2445 e_maximize_border_border_fill(bd, &x1, &y1, &x2, &y2, max);
2451 e_border_resize_limit(bd, &w, &h);
2452 /* center x-direction */
2453 x1 = x1 + (pw - w) / 2;
2454 /* center y-direction */
2455 y1 = y1 + (ph - h) / 2;
2456 if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
2457 e_border_move_resize(bd, x1, y1, w, h);
2458 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2459 e_border_move_resize(bd, bd->x, y1, bd->w, h);
2460 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2461 e_border_move_resize(bd, x1, bd->y, w, bd->h);
2465 /* Remove previous type */
2466 bd->maximized &= ~E_MAXIMIZE_TYPE;
2467 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
2468 bd->maximized |= max;
2470 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
2471 bd->maximized & E_MAXIMIZE_VERTICAL);
2473 e_remember_update(bd);
2477 e_border_unmaximize(E_Border *bd,
2481 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2482 if (!(max & E_MAXIMIZE_DIRECTION))
2484 printf("BUG: Unmaximize call without direction!\n");
2488 if ((bd->shaded) || (bd->shading)) return;
2489 ecore_x_window_shadow_tree_flush();
2490 /* Remove directions not used */
2491 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
2492 /* Can only remove existing maximization directions */
2494 if (bd->maximized & E_MAXIMIZE_TYPE)
2496 bd->pre_res_change.valid = 0;
2497 bd->need_maximize = 0;
2499 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
2503 Evas_Coord cx, cy, cw, ch;
2505 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
2507 evas_object_resize(bd->bg_object, 1000, 1000);
2508 edje_object_calc_force(bd->bg_object);
2509 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
2510 bd->client_inset.l = cx;
2511 bd->client_inset.r = 1000 - (cx + cw);
2512 bd->client_inset.t = cy;
2513 bd->client_inset.b = 1000 - (cy + ch);
2514 ecore_x_netwm_frame_size_set(bd->client.win,
2515 bd->client_inset.l, bd->client_inset.r,
2516 bd->client_inset.t, bd->client_inset.b);
2517 ecore_x_e_frame_size_set(bd->client.win,
2518 bd->client_inset.l, bd->client_inset.r,
2519 bd->client_inset.t, bd->client_inset.b);
2522 bd->maximized = E_MAXIMIZE_NONE;
2523 _e_border_move_resize_internal(bd,
2524 bd->zone->x + bd->saved.x,
2525 bd->zone->y + bd->saved.y,
2526 bd->saved.w, bd->saved.h, 0, 1);
2527 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
2528 e_hints_window_size_unset(bd);
2539 if (max & E_MAXIMIZE_VERTICAL)
2541 /* Remove vertical */
2543 y = bd->saved.y + bd->zone->y;
2544 bd->saved.h = bd->saved.y = 0;
2545 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
2547 if (max & E_MAXIMIZE_HORIZONTAL)
2549 /* Remove horizontal */
2551 x = bd->saved.x + bd->zone->x;
2552 bd->saved.w = bd->saved.x = 0;
2553 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
2556 e_border_resize_limit(bd, &w, &h);
2558 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
2560 bd->maximized = E_MAXIMIZE_NONE;
2561 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2562 e_hints_window_size_unset(bd);
2563 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
2567 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2568 e_hints_window_size_set(bd);
2571 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
2572 bd->maximized & E_MAXIMIZE_VERTICAL);
2574 e_remember_update(bd);
2578 e_border_fullscreen(E_Border *bd,
2579 E_Fullscreen policy)
2581 E_Event_Border_Fullscreen *ev;
2584 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2586 if ((bd->shaded) || (bd->shading)) return;
2587 ecore_x_window_shadow_tree_flush();
2590 bd->need_fullscreen = 1;
2593 if (!bd->fullscreen)
2595 bd->pre_res_change.valid = 0;
2597 bd->saved.x = bd->x - bd->zone->x;
2598 bd->saved.y = bd->y - bd->zone->y;
2599 bd->saved.w = bd->client.w;
2600 bd->saved.h = bd->client.h;
2601 bd->saved.maximized = bd->maximized;
2602 bd->saved.zone = bd->zone->num;
2605 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
2606 e_hints_window_size_set(bd);
2608 bd->client_inset.l = 0;
2609 bd->client_inset.r = 0;
2610 bd->client_inset.t = 0;
2611 bd->client_inset.b = 0;
2613 bd->desk->fullscreen_borders++;
2615 /* e_zone_fullscreen_set(bd->zone, 1); */
2616 if (!e_config->allow_above_fullscreen)
2617 e_border_layer_set(bd, 200);
2619 if ((eina_list_count(bd->zone->container->zones) > 1) || (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
2621 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
2623 else if (policy == E_FULLSCREEN_ZOOM)
2625 Ecore_X_Randr_Screen_Size_MM *sizes;
2626 int num_sizes, i, best_size_index = 0;
2628 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root, &screen_size.width, &screen_size.height, NULL, NULL, NULL);
2629 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root, &num_sizes);
2632 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
2633 int best_dist = INT_MAX, dist;
2635 for (i = 0; i < num_sizes; i++)
2637 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
2639 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
2640 if (dist < best_dist)
2642 best_size.width = sizes[i].width;
2643 best_size.height = sizes[i].height;
2645 best_size_index = i;
2649 if (((best_size.width != -1) && (best_size.height != -1)) &&
2650 ((best_size.width != screen_size.width) ||
2651 (best_size.height != screen_size.height)))
2653 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
2655 screen_size_index = best_size_index;
2656 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
2660 screen_size.width = -1;
2661 screen_size.height = -1;
2662 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
2667 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
2671 e_hints_window_fullscreen_set(bd, 1);
2672 e_hints_window_size_unset(bd);
2673 bd->client.border.changed = 1;
2677 ev = E_NEW(E_Event_Border_Fullscreen, 1);
2679 e_object_ref(E_OBJECT(bd));
2680 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
2681 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
2683 e_remember_update(bd);
2687 e_border_unfullscreen(E_Border *bd)
2689 E_Event_Border_Unfullscreen *ev;
2692 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2693 if ((bd->shaded) || (bd->shading)) return;
2694 ecore_x_window_shadow_tree_flush();
2697 bd->pre_res_change.valid = 0;
2699 bd->need_fullscreen = 0;
2700 bd->desk->fullscreen_borders--;
2702 if ((screen_size.width != -1) && (screen_size.height != -1))
2704 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root, screen_size_index);
2705 screen_size.width = -1;
2706 screen_size.height = -1;
2708 e_border_move_resize(bd,
2709 bd->saved.x + bd->zone->x,
2710 bd->saved.y + bd->zone->y,
2711 bd->saved.w, bd->saved.h);
2713 if (bd->saved.maximized)
2714 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
2715 bd->saved.maximized);
2717 e_border_layer_set(bd, bd->saved.layer);
2719 e_hints_window_fullscreen_set(bd, 0);
2720 bd->client.border.changed = 1;
2724 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
2726 e_object_ref(E_OBJECT(bd));
2727 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
2728 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
2730 e_remember_update(bd);
2734 e_border_iconify(E_Border *bd)
2736 E_Event_Border_Iconify *ev;
2737 unsigned int iconic;
2740 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2741 if (bd->shading) return;
2742 ecore_x_window_shadow_tree_flush();
2746 e_border_hide(bd, 1);
2747 if (bd->fullscreen) bd->desk->fullscreen_borders--;
2748 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
2751 e_hints_window_iconic_set(bd);
2752 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
2754 ev = E_NEW(E_Event_Border_Iconify, 1);
2756 e_object_ref(E_OBJECT(bd));
2757 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
2758 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
2760 if (e_config->transient.iconify)
2765 EINA_LIST_FOREACH(bd->transients, l, child)
2767 e_border_iconify(child);
2770 e_remember_update(bd);
2774 e_border_uniconify(E_Border *bd)
2777 E_Event_Border_Uniconify *ev;
2778 unsigned int iconic;
2781 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2782 if (bd->shading) return;
2783 ecore_x_window_shadow_tree_flush();
2788 if (bd->fullscreen) bd->desk->fullscreen_borders++;
2789 desk = e_desk_current_get(bd->desk->zone);
2790 e_border_desk_set(bd, desk);
2792 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
2795 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
2797 ev = E_NEW(E_Event_Border_Uniconify, 1);
2799 e_object_ref(E_OBJECT(bd));
2800 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
2801 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
2803 if (e_config->transient.iconify)
2808 EINA_LIST_FOREACH(bd->transients, l, child)
2810 e_border_uniconify(child);
2813 e_remember_update(bd);
2817 e_border_stick(E_Border *bd)
2819 E_Event_Border_Stick *ev;
2822 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2823 if (bd->sticky) return;
2825 e_hints_window_sticky_set(bd, 1);
2828 if (e_config->transient.desktop)
2832 EINA_LIST_FOREACH(bd->transients, l, child)
2835 e_hints_window_sticky_set(child, 1);
2836 e_border_show(child);
2840 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
2841 ev = E_NEW(E_Event_Border_Stick, 1);
2843 e_object_ref(E_OBJECT(bd));
2844 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
2845 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
2846 e_remember_update(bd);
2850 e_border_unstick(E_Border *bd)
2852 E_Event_Border_Unstick *ev;
2855 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2856 /* Set the desk before we unstick the border */
2857 if (!bd->sticky) return;
2859 e_hints_window_sticky_set(bd, 0);
2861 if (e_config->transient.desktop)
2865 EINA_LIST_FOREACH(bd->transients, l, child)
2868 e_hints_window_sticky_set(child, 0);
2872 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
2873 ev = E_NEW(E_Event_Border_Unstick, 1);
2875 e_object_ref(E_OBJECT(bd));
2876 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
2877 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
2879 e_border_desk_set(bd, e_desk_current_get(bd->zone));
2880 e_remember_update(bd);
2884 e_border_pinned_set(E_Border *bd,
2892 bd->borderless = set;
2893 bd->user_skip_winlist = set;
2897 stacking = E_STACKING_BELOW;
2902 stacking = E_STACKING_NONE;
2905 e_border_layer_set(bd, layer);
2906 e_hints_window_stacking_set(bd, stacking);
2908 bd->client.border.changed = 1;
2914 e_border_find_by_client_window(Ecore_X_Window win)
2918 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
2919 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
2920 (bd->client.win == win))
2926 e_border_find_all_by_client_window(Ecore_X_Window win)
2930 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
2931 if ((bd) && (bd->client.win == win))
2937 e_border_find_by_frame_window(Ecore_X_Window win)
2941 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
2942 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
2943 (bd->bg_win == win))
2949 e_border_find_by_window(Ecore_X_Window win)
2953 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
2954 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
2961 e_border_find_by_alarm(Ecore_X_Sync_Alarm alarm)
2966 EINA_LIST_FOREACH(borders, l, bd)
2968 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
2969 (bd->client.netwm.sync.alarm == alarm))
2976 e_border_focused_get(void)
2982 _e_border_shape_input_rectangle_set(E_Border* bd)
2986 if ((bd->visible) && (bd->shaped_input))
2988 Ecore_X_Rectangle rects[4];
2989 Ecore_X_Window twin, twin2;
2992 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
2993 0, 0, bd->w, bd->h);
2996 rects[0].width = bd->w;
2997 rects[0].height = bd->client_inset.t;
2999 rects[1].y = bd->client_inset.t;
3000 rects[1].width = bd->client_inset.l;
3001 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3002 rects[2].x = bd->w - bd->client_inset.r;
3003 rects[2].y = bd->client_inset.t;
3004 rects[2].width = bd->client_inset.r;
3005 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3007 rects[3].y = bd->h - bd->client_inset.b;
3008 rects[3].width = bd->w;
3009 rects[3].height = bd->client_inset.b;
3010 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
3012 twin2 = ecore_x_window_override_new
3013 (bd->zone->container->scratch_win, 0, 0,
3014 bd->w - bd->client_inset.l - bd->client_inset.r,
3015 bd->h - bd->client_inset.t - bd->client_inset.b);
3018 if ((bd->shading) || (bd->shaded))
3020 if (bd->shade.dir == E_DIRECTION_UP)
3021 y = bd->h - bd->client_inset.t - bd->client_inset.b -
3023 else if (bd->shade.dir == E_DIRECTION_LEFT)
3024 x = bd->w - bd->client_inset.l - bd->client_inset.r -
3027 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
3029 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
3030 bd->w - bd->client_inset.l - bd->client_inset.r,
3031 bd->h - bd->client_inset.t - bd->client_inset.b);
3032 ecore_x_window_shape_input_window_add_xy(twin, twin2,
3034 bd->client_inset.t);
3035 ecore_x_window_shape_input_window_set(bd->win, twin);
3036 ecore_x_window_free(twin2);
3037 ecore_x_window_free(twin);
3041 if (bd->visible) // not shaped input
3043 if (!bd->comp_hidden)
3044 ecore_x_composite_window_events_enable(bd->win);
3046 ecore_x_composite_window_events_disable(bd->win);
3050 if (!e_manager_comp_evas_get(bd->zone->container->manager))
3051 ecore_x_composite_window_events_enable(bd->win);
3053 ecore_x_composite_window_events_disable(bd->win);
3059 e_border_idler_before(void)
3068 EINA_LIST_FOREACH(e_manager_list(), ml, man)
3070 EINA_LIST_FOREACH(man->containers, cl, con)
3075 // pass 1 - eval0. fetch properties on new or on change and
3076 // call hooks to decide what to do - maybe move/resize
3077 bl = e_container_border_list_last(con);
3078 while ((bd = e_container_border_list_prev(bl)))
3080 if (bd->changed) _e_border_eval0(bd);
3082 e_container_border_list_free(bl);
3084 // layout hook - this is where a hook gets to figure out what to
3086 _e_border_container_layout_hook(con);
3088 // pass 2 - show windows needing show
3089 bl = e_container_border_list_last(con);
3090 while ((bd = e_container_border_list_prev(bl)))
3092 if ((bd->changes.visible) && (bd->visible) &&
3093 (!bd->new_client) && (!bd->changes.pos) &&
3094 (!bd->changes.size))
3097 bd->changes.visible = 0;
3100 e_container_border_list_free(bl);
3102 // pass 3 - hide windows needing hide and eval (main eval)
3103 bl = e_container_border_list_first(con);
3104 while ((bd = e_container_border_list_next(bl)))
3106 if (e_object_is_del(E_OBJECT(bd))) continue;
3108 if ((bd->changes.visible) && (!bd->visible))
3111 bd->changes.visible = 0;
3114 if (bd->changed) _e_border_eval(bd);
3116 if ((bd->changes.visible) && (bd->visible))
3119 bd->changes.visible = 0;
3122 e_container_border_list_free(bl);
3128 E_Border *bd = NULL, *bd2;
3130 EINA_LIST_FREE(focus_next, bd2)
3131 if ((!bd) && (bd2->visible)) bd = bd2;
3135 /* TODO revert focus when lost here ? */
3138 #ifdef INOUTDEBUG_FOCUS
3139 printf("%s idler focus\n", e_border_name_get(bd));
3144 focus_time = ecore_x_current_time_get();
3146 if ((bd->client.icccm.take_focus) &&
3147 (bd->client.icccm.accepts_focus))
3149 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
3150 /* TODO what if the client doesnt took focus ? */
3152 else if (!bd->client.icccm.accepts_focus)
3154 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
3156 else if (!bd->client.icccm.take_focus)
3158 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
3159 /* e_border_focus_set(bd, 1, 0); */
3165 e_border_client_list()
3167 /* FIXME: This should be a somewhat ordered list */
3171 static Ecore_X_Window action_input_win = 0;
3172 static E_Border *action_border = NULL;
3173 static Ecore_Event_Handler *action_handler_key = NULL;
3174 static Ecore_Event_Handler *action_handler_mouse = NULL;
3175 static Ecore_Timer *action_timer = NULL;
3176 static Ecore_X_Rectangle action_orig;
3179 _e_border_show(E_Border *bd)
3181 ecore_evas_show(bd->bg_ecore_evas);
3189 if (!bd->comp_hidden)
3191 _e_border_shape_input_rectangle_set(bd);
3193 // ecore_x_composite_window_events_enable(bd->win);
3194 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
3197 ecore_x_window_show(bd->win);
3201 _e_border_hide(E_Border *bd)
3203 if (!e_manager_comp_evas_get(bd->zone->container->manager))
3205 ecore_x_window_hide(bd->win);
3206 ecore_evas_hide(bd->bg_ecore_evas);
3210 ecore_x_composite_window_events_disable(bd->win);
3211 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
3216 _e_border_action_input_win_del(void)
3218 if (!action_input_win)
3221 e_grabinput_release(action_input_win, action_input_win);
3222 ecore_x_window_free(action_input_win);
3223 action_input_win = 0;
3228 _e_border_action_input_win_new(E_Border *bd)
3230 if (!action_input_win)
3232 Ecore_X_Window parent = bd->zone->container->win;
3233 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
3234 if (!action_input_win)
3238 ecore_x_window_show(action_input_win);
3239 if (e_grabinput_get(action_input_win, 0, action_input_win))
3242 _e_border_action_input_win_del();
3247 _e_border_action_finish(void)
3249 _e_border_action_input_win_del();
3253 ecore_timer_del(action_timer);
3254 action_timer = NULL;
3257 if (action_handler_key)
3259 ecore_event_handler_del(action_handler_key);
3260 action_handler_key = NULL;
3263 if (action_handler_mouse)
3265 ecore_event_handler_del(action_handler_mouse);
3266 action_handler_mouse = NULL;
3269 action_border = NULL;
3273 _e_border_action_init(E_Border *bd)
3275 action_orig.x = bd->x;
3276 action_orig.y = bd->y;
3277 action_orig.width = bd->w;
3278 action_orig.height = bd->h;
3284 _e_border_action_restore_orig(E_Border *bd)
3286 if (action_border != bd)
3289 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
3293 _e_border_key_down_modifier_apply(int modifier,
3296 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
3298 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
3311 _e_border_action_move_timeout(void *data __UNUSED__)
3313 _e_border_move_end(action_border);
3314 _e_border_action_finish();
3315 return ECORE_CALLBACK_CANCEL;
3319 _e_border_action_move_timeout_add(void)
3322 ecore_timer_del(action_timer);
3323 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
3327 _e_border_move_key_down(void *data __UNUSED__,
3328 int type __UNUSED__,
3331 Ecore_Event_Key *ev = event;
3334 if (ev->event_window != action_input_win)
3335 return ECORE_CALLBACK_PASS_ON;
3338 fputs("ERROR: no action_border!\n", stderr);
3342 x = action_border->x;
3343 y = action_border->y;
3345 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
3346 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
3347 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
3348 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
3349 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
3350 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
3351 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
3352 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
3353 else if (strcmp(ev->key, "Return") == 0)
3355 else if (strcmp(ev->key, "Escape") == 0)
3357 _e_border_action_restore_orig(action_border);
3360 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
3361 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
3364 e_border_move(action_border, x, y);
3365 _e_border_action_move_timeout_add();
3367 return ECORE_CALLBACK_PASS_ON;
3370 _e_border_move_end(action_border);
3371 _e_border_action_finish();
3372 return ECORE_CALLBACK_DONE;
3376 _e_border_move_mouse_down(void *data __UNUSED__,
3377 int type __UNUSED__,
3380 Ecore_Event_Mouse_Button *ev = event;
3382 if (ev->event_window != action_input_win)
3383 return ECORE_CALLBACK_PASS_ON;
3386 fputs("ERROR: no action_border!\n", stderr);
3388 _e_border_move_end(action_border);
3389 _e_border_action_finish();
3390 return ECORE_CALLBACK_DONE;
3394 e_border_act_move_keyboard(E_Border *bd)
3399 if (!_e_border_move_begin(bd))
3402 if (!_e_border_action_input_win_new(bd))
3404 _e_border_move_end(bd);
3408 _e_border_action_init(bd);
3409 _e_border_action_move_timeout_add();
3410 _e_border_move_update(bd);
3412 if (action_handler_key)
3413 ecore_event_handler_del(action_handler_key);
3414 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
3416 if (action_handler_mouse)
3417 ecore_event_handler_del(action_handler_mouse);
3418 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
3422 _e_border_action_resize_timeout(void *data __UNUSED__)
3424 _e_border_resize_end(action_border);
3425 _e_border_action_finish();
3426 return ECORE_CALLBACK_CANCEL;
3430 _e_border_action_resize_timeout_add(void)
3433 ecore_timer_del(action_timer);
3434 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
3438 _e_border_resize_key_down(void *data __UNUSED__,
3439 int type __UNUSED__,
3442 Ecore_Event_Key *ev = event;
3445 if (ev->event_window != action_input_win)
3446 return ECORE_CALLBACK_PASS_ON;
3449 fputs("ERROR: no action_border!\n", stderr);
3453 w = action_border->w;
3454 h = action_border->h;
3456 dx = e_config->border_keyboard.resize.dx;
3457 if (dx < action_border->client.icccm.step_w)
3458 dx = action_border->client.icccm.step_w;
3459 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
3460 if (dx < action_border->client.icccm.step_w)
3461 dx = action_border->client.icccm.step_w;
3463 dy = e_config->border_keyboard.resize.dy;
3464 if (dy < action_border->client.icccm.step_h)
3465 dy = action_border->client.icccm.step_h;
3466 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
3467 if (dy < action_border->client.icccm.step_h)
3468 dy = action_border->client.icccm.step_h;
3470 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
3472 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
3474 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
3476 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
3478 else if (strcmp(ev->key, "Return") == 0)
3480 else if (strcmp(ev->key, "Escape") == 0)
3482 _e_border_action_restore_orig(action_border);
3485 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
3486 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
3489 e_border_resize_limit(action_border, &w, &h);
3490 e_border_resize(action_border, w, h);
3491 _e_border_action_resize_timeout_add();
3493 return ECORE_CALLBACK_PASS_ON;
3496 _e_border_resize_end(action_border);
3497 _e_border_action_finish();
3498 return ECORE_CALLBACK_DONE;
3502 _e_border_resize_mouse_down(void *data __UNUSED__,
3503 int type __UNUSED__,
3506 Ecore_Event_Mouse_Button *ev = event;
3508 if (ev->event_window != action_input_win)
3509 return ECORE_CALLBACK_PASS_ON;
3512 fputs("ERROR: no action_border!\n", stderr);
3514 _e_border_resize_end(action_border);
3515 _e_border_action_finish();
3516 return ECORE_CALLBACK_DONE;
3520 e_border_act_resize_keyboard(E_Border *bd)
3525 if (!_e_border_resize_begin(bd))
3528 if (!_e_border_action_input_win_new(bd))
3530 _e_border_resize_end(bd);
3534 _e_border_action_init(bd);
3535 _e_border_action_resize_timeout_add();
3536 _e_border_resize_update(bd);
3538 if (action_handler_key)
3539 ecore_event_handler_del(action_handler_key);
3540 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
3542 if (action_handler_mouse)
3543 ecore_event_handler_del(action_handler_mouse);
3544 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
3548 e_border_act_move_begin(E_Border *bd,
3549 Ecore_Event_Mouse_Button *ev)
3552 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3553 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
3554 if (!_e_border_move_begin(bd))
3557 e_zone_edge_disable();
3559 _e_border_pointer_move_begin(bd);
3564 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
3565 _e_border_moveinfo_gather(bd, source);
3570 e_border_act_move_end(E_Border *bd,
3571 Ecore_Event_Mouse_Button *ev __UNUSED__)
3574 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3575 if (!bd->moving) return;
3577 _e_border_pointer_move_end(bd);
3578 e_zone_edge_enable();
3579 _e_border_move_end(bd);
3580 e_zone_flip_coords_handle(bd->zone, -1, -1);
3584 e_border_act_resize_begin(E_Border *bd,
3585 Ecore_Event_Mouse_Button *ev)
3588 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3589 if (bd->lock_user_size) return;
3590 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
3591 if (!_e_border_resize_begin(bd))
3593 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
3595 if (bd->mouse.current.my < (bd->y + bd->h / 2))
3597 bd->resize_mode = RESIZE_TL;
3598 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
3602 bd->resize_mode = RESIZE_BL;
3603 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
3608 if (bd->mouse.current.my < (bd->y + bd->h / 2))
3610 bd->resize_mode = RESIZE_TR;
3611 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
3615 bd->resize_mode = RESIZE_BR;
3616 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
3619 _e_border_pointer_resize_begin(bd);
3624 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
3625 _e_border_moveinfo_gather(bd, source);
3630 e_border_act_resize_end(E_Border *bd,
3631 Ecore_Event_Mouse_Button *ev __UNUSED__)
3634 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3635 if (bd->resize_mode != RESIZE_NONE)
3637 _e_border_pointer_resize_end(bd);
3638 bd->resize_mode = RESIZE_NONE;
3639 _e_border_resize_end(bd);
3640 bd->changes.reset_gravity = 1;
3646 e_border_act_menu_begin(E_Border *bd,
3647 Ecore_Event_Mouse_Button *ev,
3651 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3654 e_int_border_menu_show(bd,
3655 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
3656 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
3663 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
3664 e_int_border_menu_show(bd, x, y, key, 0);
3669 e_border_act_close_begin(E_Border *bd)
3672 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3673 if (bd->lock_close) return;
3674 if (bd->client.icccm.delete_request)
3676 bd->delete_requested = 1;
3677 ecore_x_window_delete_request_send(bd->client.win);
3678 if (bd->client.netwm.ping)
3681 else if (e_config->kill_if_close_not_possible)
3683 printf("KILL win %x (dead)\n", bd->client.win);
3684 e_border_act_kill_begin(bd);
3689 e_border_act_kill_begin(E_Border *bd)
3692 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3693 if (bd->internal) return;
3694 if (bd->lock_close) return;
3695 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
3697 kill(bd->client.netwm.pid, SIGINT);
3698 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
3699 _e_border_cb_kill_timer, bd);
3703 if (!bd->internal) ecore_x_kill(bd->client.win);
3708 e_border_icon_add(E_Border *bd,
3713 E_OBJECT_CHECK_RETURN(bd, NULL);
3714 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
3719 o = edje_object_add(evas);
3720 if (!bd->internal_icon)
3721 e_util_edje_icon_set(o, "enlightenment");
3724 if (!bd->internal_icon_key)
3728 ext = strrchr(bd->internal_icon, '.');
3729 if ((ext) && ((!strcmp(ext, ".edj"))))
3731 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
3732 e_util_edje_icon_set(o, "enlightenment");
3737 o = e_icon_add(evas);
3738 e_icon_file_set(o, bd->internal_icon);
3743 o = e_icon_add(evas);
3744 if (!e_util_icon_theme_set(o, bd->internal_icon))
3745 e_util_icon_theme_set(o, "enlightenment");
3750 edje_object_file_set(o, bd->internal_icon,
3751 bd->internal_icon_key);
3756 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
3758 if (bd->client.netwm.icons)
3760 o = e_icon_add(evas);
3761 e_icon_data_set(o, bd->client.netwm.icons[0].data,
3762 bd->client.netwm.icons[0].width,
3763 bd->client.netwm.icons[0].height);
3764 e_icon_alpha_set(o, 1);
3770 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
3772 o = e_icon_add(evas);
3775 e_icon_fdo_icon_set(o, bd->desktop->icon);
3779 else if (bd->client.netwm.icons)
3781 o = e_icon_add(evas);
3782 e_icon_data_set(o, bd->client.netwm.icons[0].data,
3783 bd->client.netwm.icons[0].width,
3784 bd->client.netwm.icons[0].height);
3785 e_icon_alpha_set(o, 1);
3790 o = e_icon_add(evas);
3791 e_util_icon_theme_set(o, "unknown");
3796 e_border_button_bindings_ungrab_all(void)
3801 EINA_LIST_FOREACH(borders, l, bd)
3803 e_focus_setdown(bd);
3804 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
3805 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
3810 e_border_button_bindings_grab_all(void)
3815 EINA_LIST_FOREACH(borders, l, bd)
3817 e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
3818 e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
3824 e_border_focus_stack_get(void)
3830 e_border_raise_stack_get(void)
3836 e_border_lost_windows_get(E_Zone *zone)
3838 Eina_List *list = NULL, *l;
3840 int loss_overlap = 5;
3842 E_OBJECT_CHECK_RETURN(zone, NULL);
3843 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
3844 EINA_LIST_FOREACH(borders, l, bd)
3848 if ((bd->zone == zone) ||
3849 (bd->zone->container == zone->container))
3851 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
3852 bd->zone->y + loss_overlap,
3853 bd->zone->w - (2 * loss_overlap),
3854 bd->zone->h - (2 * loss_overlap),
3855 bd->x, bd->y, bd->w, bd->h))
3857 list = eina_list_append(list, bd);
3859 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
3860 bd->zone->w, bd->zone->h,
3861 bd->x, bd->y, bd->w, bd->h)) &&
3864 Ecore_X_Rectangle *rect;
3867 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
3873 for (i = 0; i < num; i++)
3875 if (E_INTERSECTS(bd->zone->x + loss_overlap,
3876 bd->zone->y + loss_overlap,
3877 bd->zone->w - (2 * loss_overlap),
3878 bd->zone->h - (2 * loss_overlap),
3879 rect[i].x, rect[i].y,
3880 (int)rect[i].width, (int)rect[i].height))
3888 list = eina_list_append(list, bd);
3898 e_border_ping(E_Border *bd)
3901 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3902 if (!e_config->ping_clients) return;
3904 ecore_x_netwm_ping_send(bd->client.win);
3905 bd->ping = ecore_loop_time_get();
3906 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
3907 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
3908 e_config->ping_clients_interval,
3909 _e_border_cb_ping_poller, bd);
3913 e_border_move_cancel(void)
3917 if (move->cur_mouse_action)
3922 e_object_ref(E_OBJECT(bd));
3923 if (bd->cur_mouse_action->func.end_mouse)
3924 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
3925 else if (bd->cur_mouse_action->func.end)
3926 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
3927 e_object_unref(E_OBJECT(bd->cur_mouse_action));
3928 bd->cur_mouse_action = NULL;
3929 e_object_unref(E_OBJECT(bd));
3932 _e_border_move_end(move);
3937 e_border_resize_cancel(void)
3941 if (resize->cur_mouse_action)
3946 e_object_ref(E_OBJECT(bd));
3947 if (bd->cur_mouse_action->func.end_mouse)
3948 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
3949 else if (bd->cur_mouse_action->func.end)
3950 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
3951 e_object_unref(E_OBJECT(bd->cur_mouse_action));
3952 bd->cur_mouse_action = NULL;
3953 e_object_unref(E_OBJECT(bd));
3957 resize->resize_mode = RESIZE_NONE;
3958 _e_border_resize_end(resize);
3964 e_border_frame_recalc(E_Border *bd)
3966 Evas_Coord cx, cy, cw, ch;
3968 if (!bd->bg_object) return;
3970 bd->w -= (bd->client_inset.l + bd->client_inset.r);
3971 bd->h -= (bd->client_inset.t + bd->client_inset.b);
3973 evas_object_resize(bd->bg_object, 1000, 1000);
3974 edje_object_calc_force(bd->bg_object);
3975 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
3976 bd->client_inset.l = cx;
3977 bd->client_inset.r = 1000 - (cx + cw);
3978 bd->client_inset.t = cy;
3979 bd->client_inset.b = 1000 - (cy + ch);
3980 ecore_x_netwm_frame_size_set(bd->client.win,
3981 bd->client_inset.l, bd->client_inset.r,
3982 bd->client_inset.t, bd->client_inset.b);
3983 ecore_x_e_frame_size_set(bd->client.win,
3984 bd->client_inset.l, bd->client_inset.r,
3985 bd->client_inset.t, bd->client_inset.b);
3987 bd->w += (bd->client_inset.l + bd->client_inset.r);
3988 bd->h += (bd->client_inset.t + bd->client_inset.b);
3991 bd->changes.size = 1;
3992 if ((bd->shaped) || (bd->client.shaped))
3994 bd->need_shape_merge = 1;
3995 bd->need_shape_export = 1;
3997 if (bd->shaped_input)
3999 bd->need_shape_merge = 1;
4001 _e_border_client_move_resize_send(bd);
4005 e_border_immortal_windows_get(void)
4007 Eina_List *list = NULL, *l;
4010 EINA_LIST_FOREACH(borders, l, bd)
4013 list = eina_list_append(list, bd);
4019 e_border_name_get(const E_Border *bd)
4021 E_OBJECT_CHECK_RETURN(bd, "");
4022 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
4023 if (bd->client.netwm.name)
4024 return bd->client.netwm.name;
4025 else if (bd->client.icccm.title)
4026 return bd->client.icccm.title;
4031 e_border_signal_move_begin(E_Border *bd,
4033 const char *src __UNUSED__)
4036 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4037 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4038 if (!_e_border_move_begin(bd)) return;
4040 _e_border_pointer_move_begin(bd);
4041 e_zone_edge_disable();
4042 _e_border_moveinfo_gather(bd, sig);
4046 e_border_signal_move_end(E_Border *bd,
4047 const char *sig __UNUSED__,
4048 const char *src __UNUSED__)
4051 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4052 if (!bd->moving) return;
4054 _e_border_pointer_move_end(bd);
4055 e_zone_edge_enable();
4056 _e_border_move_end(bd);
4057 e_zone_flip_coords_handle(bd->zone, -1, -1);
4061 e_border_resizing_get(E_Border *bd)
4063 E_OBJECT_CHECK_RETURN(bd, 0);
4064 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
4065 if (bd->resize_mode == RESIZE_NONE) return 0;
4070 e_border_signal_resize_begin(E_Border *bd,
4073 const char *src __UNUSED__)
4075 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
4076 int resize_mode = RESIZE_BR;
4079 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4081 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4082 if (!_e_border_resize_begin(bd))
4084 if (!strcmp(dir, "tl"))
4086 resize_mode = RESIZE_TL;
4087 grav = ECORE_X_GRAVITY_SE;
4089 else if (!strcmp(dir, "t"))
4091 resize_mode = RESIZE_T;
4092 grav = ECORE_X_GRAVITY_S;
4094 else if (!strcmp(dir, "tr"))
4096 resize_mode = RESIZE_TR;
4097 grav = ECORE_X_GRAVITY_SW;
4099 else if (!strcmp(dir, "r"))
4101 resize_mode = RESIZE_R;
4102 grav = ECORE_X_GRAVITY_W;
4104 else if (!strcmp(dir, "br"))
4106 resize_mode = RESIZE_BR;
4107 grav = ECORE_X_GRAVITY_NW;
4109 else if (!strcmp(dir, "b"))
4111 resize_mode = RESIZE_B;
4112 grav = ECORE_X_GRAVITY_N;
4114 else if (!strcmp(dir, "bl"))
4116 resize_mode = RESIZE_BL;
4117 grav = ECORE_X_GRAVITY_NE;
4119 else if (!strcmp(dir, "l"))
4121 resize_mode = RESIZE_L;
4122 grav = ECORE_X_GRAVITY_E;
4124 bd->resize_mode = resize_mode;
4125 _e_border_pointer_resize_begin(bd);
4126 _e_border_moveinfo_gather(bd, sig);
4131 e_border_signal_resize_end(E_Border *bd,
4132 const char *dir __UNUSED__,
4133 const char *sig __UNUSED__,
4134 const char *src __UNUSED__)
4137 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4138 if (bd->resize_mode == RESIZE_NONE) return;
4139 _e_border_resize_handle(bd);
4140 _e_border_pointer_resize_end(bd);
4141 bd->resize_mode = RESIZE_NONE;
4142 _e_border_resize_end(bd);
4143 bd->changes.reset_gravity = 1;
4148 e_border_resize_limit(E_Border *bd,
4155 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4156 *w -= bd->client_inset.l + bd->client_inset.r;
4157 *h -= bd->client_inset.t + bd->client_inset.b;
4160 if ((bd->client.icccm.base_w >= 0) &&
4161 (bd->client.icccm.base_h >= 0))
4165 tw = *w - bd->client.icccm.base_w;
4166 th = *h - bd->client.icccm.base_h;
4169 a = (double)(tw) / (double)(th);
4170 if ((bd->client.icccm.min_aspect != 0.0) &&
4171 (a < bd->client.icccm.min_aspect))
4173 th = tw / bd->client.icccm.max_aspect;
4174 *h = th + bd->client.icccm.base_h;
4176 else if ((bd->client.icccm.max_aspect != 0.0) &&
4177 (a > bd->client.icccm.max_aspect))
4179 tw = th * bd->client.icccm.max_aspect;
4180 *w = tw + bd->client.icccm.base_w;
4185 a = (double)*w / (double)*h;
4186 if ((bd->client.icccm.min_aspect != 0.0) &&
4187 (a < bd->client.icccm.min_aspect))
4188 *h = *w / bd->client.icccm.min_aspect;
4189 else if ((bd->client.icccm.max_aspect != 0.0) &&
4190 (a > bd->client.icccm.max_aspect))
4191 *w = *h * bd->client.icccm.max_aspect;
4193 if (bd->client.icccm.step_w > 0)
4195 if (bd->client.icccm.base_w >= 0)
4196 *w = bd->client.icccm.base_w +
4197 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
4198 bd->client.icccm.step_w);
4200 *w = bd->client.icccm.min_w +
4201 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
4202 bd->client.icccm.step_w);
4204 if (bd->client.icccm.step_h > 0)
4206 if (bd->client.icccm.base_h >= 0)
4207 *h = bd->client.icccm.base_h +
4208 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
4209 bd->client.icccm.step_h);
4211 *h = bd->client.icccm.min_h +
4212 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
4213 bd->client.icccm.step_h);
4219 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
4220 else if (*w < bd->client.icccm.min_w)
4221 *w = bd->client.icccm.min_w;
4222 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
4223 else if (*h < bd->client.icccm.min_h)
4224 *h = bd->client.icccm.min_h;
4226 *w += bd->client_inset.l + bd->client_inset.r;
4227 *h += bd->client_inset.t + bd->client_inset.b;
4230 /* local subsystem functions */
4232 _e_border_free(E_Border *bd)
4236 efreet_desktop_free(bd->desktop);
4241 ecore_idle_enterer_del(bd->post_job);
4242 bd->post_job = NULL;
4246 e_object_del(E_OBJECT(bd->pointer));
4250 _e_border_resize_end(bd);
4252 _e_border_move_end(bd);
4253 /* TODO: Other states to end before dying? */
4255 if (bd->cur_mouse_action)
4257 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4258 bd->cur_mouse_action = NULL;
4261 E_FREE(bd->shape_rects);
4262 bd->shape_rects_num = 0;
4264 if (bd->dangling_ref_check)
4266 ecore_timer_del(bd->dangling_ref_check);
4267 bd->dangling_ref_check = NULL;
4272 ecore_timer_del(bd->kill_timer);
4273 bd->kill_timer = NULL;
4275 if (bd->ping_poller)
4277 ecore_poller_del(bd->ping_poller);
4278 bd->ping_poller = NULL;
4280 E_FREE_LIST(bd->pending_move_resize, free);
4282 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
4283 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
4285 if (bd->border_locks_dialog)
4287 e_object_del(E_OBJECT(bd->border_locks_dialog));
4288 bd->border_locks_dialog = NULL;
4290 if (bd->border_remember_dialog)
4292 e_object_del(E_OBJECT(bd->border_remember_dialog));
4293 bd->border_remember_dialog = NULL;
4295 if (bd->border_border_dialog)
4297 e_object_del(E_OBJECT(bd->border_border_dialog));
4298 bd->border_border_dialog = NULL;
4300 if (bd->border_prop_dialog)
4302 e_object_del(E_OBJECT(bd->border_prop_dialog));
4303 bd->border_prop_dialog = NULL;
4306 e_int_border_menu_del(bd);
4310 // ecore_x_window_focus(bd->zone->container->manager->root);
4311 e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE);
4312 e_hints_active_window_set(bd->zone->container->manager, NULL);
4315 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
4321 bd->remember = NULL;
4322 e_remember_unuse(rem);
4324 if (!bd->already_unparented)
4326 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
4327 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
4328 ecore_x_window_save_set_del(bd->client.win);
4329 bd->already_unparented = 1;
4331 if (bd->group) eina_list_free(bd->group);
4332 if (bd->transients) eina_list_free(bd->transients);
4333 if (bd->stick_desks) eina_list_free(bd->stick_desks);
4334 if (bd->client.netwm.icons)
4337 for (i = 0; i < bd->client.netwm.num_icons; i++)
4338 free(bd->client.netwm.icons[i].data);
4339 free(bd->client.netwm.icons);
4341 if (bd->client.netwm.extra_types)
4342 free(bd->client.netwm.extra_types);
4343 if (bd->client.border.name) eina_stringshare_del(bd->client.border.name);
4344 if (bd->bordername) eina_stringshare_del(bd->bordername);
4345 if (bd->client.icccm.title) free(bd->client.icccm.title);
4346 if (bd->client.icccm.name) free(bd->client.icccm.name);
4347 if (bd->client.icccm.class) free(bd->client.icccm.class);
4348 if (bd->client.icccm.icon_name) free(bd->client.icccm.icon_name);
4349 if (bd->client.icccm.machine) free(bd->client.icccm.machine);
4350 if (bd->client.icccm.window_role) free(bd->client.icccm.window_role);
4351 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
4355 for (i = 0; i < bd->client.icccm.command.argc; i++)
4356 free(bd->client.icccm.command.argv[i]);
4357 free(bd->client.icccm.command.argv);
4359 if (bd->client.netwm.name) free(bd->client.netwm.name);
4360 if (bd->client.netwm.icon_name) free(bd->client.netwm.icon_name);
4361 e_object_del(E_OBJECT(bd->shape));
4362 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
4363 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
4364 if (bd->icon_object) evas_object_del(bd->icon_object);
4365 evas_object_del(bd->bg_object);
4366 e_canvas_del(bd->bg_ecore_evas);
4367 ecore_evas_free(bd->bg_ecore_evas);
4368 ecore_x_window_free(bd->client.shell_win);
4369 e_focus_setdown(bd);
4370 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
4371 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
4372 ecore_x_window_free(bd->win);
4374 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
4375 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
4376 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
4377 borders = eina_list_remove(borders, bd);
4378 focus_stack = eina_list_remove(focus_stack, bd);
4379 raise_stack = eina_list_remove(raise_stack, bd);
4381 e_container_border_remove(bd);
4387 _e_border_del_dangling_ref_check(void *data)
4393 printf("EEK EEK border still around 1 second after being deleted!\n");
4394 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
4395 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
4396 bd->client.icccm.name, bd->client.icccm.class);
4397 // e_object_breadcrumb_debug(E_OBJECT(bd));
4404 _e_border_del(E_Border *bd)
4406 E_Event_Border_Remove *ev;
4412 focus_next = eina_list_remove(focus_next, bd);
4414 if (bd->fullscreen) bd->desk->fullscreen_borders--;
4416 if ((drag_border) && (drag_border->data == bd))
4418 e_object_del(E_OBJECT(drag_border));
4421 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
4423 if (bd->border_locks_dialog)
4425 e_object_del(E_OBJECT(bd->border_locks_dialog));
4426 bd->border_locks_dialog = NULL;
4428 if (bd->border_remember_dialog)
4430 e_object_del(E_OBJECT(bd->border_remember_dialog));
4431 bd->border_remember_dialog = NULL;
4433 if (bd->border_border_dialog)
4435 e_object_del(E_OBJECT(bd->border_border_dialog));
4436 bd->border_border_dialog = NULL;
4438 if (bd->border_prop_dialog)
4440 e_object_del(E_OBJECT(bd->border_prop_dialog));
4441 bd->border_prop_dialog = NULL;
4444 e_int_border_menu_del(bd);
4446 if (bd->raise_timer)
4448 ecore_timer_del(bd->raise_timer);
4449 bd->raise_timer = NULL;
4451 if (!bd->already_unparented)
4453 ecore_x_window_reparent(bd->client.win,
4454 bd->zone->container->manager->root,
4455 bd->x + bd->client_inset.l,
4456 bd->y + bd->client_inset.t);
4457 ecore_x_window_save_set_del(bd->client.win);
4458 bd->already_unparented = 1;
4459 // bd->client.win = 0;
4461 bd->already_unparented = 1;
4463 if ((!bd->new_client) && (!stopping))
4465 ev = E_NEW(E_Event_Border_Remove, 1);
4467 e_object_ref(E_OBJECT(bd));
4468 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
4469 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
4474 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
4475 if (bd->parent->modal == bd)
4476 bd->parent->modal = NULL;
4479 EINA_LIST_FREE(bd->transients, child)
4481 child->parent = NULL;
4486 bd->leader->group = eina_list_remove(bd->leader->group, bd);
4487 if (bd->leader->modal == bd)
4488 bd->leader->modal = NULL;
4491 EINA_LIST_FREE(bd->group, child)
4493 child->leader = NULL;
4497 #ifdef PRINT_LOTS_OF_DEBUG
4499 _e_border_print(E_Border *bd,
4504 printf("*Window Info*"
4508 "\tBorderless: %s\n",
4509 bd, bd->client.icccm.name, bd->client.icccm.title,
4510 bd->borderless ? "TRUE" : "FALSE");
4516 _e_border_cb_window_show_request(void *data __UNUSED__,
4517 int ev_type __UNUSED__,
4521 Ecore_X_Event_Window_Show_Request *e;
4524 bd = e_border_find_by_client_window(e->win);
4525 if (!bd) return ECORE_CALLBACK_PASS_ON;
4528 if (!bd->lock_client_iconify)
4529 e_border_uniconify(bd);
4533 /* FIXME: make border "urgent" for a bit - it wants attention */
4534 /* e_border_show(bd); */
4535 if (!bd->lock_client_stacking)
4538 return ECORE_CALLBACK_PASS_ON;
4542 _e_border_cb_window_destroy(void *data __UNUSED__,
4543 int ev_type __UNUSED__,
4547 Ecore_X_Event_Window_Destroy *e;
4550 bd = e_border_find_by_client_window(e->win);
4551 if (!bd) return ECORE_CALLBACK_PASS_ON;
4552 e_border_hide(bd, 0);
4553 e_object_del(E_OBJECT(bd));
4554 return ECORE_CALLBACK_PASS_ON;
4558 _e_border_cb_window_hide(void *data __UNUSED__,
4559 int ev_type __UNUSED__,
4563 Ecore_X_Event_Window_Hide *e;
4566 // printf("HIDE: %x, event %x\n", e->win, e->event_win);
4567 // not interested in hide events from windows other than the window in question
4568 if (e->win != e->event_win) return ECORE_CALLBACK_PASS_ON;
4569 bd = e_border_find_by_client_window(e->win);
4570 // printf(" bd = %p\n", bd);
4571 if (!bd) return ECORE_CALLBACK_PASS_ON;
4572 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
4573 if (bd->ignore_first_unmap > 0)
4575 bd->ignore_first_unmap--;
4576 return ECORE_CALLBACK_PASS_ON;
4578 /* Don't delete hidden or iconified windows */
4579 if ((bd->iconic) || ((!bd->visible) && (!bd->new_client)) ||
4580 (bd->await_hide_event > 0))
4582 // printf(" Don't delete hidden or iconified windows\n");
4583 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
4584 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
4585 if (bd->await_hide_event > 0)
4587 bd->await_hide_event--;
4591 // printf(" hide really\n");
4592 /* Only hide the border if it is visible */
4593 if (bd->visible) e_border_hide(bd, 1);
4598 // printf(" hide2\n");
4599 e_border_hide(bd, 0);
4600 e_object_del(E_OBJECT(bd));
4602 return ECORE_CALLBACK_PASS_ON;
4606 _e_border_cb_window_reparent(void *data __UNUSED__,
4607 int ev_type __UNUSED__,
4608 void *ev __UNUSED__)
4612 Ecore_X_Event_Window_Reparent *e;
4615 bd = e_border_find_by_client_window(e->win);
4617 if (e->parent == bd->client.shell_win) return 1;
4618 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
4622 e_border_hide(bd, 0);
4623 e_object_del(E_OBJECT(bd));
4625 return ECORE_CALLBACK_PASS_ON;
4629 _e_border_cb_window_configure_request(void *data __UNUSED__,
4630 int ev_type __UNUSED__,
4634 Ecore_X_Event_Window_Configure_Request *e;
4637 bd = e_border_find_by_client_window(e->win);
4640 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
4641 if (!e_util_container_window_find(e->win))
4642 ecore_x_window_configure(e->win, e->value_mask,
4643 e->x, e->y, e->w, e->h, e->border,
4644 e->abovewin, e->detail);
4645 return ECORE_CALLBACK_PASS_ON;
4648 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
4649 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
4655 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
4657 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
4659 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
4660 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
4666 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
4667 w = e->w + bd->client_inset.l + bd->client_inset.r;
4668 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
4669 h = e->h + bd->client_inset.t + bd->client_inset.b;
4670 if ((!bd->lock_client_location) && (!bd->lock_client_size))
4672 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4674 bd->saved.x = x - bd->zone->x;
4675 bd->saved.y = y - bd->zone->y;
4680 e_border_move_resize(bd, x, y, w, h);
4682 else if (!bd->lock_client_location)
4684 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4686 bd->saved.x = x - bd->zone->x;
4687 bd->saved.y = y - bd->zone->y;
4690 e_border_move(bd, x, y);
4692 else if (!bd->lock_client_size)
4694 if ((bd->shaded) || (bd->shading))
4700 if ((bd->shade.dir == E_DIRECTION_UP) ||
4701 (bd->shade.dir == E_DIRECTION_DOWN))
4703 e_border_resize(bd, w, bd->h);
4708 e_border_resize(bd, bd->w, h);
4714 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4720 e_border_resize(bd, w, h);
4726 if (!bd->lock_client_location)
4728 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4730 bd->saved.x = x - bd->zone->x;
4731 bd->saved.y = y - bd->zone->y;
4734 e_border_move(bd, x, y);
4738 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
4739 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
4745 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
4746 w = e->w + bd->client_inset.l + bd->client_inset.r;
4747 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
4748 h = e->h + bd->client_inset.t + bd->client_inset.b;
4749 if (!bd->lock_client_size)
4751 if ((bd->shaded) || (bd->shading))
4757 if ((bd->shade.dir == E_DIRECTION_UP) ||
4758 (bd->shade.dir == E_DIRECTION_DOWN))
4760 e_border_resize(bd, w, bd->h);
4765 e_border_resize(bd, bd->w, h);
4771 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
4778 * This code does resize and move a window on a
4779 * X configure request into an useful geometry.
4780 * This is really useful for size jumping file dialogs.
4785 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
4787 if (e_config->geometry_auto_resize_limit == 1)
4796 e_border_resize(bd, w, h);
4798 if (e_config->geometry_auto_move == 1)
4800 /* z{x,y,w,h} are only set here; FIXME! */
4803 // move window horizontal if resize to not useful geometry
4804 if (bd->x + bd->w > zx + zw)
4805 rx = zx + zw - bd->w;
4806 else if (bd->x < zx)
4809 // move window vertical if resize to not useful geometry
4810 if (bd->y + bd->h > zy + zh)
4811 ry = zy + zh - bd->h;
4812 else if (bd->y < zy)
4815 e_border_move(bd, rx, ry);
4821 if (!bd->lock_client_stacking)
4823 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
4824 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
4828 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
4830 obd = e_border_find_by_client_window(e->abovewin);
4832 e_border_stack_above(bd, obd);
4834 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
4836 obd = e_border_find_by_client_window(e->abovewin);
4838 e_border_stack_below(bd, obd);
4840 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
4844 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
4848 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
4853 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
4855 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
4859 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
4863 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
4867 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
4871 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
4878 _e_border_client_move_resize_send(bd);
4879 return ECORE_CALLBACK_PASS_ON;
4883 _e_border_cb_window_resize_request(void *data __UNUSED__,
4884 int ev_type __UNUSED__,
4888 Ecore_X_Event_Window_Resize_Request *e;
4891 bd = e_border_find_by_client_window(e->win);
4894 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
4895 ecore_x_window_resize(e->win, e->w, e->h);
4896 return ECORE_CALLBACK_PASS_ON;
4901 w = e->w + bd->client_inset.l + bd->client_inset.r;
4902 h = e->h + bd->client_inset.t + bd->client_inset.b;
4903 if ((bd->shaded) || (bd->shading))
4909 if ((bd->shade.dir == E_DIRECTION_UP) ||
4910 (bd->shade.dir == E_DIRECTION_DOWN))
4912 e_border_resize(bd, w, bd->h);
4917 e_border_resize(bd, bd->w, h);
4922 e_border_resize(bd, w, h);
4925 _e_border_client_move_resize_send(bd);
4926 return ECORE_CALLBACK_PASS_ON;
4930 _e_border_cb_window_gravity(void *data __UNUSED__,
4931 int ev_type __UNUSED__,
4932 void *ev __UNUSED__)
4935 // Ecore_X_Event_Window_Gravity *e;
4938 // bd = e_border_find_by_client_window(e->win);
4939 // if (!bd) return 1;
4944 _e_border_cb_window_stack_request(void *data __UNUSED__,
4945 int ev_type __UNUSED__,
4949 Ecore_X_Event_Window_Stack_Request *e;
4952 bd = e_border_find_by_client_window(e->win);
4955 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
4956 if (!e_util_container_window_find(e->win))
4958 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
4959 ecore_x_window_raise(e->win);
4960 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
4961 ecore_x_window_lower(e->win);
4963 return ECORE_CALLBACK_PASS_ON;
4965 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
4967 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
4969 return ECORE_CALLBACK_PASS_ON;
4973 _e_border_cb_window_property(void *data __UNUSED__,
4974 int ev_type __UNUSED__,
4978 Ecore_X_Event_Window_Property *e;
4981 bd = e_border_find_by_client_window(e->win);
4982 if (!bd) return ECORE_CALLBACK_PASS_ON;
4983 if (e->atom == ECORE_X_ATOM_WM_NAME)
4985 if ((!bd->client.netwm.name) &&
4986 (!bd->client.netwm.fetch.name))
4988 bd->client.icccm.fetch.title = 1;
4992 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
4994 bd->client.netwm.fetch.name = 1;
4997 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
4999 bd->client.icccm.fetch.name_class = 1;
5002 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
5004 if ((!bd->client.netwm.icon_name) &&
5005 (!bd->client.netwm.fetch.icon_name))
5007 bd->client.icccm.fetch.icon_name = 1;
5011 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
5013 bd->client.netwm.fetch.icon_name = 1;
5016 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
5018 bd->client.icccm.fetch.machine = 1;
5021 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
5023 bd->client.icccm.fetch.protocol = 1;
5026 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
5028 bd->client.icccm.fetch.hints = 1;
5031 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
5033 bd->client.icccm.fetch.size_pos_hints = 1;
5036 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
5039 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
5040 (!bd->client.netwm.fetch.type))
5043 bd->client.mwm.fetch.hints = 1;
5049 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
5051 bd->client.icccm.fetch.transient_for = 1;
5054 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
5056 bd->client.icccm.fetch.client_leader = 1;
5059 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
5061 bd->client.icccm.fetch.window_role = 1;
5064 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
5066 bd->client.netwm.fetch.icon = 1;
5069 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
5071 bd->client.qtopia.fetch.soft_menu = 1;
5074 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
5076 bd->client.qtopia.fetch.soft_menus = 1;
5079 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
5081 bd->client.vkbd.fetch.state = 1;
5084 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
5086 bd->client.vkbd.fetch.vkbd = 1;
5089 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
5091 bd->client.illume.conformant.fetch.conformant = 1;
5094 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
5096 bd->client.illume.quickpanel.fetch.state = 1;
5099 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
5101 bd->client.illume.quickpanel.fetch.quickpanel = 1;
5104 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
5106 bd->client.illume.quickpanel.fetch.priority.major = 1;
5109 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
5111 bd->client.illume.quickpanel.fetch.priority.minor = 1;
5114 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
5116 bd->client.illume.quickpanel.fetch.zone = 1;
5119 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
5121 bd->client.illume.drag.fetch.locked = 1;
5124 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
5126 bd->client.illume.drag.fetch.drag = 1;
5130 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
5132 bd->client.netwm.fetch.user_time = 1;
5135 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
5137 bd->client.netwm.fetch.strut = 1;
5140 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
5142 bd->client.netwm.fetch.strut = 1;
5146 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
5148 printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
5151 return ECORE_CALLBACK_PASS_ON;
5155 _e_border_cb_window_colormap(void *data __UNUSED__,
5156 int ev_type __UNUSED__,
5160 Ecore_X_Event_Window_Colormap *e;
5163 bd = e_border_find_by_client_window(e->win);
5164 if (!bd) return ECORE_CALLBACK_PASS_ON;
5165 return ECORE_CALLBACK_PASS_ON;
5169 _e_border_cb_window_shape(void *data __UNUSED__,
5170 int ev_type __UNUSED__,
5174 Ecore_X_Event_Window_Shape *e;
5177 bd = e_border_find_by_client_window(e->win);
5179 if (e->type == ECORE_X_SHAPE_INPUT)
5183 bd->need_shape_merge = 1;
5184 // YYY bd->shaped_input = 1;
5185 bd->changes.shape_input = 1;
5189 return ECORE_CALLBACK_PASS_ON;
5194 bd->changes.shape = 1;
5196 return ECORE_CALLBACK_PASS_ON;
5198 bd = e_border_find_by_window(e->win);
5201 bd->need_shape_export = 1;
5203 return ECORE_CALLBACK_PASS_ON;
5205 bd = e_border_find_by_frame_window(e->win);
5208 bd->need_shape_merge = 1;
5210 return ECORE_CALLBACK_PASS_ON;
5212 return ECORE_CALLBACK_PASS_ON;
5216 _e_border_cb_window_focus_in(void *data __UNUSED__,
5217 int ev_type __UNUSED__,
5221 Ecore_X_Event_Window_Focus_In *e;
5224 bd = e_border_find_by_client_window(e->win);
5225 if (!bd) return ECORE_CALLBACK_PASS_ON;
5226 #ifdef INOUTDEBUG_FOCUS
5231 const char *modes[] = {
5233 "MODE_WHILE_GRABBED",
5237 const char *details[] = {
5241 "DETAIL_NON_LINEAR",
5242 "DETAIL_NON_LINEAR_VIRTUAL",
5244 "DETAIL_POINTER_ROOT",
5245 "DETAIL_DETAIL_NONE"
5249 ct[strlen(ct) - 1] = 0;
5250 printf("FF ->IN %i 0x%x %s md=%s dt=%s\n",
5255 details[e->detail]);
5257 printf("%s cb focus in %d %d\n",
5258 e_border_name_get(bd),
5259 bd->client.icccm.accepts_focus,
5260 bd->client.icccm.take_focus);
5263 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
5265 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
5267 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
5269 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
5272 /* ignore focus in from !take_focus windows, we just gave it em */
5273 /* if (!bd->client.icccm.take_focus)
5274 * return ECORE_CALLBACK_PASS_ON; */
5276 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
5277 if (e->time >= focus_time)
5278 e_border_focus_set(bd, 1, 0);
5279 return ECORE_CALLBACK_PASS_ON;
5283 _e_border_cb_window_focus_out(void *data __UNUSED__,
5284 int ev_type __UNUSED__,
5288 Ecore_X_Event_Window_Focus_Out *e;
5291 bd = e_border_find_by_client_window(e->win);
5292 if (!bd) return ECORE_CALLBACK_PASS_ON;
5293 #ifdef INOUTDEBUG_FOCUS
5298 const char *modes[] = {
5300 "MODE_WHILE_GRABBED",
5304 const char *details[] = {
5308 "DETAIL_NON_LINEAR",
5309 "DETAIL_NON_LINEAR_VIRTUAL",
5311 "DETAIL_POINTER_ROOT",
5312 "DETAIL_DETAIL_NONE"
5316 ct[strlen(ct) - 1] = 0;
5317 printf("FF <-OUT %i 0x%x %s md=%s dt=%s\n",
5322 details[e->detail]);
5324 printf("%s cb focus out %d %d\n",
5325 e_border_name_get(bd),
5326 bd->client.icccm.accepts_focus,
5327 bd->client.icccm.take_focus);
5330 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
5332 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
5333 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
5334 return ECORE_CALLBACK_PASS_ON;
5335 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
5336 return ECORE_CALLBACK_PASS_ON;
5338 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
5340 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
5341 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
5342 return ECORE_CALLBACK_PASS_ON;
5343 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
5344 return ECORE_CALLBACK_PASS_ON;
5345 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
5346 return ECORE_CALLBACK_PASS_ON;
5347 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
5348 return ECORE_CALLBACK_PASS_ON;
5350 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
5352 /* for firefox/thunderbird (xul) menu walking */
5353 /* NB: why did i disable this before? */
5354 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
5355 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
5356 return ECORE_CALLBACK_PASS_ON;
5358 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
5360 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
5361 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
5362 return ECORE_CALLBACK_PASS_ON;
5364 e_border_focus_set(bd, 0, 0);
5365 return ECORE_CALLBACK_PASS_ON;
5369 _e_border_cb_client_message(void *data __UNUSED__,
5370 int ev_type __UNUSED__,
5371 void *ev __UNUSED__)
5375 Ecore_X_Event_Client_Message *e;
5378 bd = e_border_find_by_client_window(e->win);
5385 _e_border_cb_window_state_request(void *data __UNUSED__,
5386 int ev_type __UNUSED__,
5390 Ecore_X_Event_Window_State_Request *e;
5394 bd = e_border_find_by_client_window(e->win);
5395 if (!bd) return ECORE_CALLBACK_PASS_ON;
5397 for (i = 0; i < 2; i++)
5398 e_hints_window_state_update(bd, e->state[i], e->action);
5400 return ECORE_CALLBACK_PASS_ON;
5404 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
5405 int ev_type __UNUSED__,
5409 Ecore_X_Event_Window_Move_Resize_Request *e;
5412 bd = e_border_find_by_client_window(e->win);
5413 if (!bd) return ECORE_CALLBACK_PASS_ON;
5415 if ((bd->shaded) || (bd->shading) ||
5416 (bd->fullscreen) || (bd->moving) ||
5417 (bd->resize_mode != RESIZE_NONE))
5418 return ECORE_CALLBACK_PASS_ON;
5420 if ((e->button >= 1) && (e->button <= 3))
5422 bd->mouse.last_down[e->button - 1].mx = e->x;
5423 bd->mouse.last_down[e->button - 1].my = e->y;
5424 bd->mouse.last_down[e->button - 1].x = bd->x;
5425 bd->mouse.last_down[e->button - 1].y = bd->y;
5426 bd->mouse.last_down[e->button - 1].w = bd->w;
5427 bd->mouse.last_down[e->button - 1].h = bd->h;
5431 bd->moveinfo.down.x = bd->x;
5432 bd->moveinfo.down.y = bd->y;
5433 bd->moveinfo.down.w = bd->w;
5434 bd->moveinfo.down.h = bd->h;
5436 bd->mouse.current.mx = e->x;
5437 bd->mouse.current.my = e->y;
5438 bd->moveinfo.down.button = e->button;
5439 bd->moveinfo.down.mx = e->x;
5440 bd->moveinfo.down.my = e->y;
5443 if (!bd->lock_user_stacking)
5446 if (e->direction == MOVE)
5448 bd->cur_mouse_action = e_action_find("window_move");
5449 if (bd->cur_mouse_action)
5451 if ((!bd->cur_mouse_action->func.end_mouse) &&
5452 (!bd->cur_mouse_action->func.end))
5453 bd->cur_mouse_action = NULL;
5454 if (bd->cur_mouse_action)
5456 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5457 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
5460 return ECORE_CALLBACK_PASS_ON;
5463 if (!_e_border_resize_begin(bd))
5464 return ECORE_CALLBACK_PASS_ON;
5466 switch(e->direction)
5469 bd->resize_mode = RESIZE_TL;
5470 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
5474 bd->resize_mode = RESIZE_T;
5475 GRAV_SET(bd, ECORE_X_GRAVITY_S);
5479 bd->resize_mode = RESIZE_TR;
5480 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
5484 bd->resize_mode = RESIZE_R;
5485 GRAV_SET(bd, ECORE_X_GRAVITY_W);
5489 bd->resize_mode = RESIZE_BR;
5490 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
5494 bd->resize_mode = RESIZE_B;
5495 GRAV_SET(bd, ECORE_X_GRAVITY_N);
5499 bd->resize_mode = RESIZE_BL;
5500 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
5504 bd->resize_mode = RESIZE_L;
5505 GRAV_SET(bd, ECORE_X_GRAVITY_E);
5509 return ECORE_CALLBACK_PASS_ON;
5512 bd->cur_mouse_action = e_action_find("window_resize");
5513 if (bd->cur_mouse_action)
5515 if ((!bd->cur_mouse_action->func.end_mouse) &&
5516 (!bd->cur_mouse_action->func.end))
5517 bd->cur_mouse_action = NULL;
5519 if (bd->cur_mouse_action)
5520 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5522 return ECORE_CALLBACK_PASS_ON;
5526 _e_border_cb_desktop_change(void *data __UNUSED__,
5527 int ev_type __UNUSED__,
5531 Ecore_X_Event_Desktop_Change *e;
5534 bd = e_border_find_by_client_window(e->win);
5537 if (e->desk == 0xffffffff)
5539 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
5543 desk = e_desk_at_pos_get(bd->zone, e->desk);
5545 e_border_desk_set(bd, desk);
5550 ecore_x_netwm_desktop_set(e->win, e->desk);
5552 return ECORE_CALLBACK_PASS_ON;
5556 _e_border_cb_sync_alarm(void *data __UNUSED__,
5557 int ev_type __UNUSED__,
5561 Ecore_X_Event_Sync_Alarm *e;
5562 unsigned int serial;
5565 bd = e_border_find_by_alarm(e->alarm);
5566 if (!bd) return ECORE_CALLBACK_PASS_ON;
5568 if (bd->client.netwm.sync.wait)
5569 bd->client.netwm.sync.wait--;
5571 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
5573 E_Border_Pending_Move_Resize *pnd = NULL;
5575 /* skip pending for which we didn't get a reply */
5576 while (bd->pending_move_resize)
5578 pnd = bd->pending_move_resize->data;
5579 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
5581 if (serial == pnd->serial)
5593 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
5594 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
5599 bd->changes.size = 1;
5600 bd->changes.pos = 1;
5603 evas_render(bd->bg_evas);
5605 ecore_x_pointer_xy_get(e_manager_current_get()->root,
5606 &bd->mouse.current.mx,
5607 &bd->mouse.current.my);
5609 bd->client.netwm.sync.send_time = ecore_loop_time_get();
5610 _e_border_resize_handle(bd);
5612 return ECORE_CALLBACK_PASS_ON;
5616 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
5617 int ev_type __UNUSED__,
5618 void *ev __UNUSED__)
5623 /* mark all borders for desktop/icon updates */
5624 EINA_LIST_FOREACH(borders, l, bd)
5628 efreet_desktop_free(bd->desktop);
5631 bd->changes.icon = 1;
5635 e_init_status_set(_("Desktop files scan done"));
5638 return ECORE_CALLBACK_PASS_ON;
5642 _e_border_cb_config_icon_theme(void *data __UNUSED__,
5643 int ev_type __UNUSED__,
5644 void *ev __UNUSED__)
5649 /* mark all borders for desktop/icon updates */
5650 EINA_LIST_FOREACH(borders, l, bd)
5652 bd->changes.icon = 1;
5655 return ECORE_CALLBACK_PASS_ON;
5659 * Using '2' is bad, may change in zone flip code.
5660 * Calculate pos from e->x and e->y
5663 _e_border_cb_pointer_warp(void *data __UNUSED__,
5664 int ev_type __UNUSED__,
5667 E_Event_Pointer_Warp *e;
5670 if (!move) return ECORE_CALLBACK_PASS_ON;
5671 e_border_move(move, move->x + (e->curr.x - e->prev.x), move->y + (e->curr.y - e->prev.y));
5672 return ECORE_CALLBACK_PASS_ON;
5676 _e_border_cb_signal_bind(void *data,
5677 Evas_Object *obj __UNUSED__,
5678 const char *emission,
5684 if (e_dnd_active()) return;
5685 e_bindings_signal_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd),
5690 _e_border_cb_mouse_in(void *data,
5691 int type __UNUSED__,
5694 Ecore_X_Event_Mouse_In *ev;
5699 #ifdef INOUTDEBUG_MOUSE
5704 const char *modes[] = {
5706 "MODE_WHILE_GRABBED",
5710 const char *details[] = {
5714 "DETAIL_NON_LINEAR",
5715 "DETAIL_NON_LINEAR_VIRTUAL",
5717 "DETAIL_POINTER_ROOT",
5718 "DETAIL_DETAIL_NONE"
5722 ct[strlen(ct) - 1] = 0;
5723 printf("@@ ->IN 0x%x 0x%x %s md=%s dt=%s\n",
5724 ev->win, ev->event_win,
5727 details[ev->detail]);
5730 if (grabbed) return ECORE_CALLBACK_PASS_ON;
5731 if (ev->event_win == bd->win)
5733 e_focus_event_mouse_in(bd);
5736 if ((ev->win != bd->win) &&
5737 (ev->win != bd->event_win) &&
5738 (ev->event_win != bd->win) &&
5739 (ev->event_win != bd->event_win))
5740 return ECORE_CALLBACK_PASS_ON;
5742 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
5744 bd->mouse.current.mx = ev->root.x;
5745 bd->mouse.current.my = ev->root.y;
5746 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
5747 return ECORE_CALLBACK_PASS_ON;
5751 _e_border_cb_mouse_out(void *data,
5752 int type __UNUSED__,
5755 Ecore_X_Event_Mouse_Out *ev;
5760 #ifdef INOUTDEBUG_MOUSE
5765 const char *modes[] = {
5767 "MODE_WHILE_GRABBED",
5771 const char *details[] = {
5775 "DETAIL_NON_LINEAR",
5776 "DETAIL_NON_LINEAR_VIRTUAL",
5778 "DETAIL_POINTER_ROOT",
5779 "DETAIL_DETAIL_NONE"
5783 ct[strlen(ct) - 1] = 0;
5784 printf("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s\n",
5785 ev->win, ev->event_win,
5788 details[ev->detail]);
5791 if (grabbed) return ECORE_CALLBACK_PASS_ON;
5793 if (ev->event_win == bd->win)
5796 return ECORE_CALLBACK_PASS_ON;
5797 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
5798 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
5799 return ECORE_CALLBACK_PASS_ON;
5800 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
5801 return ECORE_CALLBACK_PASS_ON;
5802 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
5803 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
5804 return ECORE_CALLBACK_PASS_ON;
5805 e_focus_event_mouse_out(bd);
5809 if ((ev->win != bd->win) &&
5810 (ev->win != bd->event_win) &&
5811 (ev->event_win != bd->win) &&
5812 (ev->event_win != bd->event_win))
5813 return ECORE_CALLBACK_PASS_ON;
5815 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
5817 bd->mouse.current.mx = ev->root.x;
5818 bd->mouse.current.my = ev->root.y;
5819 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
5820 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
5821 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
5822 return ECORE_CALLBACK_PASS_ON;
5826 _e_border_cb_mouse_wheel(void *data,
5827 int type __UNUSED__,
5830 Ecore_Event_Mouse_Wheel *ev;
5835 if (ev->event_window == bd->win)
5837 bd->mouse.current.mx = ev->root.x;
5838 bd->mouse.current.my = ev->root.y;
5839 if (!bd->cur_mouse_action)
5840 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_BORDER,
5843 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
5844 return ECORE_CALLBACK_PASS_ON;
5848 _e_border_cb_mouse_down(void *data,
5849 int type __UNUSED__,
5852 Ecore_Event_Mouse_Button *ev;
5857 if (ev->event_window == bd->win)
5859 if ((ev->buttons >= 1) && (ev->buttons <= 3))
5861 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
5862 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
5863 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
5864 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
5865 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
5866 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
5870 bd->moveinfo.down.x = bd->x + bd->fx.x;
5871 bd->moveinfo.down.y = bd->y + bd->fx.y;
5872 bd->moveinfo.down.w = bd->w;
5873 bd->moveinfo.down.h = bd->h;
5875 bd->mouse.current.mx = ev->root.x;
5876 bd->mouse.current.my = ev->root.y;
5877 if (!bd->cur_mouse_action)
5879 bd->cur_mouse_action =
5880 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_BORDER,
5882 if (bd->cur_mouse_action)
5884 if ((!bd->cur_mouse_action->func.end_mouse) &&
5885 (!bd->cur_mouse_action->func.end))
5886 bd->cur_mouse_action = NULL;
5887 if (bd->cur_mouse_action)
5888 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5891 e_focus_event_mouse_down(bd);
5893 if (ev->window != ev->event_window)
5897 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
5901 if ((ev->buttons >= 1) && (ev->buttons <= 3))
5903 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
5904 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
5905 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
5906 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
5907 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
5908 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
5912 bd->moveinfo.down.x = bd->x + bd->fx.x;
5913 bd->moveinfo.down.y = bd->y + bd->fx.y;
5914 bd->moveinfo.down.w = bd->w;
5915 bd->moveinfo.down.h = bd->h;
5917 bd->mouse.current.mx = ev->root.x;
5918 bd->mouse.current.my = ev->root.y;
5923 else if (bd->resize_mode != RESIZE_NONE)
5929 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
5931 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
5932 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
5933 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
5935 return ECORE_CALLBACK_PASS_ON;
5939 _e_border_cb_mouse_up(void *data,
5940 int type __UNUSED__,
5943 Ecore_Event_Mouse_Button *ev;
5948 if (ev->event_window == bd->win)
5950 if ((ev->buttons >= 1) && (ev->buttons <= 3))
5952 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
5953 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
5954 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
5955 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
5957 bd->mouse.current.mx = ev->root.x;
5958 bd->mouse.current.my = ev->root.y;
5959 /* also we dont pass the same params that went in - then again that */
5960 /* should be ok as we are just ending the action if it has an end */
5961 if (bd->cur_mouse_action)
5963 if (bd->cur_mouse_action->func.end_mouse)
5964 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
5965 else if (bd->cur_mouse_action->func.end)
5966 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
5967 e_object_unref(E_OBJECT(bd->cur_mouse_action));
5968 bd->cur_mouse_action = NULL;
5972 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd), ev))
5973 e_focus_event_mouse_up(bd);
5976 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
5977 if ((ev->buttons >= 1) && (ev->buttons <= 3))
5979 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
5980 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
5981 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
5982 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
5984 bd->mouse.current.mx = ev->root.x;
5985 bd->mouse.current.my = ev->root.y;
5989 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
5990 return ECORE_CALLBACK_PASS_ON;
5994 _e_border_cb_mouse_move(void *data,
5995 int type __UNUSED__,
5998 Ecore_Event_Mouse_Move *ev;
6003 if ((ev->window != bd->event_win) &&
6004 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
6005 bd->mouse.current.mx = ev->root.x;
6006 bd->mouse.current.my = ev->root.y;
6009 int x, y, new_x, new_y;
6011 Eina_List *skiplist = NULL;
6013 // FIXME: remove? sync what for when only moving?
6014 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
6015 bd->client.netwm.sync.wait = 0;
6016 if ((bd->client.netwm.sync.request) &&
6017 (bd->client.netwm.sync.alarm) &&
6018 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
6020 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
6022 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
6023 (bd->mouse.current.mx - bd->moveinfo.down.mx);
6024 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
6025 (bd->mouse.current.my - bd->moveinfo.down.my);
6029 x = bd->moveinfo.down.x +
6030 (bd->mouse.current.mx - bd->moveinfo.down.mx);
6031 y = bd->moveinfo.down.y +
6032 (bd->mouse.current.my - bd->moveinfo.down.my);
6036 skiplist = eina_list_append(skiplist, bd);
6037 e_resist_container_border_position(bd->zone->container, skiplist,
6038 bd->x, bd->y, bd->w, bd->h,
6040 &new_x, &new_y, &new_w, &new_h);
6041 eina_list_free(skiplist);
6042 bd->shelf_fix.x = 0;
6043 bd->shelf_fix.y = 0;
6044 bd->shelf_fix.modified = 0;
6045 e_border_move(bd, new_x, new_y);
6046 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
6048 else if (bd->resize_mode != RESIZE_NONE)
6050 if ((bd->client.netwm.sync.request) &&
6051 (bd->client.netwm.sync.alarm))
6053 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
6055 E_Border_Pending_Move_Resize *pnd;
6057 if (bd->pending_move_resize)
6059 bd->changes.pos = 1;
6060 bd->changes.size = 1;
6062 _e_border_client_move_resize_send(bd);
6064 EINA_LIST_FREE(bd->pending_move_resize, pnd)
6067 bd->client.netwm.sync.wait = 0;
6069 /* sync.wait is incremented when resize_handle sends
6070 * sync-request and decremented by sync-alarm cb. so
6071 * we resize here either on initial resize, timeout or
6072 * when no new resize-request was added by sync-alarm cb.
6074 if (!bd->client.netwm.sync.wait)
6075 _e_border_resize_handle(bd);
6078 _e_border_resize_handle(bd);
6084 if ((bd->drag.x == -1) && (bd->drag.y == -1))
6086 bd->drag.x = ev->root.x;
6087 bd->drag.y = ev->root.y;
6093 dx = bd->drag.x - ev->root.x;
6094 dy = bd->drag.y - ev->root.y;
6095 if (((dx * dx) + (dy * dy)) >
6096 (e_config->drag_resist * e_config->drag_resist))
6099 if (bd->icon_object)
6101 Evas_Object *o = NULL;
6102 Evas_Coord x, y, w, h;
6103 const char *drag_types[] = { "enlightenment/border" };
6105 e_object_ref(E_OBJECT(bd));
6106 evas_object_geometry_get(bd->icon_object,
6108 drag_border = e_drag_new(bd->zone->container,
6109 bd->x + bd->fx.x + x,
6110 bd->y + bd->fx.y + y,
6111 drag_types, 1, bd, -1,
6113 _e_border_cb_drag_finished);
6114 o = e_border_icon_add(bd, drag_border->evas);
6117 /* FIXME: fallback icon for drag */
6118 o = evas_object_rectangle_add(drag_border->evas);
6119 evas_object_color_set(o, 255, 255, 255, 255);
6121 e_drag_object_set(drag_border, o);
6123 e_drag_resize(drag_border, w, h);
6124 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
6130 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
6132 return ECORE_CALLBACK_PASS_ON;
6136 _e_border_cb_grab_replay(void *data __UNUSED__,
6140 Ecore_Event_Mouse_Button *ev;
6142 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
6144 if ((e_config->pass_click_on) || (e_config->always_click_to_raise) ||
6145 (e_config->always_click_to_focus))
6149 bd = e_border_find_by_window(ev->event_window);
6152 if (bd->cur_mouse_action)
6153 return ECORE_CALLBACK_DONE;
6154 if (ev->event_window == bd->win)
6156 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_BORDER,
6157 E_OBJECT(bd), ev, NULL))
6158 return ECORE_CALLBACK_PASS_ON;
6162 return ECORE_CALLBACK_DONE;
6166 _e_border_cb_drag_finished(E_Drag *drag,
6167 int dropped __UNUSED__)
6172 e_object_unref(E_OBJECT(bd));
6177 _e_border_post_move_resize_job(void *data)
6181 bd = (E_Border *)data;
6182 if ((bd->post_move) && (bd->post_resize))
6184 ecore_x_window_move_resize(bd->win,
6189 else if (bd->post_move)
6191 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
6193 else if (bd->post_resize)
6195 ecore_x_window_resize(bd->win, bd->w, bd->h);
6202 bd->post_job = NULL;
6208 bd->post_resize = 0;
6209 bd->post_job = NULL;
6210 return ECORE_CALLBACK_CANCEL;
6214 _e_border_container_layout_hook(E_Container *con)
6216 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
6220 _e_border_eval0(E_Border *bd)
6222 int change_urgent = 0;
6225 if (e_object_is_del(E_OBJECT(bd)))
6227 fprintf(stderr, "ERROR: _e_border_eval(%p) with deleted border!\n", bd);
6231 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
6233 bd->changes.border = 0;
6235 /* fetch any info queued to be fetched */
6236 if (bd->client.netwm.fetch.state)
6238 e_hints_window_state_get(bd);
6239 bd->client.netwm.fetch.state = 0;
6242 if (bd->client.icccm.fetch.client_leader)
6244 /* TODO: What do to if the client leader isn't mapped yet? */
6245 E_Border *bd_leader = NULL;
6247 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
6248 if (bd->client.icccm.client_leader)
6249 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
6252 if (bd->leader != bd_leader)
6254 bd->leader->group = eina_list_remove(bd->leader->group, bd);
6255 if (bd->leader->modal == bd) bd->leader->modal = NULL;
6261 /* If this border is the leader of the group, don't register itself */
6262 if ((bd_leader) && (bd_leader != bd))
6264 bd_leader->group = eina_list_append(bd_leader->group, bd);
6265 bd->leader = bd_leader;
6266 /* Only set the window modal to the leader it there is no parent */
6267 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
6268 ((!bd->parent) || (bd->parent->modal != bd)))
6270 bd->leader->modal = bd;
6271 if (bd->leader->focused)
6272 e_border_focus_set(bd, 1, 1);
6278 EINA_LIST_FOREACH(bd->leader->group, l, child)
6280 if ((child != bd) && (child->focused))
6281 e_border_focus_set(bd, 1, 1);
6286 bd->client.icccm.fetch.client_leader = 0;
6289 if (bd->client.icccm.fetch.title)
6291 if (bd->client.icccm.title) free(bd->client.icccm.title);
6292 bd->client.icccm.title = ecore_x_icccm_title_get(bd->client.win);
6294 bd->client.icccm.fetch.title = 0;
6296 edje_object_part_text_set(bd->bg_object, "e.text.title",
6297 bd->client.icccm.title);
6300 if (bd->client.netwm.fetch.name)
6302 if (bd->client.netwm.name) free(bd->client.netwm.name);
6303 ecore_x_netwm_name_get(bd->client.win, &bd->client.netwm.name);
6305 bd->client.netwm.fetch.name = 0;
6307 edje_object_part_text_set(bd->bg_object, "e.text.title",
6308 bd->client.netwm.name);
6311 if (bd->client.icccm.fetch.name_class)
6314 char *pname, *pclass;
6316 pname = bd->client.icccm.name;
6317 pclass = bd->client.icccm.class;
6318 ecore_x_icccm_name_class_get(bd->client.win, &bd->client.icccm.name, &bd->client.icccm.class);
6319 if ((pname) && (bd->client.icccm.name) &&
6320 (pclass) && (bd->client.icccm.class))
6322 if (!((!strcmp(bd->client.icccm.name, pname)) &&
6323 (!strcmp(bd->client.icccm.class, pclass))))
6326 else if (((!pname) || (!pclass)) &&
6327 ((bd->client.icccm.name) || (bd->client.icccm.class)))
6329 else if (((bd->client.icccm.name) || (bd->client.icccm.class)) &&
6330 ((!pname) || (!pclass)))
6332 if (pname) free(pname);
6333 if (pclass) free(pclass);
6335 bd->changes.icon = 1;
6336 bd->client.icccm.fetch.name_class = 0;
6339 if (bd->client.icccm.fetch.state)
6341 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
6342 bd->client.icccm.fetch.state = 0;
6345 if (bd->client.e.fetch.state)
6347 e_hints_window_e_state_get(bd);
6348 bd->client.e.fetch.state = 0;
6351 if (bd->client.netwm.fetch.type)
6353 e_hints_window_type_get(bd);
6354 if ((!bd->lock_border) || (!bd->client.border.name))
6355 bd->client.border.changed = 1;
6357 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
6359 if (!bd->client.netwm.state.skip_pager)
6361 bd->client.netwm.state.skip_pager = 1;
6362 bd->client.netwm.update.state = 1;
6364 if (!bd->client.netwm.state.skip_taskbar)
6366 bd->client.netwm.state.skip_taskbar = 1;
6367 bd->client.netwm.update.state = 1;
6370 bd->client.netwm.fetch.type = 0;
6372 if (bd->client.icccm.fetch.machine)
6374 if (bd->client.icccm.machine) free(bd->client.icccm.machine);
6375 bd->client.icccm.machine = ecore_x_icccm_client_machine_get(bd->client.win);
6376 if ((bd->client.icccm.client_leader) &&
6377 (!bd->client.icccm.machine))
6378 ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
6379 bd->client.icccm.fetch.machine = 0;
6382 if (bd->client.icccm.fetch.command)
6384 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
6388 for (i = 0; i < bd->client.icccm.command.argc; i++)
6389 free(bd->client.icccm.command.argv[i]);
6390 free(bd->client.icccm.command.argv);
6392 bd->client.icccm.command.argc = 0;
6393 bd->client.icccm.command.argv = NULL;
6394 ecore_x_icccm_command_get(bd->client.win,
6395 &(bd->client.icccm.command.argc),
6396 &(bd->client.icccm.command.argv));
6397 if ((bd->client.icccm.client_leader) &&
6398 (!bd->client.icccm.command.argv))
6399 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
6400 &(bd->client.icccm.command.argc),
6401 &(bd->client.icccm.command.argv));
6402 bd->client.icccm.fetch.command = 0;
6405 if (bd->client.icccm.fetch.hints)
6407 Eina_Bool accepts_focus, is_urgent;
6409 accepts_focus = EINA_TRUE;
6410 is_urgent = EINA_FALSE;
6411 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
6412 if (ecore_x_icccm_hints_get(bd->client.win,
6414 &bd->client.icccm.initial_state,
6415 &bd->client.icccm.icon_pixmap,
6416 &bd->client.icccm.icon_mask,
6417 &bd->client.icccm.icon_window,
6418 &bd->client.icccm.window_group,
6421 bd->client.icccm.accepts_focus = accepts_focus;
6422 if (bd->client.icccm.urgent != is_urgent)
6424 bd->client.icccm.urgent = is_urgent;
6426 /* If this is a new window, set the state as requested. */
6427 if ((bd->new_client) &&
6428 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
6430 e_border_iconify(bd);
6431 e_border_hide(bd, 1);
6434 bd->client.icccm.fetch.hints = 0;
6437 if (bd->client.icccm.fetch.size_pos_hints)
6439 Eina_Bool request_pos;
6441 request_pos = EINA_FALSE;
6442 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
6444 &bd->client.icccm.gravity,
6445 &bd->client.icccm.min_w,
6446 &bd->client.icccm.min_h,
6447 &bd->client.icccm.max_w,
6448 &bd->client.icccm.max_h,
6449 &bd->client.icccm.base_w,
6450 &bd->client.icccm.base_h,
6451 &bd->client.icccm.step_w,
6452 &bd->client.icccm.step_h,
6453 &bd->client.icccm.min_aspect,
6454 &bd->client.icccm.max_aspect))
6456 bd->client.icccm.request_pos = request_pos;
6461 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
6462 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
6463 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
6464 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
6465 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
6466 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
6467 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
6468 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
6470 bd->client.icccm.fetch.size_pos_hints = 0;
6473 if (bd->client.icccm.fetch.protocol)
6476 Ecore_X_WM_Protocol *proto;
6478 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
6481 for (i = 0; i < num; i++)
6483 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
6484 bd->client.icccm.delete_request = 1;
6485 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
6486 bd->client.icccm.take_focus = 1;
6487 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
6488 bd->client.netwm.ping = 1;
6489 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
6491 bd->client.netwm.sync.request = 1;
6492 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
6493 &bd->client.netwm.sync.counter))
6494 bd->client.netwm.sync.request = 0;
6499 if (bd->client.netwm.ping)
6503 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
6504 bd->ping_poller = NULL;
6506 bd->client.icccm.fetch.protocol = 0;
6508 if (bd->client.icccm.fetch.transient_for)
6510 /* TODO: What do to if the transient for isn't mapped yet? */
6511 E_Border *bd_parent = NULL;
6513 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
6514 if (bd->client.icccm.transient_for)
6515 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
6516 /* If we already have a parent, remove it */
6519 if (bd_parent != bd->parent)
6521 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
6522 if (bd->parent->modal == bd) bd->parent->modal = NULL;
6528 if ((bd_parent) && (bd_parent != bd))
6530 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
6531 bd->parent = bd_parent;
6532 e_border_layer_set(bd, bd->parent->layer);
6533 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
6534 bd->parent->modal = bd;
6536 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
6537 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
6540 bd->client.icccm.fetch.transient_for = 0;
6543 if (bd->client.icccm.fetch.window_role)
6545 if (bd->client.icccm.window_role) free(bd->client.icccm.window_role);
6546 bd->client.icccm.window_role = ecore_x_icccm_window_role_get(bd->client.win);
6547 bd->client.icccm.fetch.window_role = 0;
6550 if (bd->client.icccm.fetch.icon_name)
6552 if (bd->client.icccm.icon_name) free(bd->client.icccm.icon_name);
6553 bd->client.icccm.icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
6554 bd->client.icccm.fetch.icon_name = 0;
6557 if (bd->client.netwm.fetch.icon_name)
6559 if (bd->client.netwm.icon_name) free(bd->client.netwm.icon_name);
6560 ecore_x_netwm_icon_name_get(bd->client.win, &bd->client.netwm.icon_name);
6561 bd->client.netwm.fetch.icon_name = 0;
6564 if (bd->client.netwm.fetch.icon)
6566 if (bd->client.netwm.icons)
6570 for (i = 0; i < bd->client.netwm.num_icons; i++)
6571 free(bd->client.netwm.icons[i].data);
6572 free(bd->client.netwm.icons);
6574 if (!ecore_x_netwm_icons_get(bd->client.win,
6575 &bd->client.netwm.icons, &bd->client.netwm.num_icons))
6577 bd->client.netwm.icons = NULL;
6578 bd->client.netwm.num_icons = 0;
6581 bd->changes.icon = 1;
6582 bd->client.netwm.fetch.icon = 0;
6584 if (bd->client.netwm.fetch.user_time)
6586 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
6587 bd->client.netwm.fetch.user_time = 0;
6589 if (bd->client.netwm.fetch.strut)
6591 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
6592 &bd->client.netwm.strut.left,
6593 &bd->client.netwm.strut.right,
6594 &bd->client.netwm.strut.top,
6595 &bd->client.netwm.strut.bottom,
6596 &bd->client.netwm.strut.left_start_y,
6597 &bd->client.netwm.strut.left_end_y,
6598 &bd->client.netwm.strut.right_start_y,
6599 &bd->client.netwm.strut.right_end_y,
6600 &bd->client.netwm.strut.top_start_x,
6601 &bd->client.netwm.strut.top_end_x,
6602 &bd->client.netwm.strut.bottom_start_x,
6603 &bd->client.netwm.strut.bottom_end_x))
6605 ecore_x_netwm_strut_get(bd->client.win,
6606 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
6607 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
6609 bd->client.netwm.strut.left_start_y = 0;
6610 bd->client.netwm.strut.left_end_y = 0;
6611 bd->client.netwm.strut.right_start_y = 0;
6612 bd->client.netwm.strut.right_end_y = 0;
6613 bd->client.netwm.strut.top_start_x = 0;
6614 bd->client.netwm.strut.top_end_x = 0;
6615 bd->client.netwm.strut.bottom_start_x = 0;
6616 bd->client.netwm.strut.bottom_end_x = 0;
6618 bd->client.netwm.fetch.strut = 0;
6620 if (bd->client.qtopia.fetch.soft_menu)
6622 e_hints_window_qtopia_soft_menu_get(bd);
6623 bd->client.qtopia.fetch.soft_menu = 0;
6626 if (bd->client.qtopia.fetch.soft_menus)
6628 e_hints_window_qtopia_soft_menus_get(bd);
6629 bd->client.qtopia.fetch.soft_menus = 0;
6632 if (bd->client.vkbd.fetch.state)
6634 e_hints_window_virtual_keyboard_state_get(bd);
6635 bd->client.vkbd.fetch.state = 0;
6638 if (bd->client.vkbd.fetch.vkbd)
6640 e_hints_window_virtual_keyboard_get(bd);
6641 bd->client.vkbd.fetch.vkbd = 0;
6644 if (bd->client.illume.conformant.fetch.conformant)
6646 bd->client.illume.conformant.conformant =
6647 ecore_x_e_illume_conformant_get(bd->client.win);
6648 bd->client.illume.conformant.fetch.conformant = 0;
6650 if (bd->client.illume.quickpanel.fetch.state)
6652 bd->client.illume.quickpanel.state =
6653 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
6654 bd->client.illume.quickpanel.fetch.state = 0;
6656 if (bd->client.illume.quickpanel.fetch.quickpanel)
6658 bd->client.illume.quickpanel.quickpanel =
6659 ecore_x_e_illume_quickpanel_get(bd->client.win);
6660 bd->client.illume.quickpanel.fetch.quickpanel = 0;
6662 if (bd->client.illume.quickpanel.fetch.priority.major)
6664 bd->client.illume.quickpanel.priority.major =
6665 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
6666 bd->client.illume.quickpanel.fetch.priority.major = 0;
6668 if (bd->client.illume.quickpanel.fetch.priority.minor)
6670 bd->client.illume.quickpanel.priority.minor =
6671 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
6672 bd->client.illume.quickpanel.fetch.priority.minor = 0;
6674 if (bd->client.illume.quickpanel.fetch.zone)
6676 bd->client.illume.quickpanel.zone =
6677 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
6678 bd->client.illume.quickpanel.fetch.zone = 0;
6680 if (bd->client.illume.drag.fetch.drag)
6682 bd->client.illume.drag.drag =
6683 ecore_x_e_illume_drag_get(bd->client.win);
6684 bd->client.illume.drag.fetch.drag = 0;
6686 if (bd->client.illume.drag.fetch.locked)
6688 bd->client.illume.drag.locked =
6689 ecore_x_e_illume_drag_locked_get(bd->client.win);
6690 bd->client.illume.drag.fetch.locked = 0;
6692 if (bd->changes.shape)
6694 Ecore_X_Rectangle *rects;
6697 bd->changes.shape = 0;
6698 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
6703 /* This doesn't fix the race, but makes it smaller. we detect
6704 * this and if cw and ch != client w/h then mark this as needing
6705 * a shape change again to fixup next event loop.
6707 ecore_x_window_size_get(bd->client.win, &cw, &ch);
6708 if ((cw != bd->client.w) || (ch != bd->client.h))
6709 bd->changes.shape = 1;
6711 (rects[0].x == 0) &&
6712 (rects[0].y == 0) &&
6713 ((int)rects[0].width == cw) &&
6714 ((int)rects[0].height == ch))
6716 if (bd->client.shaped)
6718 bd->client.shaped = 0;
6719 if (!bd->bordername)
6720 bd->client.border.changed = 1;
6725 if (!bd->client.shaped)
6727 bd->client.shaped = 1;
6728 if (!bd->bordername)
6729 bd->client.border.changed = 1;
6736 // FIXME: no rects i think can mean... totally empty window
6737 bd->client.shaped = 0;
6738 if (!bd->bordername)
6739 bd->client.border.changed = 1;
6741 bd->need_shape_merge = 1;
6743 if (bd->changes.shape_input)
6745 Ecore_X_Rectangle *rects;
6748 bd->changes.shape_input = 0;
6749 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
6754 /* This doesn't fix the race, but makes it smaller. we detect
6755 * this and if cw and ch != client w/h then mark this as needing
6756 * a shape change again to fixup next event loop.
6758 ecore_x_window_size_get(bd->client.win, &cw, &ch);
6759 if ((cw != bd->client.w) || (ch != bd->client.h))
6760 bd->changes.shape_input = 1;
6762 (rects[0].x == 0) &&
6763 (rects[0].y == 0) &&
6764 ((int)rects[0].width == cw) &&
6765 ((int)rects[0].height == ch))
6767 if (bd->shaped_input)
6769 bd->shaped_input = 0;
6770 if (!bd->bordername)
6771 bd->client.border.changed = 1;
6776 if (!bd->shaped_input)
6778 bd->shaped_input = 1;
6779 if (!bd->bordername)
6780 bd->client.border.changed = 1;
6787 bd->shaped_input = 1;
6788 if (!bd->bordername)
6789 bd->client.border.changed = 1;
6791 bd->need_shape_merge = 1;
6793 if (bd->client.mwm.fetch.hints)
6797 bd->client.mwm.exists =
6798 ecore_x_mwm_hints_get(bd->client.win,
6799 &bd->client.mwm.func,
6800 &bd->client.mwm.decor,
6801 &bd->client.mwm.input);
6802 pb = bd->client.mwm.borderless;
6803 bd->client.mwm.borderless = 0;
6804 if (bd->client.mwm.exists)
6806 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
6807 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
6808 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
6809 bd->client.mwm.borderless = 1;
6811 if (bd->client.mwm.borderless != pb)
6813 if ((!bd->lock_border) || (!bd->client.border.name))
6814 bd->client.border.changed = 1;
6816 bd->client.mwm.fetch.hints = 0;
6819 if (bd->client.netwm.update.state)
6821 e_hints_window_state_set(bd);
6822 /* Some stats might change the border, like modal */
6823 if (((!bd->lock_border) || (!bd->client.border.name)) &&
6824 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
6826 bd->client.border.changed = 1;
6830 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
6832 bd->parent->modal = bd;
6833 if (bd->parent->focused)
6834 e_border_focus_set(bd, 1, 1);
6837 else if (bd->leader)
6839 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
6841 bd->leader->modal = bd;
6842 if (bd->leader->focused)
6843 e_border_focus_set(bd, 1, 1);
6849 EINA_LIST_FOREACH(bd->leader->group, l, child)
6851 if ((child != bd) && (child->focused))
6852 e_border_focus_set(bd, 1, 1);
6857 bd->client.netwm.update.state = 0;
6862 E_Event_Border_Add *ev;
6864 ev = E_NEW(E_Event_Border_Add, 1);
6866 e_object_ref(E_OBJECT(bd));
6867 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
6868 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
6870 if ((!bd->lock_border) || (!bd->client.border.name))
6871 bd->client.border.changed = 1;
6874 /* PRE_POST_FETCH calls e_remember apply for new client */
6875 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
6876 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
6877 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
6879 if (bd->need_reparent)
6882 ecore_x_window_save_set_add(bd->client.win);
6883 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
6886 if ((bd->new_client) && (bd->internal) &&
6887 (bd->internal_ecore_evas))
6888 ecore_evas_show(bd->internal_ecore_evas);
6889 ecore_x_window_show(bd->client.win);
6891 bd->need_reparent = 0;
6894 if ((bd->client.border.changed) && (!bd->shaded) &&
6895 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
6897 const char *bordername;
6900 bordername = "borderless";
6901 else if (bd->bordername)
6902 bordername = bd->bordername;
6903 else if ((bd->client.mwm.borderless) || (bd->borderless))
6904 bordername = "borderless";
6905 else if (((bd->client.icccm.transient_for != 0) ||
6906 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
6907 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
6908 (bd->client.icccm.min_h == bd->client.icccm.max_h))
6909 bordername = "noresize_dialog";
6910 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
6911 (bd->client.icccm.min_h == bd->client.icccm.max_h))
6912 bordername = "noresize";
6913 else if (bd->client.shaped)
6914 bordername = "shaped";
6915 else if ((!bd->client.icccm.accepts_focus) &&
6916 (!bd->client.icccm.take_focus))
6917 bordername = "nofocus";
6918 else if (bd->client.icccm.urgent)
6919 bordername = "urgent";
6920 else if ((bd->client.icccm.transient_for != 0) ||
6921 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
6922 bordername = "dialog";
6923 else if (bd->client.netwm.state.modal)
6924 bordername = "modal";
6925 else if ((bd->client.netwm.state.skip_taskbar) ||
6926 (bd->client.netwm.state.skip_pager))
6927 bordername = "skipped";
6929 bordername = e_config->theme_default_border_style;
6930 if (!bordername) bordername = "default";
6932 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
6936 Evas_Coord cx, cy, cw, ch;
6939 bd->changes.border = 1;
6940 if (bd->client.border.name)
6941 eina_stringshare_del(bd->client.border.name);
6942 bd->client.border.name = eina_stringshare_add(bordername);
6946 bd->w -= (bd->client_inset.l + bd->client_inset.r);
6947 bd->h -= (bd->client_inset.t + bd->client_inset.b);
6948 bd->client_inset.l = 0;
6949 bd->client_inset.r = 0;
6950 bd->client_inset.t = 0;
6951 bd->client_inset.b = 0;
6952 bd->changes.size = 1;
6953 evas_object_del(bd->bg_object);
6955 o = edje_object_add(bd->bg_evas);
6956 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border",
6957 bd->client.border.name);
6958 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
6959 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
6961 ok = e_theme_edje_object_set(o, "base/theme/borders",
6962 "e/widgets/border/default/border");
6965 /* Reset default border style to default */
6966 if (e_config->theme_default_border_style)
6967 eina_stringshare_del(e_config->theme_default_border_style);
6968 e_config->theme_default_border_style = eina_stringshare_add("default");
6969 e_config_save_queue();
6976 const char *shape_option, *argb_option;
6981 if (!bd->client.argb)
6983 argb_option = edje_object_data_get(o, "argb");
6984 if ((argb_option) && (!strcmp(argb_option, "1")))
6987 if (use_argb != bd->argb)
6988 _e_border_frame_replace(bd, use_argb);
6995 shape_option = edje_object_data_get(o, "shaped");
6996 if ((shape_option) && (!strcmp(shape_option, "1")))
7000 if (bd->client.netwm.name)
7001 edje_object_part_text_set(o, "e.text.title",
7002 bd->client.netwm.name);
7003 else if (bd->client.icccm.title)
7004 edje_object_part_text_set(o, "e.text.title",
7005 bd->client.icccm.title);
7006 evas_object_resize(o, 1000, 1000);
7007 edje_object_calc_force(o);
7008 edje_object_part_geometry_get(o, "e.swallow.client",
7009 &cx, &cy, &cw, &ch);
7011 r = 1000 - (cx + cw);
7013 b = 1000 - (cy + ch);
7018 bd->bg_object = NULL;
7024 bd->client_inset.l = l;
7025 bd->client_inset.r = r;
7026 bd->client_inset.t = t;
7027 bd->client_inset.b = b;
7028 ecore_x_netwm_frame_size_set(bd->client.win, l, r, t, b);
7029 ecore_x_e_frame_size_set(bd->client.win, l, r, t, b);
7030 bd->w += (bd->client_inset.l + bd->client_inset.r);
7031 bd->h += (bd->client_inset.t + bd->client_inset.b);
7032 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
7033 bd->changes.size = 1;
7034 ecore_x_window_move(bd->client.shell_win, l, t);
7036 if (bd->maximized != E_MAXIMIZE_NONE)
7041 E_Maximize maximized = bd->maximized;
7043 /* to force possible resizes */
7044 bd->maximized = E_MAXIMIZE_NONE;
7046 zx = zy = zw = zh = 0;
7048 switch (maximized & E_MAXIMIZE_TYPE)
7050 case E_MAXIMIZE_FULLSCREEN:
7056 Evas_Coord cx, cy, cw, ch;
7058 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
7060 evas_object_resize(bd->bg_object, w, h);
7061 edje_object_calc_force(bd->bg_object);
7062 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
7063 bd->client_inset.l = cx;
7064 bd->client_inset.r = w - (cx + cw);
7065 bd->client_inset.t = cy;
7066 bd->client_inset.b = h - (cy + ch);
7067 ecore_x_netwm_frame_size_set(bd->client.win,
7068 bd->client_inset.l, bd->client_inset.r,
7069 bd->client_inset.t, bd->client_inset.b);
7070 ecore_x_e_frame_size_set(bd->client.win,
7071 bd->client_inset.l, bd->client_inset.r,
7072 bd->client_inset.t, bd->client_inset.b);
7074 e_border_resize_limit(bd, &w, &h);
7075 /* center x-direction */
7076 x1 = bd->zone->x + (bd->zone->w - w) / 2;
7077 /* center y-direction */
7078 y1 = bd->zone->y + (bd->zone->h - h) / 2;
7080 if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
7081 _e_border_move_resize_internal(bd, x1, y1, w, h, 0, 1);
7082 else if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
7083 _e_border_move_resize_internal(bd, bd->x, y1, bd->w, h, 0, 1);
7085 else if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
7086 _e_border_move_resize_internal(bd, x1, bd->y, w, bd->h, 0, 1);
7089 case E_MAXIMIZE_SMART:
7090 case E_MAXIMIZE_EXPAND:
7092 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
7104 if (bd->x < zx) // window left not useful coordinates
7106 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
7107 x1 = zx + zw - bd->w;
7108 else // window normal position
7111 if (bd->y < zy) // window top not useful coordinates
7113 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
7114 y1 = zy + zh - bd->h;
7115 else // window normal position
7118 if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
7119 _e_border_move_resize_internal(bd, zx, zy, zw, zh, 0, 1);
7120 else if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
7121 _e_border_move_resize_internal(bd, x1, zy, w, zh, 0, 1);
7122 else if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
7123 _e_border_move_resize_internal(bd, zx, y1, zw, h, 0, 1);
7126 case E_MAXIMIZE_FILL:
7129 x2 = bd->zone->x + bd->zone->w;
7130 y2 = bd->zone->y + bd->zone->h;
7132 /* walk through all shelves */
7133 e_maximize_border_shelf_fill(bd, &x1, &y1, &x2, &y2, maximized);
7135 /* walk through all windows */
7136 e_maximize_border_border_fill(bd, &x1, &y1, &x2, &y2, maximized);
7142 e_border_resize_limit(bd, &w, &h);
7143 /* center x-direction */
7144 x1 = x1 + (pw - w) / 2;
7145 /* center y-direction */
7146 y1 = y1 + (ph - h) / 2;
7147 if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
7148 _e_border_move_resize_internal(bd, x1, y1, w, h, 0, 1);
7149 else if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
7150 _e_border_move_resize_internal(bd, bd->x, y1, bd->w, h, 0, 1);
7151 else if ((maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
7152 _e_border_move_resize_internal(bd, x1, bd->y, w, bd->h, 0, 1);
7155 /* restore maximized state */
7156 bd->maximized = maximized;
7158 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
7159 bd->maximized & E_MAXIMIZE_VERTICAL);
7163 edje_object_signal_callback_add(bd->bg_object, "*", "*",
7164 _e_border_cb_signal_bind, bd);
7167 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
7168 if (bd->icon_object)
7169 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
7172 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
7174 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
7176 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
7177 if (bd->client.icccm.urgent)
7178 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
7179 // FIXME: in eval -do differently
7180 // edje_object_message_signal_process(bd->bg_object);
7181 // e_border_frame_recalc(bd);
7183 evas_object_move(bd->bg_object, 0, 0);
7184 evas_object_resize(bd->bg_object, bd->w, bd->h);
7185 evas_object_show(bd->bg_object);
7188 bd->client.border.changed = 0;
7190 if (bd->icon_object)
7194 evas_object_show(bd->icon_object);
7195 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
7198 evas_object_hide(bd->icon_object);
7202 if (rem_change) e_remember_update(bd);
7206 E_Event_Border_Urgent_Change *ev;
7208 if (bd->client.icccm.urgent)
7209 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
7211 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
7213 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
7215 e_object_ref(E_OBJECT(bd));
7216 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
7217 _e_border_event_border_urgent_change_free, NULL);
7220 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
7223 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
7225 _e_border_latest_stacked_focus (E_Border* bd)
7227 Eina_List *l = NULL;
7231 root_w = bd->zone->w;
7232 root_h = bd->zone->h;
7235 bl = e_container_border_list_last(bd->zone->container);
7236 while ((temp_bd = e_container_border_list_prev(bl)))
7238 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
7239 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
7241 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
7242 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
7243 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
7244 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
7245 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
7246 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
7247 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
7255 /* this border is the top of the latest stack */
7256 e_border_focus_set (temp_bd, 1, 1);
7262 e_container_border_list_free(bl);
7266 _e_border_check_stack (E_Border *bd)
7268 Eina_List* l = NULL;
7269 E_Border* temp_bd = NULL;;
7270 E_Border* top_bd = NULL;
7271 int passed_focus = 0;
7273 int root_w = bd->zone->w;
7274 int root_h = bd->zone->h;
7277 bl = e_container_border_list_last(bd->zone->container);
7278 while ((temp_bd = e_container_border_list_prev(bl)))
7280 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
7281 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
7283 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
7284 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
7285 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
7286 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
7287 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
7288 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
7289 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
7295 e_border_focus_set_with_pointer(bd);
7302 e_border_focus_set_with_pointer(top_bd);
7311 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
7313 if (!bd->lock_focus_out)
7315 e_border_focus_latest_set(bd);
7327 if (temp_bd == focused)
7333 e_container_border_list_free(bl);
7337 _e_border_focus_top_stack_set (E_Border* bd)
7339 Eina_List *l = NULL;
7343 root_w = bd->zone->w;
7344 root_h = bd->zone->h;
7347 bl = e_container_border_list_last(bd->zone->container);
7348 while ((temp_bd = e_container_border_list_prev(bl)))
7350 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
7351 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
7353 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
7354 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
7355 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
7356 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
7357 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
7358 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
7359 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
7361 if (!temp_bd->focused)
7363 /* this border is the top of the latest stack */
7364 e_border_focus_set (temp_bd, 1, 1);
7369 e_container_border_list_free(bl);
7374 _e_border_eval(E_Border *bd)
7376 E_Event_Border_Property *event;
7377 E_Border_Pending_Move_Resize *pnd;
7381 if (e_object_is_del(E_OBJECT(bd)))
7383 fprintf(stderr, "ERROR: _e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
7388 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
7392 int zx = 0, zy = 0, zw = 0, zh = 0;
7395 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
7398 * Limit maximum size of windows to useful geometry
7400 // TODO: temoporary limited maximize algorithm
7412 if ((rw != bd->w) || (rh != bd->h))
7416 e_border_resize (bd, bd->w, bd->h);
7422 bd->x -= bd->client_inset.l;
7423 bd->y -= bd->client_inset.t;
7424 bd->changes.pos = 1;
7427 else if (!bd->placed)
7429 if (bd->client.icccm.request_pos)
7431 Ecore_X_Window_Attributes *att;
7434 att = &bd->client.initial_attributes;
7435 bw = att->border * 2;
7436 switch (bd->client.icccm.gravity)
7438 case ECORE_X_GRAVITY_N:
7439 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
7443 case ECORE_X_GRAVITY_NE:
7444 bd->x = (att->x - (bw)) - (bd->client_inset.l);
7448 case ECORE_X_GRAVITY_E:
7449 bd->x = (att->x - (bw)) - (bd->client_inset.l);
7450 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
7453 case ECORE_X_GRAVITY_SE:
7454 bd->x = (att->x - (bw)) - (bd->client_inset.l);
7455 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7458 case ECORE_X_GRAVITY_S:
7459 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
7460 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7463 case ECORE_X_GRAVITY_SW:
7465 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7468 case ECORE_X_GRAVITY_W:
7470 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7473 case ECORE_X_GRAVITY_CENTER:
7474 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
7475 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
7478 case ECORE_X_GRAVITY_NW:
7485 * This ensures that windows that like to open with a x/y
7486 * position smaller than returned by e_zone_useful_geometry_get()
7487 * are moved to useful positions.
7496 if (bd->x + bd->w > zw)
7497 bd->x = zx + zw - bd->w;
7499 if (bd->y + bd->h > zh)
7500 bd->y = zy + zh - bd->h;
7503 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
7505 bd->changes.pos = 1;
7511 /* FIXME: special placement for dialogs etc. etc. etc goes
7513 /* FIXME: what if parent is not on this desktop - or zone? */
7514 if ((bd->parent) && (bd->parent->visible))
7516 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
7517 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
7518 bd->changes.pos = 1;
7522 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
7524 /* TODO: Place in center of group */
7527 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
7529 bd->x = zx + ((zw - bd->w) / 2);
7530 bd->y = zy + ((zh - bd->h) / 2);
7531 bd->changes.pos = 1;
7536 Eina_List *skiplist = NULL;
7540 new_x = zx + (rand() % (zw - bd->w));
7544 new_y = zy + (rand() % (zh - bd->h));
7548 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
7550 skiplist = eina_list_append(skiplist, bd);
7551 e_place_zone_region_smart(bd->zone, skiplist,
7552 bd->x, bd->y, bd->w, bd->h,
7554 eina_list_free(skiplist);
7556 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
7558 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
7563 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
7564 bd->client_inset.t, &new_x, &new_y);
7568 bd->changes.pos = 1;
7572 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7574 if ((!bd->lock_client_location) && (pnd->move))
7578 bd->changes.pos = 1;
7580 if (pnd->without_border)
7582 bd->x -= bd->client_inset.l;
7583 bd->y -= bd->client_inset.t;
7586 if ((!bd->lock_client_size) && (pnd->resize))
7588 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
7589 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
7590 bd->client.w = pnd->w;
7591 bd->client.h = pnd->h;
7592 bd->changes.size = 1;
7597 /* Recreate state */
7598 e_hints_window_init(bd);
7599 if ((bd->client.e.state.centered) &&
7601 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
7603 bd->x = zx + (zw - bd->w) / 2;
7604 bd->y = zy + (zh - bd->h) / 2;
7605 bd->changes.pos = 1;
7609 _e_border_client_move_resize_send(bd);
7611 /* if the explicit geometry request asks for the app to be
7612 * in another zone - well move it there */
7616 zone = e_container_zone_at_point_get(bd->zone->container,
7617 bd->x + (bd->w / 2),
7618 bd->y + (bd->h / 2));
7620 zone = e_container_zone_at_point_get(bd->zone->container,
7624 zone = e_container_zone_at_point_get(bd->zone->container,
7628 zone = e_container_zone_at_point_get(bd->zone->container,
7632 zone = e_container_zone_at_point_get(bd->zone->container,
7635 if ((zone) && (zone != bd->zone))
7637 e_border_zone_set(bd, zone);
7638 /* e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh); */
7643 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
7645 /* effect changes to the window border itself */
7646 if ((bd->changes.shading))
7648 /* show at start of unshade (but don't hide until end of shade) */
7650 ecore_x_window_raise(bd->client.shell_win);
7651 bd->changes.shading = 0;
7654 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
7657 ecore_x_window_lower(bd->client.shell_win);
7659 ecore_x_window_raise(bd->client.shell_win);
7660 bd->changes.shaded = 0;
7663 else if ((bd->changes.shaded) && (bd->changes.pos))
7666 ecore_x_window_lower(bd->client.shell_win);
7668 ecore_x_window_raise(bd->client.shell_win);
7669 bd->changes.size = 1;
7670 bd->changes.shaded = 0;
7673 else if ((bd->changes.shaded) && (bd->changes.size))
7676 ecore_x_window_lower(bd->client.shell_win);
7678 ecore_x_window_raise(bd->client.shell_win);
7679 bd->changes.shaded = 0;
7682 else if (bd->changes.shaded)
7685 ecore_x_window_lower(bd->client.shell_win);
7687 ecore_x_window_raise(bd->client.shell_win);
7688 bd->changes.size = 1;
7689 bd->changes.shaded = 0;
7693 if (bd->changes.size)
7695 int x = 0, y = 0, xx = 0, yy = 0;
7697 if ((bd->shaded) && (!bd->shading))
7699 evas_obscured_clear(bd->bg_evas);
7703 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
7704 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
7706 evas_obscured_clear(bd->bg_evas);
7707 evas_obscured_rectangle_add(bd->bg_evas,
7708 bd->client_inset.l, bd->client_inset.t, xx, yy);
7712 if (bd->shade.dir == E_DIRECTION_UP)
7714 y = yy - bd->client.h;
7716 else if (bd->shade.dir == E_DIRECTION_LEFT)
7718 x = xx - bd->client.w;
7723 if (!bd->changes.pos)
7725 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
7726 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
7727 bd->post_resize = 1;
7731 ecore_x_window_move_resize(bd->win,
7737 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
7739 if ((!bd->shaded) || (bd->shading))
7740 ecore_x_window_move_resize(bd->client.shell_win,
7741 bd->client_inset.l, bd->client_inset.t, xx, yy);
7743 if (bd->internal_ecore_evas)
7744 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
7746 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
7748 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
7749 evas_object_resize(bd->bg_object, bd->w, bd->h);
7750 e_container_shape_resize(bd->shape, bd->w, bd->h);
7751 if (bd->changes.pos)
7752 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
7754 _e_border_client_move_resize_send(bd);
7756 bd->changes.pos = 0;
7757 bd->changes.size = 0;
7760 else if (bd->changes.pos)
7762 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
7763 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
7766 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
7768 _e_border_client_move_resize_send(bd);
7770 bd->changes.pos = 0;
7774 if (bd->changes.reset_gravity)
7776 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
7777 bd->changes.reset_gravity = 0;
7781 if (bd->need_shape_merge)
7783 _e_border_shape_input_rectangle_set(bd);
7784 if ((bd->shaped) || (bd->client.shaped))
7786 Ecore_X_Window twin, twin2;
7789 twin = ecore_x_window_override_new
7790 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
7792 ecore_x_window_shape_window_set(twin, bd->bg_win);
7795 Ecore_X_Rectangle rects[4];
7799 rects[0].width = bd->w;
7800 rects[0].height = bd->client_inset.t;
7802 rects[1].y = bd->client_inset.t;
7803 rects[1].width = bd->client_inset.l;
7804 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
7805 rects[2].x = bd->w - bd->client_inset.r;
7806 rects[2].y = bd->client_inset.t;
7807 rects[2].width = bd->client_inset.r;
7808 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
7810 rects[3].y = bd->h - bd->client_inset.b;
7811 rects[3].width = bd->w;
7812 rects[3].height = bd->client_inset.b;
7813 ecore_x_window_shape_rectangles_set(twin, rects, 4);
7815 twin2 = ecore_x_window_override_new
7816 (bd->zone->container->scratch_win, 0, 0,
7817 bd->w - bd->client_inset.l - bd->client_inset.r,
7818 bd->h - bd->client_inset.t - bd->client_inset.b);
7821 if ((bd->shading) || (bd->shaded))
7823 if (bd->shade.dir == E_DIRECTION_UP)
7824 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
7825 else if (bd->shade.dir == E_DIRECTION_LEFT)
7826 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
7828 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
7830 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
7831 bd->w - bd->client_inset.l - bd->client_inset.r,
7832 bd->h - bd->client_inset.t - bd->client_inset.b);
7833 ecore_x_window_shape_window_add_xy(twin, twin2,
7835 bd->client_inset.t);
7836 ecore_x_window_free(twin2);
7837 ecore_x_window_shape_window_set(bd->win, twin);
7838 ecore_x_window_free(twin);
7841 ecore_x_window_shape_mask_set(bd->win, 0);
7842 // bd->need_shape_export = 1;
7843 bd->need_shape_merge = 0;
7846 if (bd->need_shape_export)
7848 Ecore_X_Rectangle *rects, *orects;
7851 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
7857 if ((num == bd->shape_rects_num) && (bd->shape_rects))
7861 orects = bd->shape_rects;
7863 for (i = 0; i < num; i++)
7867 rects[i].width -= rects[i].x;
7870 if ((rects[i].x + (int)rects[i].width) > bd->w)
7871 rects[i].width = rects[i].width - rects[i].x;
7874 rects[i].height -= rects[i].y;
7877 if ((rects[i].y + (int)rects[i].height) > bd->h)
7878 rects[i].height = rects[i].height - rects[i].y;
7880 if ((orects[i].x != rects[i].x) ||
7881 (orects[i].y != rects[i].y) ||
7882 (orects[i].width != rects[i].width) ||
7883 (orects[i].height != rects[i].height))
7892 if (bd->client.shaped)
7893 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
7895 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
7896 E_FREE(bd->shape_rects);
7897 bd->shape_rects = rects;
7898 bd->shape_rects_num = num;
7899 e_container_shape_rects_set(bd->shape, rects, num);
7906 E_FREE(bd->shape_rects);
7907 bd->shape_rects = NULL;
7908 bd->shape_rects_num = 0;
7909 e_container_shape_rects_set(bd->shape, NULL, 0);
7911 bd->need_shape_export = 0;
7914 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
7918 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
7919 if ((!bd->placed) && (!bd->re_manage) &&
7920 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
7921 (!((bd->client.icccm.transient_for != 0) ||
7922 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
7923 (!move) && (!resize))
7925 /* Set this window into moving state */
7927 bd->cur_mouse_action = e_action_find("window_move");
7928 if (bd->cur_mouse_action)
7930 if ((!bd->cur_mouse_action->func.end_mouse) &&
7931 (!bd->cur_mouse_action->func.end))
7932 bd->cur_mouse_action = NULL;
7933 if (bd->cur_mouse_action)
7935 bd->x = x - (bd->w >> 1);
7936 bd->y = y - (bd->client_inset.t >> 1);
7938 bd->changes.pos = 1;
7940 _e_border_client_move_resize_send(bd);
7947 if (bd->cur_mouse_action)
7949 bd->moveinfo.down.x = bd->x + bd->fx.x;
7950 bd->moveinfo.down.y = bd->y + bd->fx.y;
7951 bd->moveinfo.down.w = bd->w;
7952 bd->moveinfo.down.h = bd->h;
7953 bd->mouse.current.mx = x;
7954 bd->mouse.current.my = y;
7955 bd->moveinfo.down.button = 0;
7956 bd->moveinfo.down.mx = x;
7957 bd->moveinfo.down.my = y;
7960 e_object_ref(E_OBJECT(bd->cur_mouse_action));
7961 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
7962 if (e_config->border_raise_on_mouse_action)
7964 e_border_focus_set(bd, 1, 1);
7966 bd->changes.visible = 0;
7970 if (bd->changes.icon)
7974 efreet_desktop_free(bd->desktop);
7977 if (bd->icon_object)
7979 evas_object_del(bd->icon_object);
7980 bd->icon_object = NULL;
7982 if (bd->remember && bd->remember->prop.desktop_file)
7984 const char *desktop = bd->remember->prop.desktop_file;
7986 bd->desktop = efreet_desktop_get(desktop);
7988 bd->desktop = efreet_util_desktop_name_find(desktop);
7992 if ((bd->client.icccm.name) && (bd->client.icccm.class))
7993 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
7994 bd->client.icccm.class);
7998 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
7999 bd->client.netwm.pid);
8000 if (bd->desktop) efreet_desktop_ref(bd->desktop);
8002 if (!bd->desktop && bd->client.icccm.name)
8004 /* this works for most cases as fallback. useful when app is
8006 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
8008 if (!bd->desktop && bd->client.icccm.transient_for)
8010 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
8011 if (bd2 && bd2->desktop)
8013 efreet_desktop_ref(bd2->desktop);
8014 bd->desktop = bd2->desktop;
8019 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
8020 bd->desktop->orig_path);
8023 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
8024 if ((bd->focused) && (bd->icon_object))
8025 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
8028 evas_object_show(bd->icon_object);
8029 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
8032 evas_object_hide(bd->icon_object);
8035 E_Event_Border_Icon_Change *ev;
8037 ev = E_NEW(E_Event_Border_Icon_Change, 1);
8039 e_object_ref(E_OBJECT(bd));
8040 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
8041 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
8042 _e_border_event_border_icon_change_free, NULL);
8044 bd->changes.icon = 0;
8049 bd->changes.stack = 0;
8050 bd->changes.prop = 0;
8052 if ((bd->take_focus) || (bd->want_focus))
8055 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8056 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
8057 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
8060 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
8065 #ifdef INOUTDEBUG_FOCUS
8066 printf("__________ focus new window _________\n");
8069 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8070 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
8071 _e_border_check_stack(bd);
8074 e_border_focus_set_with_pointer(bd);
8076 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
8078 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
8079 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
8080 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
8081 e_border_focused_get())))
8083 #ifdef INOUTDEBUG_FOCUS
8084 printf("__________ focus new dialog _________\n");
8087 e_border_focus_set_with_pointer(bd);
8092 #ifdef INOUTDEBUG_FOCUS
8093 printf("__________ window takes focus _________\n");
8095 /* focus window by default when it is the only one on desk */
8096 E_Border *bd2 = NULL;
8098 EINA_LIST_FOREACH(focus_stack, l, bd2)
8100 if (bd == bd2) continue;
8101 if ((!bd2->iconic) && (bd2->visible) && (bd->desk == bd2->desk))
8106 e_border_focus_set_with_pointer(bd);
8110 if (bd->need_maximize)
8113 max = bd->maximized;
8114 bd->maximized = E_MAXIMIZE_NONE;
8115 e_border_maximize(bd, max);
8116 bd->need_maximize = 0;
8119 if (bd->need_fullscreen)
8121 e_border_fullscreen(bd, e_config->fullscreen_policy);
8122 bd->need_fullscreen = 0;
8126 e_remember_update(bd);
8128 if (send_event) // FIXME: send only if a property changed - above need to
8129 { // check on that. for now - always send.
8130 event = E_NEW(E_Event_Border_Property, 1);
8132 e_object_ref(E_OBJECT(bd));
8133 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
8135 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
8139 _e_border_moveinfo_gather(E_Border *bd,
8142 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
8143 else if (e_util_glob_match(source, "mouse,*,2"))
8144 bd->moveinfo.down.button = 2;
8145 else if (e_util_glob_match(source, "mouse,*,3"))
8146 bd->moveinfo.down.button = 3;
8147 else bd->moveinfo.down.button = 0;
8148 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
8150 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
8151 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
8155 bd->moveinfo.down.mx = bd->mouse.current.mx;
8156 bd->moveinfo.down.my = bd->mouse.current.my;
8161 _e_border_resize_handle(E_Border *bd)
8164 int new_x, new_y, new_w, new_h;
8166 Eina_List *skiplist = NULL;
8173 if ((bd->resize_mode == RESIZE_TR) ||
8174 (bd->resize_mode == RESIZE_R) ||
8175 (bd->resize_mode == RESIZE_BR))
8177 if ((bd->moveinfo.down.button >= 1) &&
8178 (bd->moveinfo.down.button <= 3))
8179 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
8180 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8182 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
8184 else if ((bd->resize_mode == RESIZE_TL) ||
8185 (bd->resize_mode == RESIZE_L) ||
8186 (bd->resize_mode == RESIZE_BL))
8188 if ((bd->moveinfo.down.button >= 1) &&
8189 (bd->moveinfo.down.button <= 3))
8190 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
8191 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8193 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
8196 if ((bd->resize_mode == RESIZE_TL) ||
8197 (bd->resize_mode == RESIZE_T) ||
8198 (bd->resize_mode == RESIZE_TR))
8200 if ((bd->moveinfo.down.button >= 1) &&
8201 (bd->moveinfo.down.button <= 3))
8202 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
8203 (bd->mouse.current.my - bd->moveinfo.down.my);
8205 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
8207 else if ((bd->resize_mode == RESIZE_BL) ||
8208 (bd->resize_mode == RESIZE_B) ||
8209 (bd->resize_mode == RESIZE_BR))
8211 if ((bd->moveinfo.down.button >= 1) &&
8212 (bd->moveinfo.down.button <= 3))
8213 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
8214 (bd->mouse.current.my - bd->moveinfo.down.my);
8216 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
8222 if ((bd->resize_mode == RESIZE_TL) ||
8223 (bd->resize_mode == RESIZE_L) ||
8224 (bd->resize_mode == RESIZE_BL))
8226 if ((bd->resize_mode == RESIZE_TL) ||
8227 (bd->resize_mode == RESIZE_T) ||
8228 (bd->resize_mode == RESIZE_TR))
8231 skiplist = eina_list_append(skiplist, bd);
8232 e_resist_container_border_position(bd->zone->container, skiplist,
8233 bd->x, bd->y, bd->w, bd->h,
8235 &new_x, &new_y, &new_w, &new_h);
8236 eina_list_free(skiplist);
8240 e_border_resize_limit(bd, &new_w, &new_h);
8241 if ((bd->resize_mode == RESIZE_TL) ||
8242 (bd->resize_mode == RESIZE_L) ||
8243 (bd->resize_mode == RESIZE_BL))
8244 new_x += (w - new_w);
8245 if ((bd->resize_mode == RESIZE_TL) ||
8246 (bd->resize_mode == RESIZE_T) ||
8247 (bd->resize_mode == RESIZE_TR))
8248 new_y += (h - new_h);
8250 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
8254 _e_border_shade_animator(void *data)
8256 E_Border *bd = data;
8258 double dur = bd->client.h / e_config->border_shade_speed;
8260 dt = ecore_loop_time_get() - bd->shade.start;
8263 if (val < 0.0) val = 0.0;
8267 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
8270 bd->shade.val = (1 - cos(val * M_PI)) / 2.0;
8272 bd->shade.val = 0.5 + (cos(val * M_PI) / 2.0);
8274 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
8277 bd->shade.val = sin(val * M_PI / 2.0);
8279 bd->shade.val = 1 - sin(val * M_PI / 2.0);
8281 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
8284 bd->shade.val = 1 - cos(val * M_PI / 2.0);
8286 bd->shade.val = cos(val * M_PI / 2.0);
8288 else /* LINEAR if none of the others */
8291 bd->shade.val = val;
8293 bd->shade.val = 1 - val;
8296 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
8297 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
8298 else if (bd->shade.val > .999)
8299 bd->shade.val = 1.0;
8301 if (bd->shade.dir == E_DIRECTION_UP)
8302 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
8303 else if (bd->shade.dir == E_DIRECTION_DOWN)
8305 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
8306 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
8307 bd->changes.pos = 1;
8309 else if (bd->shade.dir == E_DIRECTION_LEFT)
8310 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
8311 else if (bd->shade.dir == E_DIRECTION_RIGHT)
8313 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
8314 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
8315 bd->changes.pos = 1;
8318 if ((bd->shaped) || (bd->client.shaped))
8320 bd->need_shape_merge = 1;
8321 bd->need_shape_export = 1;
8323 if (bd->shaped_input)
8325 bd->need_shape_merge = 1;
8327 bd->changes.size = 1;
8331 if ((bd->shaded && (bd->shade.val == 1)) ||
8332 ((!bd->shaded) && (bd->shade.val == 0)))
8334 E_Event_Border_Resize *ev;
8337 bd->shaded = !(bd->shaded);
8338 bd->changes.size = 1;
8339 bd->changes.shaded = 1;
8340 bd->changes.shading = 1;
8342 bd->shade.anim = NULL;
8345 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
8347 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
8348 edje_object_message_signal_process(bd->bg_object);
8349 e_border_frame_recalc(bd);
8351 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
8352 ev = E_NEW(E_Event_Border_Resize, 1);
8354 e_object_ref(E_OBJECT(bd));
8355 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
8356 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
8357 return ECORE_CALLBACK_CANCEL;
8359 return ECORE_CALLBACK_RENEW;
8363 _e_border_event_border_resize_free(void *data __UNUSED__,
8366 E_Event_Border_Resize *e;
8369 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
8370 e_object_unref(E_OBJECT(e->border));
8375 _e_border_event_border_move_free(void *data __UNUSED__,
8378 E_Event_Border_Move *e;
8381 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
8382 e_object_unref(E_OBJECT(e->border));
8387 _e_border_event_border_add_free(void *data __UNUSED__,
8390 E_Event_Border_Add *e;
8393 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
8394 e_object_unref(E_OBJECT(e->border));
8399 _e_border_event_border_remove_free(void *data __UNUSED__,
8402 E_Event_Border_Remove *e;
8405 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
8406 e_object_unref(E_OBJECT(e->border));
8411 _e_border_event_border_show_free(void *data __UNUSED__,
8414 E_Event_Border_Show *e;
8417 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
8418 e_object_unref(E_OBJECT(e->border));
8423 _e_border_event_border_hide_free(void *data __UNUSED__,
8426 E_Event_Border_Hide *e;
8429 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
8430 e_object_unref(E_OBJECT(e->border));
8435 _e_border_event_border_iconify_free(void *data __UNUSED__,
8438 E_Event_Border_Iconify *e;
8441 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
8442 e_object_unref(E_OBJECT(e->border));
8447 _e_border_event_border_uniconify_free(void *data __UNUSED__,
8450 E_Event_Border_Uniconify *e;
8453 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
8454 e_object_unref(E_OBJECT(e->border));
8459 _e_border_event_border_stick_free(void *data __UNUSED__,
8462 E_Event_Border_Stick *e;
8465 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
8466 e_object_unref(E_OBJECT(e->border));
8471 _e_border_event_border_unstick_free(void *data __UNUSED__,
8474 E_Event_Border_Unstick *e;
8477 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
8478 e_object_unref(E_OBJECT(e->border));
8483 _e_border_event_border_zone_set_free(void *data __UNUSED__,
8486 E_Event_Border_Zone_Set *e;
8489 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
8490 e_object_unref(E_OBJECT(e->border));
8491 e_object_unref(E_OBJECT(e->zone));
8496 _e_border_event_border_desk_set_free(void *data __UNUSED__,
8499 E_Event_Border_Desk_Set *e;
8502 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
8503 e_object_unref(E_OBJECT(e->border));
8504 e_object_unref(E_OBJECT(e->desk));
8509 _e_border_event_border_stack_free(void *data __UNUSED__,
8512 E_Event_Border_Stack *e;
8515 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
8516 e_object_unref(E_OBJECT(e->border));
8519 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
8520 e_object_unref(E_OBJECT(e->stack));
8526 _e_border_event_border_icon_change_free(void *data __UNUSED__,
8529 E_Event_Border_Icon_Change *e;
8532 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
8533 e_object_unref(E_OBJECT(e->border));
8538 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
8541 E_Event_Border_Urgent_Change *e;
8544 e_object_unref(E_OBJECT(e->border));
8549 _e_border_event_border_focus_in_free(void *data __UNUSED__,
8552 E_Event_Border_Focus_In *e;
8555 e_object_unref(E_OBJECT(e->border));
8560 _e_border_event_border_focus_out_free(void *data __UNUSED__,
8563 E_Event_Border_Focus_Out *e;
8566 e_object_unref(E_OBJECT(e->border));
8571 _e_border_event_border_property_free(void *data __UNUSED__,
8574 E_Event_Border_Property *e;
8577 e_object_unref(E_OBJECT(e->border));
8582 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
8585 E_Event_Border_Fullscreen *e;
8588 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
8589 e_object_unref(E_OBJECT(e->border));
8594 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
8597 E_Event_Border_Unfullscreen *e;
8600 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
8601 e_object_unref(E_OBJECT(e->border));
8606 _e_border_zone_update(E_Border *bd)
8612 /* still within old zone - leave it there */
8613 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
8614 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
8616 /* find a new zone */
8617 con = bd->zone->container;
8618 EINA_LIST_FOREACH(con->zones, l, zone)
8620 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
8621 zone->x, zone->y, zone->w, zone->h))
8623 e_border_zone_set(bd, zone);
8630 _e_border_resize_begin(E_Border *bd)
8632 if (!bd->lock_user_stacking)
8634 if (e_config->border_raise_on_mouse_action)
8637 if ((bd->shaded) || (bd->shading) ||
8638 (bd->fullscreen) || (bd->lock_user_size))
8641 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
8647 if (bd->client.netwm.sync.request)
8649 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
8650 bd->client.netwm.sync.serial = 1;
8651 bd->client.netwm.sync.wait = 0;
8652 bd->client.netwm.sync.send_time = ecore_loop_time_get();
8655 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
8662 _e_border_resize_end(E_Border *bd)
8666 e_grabinput_release(bd->win, bd->win);
8669 if (bd->client.netwm.sync.alarm)
8671 E_Border_Pending_Move_Resize *pnd;
8673 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
8674 bd->client.netwm.sync.alarm = 0;
8675 /* resize to last geometry if sync alarm for it was not yet handled */
8676 if (bd->pending_move_resize)
8679 bd->changes.pos = 1;
8680 bd->changes.size = 1;
8681 _e_border_client_move_resize_send(bd);
8684 EINA_LIST_FREE(bd->pending_move_resize, pnd)
8688 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
8692 /* If this border was maximized, we need to unset Maximized state or
8693 * on restart, E still thinks it's maximized */
8694 if (bd->maximized != E_MAXIMIZE_NONE)
8695 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
8696 bd->maximized & E_MAXIMIZE_NONE);
8701 _e_border_resize_update(E_Border *bd)
8703 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
8707 _e_border_move_begin(E_Border *bd)
8709 if (!bd->lock_user_stacking)
8711 if (e_config->border_raise_on_mouse_action)
8714 if ((bd->fullscreen) || (bd->lock_user_location))
8717 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
8723 if (bd->client.netwm.sync.request)
8725 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
8726 bd->client.netwm.sync.serial = 0;
8727 bd->client.netwm.sync.wait = 0;
8728 bd->client.netwm.sync.time = ecore_loop_time_get();
8731 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
8738 _e_border_move_end(E_Border *bd)
8742 e_grabinput_release(bd->win, bd->win);
8746 if (bd->client.netwm.sync.alarm)
8748 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
8749 bd->client.netwm.sync.alarm = 0;
8752 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
8759 _e_border_move_update(E_Border *bd)
8761 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
8765 _e_border_cb_ping_poller(void *data)
8775 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
8778 ecore_timer_del(bd->kill_timer);
8779 bd->kill_timer = NULL;
8788 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
8789 /* FIXME: if below dialog is up - hide it now */
8791 if (bd->delete_requested)
8793 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
8794 e_border_act_kill_begin(bd);
8797 bd->ping_poller = NULL;
8799 return ECORE_CALLBACK_CANCEL;
8803 _e_border_cb_kill_timer(void *data)
8808 // dont wait until it's hung -
8811 if (bd->client.netwm.pid > 1)
8812 kill(bd->client.netwm.pid, SIGKILL);
8814 bd->kill_timer = NULL;
8815 return ECORE_CALLBACK_CANCEL;
8819 _e_border_pointer_resize_begin(E_Border *bd)
8821 switch (bd->resize_mode)
8824 e_pointer_type_push(bd->pointer, bd, "resize_tl");
8828 e_pointer_type_push(bd->pointer, bd, "resize_t");
8832 e_pointer_type_push(bd->pointer, bd, "resize_tr");
8836 e_pointer_type_push(bd->pointer, bd, "resize_r");
8840 e_pointer_type_push(bd->pointer, bd, "resize_br");
8844 e_pointer_type_push(bd->pointer, bd, "resize_b");
8848 e_pointer_type_push(bd->pointer, bd, "resize_bl");
8852 e_pointer_type_push(bd->pointer, bd, "resize_l");
8858 _e_border_pointer_resize_end(E_Border *bd)
8860 switch (bd->resize_mode)
8863 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
8867 e_pointer_type_pop(bd->pointer, bd, "resize_t");
8871 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
8875 e_pointer_type_pop(bd->pointer, bd, "resize_r");
8879 e_pointer_type_pop(bd->pointer, bd, "resize_br");
8883 e_pointer_type_pop(bd->pointer, bd, "resize_b");
8887 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
8891 e_pointer_type_pop(bd->pointer, bd, "resize_l");
8897 _e_border_pointer_move_begin(E_Border *bd)
8899 e_pointer_type_push(bd->pointer, bd, "move");
8903 _e_border_pointer_move_end(E_Border *bd)
8905 e_pointer_type_pop(bd->pointer, bd, "move");
8908 static Eina_List *_e_border_hooks = NULL;
8909 static int _e_border_hooks_delete = 0;
8910 static int _e_border_hooks_walking = 0;
8913 _e_border_hooks_clean(void)
8918 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
8922 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
8929 _e_border_hook_call(E_Border_Hook_Point hookpoint,
8935 _e_border_hooks_walking++;
8936 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
8938 if (bh->delete_me) continue;
8939 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
8941 _e_border_hooks_walking--;
8942 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
8943 _e_border_hooks_clean();
8946 EAPI E_Border_Hook *
8947 e_border_hook_add(E_Border_Hook_Point hookpoint,
8948 void (*func)(void *data,
8954 bh = E_NEW(E_Border_Hook, 1);
8955 if (!bh) return NULL;
8956 bh->hookpoint = hookpoint;
8959 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
8964 e_border_hook_del(E_Border_Hook *bh)
8967 if (_e_border_hooks_walking == 0)
8969 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
8973 _e_border_hooks_delete++;
8977 e_border_focus_track_freeze(void)
8979 focus_track_frozen++;
8983 e_border_focus_track_thaw(void)
8985 focus_track_frozen--;
8989 e_border_under_pointer_get(E_Desk *desk,
8992 E_Border *bd = NULL, *cbd;
8996 /* We need to ensure that we can get the container window for the
8997 * zone of either the given desk or the desk of the excluded
8998 * window, so return if neither is given */
9000 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
9002 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
9006 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
9009 /* If a border was specified which should be excluded from the list
9010 * (because it will be closed shortly for example), skip */
9011 if ((exclude) && (cbd == exclude)) continue;
9012 if ((desk) && (cbd->desk != desk)) continue;
9013 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
9015 /* If the layer is higher, the position of the window is higher
9016 * (always on top vs always below) */
9017 if (!bd || (cbd->layer > bd->layer))
9027 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
9034 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
9035 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
9036 (y - warp_y) > 5 || (y - warp_y) < -5)
9038 /* User moved the mouse, so stop warping */
9043 /* We just use the same warp speed as configured
9044 * for the windowlist */
9045 spd = e_config->winlist_warp_speed;
9048 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
9049 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
9050 if (warp_x == x && warp_y == y)
9057 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
9058 return ECORE_CALLBACK_RENEW;
9061 ecore_timer_del(warp_timer);
9063 return ECORE_CALLBACK_CANCEL;
9067 e_border_pointer_warp_to_center(E_Border *bd)
9071 /* Do not slide pointer when disabled (probably breaks focus
9072 * on sloppy/mouse focus but requested by users). */
9073 if (!e_config->pointer_slide) return 0;
9074 /* Only warp the pointer if it is not already in the area of
9075 * the given border */
9076 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
9077 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
9078 (y >= bd->y) && (y <= (bd->y + bd->h)))
9081 warp_to_x = bd->x + (bd->w / 2);
9082 if (warp_to_x < (bd->zone->x + 1))
9083 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
9084 else if (warp_to_x > (bd->zone->x + bd->zone->w))
9085 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
9087 warp_to_y = bd->y + (bd->h / 2);
9088 if (warp_to_y < (bd->zone->y + 1))
9089 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
9090 else if (warp_to_y > (bd->zone->y + bd->zone->h))
9091 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
9094 warp_to_win = bd->zone->container->win;
9095 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
9097 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
9102 e_border_comp_hidden_set(E_Border *bd,
9106 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
9108 if (bd->comp_hidden == hidden) return;
9110 bd->comp_hidden = hidden;
9112 if (bd->comp_hidden)
9114 ecore_x_composite_window_events_disable(bd->win);
9115 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
9119 _e_border_shape_input_rectangle_set(bd);
9120 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
9123 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/