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_pri_raise(E_Border *bd);
20 static void _e_border_pri_norm(E_Border *bd);
21 static void _e_border_free(E_Border *bd);
22 static void _e_border_del(E_Border *bd);
24 #ifdef PRINT_LOTS_OF_DEBUG
25 #define E_PRINT_BORDER_INFO(X) \
26 _e_border_print(X, __PRETTY_FUNC__)
28 static void _e_border_print(E_Border *bd,
32 /* FIXME: these likely belong in a separate icccm/client handler */
33 /* and the border needs to become a dumb object that just does what its */
35 static Eina_Bool _e_border_cb_window_show_request(void *data,
38 static Eina_Bool _e_border_cb_window_destroy(void *data,
41 static Eina_Bool _e_border_cb_window_hide(void *data,
44 static Eina_Bool _e_border_cb_window_reparent(void *data,
47 static Eina_Bool _e_border_cb_window_configure_request(void *data,
50 static Eina_Bool _e_border_cb_window_resize_request(void *data,
53 static Eina_Bool _e_border_cb_window_gravity(void *data,
56 static Eina_Bool _e_border_cb_window_stack_request(void *data,
59 static Eina_Bool _e_border_cb_window_property(void *data,
62 static Eina_Bool _e_border_cb_window_colormap(void *data,
65 static Eina_Bool _e_border_cb_window_shape(void *data,
68 static Eina_Bool _e_border_cb_window_focus_in(void *data,
71 static Eina_Bool _e_border_cb_window_focus_out(void *data,
74 static Eina_Bool _e_border_cb_client_message(void *data,
78 static Eina_Bool _e_border_cb_window_state_request(void *data,
81 static Eina_Bool _e_border_cb_window_move_resize_request(void *data,
84 static Eina_Bool _e_border_cb_desktop_change(void *data,
87 static Eina_Bool _e_border_cb_sync_alarm(void *data,
90 static Eina_Bool _e_border_cb_efreet_cache_update(void *data,
93 static Eina_Bool _e_border_cb_config_icon_theme(void *data,
97 static Eina_Bool _e_border_cb_pointer_warp(void *data,
100 static void _e_border_cb_signal_bind(void *data,
102 const char *emission,
104 static Eina_Bool _e_border_cb_mouse_in(void *data,
107 static Eina_Bool _e_border_cb_mouse_out(void *data,
110 static Eina_Bool _e_border_cb_mouse_wheel(void *data,
113 static Eina_Bool _e_border_cb_mouse_down(void *data,
116 static Eina_Bool _e_border_cb_mouse_up(void *data,
119 static Eina_Bool _e_border_cb_mouse_move(void *data,
122 static Eina_Bool _e_border_cb_grab_replay(void *data,
125 static void _e_border_cb_drag_finished(E_Drag *drag,
128 static void _e_border_eval(E_Border *bd);
129 static void _e_border_eval0(E_Border *bd);
130 static void _e_border_container_layout_hook(E_Container *con);
132 static void _e_border_moveinfo_gather(E_Border *bd,
134 static void _e_border_resize_handle(E_Border *bd);
136 static Eina_Bool _e_border_shade_animator(void *data);
138 static void _e_border_event_border_add_free(void *data,
140 static void _e_border_event_border_remove_free(void *data,
142 static void _e_border_event_border_zone_set_free(void *data,
144 static void _e_border_event_border_desk_set_free(void *data,
146 static void _e_border_event_border_stack_free(void *data,
148 static void _e_border_event_border_icon_change_free(void *data,
150 static void _e_border_event_border_urgent_change_free(void *data,
152 static void _e_border_event_border_focus_in_free(void *data,
154 static void _e_border_event_border_focus_out_free(void *data,
156 static void _e_border_event_border_resize_free(void *data,
158 static void _e_border_event_border_move_free(void *data,
160 static void _e_border_event_border_show_free(void *data,
162 static void _e_border_event_border_hide_free(void *data,
164 static void _e_border_event_border_iconify_free(void *data,
166 static void _e_border_event_border_uniconify_free(void *data,
168 static void _e_border_event_border_stick_free(void *data,
170 static void _e_border_event_border_unstick_free(void *data,
172 static void _e_border_event_border_property_free(void *data,
174 static void _e_border_event_border_fullscreen_free(void *data,
176 static void _e_border_event_border_unfullscreen_free(void *data,
179 static void _e_border_zone_update(E_Border *bd);
181 static int _e_border_resize_begin(E_Border *bd);
182 static int _e_border_resize_end(E_Border *bd);
183 static void _e_border_resize_update(E_Border *bd);
185 static int _e_border_move_begin(E_Border *bd);
186 static int _e_border_move_end(E_Border *bd);
187 static void _e_border_move_update(E_Border *bd);
189 static Eina_Bool _e_border_cb_ping_poller(void *data);
190 static Eina_Bool _e_border_cb_kill_timer(void *data);
192 static void _e_border_pointer_resize_begin(E_Border *bd);
193 static void _e_border_pointer_resize_end(E_Border *bd);
194 static void _e_border_pointer_move_begin(E_Border *bd);
195 static void _e_border_pointer_move_end(E_Border *bd);
197 static void _e_border_hook_call(E_Border_Hook_Point hookpoint,
200 static void _e_border_client_move_resize_send(E_Border *bd);
202 static void _e_border_frame_replace(E_Border *bd,
205 static void _e_border_shape_input_rectangle_set(E_Border* bd);
206 static void _e_border_show(E_Border *bd);
207 static void _e_border_hide(E_Border *bd);
210 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
211 static void _e_border_latest_stacked_focus (E_Border* bd);
212 static void _e_border_check_stack (E_Border *bd);
213 static void _e_border_focus_top_stack_set (E_Border* bd);
216 /* local subsystem globals */
217 static Eina_List *handlers = NULL;
218 static Eina_List *borders = NULL;
219 static Eina_Hash *borders_hash = NULL;
220 static E_Border *focused = NULL;
221 static E_Border *focusing = NULL;
222 static Eina_List *focus_next = NULL;
223 static Ecore_X_Time focus_time = 0;
225 static E_Border *bdresize = NULL;
226 static E_Border *bdmove = NULL;
227 static E_Drag *drag_border = NULL;
229 static int grabbed = 0;
231 static Eina_List *focus_stack = NULL;
232 static Eina_List *raise_stack = NULL;
234 static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 };
235 static int screen_size_index = -1;
237 static int focus_track_frozen = 0;
239 static int warp_to = 0;
240 static int warp_to_x = 0;
241 static int warp_to_y = 0;
242 static int warp_x = 0;
243 static int warp_y = 0;
244 static Ecore_X_Window warp_to_win;
245 static Ecore_Timer *warp_timer = NULL;
247 EAPI int E_EVENT_BORDER_ADD = 0;
248 EAPI int E_EVENT_BORDER_REMOVE = 0;
249 EAPI int E_EVENT_BORDER_ZONE_SET = 0;
250 EAPI int E_EVENT_BORDER_DESK_SET = 0;
251 EAPI int E_EVENT_BORDER_RESIZE = 0;
252 EAPI int E_EVENT_BORDER_MOVE = 0;
253 EAPI int E_EVENT_BORDER_SHOW = 0;
254 EAPI int E_EVENT_BORDER_HIDE = 0;
255 EAPI int E_EVENT_BORDER_ICONIFY = 0;
256 EAPI int E_EVENT_BORDER_UNICONIFY = 0;
257 EAPI int E_EVENT_BORDER_STICK = 0;
258 EAPI int E_EVENT_BORDER_UNSTICK = 0;
259 EAPI int E_EVENT_BORDER_STACK = 0;
260 EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
261 EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
262 EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
263 EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
264 EAPI int E_EVENT_BORDER_PROPERTY = 0;
265 EAPI int E_EVENT_BORDER_FULLSCREEN = 0;
266 EAPI int E_EVENT_BORDER_UNFULLSCREEN = 0;
268 #define GRAV_SET(bd, grav) \
269 ecore_x_window_gravity_set(bd->bg_win, grav); \
270 ecore_x_window_gravity_set(bd->client.shell_win, grav); \
271 ecore_x_window_gravity_set(bd->client.win, grav);
273 /* externally accessible functions */
277 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
278 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
279 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
280 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
281 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
282 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
283 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
284 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
285 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
286 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
287 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
288 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
289 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
290 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
291 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
292 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
293 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
294 handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
296 ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
298 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
299 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
300 handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_ICON_CACHE_UPDATE, _e_border_cb_efreet_cache_update, NULL));
301 handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
303 if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
305 E_EVENT_BORDER_ADD = ecore_event_type_new();
306 E_EVENT_BORDER_REMOVE = ecore_event_type_new();
307 E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
308 E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
309 E_EVENT_BORDER_RESIZE = ecore_event_type_new();
310 E_EVENT_BORDER_MOVE = ecore_event_type_new();
311 E_EVENT_BORDER_SHOW = ecore_event_type_new();
312 E_EVENT_BORDER_HIDE = ecore_event_type_new();
313 E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
314 E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
315 E_EVENT_BORDER_STICK = ecore_event_type_new();
316 E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
317 E_EVENT_BORDER_STACK = ecore_event_type_new();
318 E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
319 E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
320 E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
321 E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
322 E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
323 E_EVENT_BORDER_FULLSCREEN = ecore_event_type_new();
324 E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new();
332 e_border_shutdown(void)
334 E_FREE_LIST(handlers, ecore_event_handler_del);
336 if (borders_hash) eina_hash_free(borders_hash);
343 e_border_new(E_Container *con,
349 Ecore_X_Window_Attributes *att;
350 unsigned int managed, desk[2];
353 bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
354 if (!bd) return NULL;
355 ecore_x_window_shadow_tree_flush();
356 e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
360 /* FIXME: ewww - round trip */
361 bd->client.argb = ecore_x_window_argb_get(win);
363 bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
366 bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
367 ecore_x_window_shape_events_select(bd->win, 1);
369 e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
370 e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
372 bd->bg_ecore_evas = e_canvas_new(bd->win,
373 0, 0, bd->w, bd->h, 1, 0,
375 ecore_evas_ignore_events_set(bd->bg_ecore_evas, EINA_TRUE);
376 e_canvas_add(bd->bg_ecore_evas);
377 bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
378 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
379 ecore_x_window_shape_events_select(bd->bg_win, 1);
380 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
381 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
383 bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
385 bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
386 ecore_x_window_container_manage(bd->client.shell_win);
387 if (!internal) ecore_x_window_client_manage(win);
388 /* FIXME: Round trip. XCB */
389 /* fetch needed to avoid grabbing the server as window may vanish */
390 att = &bd->client.initial_attributes;
391 if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
393 // printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
394 e_canvas_del(bd->bg_ecore_evas);
395 ecore_evas_free(bd->bg_ecore_evas);
396 ecore_x_window_free(bd->client.shell_win);
397 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
398 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
399 ecore_x_window_free(bd->win);
404 /* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
405 * bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
407 /* FIXME: if first_map is 1 then we should ignore the first hide event
408 * or ensure the window is already hidden and events flushed before we
409 * create a border for it */
412 // printf("##- FIRST MAP\n");
417 // needed to be 1 for internal windw and on restart.
418 // bd->ignore_first_unmap = 2;
421 bd->client.win = win;
422 bd->zone = e_zone_current_get(con);
424 _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
426 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
427 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
428 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
429 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
430 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
431 bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
433 bd->client.icccm.title = NULL;
434 bd->client.icccm.name = NULL;
435 bd->client.icccm.class = NULL;
436 bd->client.icccm.icon_name = NULL;
437 bd->client.icccm.machine = NULL;
438 bd->client.icccm.min_w = 1;
439 bd->client.icccm.min_h = 1;
440 bd->client.icccm.max_w = 32767;
441 bd->client.icccm.max_h = 32767;
442 bd->client.icccm.base_w = 0;
443 bd->client.icccm.base_h = 0;
444 bd->client.icccm.step_w = -1;
445 bd->client.icccm.step_h = -1;
446 bd->client.icccm.min_aspect = 0.0;
447 bd->client.icccm.max_aspect = 0.0;
448 bd->client.icccm.accepts_focus = 1;
450 bd->client.netwm.pid = 0;
451 bd->client.netwm.name = NULL;
452 bd->client.netwm.icon_name = NULL;
453 bd->client.netwm.desktop = 0;
454 bd->client.netwm.state.modal = 0;
455 bd->client.netwm.state.sticky = 0;
456 bd->client.netwm.state.shaded = 0;
457 bd->client.netwm.state.hidden = 0;
458 bd->client.netwm.state.maximized_v = 0;
459 bd->client.netwm.state.maximized_h = 0;
460 bd->client.netwm.state.skip_taskbar = 0;
461 bd->client.netwm.state.skip_pager = 0;
462 bd->client.netwm.state.fullscreen = 0;
463 bd->client.netwm.state.stacking = E_STACKING_NONE;
464 bd->client.netwm.action.move = 0;
465 bd->client.netwm.action.resize = 0;
466 bd->client.netwm.action.minimize = 0;
467 bd->client.netwm.action.shade = 0;
468 bd->client.netwm.action.stick = 0;
469 bd->client.netwm.action.maximized_h = 0;
470 bd->client.netwm.action.maximized_v = 0;
471 bd->client.netwm.action.fullscreen = 0;
472 bd->client.netwm.action.change_desktop = 0;
473 bd->client.netwm.action.close = 0;
474 bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
480 atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
481 bd->client.icccm.fetch.command = 1;
484 Eina_Bool video_parent = EINA_FALSE;
485 Eina_Bool video_position = EINA_FALSE;
488 for (i = 0; i < at_num; i++)
490 if (atoms[i] == ECORE_X_ATOM_WM_NAME)
491 bd->client.icccm.fetch.title = 1;
492 else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
493 bd->client.icccm.fetch.name_class = 1;
494 else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
495 bd->client.icccm.fetch.icon_name = 1;
496 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
497 bd->client.icccm.fetch.machine = 1;
498 else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
499 bd->client.icccm.fetch.hints = 1;
500 else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
501 bd->client.icccm.fetch.size_pos_hints = 1;
502 else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
503 bd->client.icccm.fetch.protocol = 1;
504 else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
505 bd->client.mwm.fetch.hints = 1;
506 else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
508 bd->client.icccm.fetch.transient_for = 1;
509 bd->client.netwm.fetch.type = 1;
511 else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
512 bd->client.icccm.fetch.client_leader = 1;
513 else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
514 bd->client.icccm.fetch.window_role = 1;
515 else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
516 bd->client.icccm.fetch.state = 1;
518 /* netwm, loop again, netwm will ignore some icccm, so we
519 * have to be sure that netwm is checked after */
520 for (i = 0; i < at_num; i++)
522 if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
525 bd->client.icccm.fetch.title = 0;
526 bd->client.netwm.fetch.name = 1;
528 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
531 bd->client.icccm.fetch.icon_name = 0;
532 bd->client.netwm.fetch.icon_name = 1;
534 else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
536 bd->client.netwm.fetch.icon = 1;
538 else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
540 bd->client.netwm.fetch.user_time = 1;
542 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
544 printf("ECORE_X_ATOM_NET_WM_STRUT\n");
545 bd->client.netwm.fetch.strut = 1;
547 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
549 printf("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL\n");
550 bd->client.netwm.fetch.strut = 1;
552 else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
555 bd->client.mwm.fetch.hints = 0;
557 bd->client.netwm.fetch.type = 1;
559 else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
561 bd->client.netwm.fetch.state = 1;
564 /* other misc atoms */
565 for (i = 0; i < at_num; i++)
567 /* loop to check for own atoms */
568 if (atoms[i] == E_ATOM_WINDOW_STATE)
570 bd->client.e.fetch.state = 1;
572 /* loop to check for qtopia atoms */
573 if (atoms[i] == ATM__QTOPIA_SOFT_MENU)
574 bd->client.qtopia.fetch.soft_menu = 1;
575 else if (atoms[i] == ATM__QTOPIA_SOFT_MENUS)
576 bd->client.qtopia.fetch.soft_menus = 1;
577 /* loop to check for vkbd atoms */
578 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
579 bd->client.vkbd.fetch.state = 1;
580 else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
581 bd->client.vkbd.fetch.vkbd = 1;
582 /* loop to check for illume atoms */
583 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
584 bd->client.illume.conformant.fetch.conformant = 1;
585 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
586 bd->client.illume.quickpanel.fetch.state = 1;
587 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
588 bd->client.illume.quickpanel.fetch.quickpanel = 1;
589 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
590 bd->client.illume.quickpanel.fetch.priority.major = 1;
591 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
592 bd->client.illume.quickpanel.fetch.priority.minor = 1;
593 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
594 bd->client.illume.quickpanel.fetch.zone = 1;
595 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
596 bd->client.illume.drag.fetch.locked = 1;
597 else if (atoms[i] == ECORE_X_ATOM_E_ILLUME_DRAG)
598 bd->client.illume.drag.fetch.drag = 1;
599 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_PARENT)
600 video_parent = EINA_TRUE;
601 else if (atoms[i] == ECORE_X_ATOM_E_VIDEO_POSITION)
602 video_position = EINA_TRUE;
604 if (video_position && video_parent)
606 bd->client.e.state.video = 1;
607 bd->client.e.fetch.video_parent = 1;
608 bd->client.e.fetch.video_position = 1;
609 ecore_x_window_lower(bd->win);
610 ecore_x_composite_window_events_disable(bd->win);
611 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
612 fprintf(stderr, "We found a video window \\o/ %x\n", win);
617 bd->client.border.changed = 1;
619 bd->client.w = att->w;
620 bd->client.h = att->h;
622 bd->w = bd->client.w;
623 bd->h = bd->client.h;
625 bd->resize_mode = RESIZE_NONE;
627 bd->saved.layer = bd->layer;
628 bd->changes.icon = 1;
629 bd->changes.size = 1;
630 bd->changes.shape = 1;
631 bd->changes.shape_input = 1;
633 bd->offer_resistance = 1;
635 /* just to friggin make java happy - we're DELAYING the reparent until
638 /* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
639 bd->need_reparent = 1;
641 ecore_x_window_border_width_set(win, 0);
642 ecore_x_window_show(bd->event_win);
643 ecore_x_window_show(bd->client.shell_win);
644 bd->shape = e_container_shape_add(con);
650 // bd->zone = e_zone_current_get(con);
651 bd->desk = e_desk_current_get(bd->zone);
652 e_container_border_add(bd);
653 borders = eina_list_append(borders, bd);
654 bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
657 printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
658 printf("optimisations failing due to bizarre client behavior. will\n");
659 printf("work around.\n");
660 printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
661 bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
663 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
664 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
665 eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
667 eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
668 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
669 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
671 ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
672 ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
673 ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
674 e_desk_xy_get(bd->desk, &deskx, &desky);
677 ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
679 focus_stack = eina_list_append(focus_stack, bd);
681 bd->pointer = e_pointer_window_new(bd->win, 0);
686 e_border_res_change_geometry_save(E_Border *bd)
689 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
691 if (bd->pre_res_change.valid) return;
692 bd->pre_res_change.valid = 1;
693 bd->pre_res_change.x = bd->x;
694 bd->pre_res_change.y = bd->y;
695 bd->pre_res_change.w = bd->w;
696 bd->pre_res_change.h = bd->h;
697 bd->pre_res_change.saved.x = bd->saved.x;
698 bd->pre_res_change.saved.y = bd->saved.y;
699 bd->pre_res_change.saved.w = bd->saved.w;
700 bd->pre_res_change.saved.h = bd->saved.h;
704 e_border_res_change_geometry_restore(E_Border *bd)
708 unsigned char valid : 1;
717 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
718 if (!bd->pre_res_change.valid) return;
719 if (bd->new_client) return;
721 ecore_x_window_shadow_tree_flush();
722 memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
726 e_border_unfullscreen(bd);
727 e_border_fullscreen(bd, e_config->fullscreen_policy);
729 else if (bd->maximized != E_MAXIMIZE_NONE)
734 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
735 e_border_maximize(bd, max);
739 int x, y, w, h, zx, zy, zw, zh;
741 bd->saved.x = bd->pre_res_change.saved.x;
742 bd->saved.y = bd->pre_res_change.saved.y;
743 bd->saved.w = bd->pre_res_change.saved.w;
744 bd->saved.h = bd->pre_res_change.saved.h;
746 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
748 if (bd->saved.w > zw)
750 if ((bd->saved.x + bd->saved.w) > (zx + zw))
751 bd->saved.x = zx + zw - bd->saved.w;
753 if (bd->saved.h > zh)
755 if ((bd->saved.y + bd->saved.h) > (zy + zh))
756 bd->saved.y = zy + zh - bd->saved.h;
758 x = bd->pre_res_change.x;
759 y = bd->pre_res_change.y;
760 w = bd->pre_res_change.w;
761 h = bd->pre_res_change.h;
766 if ((x + w) > (zx + zw))
768 if ((y + h) > (zy + zh))
770 e_border_move_resize(bd, x, y, w, h);
772 memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
776 e_border_zone_set(E_Border *bd,
779 E_Event_Border_Zone_Set *ev;
782 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
783 E_OBJECT_CHECK(zone);
784 E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
786 if (bd->zone == zone) return;
788 /* if the window does not lie in the new zone, move it so that it does */
789 if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
792 /* first guess -- get offset from old zone, and apply to new zone */
793 x = zone->x + (bd->x - bd->zone->x);
794 y = zone->y + (bd->y - bd->zone->y);
796 /* keep window from hanging off bottom and left */
797 if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
798 if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
800 /* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
801 if (x < zone->x) x = zone->x;
802 if (y < zone->y) y = zone->y;
804 if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
806 /* still not in zone at all, so just move it to closest edge */
807 if (x < zone->x) x = zone->x;
808 if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
809 if (y < zone->y) y = zone->y;
810 if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
812 e_border_move(bd, x, y);
817 if (bd->desk->zone != bd->zone)
818 e_border_desk_set(bd, e_desk_current_get(bd->zone));
820 ev = E_NEW(E_Event_Border_Zone_Set, 1);
822 e_object_ref(E_OBJECT(bd));
823 // e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
825 e_object_ref(E_OBJECT(zone));
827 ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
829 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
830 e_remember_update(bd);
834 e_border_desk_set(E_Border *bd,
837 E_Event_Border_Desk_Set *ev;
841 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
842 E_OBJECT_CHECK(desk);
843 E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
844 if (bd->desk == desk) return;
845 ecore_x_window_shadow_tree_flush();
848 bd->desk->fullscreen_borders--;
849 desk->fullscreen_borders++;
853 e_border_zone_set(bd, desk->zone);
855 _e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
856 e_hints_window_desktop_set(bd);
858 ev = E_NEW(E_Event_Border_Desk_Set, 1);
860 e_object_ref(E_OBJECT(bd));
861 // e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
863 e_object_ref(E_OBJECT(old_desk));
864 ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
866 if (bd->ignore_first_unmap != 1)
868 if ((bd->desk->visible) || (bd->sticky))
871 e_border_hide(bd, 1);
874 if (e_config->transient.desktop)
878 EINA_LIST_FOREACH(bd->transients, l, child)
880 e_border_desk_set(child, bd->desk);
883 e_remember_update(bd);
887 e_border_show(E_Border *bd)
889 E_Event_Border_Show *ev;
890 unsigned int visible;
893 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
894 if (bd->visible) return;
895 ecore_x_window_shadow_tree_flush();
896 e_container_shape_show(bd->shape);
897 if (!bd->need_reparent)
898 ecore_x_window_show(bd->client.win);
899 e_hints_window_visible_set(bd);
901 bd->changes.visible = 1;
904 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
905 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
907 ev = E_NEW(E_Event_Border_Show, 1);
909 e_object_ref(E_OBJECT(bd));
910 // e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
911 ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
915 e_border_hide(E_Border *bd,
918 unsigned int visible;
921 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
922 if (!bd->visible) goto send_event;
923 ecore_x_window_shadow_tree_flush();
925 _e_border_move_end(bd);
926 if (bd->resize_mode != RESIZE_NONE)
928 _e_border_pointer_resize_end(bd);
929 bd->resize_mode = RESIZE_NONE;
930 _e_border_resize_end(bd);
933 e_container_shape_hide(bd->shape);
934 if (!bd->iconic) e_hints_window_hidden_set(bd);
937 bd->changes.visible = 1;
939 if (!bd->need_reparent)
943 e_border_focus_set(bd, 0, 1);
951 con = e_container_current_get(e_manager_current_get());
952 zone = e_zone_current_get(con);
953 desk = e_desk_current_get(zone);
956 (bd->parent->desk == desk) && (bd->parent->modal == bd))
957 e_border_focus_set(bd->parent, 1, 1);
958 else if (e_config->focus_revert_on_hide_or_close)
960 /* When using pointer focus, the border under the
961 * pointer (if any) gets focused, in sloppy/click
962 * focus the last focused window on the current
964 if (e_config->focus_policy == E_FOCUS_MOUSE)
966 pbd = e_border_under_pointer_get(desk, bd);
968 e_border_focus_set(pbd, 1, 1);
970 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
971 else if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) &&
972 (e_config->focus_policy == E_FOCUS_CLICK))
973 _e_border_latest_stacked_focus(bd);
976 e_desk_last_focused_focus(desk);
982 /* Make sure that this border isn't deleted */
983 bd->await_hide_event++;
987 if (!e_manager_comp_evas_get(bd->zone->container->manager))
988 ecore_x_window_hide(bd->client.win);
993 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
995 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
1002 E_Event_Border_Hide *ev;
1004 ev = E_NEW(E_Event_Border_Hide, 1);
1006 e_object_ref(E_OBJECT(bd));
1007 // e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
1008 ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
1013 _pri_adj(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_children, Eina_Bool do_children)
1017 if (use_adj) newpri = getpriority(PRIO_PROCESS, pid) + adj;
1018 setpriority(PRIO_PROCESS, pid, newpri);
1019 // shouldnt need to do this as default ionice class is "none" (0), and
1020 // this inherits io priority FROM nice level
1021 // ioprio_set(IOPRIO_WHO_PROCESS, pid,
1022 // IOPRIO_PRIO_VALUE(2, 5));
1026 char *file, buf[PATH_MAX];
1030 // yes - this is /proc specific... so this may not work on some
1031 // os's - works on linux. too bad for others.
1032 files = ecore_file_ls("/proc");
1033 EINA_LIST_FREE(files, file)
1035 if (isdigit(file[0]))
1037 snprintf(buf, sizeof(buf), "/proc/%s/stat", file);
1038 f = fopen(buf, "r");
1043 if (fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid) == 2)
1049 _pri_adj(pid2, set, adj, EINA_TRUE,
1050 adj_children, do_children);
1052 _pri_adj(pid2, set, adj, use_adj,
1053 adj_children, do_children);
1065 _e_border_pri_raise(E_Border *bd)
1067 if (bd->client.netwm.pid <= 0) return;
1068 if (bd->client.netwm.pid == getpid()) return;
1069 _pri_adj(bd->client.netwm.pid,
1070 e_config->priority - 1, -1, EINA_FALSE,
1071 // EINA_TRUE, EINA_TRUE);
1072 EINA_TRUE, EINA_FALSE);
1073 // printf("WIN: pid %i, title %s (HI!!!!!!!!!!!!!!!!!!)\n",
1074 // bd->client.netwm.pid, e_border_name_get(bd));
1078 _e_border_pri_norm(E_Border *bd)
1080 if (bd->client.netwm.pid <= 0) return;
1081 if (bd->client.netwm.pid == getpid()) return;
1082 _pri_adj(bd->client.netwm.pid,
1083 e_config->priority, 1, EINA_FALSE,
1084 // EINA_TRUE, EINA_TRUE);
1085 EINA_TRUE, EINA_FALSE);
1086 // printf("WIN: pid %i, title %s (NORMAL)\n",
1087 // bd->client.netwm.pid, e_border_name_get(bd));
1091 _e_border_frame_replace(E_Border *bd, Eina_Bool argb)
1094 Ecore_Evas *bg_ecore_evas;
1100 bg_ecore_evas = bd->bg_ecore_evas;
1102 /* unregister old frame window */
1103 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1104 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
1106 e_focus_setdown(bd);
1107 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
1108 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
1110 if (bd->icon_object)
1111 evas_object_del(bd->icon_object);
1113 evas_object_del(bd->bg_object);
1114 e_canvas_del(bg_ecore_evas);
1115 ecore_evas_free(bg_ecore_evas);
1118 e_object_del(E_OBJECT(bd->pointer));
1120 /* create new frame */
1122 bd->win = ecore_x_window_manager_argb_new(bd->zone->container->win,
1123 bd->x, bd->y, bd->w, bd->h);
1126 bd->win = ecore_x_window_override_new(bd->zone->container->win,
1127 bd->x, bd->y, bd->w, bd->h);
1128 ecore_x_window_shape_events_select(bd->win, 1);
1131 ecore_x_window_configure(bd->win,
1132 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
1133 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
1135 win, ECORE_X_WINDOW_STACK_BELOW);
1137 e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
1138 e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
1141 bd->bg_ecore_evas = e_canvas_new(bd->win,
1142 0, 0, bd->w, bd->h, 1, 0,
1145 e_canvas_add(bd->bg_ecore_evas);
1146 ecore_x_window_reparent(bd->event_win, bd->win, 0, 0);
1148 bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
1149 ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
1150 ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
1152 ecore_x_window_shape_events_select(bd->bg_win, 1);
1154 /* move client with shell win over to new frame */
1155 ecore_x_window_reparent(bd->client.shell_win, bd->win,
1156 bd->client_inset.l, bd->client_inset.t);
1158 bd->pointer = e_pointer_window_new(bd->win, 0);
1160 eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
1161 eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
1168 ecore_evas_show(bd->bg_ecore_evas);
1169 ecore_x_window_show(bd->win);
1171 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
1172 ecore_x_window_show(tmp->win);
1175 bd->bg_object = edje_object_add(bd->bg_evas);
1176 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
1177 e_theme_edje_object_set(bd->bg_object, "base/theme/borders", buf);
1179 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
1181 /* cleanup old frame */
1182 ecore_x_window_free(win);
1186 _e_border_client_move_resize_send(E_Border *bd)
1188 if (bd->internal_ecore_evas)
1189 ecore_evas_managed_move(bd->internal_ecore_evas,
1190 bd->x + bd->fx.x + bd->client_inset.l,
1191 bd->y + bd->fx.y + bd->client_inset.t);
1193 ecore_x_icccm_move_resize_send(bd->client.win,
1194 bd->x + bd->fx.x + bd->client_inset.l,
1195 bd->y + bd->fx.y + bd->client_inset.t,
1201 _e_border_pending_move_resize_add(E_Border *bd,
1208 Eina_Bool without_border,
1209 unsigned int serial)
1211 E_Border_Pending_Move_Resize *pnd;
1213 pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
1215 pnd->resize = resize;
1217 pnd->without_border = without_border;
1222 pnd->serial = serial;
1223 bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
1227 _e_border_move_internal(E_Border *bd,
1230 Eina_Bool without_border)
1232 E_Event_Border_Move *ev;
1235 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1237 ecore_x_window_shadow_tree_flush();
1240 _e_border_pending_move_resize_add(bd, 1, 0, x, y, 0, 0, without_border, 0);
1246 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1248 if (e_config->allow_manip)
1251 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1256 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1261 else if (e_config->allow_manip)
1269 x -= bd->client_inset.l;
1270 y -= bd->client_inset.t;
1273 if ((x == bd->x) && (y == bd->y)) return;
1274 bd->pre_res_change.valid = 0;
1278 bd->changes.pos = 1;
1280 if (bd->client.netwm.sync.request)
1282 bd->client.netwm.sync.wait++;
1283 ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
1286 _e_border_client_move_resize_send(bd);
1287 _e_border_move_update(bd);
1288 ev = E_NEW(E_Event_Border_Move, 1);
1290 e_object_ref(E_OBJECT(bd));
1291 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1292 ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
1293 _e_border_zone_update(bd);
1297 * Move window to coordinates that already account border decorations.
1299 * This call will consider given position already accounts border
1300 * decorations, so it will not be considered later. This will just
1301 * work properly with borders that have being evaluated and border
1302 * decorations are known (border->client_inset).
1304 * @parm x horizontal position to place window.
1305 * @parm y vertical position to place window.
1307 * @see e_border_move_without_border()
1310 e_border_move(E_Border *bd,
1317 _e_border_move_internal(bd, x, y, 0);
1321 * Move window to coordinates that do not account border decorations yet.
1323 * This call will consider given position does not account border
1324 * decoration, so these values (border->client_inset) will be
1325 * accounted automatically. This is specially useful when it is a new
1326 * client and has not be evaluated yet, in this case
1327 * border->client_inset will be zeroed and no information is known. It
1328 * will mark pending requests so border will be accounted on
1329 * evalutation phase.
1331 * @parm x horizontal position to place window.
1332 * @parm y vertical position to place window.
1334 * @see e_border_move()
1337 e_border_move_without_border(E_Border *bd,
1344 _e_border_move_internal(bd, x, y, 1);
1348 e_border_center(E_Border *bd)
1352 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1354 e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
1355 e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
1359 e_border_center_pos_get(E_Border *bd,
1365 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1367 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
1368 if (x) *x = zx + (zw - bd->w) / 2;
1369 if (y) *y = zy + (zh - bd->h) / 2;
1373 e_border_fx_offset(E_Border *bd,
1378 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1380 if ((x == bd->fx.x) && (y == bd->fx.y)) return;
1384 bd->changes.pos = 1;
1387 if (bd->moving) _e_border_move_update(bd);
1391 _e_border_move_resize_internal(E_Border *bd,
1396 Eina_Bool without_border,
1399 E_Event_Border_Move *mev;
1400 E_Event_Border_Resize *rev;
1403 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1405 ecore_x_window_shadow_tree_flush();
1409 _e_border_pending_move_resize_add(bd, move, 1, x, y, w, h, without_border, 0);
1415 if ((bd->maximized & E_MAXIMIZE_DIRECTION) != E_MAXIMIZE_BOTH)
1417 if (e_config->allow_manip)
1420 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
1426 if ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
1433 if (e_config->allow_manip)
1441 x -= bd->client_inset.l;
1442 y -= bd->client_inset.t;
1443 w += (bd->client_inset.l + bd->client_inset.r);
1444 h += (bd->client_inset.t + bd->client_inset.b);
1447 if ((!move || ((x == bd->x) && (y == bd->y))) &&
1448 (w == bd->w) && (h == bd->h))
1451 bd->pre_res_change.valid = 0;
1454 bd->changes.pos = 1;
1460 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
1461 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
1463 if ((bd->shaped) || (bd->client.shaped))
1465 bd->need_shape_merge = 1;
1466 bd->need_shape_export = 1;
1468 if (bd->shaped_input)
1470 bd->need_shape_merge = 1;
1473 if (bd->internal_ecore_evas)
1476 bd->changes.size = 1;
1480 if (bdresize && bd->client.netwm.sync.request)
1482 bd->client.netwm.sync.wait++;
1483 /* Don't use x and y as supplied to this function, as it is called with 0, 0
1484 * when no move is intended. The border geometry is set above anyways.
1486 _e_border_pending_move_resize_add(bd, move, 1, bd->x, bd->y, bd->w, bd->h, without_border,
1487 bd->client.netwm.sync.serial);
1488 ecore_x_netwm_sync_request_send(bd->client.win,
1489 bd->client.netwm.sync.serial++);
1494 bd->changes.size = 1;
1498 _e_border_client_move_resize_send(bd);
1500 _e_border_resize_update(bd);
1503 mev = E_NEW(E_Event_Border_Move, 1);
1505 e_object_ref(E_OBJECT(bd));
1506 // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
1507 ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
1510 rev = E_NEW(E_Event_Border_Resize, 1);
1512 e_object_ref(E_OBJECT(bd));
1513 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
1514 ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
1515 _e_border_zone_update(bd);
1519 * Move and resize window to values that already account border decorations.
1521 * This call will consider given values already accounts border
1522 * decorations, so it will not be considered later. This will just
1523 * work properly with borders that have being evaluated and border
1524 * decorations are known (border->client_inset).
1526 * @parm x horizontal position to place window.
1527 * @parm y vertical position to place window.
1528 * @parm w horizontal window size.
1529 * @parm h vertical window size.
1531 * @see e_border_move_resize_without_border()
1534 e_border_move_resize(E_Border *bd,
1543 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
1547 * Move and resize window to values that do not account border decorations yet.
1549 * This call will consider given values already accounts border
1550 * decorations, so it will not be considered later. This will just
1551 * work properly with borders that have being evaluated and border
1552 * decorations are known (border->client_inset).
1554 * @parm x horizontal position to place window.
1555 * @parm y vertical position to place window.
1556 * @parm w horizontal window size.
1557 * @parm h vertical window size.
1559 * @see e_border_move_resize()
1562 e_border_move_resize_without_border(E_Border *bd,
1571 _e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
1575 * Resize window to values that already account border decorations.
1577 * This call will consider given size already accounts border
1578 * decorations, so it will not be considered later. This will just
1579 * work properly with borders that have being evaluated and border
1580 * decorations are known (border->client_inset).
1582 * @parm w horizontal window size.
1583 * @parm h vertical window size.
1585 * @see e_border_resize_without_border()
1588 e_border_resize(E_Border *bd,
1595 _e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
1599 * Resize window to values that do not account border decorations yet.
1601 * This call will consider given size does not account border
1602 * decoration, so these values (border->client_inset) will be
1603 * accounted automatically. This is specially useful when it is a new
1604 * client and has not be evaluated yet, in this case
1605 * border->client_inset will be zeroed and no information is known. It
1606 * will mark pending requests so border will be accounted on
1607 * evalutation phase.
1609 * @parm w horizontal window size.
1610 * @parm h vertical window size.
1612 * @see e_border_resize()
1615 e_border_resize_without_border(E_Border *bd,
1622 _e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
1626 e_border_layer_set(E_Border *bd,
1632 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1634 ecore_x_window_shadow_tree_flush();
1636 oldraise = e_config->transient.raise;
1638 bd->saved.layer = bd->layer;
1640 if (e_config->transient.layer)
1645 /* We need to set raise to one, else the child wont
1646 * follow to the new layer. It should be like this,
1647 * even if the user usually doesn't want to raise
1650 e_config->transient.raise = 1;
1651 EINA_LIST_FOREACH(bd->transients, l, child)
1653 child->layer = layer;
1657 e_config->transient.raise = oldraise;
1661 e_border_raise(E_Border *bd)
1663 E_Event_Border_Stack *ev;
1664 E_Border *last = NULL, *child;
1668 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1670 ecore_x_window_shadow_tree_flush();
1672 if (e_config->transient.raise)
1674 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1675 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
1678 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1680 /* Don't stack iconic transients. If the user wants these shown,
1681 * thats another option.
1686 e_border_stack_below(child, last);
1691 /* First raise the border to find out which border we will end up above */
1692 above = e_container_border_raise(child);
1696 /* We ended up above a border, now we must stack this border to
1697 * generate the stacking event, and to check if this transient
1698 * has other transients etc.
1700 e_border_stack_above(child, above);
1704 /* If we didn't end up above any border, we are on the bottom! */
1705 e_border_lower(child);
1711 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1715 EINA_LIST_FOREACH(bd->transients, l, child)
1717 /* Don't stack iconic transients. If the user wants these shown,
1718 * thats another option.
1722 child->layer = bd->layer;
1723 if (!last) last = child;
1724 e_border_raise (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, raise this border */
1747 above = e_container_border_raise(bd);
1748 e_border_raise_latest_set(bd);
1751 /* We ended up above a border */
1753 e_object_ref(E_OBJECT(above));
1754 ev->type = E_STACKING_ABOVE;
1758 /* No border to raise above, same as a lower! */
1760 ev->type = E_STACKING_ABOVE;
1764 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1765 e_remember_update(bd);
1769 e_border_lower(E_Border *bd)
1771 E_Event_Border_Stack *ev;
1772 E_Border *last = NULL, *child;
1776 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1778 ecore_x_window_shadow_tree_flush();
1780 if (e_config->transient.lower)
1782 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1783 if (e_config->focus_setting != E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
1786 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1788 /* Don't stack iconic transients. If the user wants these shown,
1789 * thats another option.
1794 e_border_stack_below(child, last);
1799 /* First lower the border to find out which border we will end up below */
1800 below = e_container_border_lower(child);
1804 /* We ended up below a border, now we must stack this border to
1805 * generate the stacking event, and to check if this transient
1806 * has other transients etc.
1808 e_border_stack_below(child, below);
1812 /* If we didn't end up below any border, we are on top! */
1813 e_border_raise(child);
1819 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
1823 EINA_LIST_FOREACH(bd->transients, l, child)
1825 /* Don't stack iconic transients. If the user wants these shown,
1826 * thats another option.
1830 child->layer = bd->layer;
1831 e_border_lower (child);
1839 ev = E_NEW(E_Event_Border_Stack, 1);
1841 e_object_ref(E_OBJECT(bd));
1845 e_container_border_stack_below(bd, last);
1847 e_object_ref(E_OBJECT(last));
1848 ev->type = E_STACKING_BELOW;
1854 /* If we don't have any children, lower this border */
1855 below = e_container_border_lower(bd);
1858 /* We ended up below a border */
1860 e_object_ref(E_OBJECT(below));
1861 ev->type = E_STACKING_BELOW;
1865 /* No border to hide under, same as a raise! */
1867 ev->type = E_STACKING_BELOW;
1871 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1872 e_remember_update(bd);
1876 e_border_stack_above(E_Border *bd,
1879 /* TODO: Should stack above allow the border to change level */
1880 E_Event_Border_Stack *ev;
1881 E_Border *last = NULL, *child;
1885 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1887 ecore_x_window_shadow_tree_flush();
1889 if (e_config->transient.raise)
1891 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1893 /* Don't stack iconic transients. If the user wants these shown,
1894 * thats another option.
1899 e_border_stack_below(child, last);
1901 e_border_stack_above(child, above);
1907 ev = E_NEW(E_Event_Border_Stack, 1);
1909 e_object_ref(E_OBJECT(bd));
1913 e_container_border_stack_below(bd, last);
1915 e_object_ref(E_OBJECT(last));
1916 ev->type = E_STACKING_BELOW;
1920 e_container_border_stack_above(bd, above);
1922 e_object_ref(E_OBJECT(above));
1923 ev->type = E_STACKING_ABOVE;
1926 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1927 e_remember_update(bd);
1931 e_border_stack_below(E_Border *bd,
1934 /* TODO: Should stack below allow the border to change level */
1935 E_Event_Border_Stack *ev;
1936 E_Border *last = NULL, *child;
1940 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
1942 ecore_x_window_shadow_tree_flush();
1944 if (e_config->transient.lower)
1946 EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
1948 /* Don't stack iconic transients. If the user wants these shown,
1949 * thats another option.
1954 e_border_stack_below(child, last);
1956 e_border_stack_below(child, below);
1962 ev = E_NEW(E_Event_Border_Stack, 1);
1964 e_object_ref(E_OBJECT(bd));
1968 e_container_border_stack_below(bd, last);
1970 e_object_ref(E_OBJECT(last));
1971 ev->type = E_STACKING_BELOW;
1975 e_container_border_stack_below(bd, below);
1977 e_object_ref(E_OBJECT(below));
1978 ev->type = E_STACKING_BELOW;
1981 ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
1982 e_remember_update(bd);
1986 e_border_focus_latest_set(E_Border *bd)
1988 focus_stack = eina_list_remove(focus_stack, bd);
1989 focus_stack = eina_list_prepend(focus_stack, bd);
1993 e_border_raise_latest_set(E_Border *bd)
1995 raise_stack = eina_list_remove(raise_stack, bd);
1996 raise_stack = eina_list_prepend(raise_stack, bd);
2000 * Sets the focus to the given border if necessary
2001 * There are 3 cases of different focus_policy-configurations:
2003 * - E_FOCUS_CLICK: just set the focus, the most simple one
2005 * - E_FOCUS_MOUSE: focus is where the mouse is, so try to
2006 * warp the pointer to the window. If this fails (because
2007 * the pointer is already in the window), just set the focus.
2009 * - E_FOCUS_SLOPPY: focus is where the mouse is or on the
2010 * last window which was focused, if the mouse is on the
2011 * desktop. So, we need to look if there is another window
2012 * under the pointer and warp to pointer to the right
2013 * one if so (also, we set the focus afterwards). In case
2014 * there is no window under pointer, the pointer is on the
2015 * desktop and so we just set the focus.
2018 * This function is to be called when setting the focus was not
2019 * explicitly triggered by the user (by moving the mouse or
2020 * clicking for example), but implicitly (by closing a window,
2021 * the last focused window should get focus).
2025 e_border_focus_set_with_pointer(E_Border *bd)
2027 #ifdef PRINT_LOTS_OF_DEBUG
2028 E_PRINT_BORDER_INFO(bd);
2030 /* note: this is here as it seems there are enough apps that do not even
2031 * expect us to emulate a look of focus but not actually set x input
2032 * focus as we do - so simply abort any focuse set on such windows */
2033 /* be strict about accepting focus hint */
2034 if ((!bd->client.icccm.accepts_focus) &&
2035 (!bd->client.icccm.take_focus)) return;
2036 if (bd->lock_focus_out) return;
2038 e_border_focus_set(bd, 1, 1);
2040 if (e_config->focus_policy == E_FOCUS_CLICK)
2043 if (e_config->focus_policy == E_FOCUS_SLOPPY)
2045 if (e_border_under_pointer_get(bd->desk, bd))
2046 e_border_pointer_warp_to_center(bd);
2050 e_border_pointer_warp_to_center(bd);
2055 e_border_focus_set(E_Border *bd,
2059 E_Border *bd_unfocus = NULL;
2060 Eina_Bool focus_changed = EINA_FALSE;
2063 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2064 /* note: this is here as it seems there are enough apps that do not even
2065 * expect us to emulate a look of focus but not actually set x input
2066 * focus as we do - so simply abort any focuse set on such windows */
2067 /* be strict about accepting focus hint */
2068 if ((!bd->client.icccm.accepts_focus) &&
2069 (!bd->client.icccm.take_focus))
2071 if ((set) && (focus) && (bd->lock_focus_out)) return;
2072 /* dont focus an iconified window. that's silly! */
2081 /* FIXME: hack for deskflip animation:
2082 * dont update focus when sliding previous desk */
2083 if ((!bd->sticky) && (bd->desk != e_desk_current_get(bd->desk->zone)))
2087 if ((bd->modal) && (bd->modal != bd) && (bd->modal->visible))
2089 e_border_focus_set(bd->modal, focus, set);
2092 else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
2094 e_border_focus_set(bd->leader->modal, focus, set);
2102 if (bd->visible && bd->changes.visible)
2107 else if ((!bd->focused) || (focus_next && (bd != eina_list_data_get(focus_next))))
2111 if ((l = eina_list_data_find_list(focus_next, bd)))
2112 focus_next = eina_list_promote_list(focus_next, l);
2114 focus_next = eina_list_prepend(focus_next, bd);
2122 if (focused) bd_unfocus = focused;
2123 if (focusing == bd) focusing = NULL;
2127 focus_changed = EINA_TRUE;
2133 focus_next = eina_list_remove(focus_next, bd);
2134 if (bd == focusing) focusing = NULL;
2139 /* should always be the case. anyway */
2140 if (bd == focused) focused = NULL;
2142 if ((set) && (!focus_next) && (!focusing))
2144 e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE);
2150 (!e_object_is_del(E_OBJECT(bd_unfocus)) &&
2151 (e_object_ref_get(E_OBJECT(bd_unfocus)) > 0)))
2153 E_Event_Border_Focus_Out *ev;
2155 bd_unfocus->focused = 0;
2156 e_focus_event_focus_out(bd_unfocus);
2158 if (bd_unfocus->raise_timer)
2159 ecore_timer_del(bd_unfocus->raise_timer);
2160 bd_unfocus->raise_timer = NULL;
2162 edje_object_signal_emit(bd_unfocus->bg_object, "e,state,unfocused", "e");
2163 if (bd_unfocus->icon_object)
2164 edje_object_signal_emit(bd_unfocus->icon_object, "e,state,unfocused", "e");
2166 ev = E_NEW(E_Event_Border_Focus_Out, 1);
2167 ev->border = bd_unfocus;
2168 e_object_ref(E_OBJECT(bd_unfocus));
2170 ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
2171 _e_border_event_border_focus_out_free, NULL);
2176 E_Event_Border_Focus_In *ev;
2178 e_focus_event_focus_in(bd);
2180 if (!focus_track_frozen)
2181 e_border_focus_latest_set(bd);
2183 e_hints_active_window_set(bd->zone->container->manager, bd);
2185 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2186 if (bd->icon_object)
2187 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
2189 ev = E_NEW(E_Event_Border_Focus_In, 1);
2191 e_object_ref(E_OBJECT(bd));
2193 ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
2194 _e_border_event_border_focus_in_free, NULL);
2199 e_border_shade(E_Border *bd,
2202 E_Event_Border_Resize *ev;
2207 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2208 if ((bd->shaded) || (bd->shading) || (bd->fullscreen) ||
2209 ((bd->maximized) && (!e_config->allow_manip))) return;
2210 if ((bd->client.border.name) &&
2211 (!strcmp("borderless", bd->client.border.name))) return;
2213 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2214 ecore_x_window_hide(tmp->win);
2216 ecore_x_window_shadow_tree_flush();
2218 bd->shade.x = bd->x;
2219 bd->shade.y = bd->y;
2220 bd->shade.dir = dir;
2222 e_hints_window_shaded_set(bd, 1);
2223 e_hints_window_shade_direction_set(bd, dir);
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 ||
2233 bd->shade.dir == E_DIRECTION_LEFT)
2234 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2236 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2238 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2239 edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
2243 if (bd->shade.dir == E_DIRECTION_UP)
2245 bd->h = bd->client_inset.t + bd->client_inset.b;
2247 else if (bd->shade.dir == E_DIRECTION_DOWN)
2249 bd->h = bd->client_inset.t + bd->client_inset.b;
2250 bd->y = bd->y + bd->client.h;
2251 bd->changes.pos = 1;
2253 else if (bd->shade.dir == E_DIRECTION_LEFT)
2255 bd->w = bd->client_inset.l + bd->client_inset.r;
2257 else if (bd->shade.dir == E_DIRECTION_RIGHT)
2259 bd->w = bd->client_inset.l + bd->client_inset.r;
2260 bd->x = bd->x + bd->client.w;
2261 bd->changes.pos = 1;
2264 if ((bd->shaped) || (bd->client.shaped))
2266 bd->need_shape_merge = 1;
2267 bd->need_shape_export = 1;
2269 if (bd->shaped_input)
2271 bd->need_shape_merge = 1;
2274 bd->changes.size = 1;
2276 bd->changes.shaded = 1;
2278 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
2279 e_border_frame_recalc(bd);
2280 ev = E_NEW(E_Event_Border_Resize, 1);
2282 /* The resize is added in the animator when animation complete */
2283 /* For non-animated, we add it immediately with the new size */
2284 e_object_ref(E_OBJECT(bd));
2285 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2286 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
2289 e_remember_update(bd);
2293 e_border_unshade(E_Border *bd,
2296 E_Event_Border_Resize *ev;
2301 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2302 if ((!bd->shaded) || (bd->shading))
2305 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
2306 ecore_x_window_show(tmp->win);
2308 ecore_x_window_shadow_tree_flush();
2310 bd->shade.dir = dir;
2312 e_hints_window_shaded_set(bd, 0);
2313 e_hints_window_shade_direction_set(bd, dir);
2315 if (bd->shade.dir == E_DIRECTION_UP ||
2316 bd->shade.dir == E_DIRECTION_LEFT)
2318 bd->shade.x = bd->x;
2319 bd->shade.y = bd->y;
2323 bd->shade.x = bd->x - bd->client.w;
2324 bd->shade.y = bd->y - bd->client.h;
2326 if (e_config->border_shade_animate)
2328 bd->shade.start = ecore_loop_time_get();
2330 bd->changes.shading = 1;
2333 if (bd->shade.dir == E_DIRECTION_UP)
2335 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2336 ecore_x_window_move_resize(bd->client.win, 0,
2337 bd->h - (bd->client_inset.t + bd->client_inset.b) -
2339 bd->client.w, bd->client.h);
2341 else if (bd->shade.dir == E_DIRECTION_LEFT)
2343 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
2344 ecore_x_window_move_resize(bd->client.win,
2345 bd->w - (bd->client_inset.l + bd->client_inset.r) -
2347 0, bd->client.w, bd->client.h);
2350 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
2352 bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
2353 edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
2357 if (bd->shade.dir == E_DIRECTION_UP)
2359 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
2361 else if (bd->shade.dir == E_DIRECTION_DOWN)
2363 bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
2364 bd->y = bd->y - bd->client.h;
2365 bd->changes.pos = 1;
2367 else if (bd->shade.dir == E_DIRECTION_LEFT)
2369 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
2371 else if (bd->shade.dir == E_DIRECTION_RIGHT)
2373 bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
2374 bd->x = bd->x - bd->client.w;
2375 bd->changes.pos = 1;
2377 if ((bd->shaped) || (bd->client.shaped))
2379 bd->need_shape_merge = 1;
2380 bd->need_shape_export = 1;
2382 if (bd->shaped_input)
2384 bd->need_shape_merge = 1;
2387 bd->changes.size = 1;
2389 bd->changes.shaded = 1;
2391 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
2392 e_border_frame_recalc(bd);
2393 ev = E_NEW(E_Event_Border_Resize, 1);
2395 /* The resize is added in the animator when animation complete */
2396 /* For non-animated, we add it immediately with the new size */
2397 e_object_ref(E_OBJECT(bd));
2398 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
2399 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
2402 e_remember_update(bd);
2406 _e_border_client_inset_calc(E_Border *bd)
2409 Evas_Coord cx, cy, cw, ch;
2413 evas_object_resize(bd->bg_object, 1000, 1000);
2414 edje_object_calc_force(bd->bg_object);
2415 edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
2416 bd->client_inset.l = cx;
2417 bd->client_inset.r = 1000 - (cx + cw);
2418 bd->client_inset.t = cy;
2419 bd->client_inset.b = 1000 - (cy + ch);
2423 bd->client_inset.l = 0;
2424 bd->client_inset.r = 0;
2425 bd->client_inset.t = 0;
2426 bd->client_inset.b = 0;
2429 ecore_x_netwm_frame_size_set(bd->client.win,
2430 bd->client_inset.l, bd->client_inset.r,
2431 bd->client_inset.t, bd->client_inset.b);
2432 ecore_x_e_frame_size_set(bd->client.win,
2433 bd->client_inset.l, bd->client_inset.r,
2434 bd->client_inset.t, bd->client_inset.b);
2438 _e_border_maximize(E_Border *bd, E_Maximize max)
2444 zx = zy = zw = zh = 0;
2446 switch (max & E_MAXIMIZE_TYPE)
2448 case E_MAXIMIZE_NONE:
2452 case E_MAXIMIZE_FULLSCREEN:
2458 edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
2459 _e_border_client_inset_calc(bd);
2461 e_border_resize_limit(bd, &w, &h);
2462 /* center x-direction */
2463 x1 = bd->zone->x + (bd->zone->w - w) / 2;
2464 /* center y-direction */
2465 y1 = bd->zone->y + (bd->zone->h - h) / 2;
2467 if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
2468 e_border_move_resize(bd, x1, y1, w, h);
2469 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2470 e_border_move_resize(bd, bd->x, y1, bd->w, h);
2471 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2472 e_border_move_resize(bd, x1, bd->y, w, bd->h);
2475 case E_MAXIMIZE_SMART:
2476 case E_MAXIMIZE_EXPAND:
2478 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
2490 if (bd->x < zx) // window left not useful coordinates
2492 else if (bd->x + bd->w > zx + zw) // window right not useful coordinates
2493 x1 = zx + zw - bd->w;
2494 else // window normal position
2497 if (bd->y < zy) // window top not useful coordinates
2499 else if (bd->y + bd->h > zy + zh) // window bottom not useful coordinates
2500 y1 = zy + zh - bd->h;
2501 else // window normal position
2504 if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
2505 e_border_move_resize(bd, zx, zy, zw, zh);
2506 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2507 e_border_move_resize(bd, x1, zy, w, zh);
2508 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2509 e_border_move_resize(bd, zx, y1, zw, h);
2510 edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
2513 case E_MAXIMIZE_FILL:
2516 x2 = bd->zone->x + bd->zone->w;
2517 y2 = bd->zone->y + bd->zone->h;
2519 /* walk through all shelves */
2520 e_maximize_border_shelf_fill(bd, &x1, &y1, &x2, &y2, max);
2522 /* walk through all windows */
2523 e_maximize_border_border_fill(bd, &x1, &y1, &x2, &y2, max);
2529 e_border_resize_limit(bd, &w, &h);
2530 /* center x-direction */
2531 x1 = x1 + (pw - w) / 2;
2532 /* center y-direction */
2533 y1 = y1 + (ph - h) / 2;
2534 if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
2535 e_border_move_resize(bd, x1, y1, w, h);
2536 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
2537 e_border_move_resize(bd, bd->x, y1, bd->w, h);
2538 else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
2539 e_border_move_resize(bd, x1, bd->y, w, bd->h);
2545 e_border_maximize(E_Border *bd,
2549 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2551 if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
2553 if ((bd->shaded) || (bd->shading)) return;
2554 ecore_x_window_shadow_tree_flush();
2556 e_border_unfullscreen(bd);
2557 /* Only allow changes in vertical/ horizontal maximization */
2558 if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
2559 ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
2562 bd->need_maximize = 1;
2563 bd->maximized &= ~E_MAXIMIZE_TYPE;
2564 bd->maximized |= max;
2568 bd->pre_res_change.valid = 0;
2569 if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
2571 /* Horizontal hasn't been set */
2572 bd->saved.x = bd->x - bd->zone->x;
2573 bd->saved.w = bd->w;
2575 if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
2577 /* Vertical hasn't been set */
2578 bd->saved.y = bd->y - bd->zone->y;
2579 bd->saved.h = bd->h;
2581 bd->saved.zone = bd->zone->num;
2582 e_hints_window_size_set(bd);
2586 _e_border_maximize(bd, max);
2589 /* Remove previous type */
2590 bd->maximized &= ~E_MAXIMIZE_TYPE;
2591 /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
2592 bd->maximized |= max;
2594 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
2595 bd->maximized & E_MAXIMIZE_VERTICAL);
2596 e_remember_update(bd);
2600 e_border_unmaximize(E_Border *bd,
2604 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2605 if (!(max & E_MAXIMIZE_DIRECTION))
2607 printf("BUG: Unmaximize call without direction!\n");
2611 if ((bd->shaded) || (bd->shading)) return;
2612 ecore_x_window_shadow_tree_flush();
2613 /* Remove directions not used */
2614 max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
2615 /* Can only remove existing maximization directions */
2617 if (bd->maximized & E_MAXIMIZE_TYPE)
2619 bd->pre_res_change.valid = 0;
2620 bd->need_maximize = 0;
2622 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
2626 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
2627 _e_border_client_inset_calc(bd);
2630 bd->maximized = E_MAXIMIZE_NONE;
2631 _e_border_move_resize_internal(bd,
2632 bd->zone->x + bd->saved.x,
2633 bd->zone->y + bd->saved.y,
2634 bd->saved.w, bd->saved.h, 0, 1);
2635 bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
2636 e_hints_window_size_unset(bd);
2647 if (max & E_MAXIMIZE_VERTICAL)
2649 /* Remove vertical */
2651 y = bd->saved.y + bd->zone->y;
2652 bd->saved.h = bd->saved.y = 0;
2653 bd->maximized &= ~E_MAXIMIZE_VERTICAL;
2655 if (max & E_MAXIMIZE_HORIZONTAL)
2657 /* Remove horizontal */
2659 x = bd->saved.x + bd->zone->x;
2660 bd->saved.w = bd->saved.x = 0;
2661 bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
2664 e_border_resize_limit(bd, &w, &h);
2666 if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
2668 bd->maximized = E_MAXIMIZE_NONE;
2669 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2670 e_hints_window_size_unset(bd);
2671 edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
2675 _e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
2676 e_hints_window_size_set(bd);
2679 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
2680 bd->maximized & E_MAXIMIZE_VERTICAL);
2682 e_remember_update(bd);
2686 e_border_fullscreen(E_Border *bd,
2687 E_Fullscreen policy)
2689 E_Event_Border_Fullscreen *ev;
2692 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2694 if ((bd->shaded) || (bd->shading)) return;
2695 ecore_x_window_shadow_tree_flush();
2698 bd->need_fullscreen = 1;
2701 if (!bd->fullscreen)
2703 bd->pre_res_change.valid = 0;
2705 bd->saved.x = bd->x - bd->zone->x;
2706 bd->saved.y = bd->y - bd->zone->y;
2707 bd->saved.w = bd->client.w;
2708 bd->saved.h = bd->client.h;
2709 bd->saved.maximized = bd->maximized;
2710 bd->saved.zone = bd->zone->num;
2713 e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
2714 e_hints_window_size_set(bd);
2716 bd->client_inset.l = 0;
2717 bd->client_inset.r = 0;
2718 bd->client_inset.t = 0;
2719 bd->client_inset.b = 0;
2721 bd->desk->fullscreen_borders++;
2723 /* e_zone_fullscreen_set(bd->zone, 1); */
2724 if (!e_config->allow_above_fullscreen)
2725 e_border_layer_set(bd, 300);
2727 if ((eina_list_count(bd->zone->container->zones) > 1) ||
2728 (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
2730 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
2732 else if (policy == E_FULLSCREEN_ZOOM)
2734 Ecore_X_Randr_Screen_Size_MM *sizes;
2735 int num_sizes, i, best_size_index = 0;
2737 ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root,
2739 &screen_size.height,
2741 sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root,
2745 Ecore_X_Randr_Screen_Size best_size = { -1, -1 };
2746 int best_dist = INT_MAX, dist;
2748 for (i = 0; i < num_sizes; i++)
2750 if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
2752 dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
2753 if (dist < best_dist)
2755 best_size.width = sizes[i].width;
2756 best_size.height = sizes[i].height;
2758 best_size_index = i;
2762 if (((best_size.width != -1) && (best_size.height != -1)) &&
2763 ((best_size.width != screen_size.width) ||
2764 (best_size.height != screen_size.height)))
2766 if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
2768 screen_size_index = best_size_index;
2769 e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
2773 screen_size.width = -1;
2774 screen_size.height = -1;
2775 e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
2780 e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
2784 e_hints_window_fullscreen_set(bd, 1);
2785 e_hints_window_size_unset(bd);
2786 bd->client.border.changed = 1;
2790 ev = E_NEW(E_Event_Border_Fullscreen, 1);
2792 e_object_ref(E_OBJECT(bd));
2793 // e_object_breadcrumb_add(E_OBJECT(bd), "border_fullscreen_event");
2794 ecore_event_add(E_EVENT_BORDER_FULLSCREEN, ev, _e_border_event_border_fullscreen_free, NULL);
2796 e_remember_update(bd);
2800 e_border_unfullscreen(E_Border *bd)
2802 E_Event_Border_Unfullscreen *ev;
2805 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2806 if ((bd->shaded) || (bd->shading)) return;
2807 ecore_x_window_shadow_tree_flush();
2810 bd->pre_res_change.valid = 0;
2812 bd->need_fullscreen = 0;
2813 bd->desk->fullscreen_borders--;
2815 if ((screen_size.width != -1) && (screen_size.height != -1))
2817 ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root,
2819 screen_size.width = -1;
2820 screen_size.height = -1;
2822 e_border_move_resize(bd,
2823 bd->saved.x + bd->zone->x,
2824 bd->saved.y + bd->zone->y,
2825 bd->saved.w, bd->saved.h);
2827 if (bd->saved.maximized)
2828 e_border_maximize(bd, (e_config->maximize_policy & E_MAXIMIZE_TYPE) |
2829 bd->saved.maximized);
2831 e_border_layer_set(bd, bd->saved.layer);
2833 e_hints_window_fullscreen_set(bd, 0);
2834 bd->client.border.changed = 1;
2838 ev = E_NEW(E_Event_Border_Unfullscreen, 1);
2840 e_object_ref(E_OBJECT(bd));
2841 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unfullscreen_event");
2842 ecore_event_add(E_EVENT_BORDER_UNFULLSCREEN, ev, _e_border_event_border_unfullscreen_free, NULL);
2844 e_remember_update(bd);
2848 e_border_iconify(E_Border *bd)
2850 E_Event_Border_Iconify *ev;
2851 unsigned int iconic;
2854 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2855 if (bd->shading) return;
2856 ecore_x_window_shadow_tree_flush();
2860 e_border_hide(bd, 1);
2861 if (bd->fullscreen) bd->desk->fullscreen_borders--;
2862 edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
2865 e_hints_window_iconic_set(bd);
2866 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
2868 ev = E_NEW(E_Event_Border_Iconify, 1);
2870 e_object_ref(E_OBJECT(bd));
2871 // e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
2872 ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
2874 if (e_config->transient.iconify)
2879 EINA_LIST_FOREACH(bd->transients, l, child)
2881 e_border_iconify(child);
2884 e_remember_update(bd);
2888 e_border_uniconify(E_Border *bd)
2891 E_Event_Border_Uniconify *ev;
2892 unsigned int iconic;
2895 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2896 if (bd->shading) return;
2897 ecore_x_window_shadow_tree_flush();
2902 if (bd->fullscreen) bd->desk->fullscreen_borders++;
2903 desk = e_desk_current_get(bd->desk->zone);
2904 e_border_desk_set(bd, desk);
2906 edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
2909 ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
2911 ev = E_NEW(E_Event_Border_Uniconify, 1);
2913 e_object_ref(E_OBJECT(bd));
2914 // e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
2915 ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
2917 if (e_config->transient.iconify)
2922 EINA_LIST_FOREACH(bd->transients, l, child)
2924 e_border_uniconify(child);
2927 e_remember_update(bd);
2931 e_border_stick(E_Border *bd)
2933 E_Event_Border_Stick *ev;
2936 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2937 if (bd->sticky) return;
2939 e_hints_window_sticky_set(bd, 1);
2942 if (e_config->transient.desktop)
2946 EINA_LIST_FOREACH(bd->transients, l, child)
2949 e_hints_window_sticky_set(child, 1);
2950 e_border_show(child);
2954 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
2955 ev = E_NEW(E_Event_Border_Stick, 1);
2957 e_object_ref(E_OBJECT(bd));
2958 // e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
2959 ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
2960 e_remember_update(bd);
2964 e_border_unstick(E_Border *bd)
2966 E_Event_Border_Unstick *ev;
2969 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2970 /* Set the desk before we unstick the border */
2971 if (!bd->sticky) return;
2973 e_hints_window_sticky_set(bd, 0);
2975 if (e_config->transient.desktop)
2979 EINA_LIST_FOREACH(bd->transients, l, child)
2982 e_hints_window_sticky_set(child, 0);
2986 edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
2987 ev = E_NEW(E_Event_Border_Unstick, 1);
2989 e_object_ref(E_OBJECT(bd));
2990 // e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
2991 ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
2993 e_border_desk_set(bd, e_desk_current_get(bd->zone));
2994 e_remember_update(bd);
2998 e_border_pinned_set(E_Border *bd,
3006 bd->borderless = set;
3007 bd->user_skip_winlist = set;
3011 stacking = E_STACKING_BELOW;
3016 stacking = E_STACKING_NONE;
3019 e_border_layer_set(bd, layer);
3020 e_hints_window_stacking_set(bd, stacking);
3022 bd->client.border.changed = 1;
3028 e_border_find_by_client_window(Ecore_X_Window win)
3032 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3033 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3034 (bd->client.win == win))
3040 e_border_find_all_by_client_window(Ecore_X_Window win)
3044 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3045 if ((bd) && (bd->client.win == win))
3051 e_border_find_by_frame_window(Ecore_X_Window win)
3055 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3056 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3057 (bd->bg_win == win))
3063 e_border_find_by_window(Ecore_X_Window win)
3067 bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
3068 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3075 e_border_find_by_alarm(Ecore_X_Sync_Alarm alarm)
3080 EINA_LIST_FOREACH(borders, l, bd)
3082 if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
3083 (bd->client.netwm.sync.alarm == alarm))
3090 e_border_focused_get(void)
3096 _e_border_shape_input_rectangle_set(E_Border* bd)
3100 if ((bd->visible) && (bd->shaped_input))
3102 Ecore_X_Rectangle rects[4];
3103 Ecore_X_Window twin, twin2;
3106 twin = ecore_x_window_override_new(bd->zone->container->scratch_win,
3107 0, 0, bd->w, bd->h);
3110 rects[0].width = bd->w;
3111 rects[0].height = bd->client_inset.t;
3113 rects[1].y = bd->client_inset.t;
3114 rects[1].width = bd->client_inset.l;
3115 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3116 rects[2].x = bd->w - bd->client_inset.r;
3117 rects[2].y = bd->client_inset.t;
3118 rects[2].width = bd->client_inset.r;
3119 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
3121 rects[3].y = bd->h - bd->client_inset.b;
3122 rects[3].width = bd->w;
3123 rects[3].height = bd->client_inset.b;
3124 ecore_x_window_shape_input_rectangles_set(twin, rects, 4);
3126 twin2 = ecore_x_window_override_new
3127 (bd->zone->container->scratch_win, 0, 0,
3128 bd->w - bd->client_inset.l - bd->client_inset.r,
3129 bd->h - bd->client_inset.t - bd->client_inset.b);
3132 if ((bd->shading) || (bd->shaded))
3134 if (bd->shade.dir == E_DIRECTION_UP)
3135 y = bd->h - bd->client_inset.t - bd->client_inset.b -
3137 else if (bd->shade.dir == E_DIRECTION_LEFT)
3138 x = bd->w - bd->client_inset.l - bd->client_inset.r -
3141 ecore_x_window_shape_input_window_set_xy(twin2, bd->client.win,
3143 ecore_x_window_shape_input_rectangle_clip(twin2, 0, 0,
3144 bd->w - bd->client_inset.l - bd->client_inset.r,
3145 bd->h - bd->client_inset.t - bd->client_inset.b);
3146 ecore_x_window_shape_input_window_add_xy(twin, twin2,
3148 bd->client_inset.t);
3149 ecore_x_window_shape_input_window_set(bd->win, twin);
3150 ecore_x_window_free(twin2);
3151 ecore_x_window_free(twin);
3155 if (bd->visible) // not shaped input
3157 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
3158 ecore_x_composite_window_events_enable(bd->win);
3160 ecore_x_composite_window_events_disable(bd->win);
3164 if (!e_manager_comp_evas_get(bd->zone->container->manager))
3165 ecore_x_composite_window_events_enable(bd->win);
3167 ecore_x_composite_window_events_disable(bd->win);
3173 e_border_idler_before(void)
3182 EINA_LIST_FOREACH(e_manager_list(), ml, man)
3184 EINA_LIST_FOREACH(man->containers, cl, con)
3189 // pass 1 - eval0. fetch properties on new or on change and
3190 // call hooks to decide what to do - maybe move/resize
3191 bl = e_container_border_list_last(con);
3192 while ((bd = e_container_border_list_prev(bl)))
3194 if (bd->changed) _e_border_eval0(bd);
3196 e_container_border_list_free(bl);
3198 // layout hook - this is where a hook gets to figure out what to
3200 _e_border_container_layout_hook(con);
3202 // pass 2 - show windows needing show
3203 bl = e_container_border_list_last(con);
3204 while ((bd = e_container_border_list_prev(bl)))
3206 if ((bd->changes.visible) && (bd->visible) &&
3207 (!bd->new_client) && (!bd->changes.pos) &&
3208 (!bd->changes.size))
3211 bd->changes.visible = 0;
3214 e_container_border_list_free(bl);
3216 // pass 3 - hide windows needing hide and eval (main eval)
3217 bl = e_container_border_list_first(con);
3218 while ((bd = e_container_border_list_next(bl)))
3220 if (e_object_is_del(E_OBJECT(bd))) continue;
3222 if ((bd->changes.visible) && (!bd->visible))
3225 bd->changes.visible = 0;
3228 if (bd->changed) _e_border_eval(bd);
3230 if ((bd->changes.visible) && (bd->visible))
3233 bd->changes.visible = 0;
3236 e_container_border_list_free(bl);
3242 E_Border *bd = NULL, *bd2;
3244 EINA_LIST_FREE(focus_next, bd2)
3245 if ((!bd) && (bd2->visible)) bd = bd2;
3249 /* TODO revert focus when lost here ? */
3255 /* already focused. but anyway dont be so strict, this
3256 fcks up illume setting focus on internal windows */
3260 focus_time = ecore_x_current_time_get();
3264 if ((bd->client.icccm.take_focus) &&
3265 (bd->client.icccm.accepts_focus))
3267 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
3268 /* TODO what if the client doesnt took focus ? */
3270 else if (!bd->client.icccm.accepts_focus)
3272 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
3274 else if (!bd->client.icccm.take_focus)
3276 e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
3277 /* e_border_focus_set(bd, 1, 0); */
3283 e_border_client_list()
3285 /* FIXME: This should be a somewhat ordered list */
3289 static Ecore_X_Window action_input_win = 0;
3290 static E_Border *action_border = NULL;
3291 static Ecore_Event_Handler *action_handler_key = NULL;
3292 static Ecore_Event_Handler *action_handler_mouse = NULL;
3293 static Ecore_Timer *action_timer = NULL;
3294 static Ecore_X_Rectangle action_orig;
3297 _e_border_show(E_Border *bd)
3302 ecore_evas_show(bd->bg_ecore_evas);
3310 if (!((bd->comp_hidden) || (bd->tmp_input_hidden > 0)))
3312 _e_border_shape_input_rectangle_set(bd);
3314 // ecore_x_composite_window_events_enable(bd->win);
3315 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
3318 ecore_x_window_show(bd->win);
3320 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3321 ecore_x_window_show(tmp->win);
3325 _e_border_hide(E_Border *bd)
3330 if (!e_manager_comp_evas_get(bd->zone->container->manager))
3332 ecore_x_window_hide(bd->win);
3333 ecore_evas_hide(bd->bg_ecore_evas);
3335 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
3336 ecore_x_window_hide(tmp->win);
3340 ecore_x_composite_window_events_disable(bd->win);
3341 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
3346 _e_border_action_input_win_del(void)
3348 if (!action_input_win)
3351 e_grabinput_release(action_input_win, action_input_win);
3352 ecore_x_window_free(action_input_win);
3353 action_input_win = 0;
3358 _e_border_action_input_win_new(E_Border *bd)
3360 if (!action_input_win)
3362 Ecore_X_Window parent = bd->zone->container->win;
3363 action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
3364 if (!action_input_win)
3368 ecore_x_window_show(action_input_win);
3369 if (e_grabinput_get(action_input_win, 0, action_input_win))
3372 _e_border_action_input_win_del();
3377 _e_border_action_finish(void)
3379 _e_border_action_input_win_del();
3383 ecore_timer_del(action_timer);
3384 action_timer = NULL;
3387 if (action_handler_key)
3389 ecore_event_handler_del(action_handler_key);
3390 action_handler_key = NULL;
3393 if (action_handler_mouse)
3395 ecore_event_handler_del(action_handler_mouse);
3396 action_handler_mouse = NULL;
3399 action_border = NULL;
3403 _e_border_action_init(E_Border *bd)
3405 action_orig.x = bd->x;
3406 action_orig.y = bd->y;
3407 action_orig.width = bd->w;
3408 action_orig.height = bd->h;
3414 _e_border_action_restore_orig(E_Border *bd)
3416 if (action_border != bd)
3419 e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
3423 _e_border_key_down_modifier_apply(int modifier,
3426 if (modifier & ECORE_EVENT_MODIFIER_CTRL)
3428 else if (modifier & ECORE_EVENT_MODIFIER_ALT)
3441 _e_border_action_move_timeout(void *data __UNUSED__)
3443 _e_border_move_end(action_border);
3444 _e_border_action_finish();
3445 return ECORE_CALLBACK_CANCEL;
3449 _e_border_action_move_timeout_add(void)
3452 ecore_timer_del(action_timer);
3453 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
3457 _e_border_move_key_down(void *data __UNUSED__,
3458 int type __UNUSED__,
3461 Ecore_Event_Key *ev = event;
3464 if (ev->event_window != action_input_win)
3465 return ECORE_CALLBACK_PASS_ON;
3468 fputs("ERROR: no action_border!\n", stderr);
3472 x = action_border->x;
3473 y = action_border->y;
3475 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
3476 y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
3477 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
3478 y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
3479 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
3480 x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
3481 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
3482 x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
3483 else if (strcmp(ev->key, "Return") == 0)
3485 else if (strcmp(ev->key, "Escape") == 0)
3487 _e_border_action_restore_orig(action_border);
3490 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
3491 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
3494 e_border_move(action_border, x, y);
3495 _e_border_action_move_timeout_add();
3497 return ECORE_CALLBACK_PASS_ON;
3500 _e_border_move_end(action_border);
3501 _e_border_action_finish();
3502 return ECORE_CALLBACK_DONE;
3506 _e_border_move_mouse_down(void *data __UNUSED__,
3507 int type __UNUSED__,
3510 Ecore_Event_Mouse_Button *ev = event;
3512 if (ev->event_window != action_input_win)
3513 return ECORE_CALLBACK_PASS_ON;
3516 fputs("ERROR: no action_border!\n", stderr);
3518 _e_border_move_end(action_border);
3519 _e_border_action_finish();
3520 return ECORE_CALLBACK_DONE;
3524 e_border_act_move_keyboard(E_Border *bd)
3529 if (!_e_border_move_begin(bd))
3532 if (!_e_border_action_input_win_new(bd))
3534 _e_border_move_end(bd);
3538 _e_border_action_init(bd);
3539 _e_border_action_move_timeout_add();
3540 _e_border_move_update(bd);
3542 if (action_handler_key)
3543 ecore_event_handler_del(action_handler_key);
3544 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
3546 if (action_handler_mouse)
3547 ecore_event_handler_del(action_handler_mouse);
3548 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
3552 _e_border_action_resize_timeout(void *data __UNUSED__)
3554 _e_border_resize_end(action_border);
3555 _e_border_action_finish();
3556 return ECORE_CALLBACK_CANCEL;
3560 _e_border_action_resize_timeout_add(void)
3563 ecore_timer_del(action_timer);
3564 action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
3568 _e_border_resize_key_down(void *data __UNUSED__,
3569 int type __UNUSED__,
3572 Ecore_Event_Key *ev = event;
3575 if (ev->event_window != action_input_win)
3576 return ECORE_CALLBACK_PASS_ON;
3579 fputs("ERROR: no action_border!\n", stderr);
3583 w = action_border->w;
3584 h = action_border->h;
3586 dx = e_config->border_keyboard.resize.dx;
3587 if (dx < action_border->client.icccm.step_w)
3588 dx = action_border->client.icccm.step_w;
3589 dx = _e_border_key_down_modifier_apply(ev->modifiers, dx);
3590 if (dx < action_border->client.icccm.step_w)
3591 dx = action_border->client.icccm.step_w;
3593 dy = e_config->border_keyboard.resize.dy;
3594 if (dy < action_border->client.icccm.step_h)
3595 dy = action_border->client.icccm.step_h;
3596 dy = _e_border_key_down_modifier_apply(ev->modifiers, dy);
3597 if (dy < action_border->client.icccm.step_h)
3598 dy = action_border->client.icccm.step_h;
3600 if ((strcmp(ev->key, "Up") == 0) || (strcmp(ev->key, "k") == 0))
3602 else if ((strcmp(ev->key, "Down") == 0) || (strcmp(ev->key, "j") == 0))
3604 else if ((strcmp(ev->key, "Left") == 0) || (strcmp(ev->key, "h") == 0))
3606 else if ((strcmp(ev->key, "Right") == 0) || (strcmp(ev->key, "l") == 0))
3608 else if (strcmp(ev->key, "Return") == 0)
3610 else if (strcmp(ev->key, "Escape") == 0)
3612 _e_border_action_restore_orig(action_border);
3615 else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
3616 (strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
3619 e_border_resize_limit(action_border, &w, &h);
3620 e_border_resize(action_border, w, h);
3621 _e_border_action_resize_timeout_add();
3623 return ECORE_CALLBACK_PASS_ON;
3626 _e_border_resize_end(action_border);
3627 _e_border_action_finish();
3628 return ECORE_CALLBACK_DONE;
3632 _e_border_resize_mouse_down(void *data __UNUSED__,
3633 int type __UNUSED__,
3636 Ecore_Event_Mouse_Button *ev = event;
3638 if (ev->event_window != action_input_win)
3639 return ECORE_CALLBACK_PASS_ON;
3642 fputs("ERROR: no action_border!\n", stderr);
3644 _e_border_resize_end(action_border);
3645 _e_border_action_finish();
3646 return ECORE_CALLBACK_DONE;
3650 e_border_act_resize_keyboard(E_Border *bd)
3655 if (!_e_border_resize_begin(bd))
3658 if (!_e_border_action_input_win_new(bd))
3660 _e_border_resize_end(bd);
3664 _e_border_action_init(bd);
3665 _e_border_action_resize_timeout_add();
3666 _e_border_resize_update(bd);
3668 if (action_handler_key)
3669 ecore_event_handler_del(action_handler_key);
3670 action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
3672 if (action_handler_mouse)
3673 ecore_event_handler_del(action_handler_mouse);
3674 action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
3678 e_border_act_move_begin(E_Border *bd,
3679 Ecore_Event_Mouse_Button *ev)
3682 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3683 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
3684 if (!_e_border_move_begin(bd))
3687 e_zone_edge_disable();
3689 _e_border_pointer_move_begin(bd);
3694 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
3695 _e_border_moveinfo_gather(bd, source);
3700 e_border_act_move_end(E_Border *bd,
3701 Ecore_Event_Mouse_Button *ev __UNUSED__)
3704 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3705 if (!bd->moving) return;
3707 _e_border_pointer_move_end(bd);
3708 e_zone_edge_enable();
3709 _e_border_move_end(bd);
3710 e_zone_flip_coords_handle(bd->zone, -1, -1);
3714 e_border_act_resize_begin(E_Border *bd,
3715 Ecore_Event_Mouse_Button *ev)
3718 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3719 if (bd->lock_user_size) return;
3720 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
3721 if (!_e_border_resize_begin(bd))
3723 if (bd->mouse.current.mx < (bd->x + bd->w / 2))
3725 if (bd->mouse.current.my < (bd->y + bd->h / 2))
3727 bd->resize_mode = RESIZE_TL;
3728 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
3732 bd->resize_mode = RESIZE_BL;
3733 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
3738 if (bd->mouse.current.my < (bd->y + bd->h / 2))
3740 bd->resize_mode = RESIZE_TR;
3741 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
3745 bd->resize_mode = RESIZE_BR;
3746 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
3749 _e_border_pointer_resize_begin(bd);
3754 snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
3755 _e_border_moveinfo_gather(bd, source);
3760 e_border_act_resize_end(E_Border *bd,
3761 Ecore_Event_Mouse_Button *ev __UNUSED__)
3764 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3765 if (bd->resize_mode != RESIZE_NONE)
3767 _e_border_pointer_resize_end(bd);
3768 bd->resize_mode = RESIZE_NONE;
3769 _e_border_resize_end(bd);
3770 bd->changes.reset_gravity = 1;
3776 e_border_act_menu_begin(E_Border *bd,
3777 Ecore_Event_Mouse_Button *ev,
3781 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3784 e_int_border_menu_show(bd,
3785 bd->x + bd->fx.x + ev->x - bd->zone->container->x,
3786 bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
3793 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
3794 e_int_border_menu_show(bd, x, y, key, 0);
3799 e_border_act_close_begin(E_Border *bd)
3802 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3803 if (bd->lock_close) return;
3804 if (bd->client.icccm.delete_request)
3806 bd->delete_requested = 1;
3807 ecore_x_window_delete_request_send(bd->client.win);
3808 if (bd->client.netwm.ping)
3811 else if (e_config->kill_if_close_not_possible)
3813 e_border_act_kill_begin(bd);
3818 e_border_act_kill_begin(E_Border *bd)
3821 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
3822 if (bd->internal) return;
3823 if (bd->lock_close) return;
3824 if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
3826 kill(bd->client.netwm.pid, SIGINT);
3827 bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
3828 _e_border_cb_kill_timer, bd);
3832 if (!bd->internal) ecore_x_kill(bd->client.win);
3837 e_border_icon_add(E_Border *bd,
3842 E_OBJECT_CHECK_RETURN(bd, NULL);
3843 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
3848 if (!bd->internal_icon)
3850 o = e_icon_add(evas);
3851 e_util_icon_theme_set(o, "enlightenment");
3855 if (!bd->internal_icon_key)
3859 ext = strrchr(bd->internal_icon, '.');
3860 if ((ext) && ((!strcmp(ext, ".edj"))))
3862 o = edje_object_add(evas);
3863 if (!edje_object_file_set(o, bd->internal_icon, "icon"))
3864 e_util_icon_theme_set(o, "enlightenment");
3868 o = e_icon_add(evas);
3869 e_icon_file_set(o, bd->internal_icon);
3873 o = e_icon_add(evas);
3874 if (!e_util_icon_theme_set(o, bd->internal_icon))
3875 e_util_icon_theme_set(o, "enlightenment");
3880 o = edje_object_add(evas);
3881 edje_object_file_set(o, bd->internal_icon,
3882 bd->internal_icon_key);
3887 if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
3889 if (bd->client.netwm.icons)
3891 o = e_icon_add(evas);
3892 e_icon_data_set(o, bd->client.netwm.icons[0].data,
3893 bd->client.netwm.icons[0].width,
3894 bd->client.netwm.icons[0].height);
3895 e_icon_alpha_set(o, 1);
3901 if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
3903 o = e_icon_add(evas);
3906 e_icon_fdo_icon_set(o, bd->desktop->icon);
3910 else if (bd->client.netwm.icons)
3912 o = e_icon_add(evas);
3913 e_icon_data_set(o, bd->client.netwm.icons[0].data,
3914 bd->client.netwm.icons[0].width,
3915 bd->client.netwm.icons[0].height);
3916 e_icon_alpha_set(o, 1);
3921 o = e_icon_add(evas);
3922 e_util_icon_theme_set(o, "unknown");
3927 e_border_button_bindings_ungrab_all(void)
3932 EINA_LIST_FOREACH(borders, l, bd)
3934 e_focus_setdown(bd);
3935 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
3936 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
3941 e_border_button_bindings_grab_all(void)
3946 EINA_LIST_FOREACH(borders, l, bd)
3948 e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
3949 e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
3955 e_border_focus_stack_get(void)
3961 e_border_raise_stack_get(void)
3967 e_border_lost_windows_get(E_Zone *zone)
3969 Eina_List *list = NULL, *l;
3971 int loss_overlap = 5;
3973 E_OBJECT_CHECK_RETURN(zone, NULL);
3974 E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
3975 EINA_LIST_FOREACH(borders, l, bd)
3980 if ((bd->zone != zone) ||
3981 (bd->zone->container != zone->container))
3984 if (!E_INTERSECTS(bd->zone->x + loss_overlap,
3985 bd->zone->y + loss_overlap,
3986 bd->zone->w - (2 * loss_overlap),
3987 bd->zone->h - (2 * loss_overlap),
3988 bd->x, bd->y, bd->w, bd->h))
3990 list = eina_list_append(list, bd);
3992 else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
3993 bd->zone->w, bd->zone->h,
3994 bd->x, bd->y, bd->w, bd->h)) &&
3997 Ecore_X_Rectangle *rect;
4000 rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
4006 for (i = 0; i < num; i++)
4008 if (E_INTERSECTS(bd->zone->x + loss_overlap,
4009 bd->zone->y + loss_overlap,
4010 bd->zone->w - (2 * loss_overlap),
4011 bd->zone->h - (2 * loss_overlap),
4012 rect[i].x, rect[i].y,
4013 (int)rect[i].width, (int)rect[i].height))
4021 list = eina_list_append(list, bd);
4029 e_border_ping(E_Border *bd)
4032 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4033 if (!e_config->ping_clients) return;
4035 ecore_x_netwm_ping_send(bd->client.win);
4036 bd->ping = ecore_loop_time_get();
4037 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
4038 bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
4039 e_config->ping_clients_interval,
4040 _e_border_cb_ping_poller, bd);
4044 e_border_move_cancel(void)
4048 if (bdmove->cur_mouse_action)
4053 e_object_ref(E_OBJECT(bd));
4054 if (bd->cur_mouse_action->func.end_mouse)
4055 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
4056 else if (bd->cur_mouse_action->func.end)
4057 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
4058 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4059 bd->cur_mouse_action = NULL;
4060 e_object_unref(E_OBJECT(bd));
4063 _e_border_move_end(bdmove);
4068 e_border_resize_cancel(void)
4072 if (bdresize->cur_mouse_action)
4077 e_object_ref(E_OBJECT(bd));
4078 if (bd->cur_mouse_action->func.end_mouse)
4079 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", NULL);
4080 else if (bd->cur_mouse_action->func.end)
4081 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
4082 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4083 bd->cur_mouse_action = NULL;
4084 e_object_unref(E_OBJECT(bd));
4088 bdresize->resize_mode = RESIZE_NONE;
4089 _e_border_resize_end(bdresize);
4095 e_border_frame_recalc(E_Border *bd)
4097 if (!bd->bg_object) return;
4099 bd->w -= (bd->client_inset.l + bd->client_inset.r);
4100 bd->h -= (bd->client_inset.t + bd->client_inset.b);
4102 _e_border_client_inset_calc(bd);
4104 bd->w += (bd->client_inset.l + bd->client_inset.r);
4105 bd->h += (bd->client_inset.t + bd->client_inset.b);
4108 bd->changes.size = 1;
4109 if ((bd->shaped) || (bd->client.shaped))
4111 bd->need_shape_merge = 1;
4112 bd->need_shape_export = 1;
4114 if (bd->shaped_input)
4116 bd->need_shape_merge = 1;
4118 _e_border_client_move_resize_send(bd);
4122 e_border_immortal_windows_get(void)
4124 Eina_List *list = NULL, *l;
4127 EINA_LIST_FOREACH(borders, l, bd)
4130 list = eina_list_append(list, bd);
4136 e_border_name_get(const E_Border *bd)
4138 E_OBJECT_CHECK_RETURN(bd, "");
4139 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
4140 if (bd->client.netwm.name)
4141 return bd->client.netwm.name;
4142 else if (bd->client.icccm.title)
4143 return bd->client.icccm.title;
4148 e_border_signal_move_begin(E_Border *bd,
4150 const char *src __UNUSED__)
4153 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4155 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4156 if (!_e_border_move_begin(bd)) return;
4158 _e_border_pointer_move_begin(bd);
4159 e_zone_edge_disable();
4160 _e_border_moveinfo_gather(bd, sig);
4161 if (bd->cur_mouse_action)
4163 if ((!bd->cur_mouse_action->func.end_mouse) &&
4164 (!bd->cur_mouse_action->func.end))
4165 bd->cur_mouse_action = NULL;
4167 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4169 bd->cur_mouse_action = e_action_find("window_move");
4170 if (bd->cur_mouse_action)
4171 e_object_ref(E_OBJECT(bd->cur_mouse_action));
4175 e_border_signal_move_end(E_Border *bd,
4176 const char *sig __UNUSED__,
4177 const char *src __UNUSED__)
4180 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4181 if (!bd->moving) return;
4183 _e_border_pointer_move_end(bd);
4184 e_zone_edge_enable();
4185 _e_border_move_end(bd);
4186 e_zone_flip_coords_handle(bd->zone, -1, -1);
4190 e_border_resizing_get(E_Border *bd)
4192 E_OBJECT_CHECK_RETURN(bd, 0);
4193 E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
4194 if (bd->resize_mode == RESIZE_NONE) return 0;
4199 e_border_signal_resize_begin(E_Border *bd,
4202 const char *src __UNUSED__)
4204 Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
4205 int resize_mode = RESIZE_BR;
4208 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4210 if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
4211 if (!_e_border_resize_begin(bd))
4213 if (!strcmp(dir, "tl"))
4215 resize_mode = RESIZE_TL;
4216 grav = ECORE_X_GRAVITY_SE;
4218 else if (!strcmp(dir, "t"))
4220 resize_mode = RESIZE_T;
4221 grav = ECORE_X_GRAVITY_S;
4223 else if (!strcmp(dir, "tr"))
4225 resize_mode = RESIZE_TR;
4226 grav = ECORE_X_GRAVITY_SW;
4228 else if (!strcmp(dir, "r"))
4230 resize_mode = RESIZE_R;
4231 grav = ECORE_X_GRAVITY_W;
4233 else if (!strcmp(dir, "br"))
4235 resize_mode = RESIZE_BR;
4236 grav = ECORE_X_GRAVITY_NW;
4238 else if (!strcmp(dir, "b"))
4240 resize_mode = RESIZE_B;
4241 grav = ECORE_X_GRAVITY_N;
4243 else if (!strcmp(dir, "bl"))
4245 resize_mode = RESIZE_BL;
4246 grav = ECORE_X_GRAVITY_NE;
4248 else if (!strcmp(dir, "l"))
4250 resize_mode = RESIZE_L;
4251 grav = ECORE_X_GRAVITY_E;
4253 bd->resize_mode = resize_mode;
4254 _e_border_pointer_resize_begin(bd);
4255 _e_border_moveinfo_gather(bd, sig);
4257 if (bd->cur_mouse_action)
4259 if ((!bd->cur_mouse_action->func.end_mouse) &&
4260 (!bd->cur_mouse_action->func.end))
4261 bd->cur_mouse_action = NULL;
4263 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4265 bd->cur_mouse_action = e_action_find("window_resize");
4266 if (bd->cur_mouse_action)
4267 e_object_ref(E_OBJECT(bd->cur_mouse_action));
4271 e_border_signal_resize_end(E_Border *bd,
4272 const char *dir __UNUSED__,
4273 const char *sig __UNUSED__,
4274 const char *src __UNUSED__)
4277 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4278 if (bd->resize_mode == RESIZE_NONE) return;
4279 _e_border_resize_handle(bd);
4280 _e_border_pointer_resize_end(bd);
4281 bd->resize_mode = RESIZE_NONE;
4282 _e_border_resize_end(bd);
4283 bd->changes.reset_gravity = 1;
4288 e_border_resize_limit(E_Border *bd,
4295 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
4296 *w -= bd->client_inset.l + bd->client_inset.r;
4297 *h -= bd->client_inset.t + bd->client_inset.b;
4300 if ((bd->client.icccm.base_w >= 0) &&
4301 (bd->client.icccm.base_h >= 0))
4305 tw = *w - bd->client.icccm.base_w;
4306 th = *h - bd->client.icccm.base_h;
4309 a = (double)(tw) / (double)(th);
4310 if ((bd->client.icccm.min_aspect != 0.0) &&
4311 (a < bd->client.icccm.min_aspect))
4313 th = tw / bd->client.icccm.max_aspect;
4314 *h = th + bd->client.icccm.base_h;
4316 else if ((bd->client.icccm.max_aspect != 0.0) &&
4317 (a > bd->client.icccm.max_aspect))
4319 tw = th * bd->client.icccm.max_aspect;
4320 *w = tw + bd->client.icccm.base_w;
4325 a = (double)*w / (double)*h;
4326 if ((bd->client.icccm.min_aspect != 0.0) &&
4327 (a < bd->client.icccm.min_aspect))
4328 *h = *w / bd->client.icccm.min_aspect;
4329 else if ((bd->client.icccm.max_aspect != 0.0) &&
4330 (a > bd->client.icccm.max_aspect))
4331 *w = *h * bd->client.icccm.max_aspect;
4333 if (bd->client.icccm.step_w > 0)
4335 if (bd->client.icccm.base_w >= 0)
4336 *w = bd->client.icccm.base_w +
4337 (((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
4338 bd->client.icccm.step_w);
4340 *w = bd->client.icccm.min_w +
4341 (((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
4342 bd->client.icccm.step_w);
4344 if (bd->client.icccm.step_h > 0)
4346 if (bd->client.icccm.base_h >= 0)
4347 *h = bd->client.icccm.base_h +
4348 (((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
4349 bd->client.icccm.step_h);
4351 *h = bd->client.icccm.min_h +
4352 (((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
4353 bd->client.icccm.step_h);
4359 if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
4360 else if (*w < bd->client.icccm.min_w)
4361 *w = bd->client.icccm.min_w;
4362 if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
4363 else if (*h < bd->client.icccm.min_h)
4364 *h = bd->client.icccm.min_h;
4366 *w += bd->client_inset.l + bd->client_inset.r;
4367 *h += bd->client_inset.t + bd->client_inset.b;
4370 /* local subsystem functions */
4372 _e_border_free(E_Border *bd)
4374 if (bd->client.e.state.video_parent)
4379 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
4381 /* FIXME: cleanup memory */
4384 if (bd->client.e.state.video_child)
4386 /* FIXME: cleanup also */
4390 efreet_desktop_free(bd->desktop);
4395 ecore_idle_enterer_del(bd->post_job);
4396 bd->post_job = NULL;
4400 e_object_del(E_OBJECT(bd->pointer));
4404 _e_border_resize_end(bd);
4406 _e_border_move_end(bd);
4407 /* TODO: Other states to end before dying? */
4409 if (bd->cur_mouse_action)
4411 e_object_unref(E_OBJECT(bd->cur_mouse_action));
4412 bd->cur_mouse_action = NULL;
4415 E_FREE(bd->shape_rects);
4416 bd->shape_rects_num = 0;
4418 if (bd->dangling_ref_check)
4420 ecore_timer_del(bd->dangling_ref_check);
4421 bd->dangling_ref_check = NULL;
4426 ecore_timer_del(bd->kill_timer);
4427 bd->kill_timer = NULL;
4429 if (bd->ping_poller)
4431 ecore_poller_del(bd->ping_poller);
4432 bd->ping_poller = NULL;
4434 E_FREE_LIST(bd->pending_move_resize, free);
4436 if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
4437 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
4439 if (bd->border_locks_dialog)
4441 e_object_del(E_OBJECT(bd->border_locks_dialog));
4442 bd->border_locks_dialog = NULL;
4444 if (bd->border_remember_dialog)
4446 e_object_del(E_OBJECT(bd->border_remember_dialog));
4447 bd->border_remember_dialog = NULL;
4449 if (bd->border_border_dialog)
4451 e_object_del(E_OBJECT(bd->border_border_dialog));
4452 bd->border_border_dialog = NULL;
4454 if (bd->border_prop_dialog)
4456 e_object_del(E_OBJECT(bd->border_prop_dialog));
4457 bd->border_prop_dialog = NULL;
4460 e_int_border_menu_del(bd);
4467 if ((!focus_next) && (!focusing))
4469 e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE);
4470 e_hints_active_window_set(bd->zone->container->manager, NULL);
4475 E_FREE_LIST(bd->handlers, ecore_event_handler_del);
4481 bd->remember = NULL;
4482 e_remember_unuse(rem);
4484 if (!bd->already_unparented)
4486 ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
4487 bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
4488 ecore_x_window_save_set_del(bd->client.win);
4489 bd->already_unparented = 1;
4491 if (bd->group) eina_list_free(bd->group);
4492 if (bd->transients) eina_list_free(bd->transients);
4493 if (bd->stick_desks) eina_list_free(bd->stick_desks);
4494 if (bd->client.netwm.icons)
4497 for (i = 0; i < bd->client.netwm.num_icons; i++)
4498 free(bd->client.netwm.icons[i].data);
4499 free(bd->client.netwm.icons);
4501 if (bd->client.netwm.extra_types)
4502 free(bd->client.netwm.extra_types);
4503 if (bd->client.border.name)
4504 eina_stringshare_del(bd->client.border.name);
4506 eina_stringshare_del(bd->bordername);
4507 if (bd->client.icccm.name)
4508 eina_stringshare_del(bd->client.icccm.name);
4509 if (bd->client.icccm.class)
4510 eina_stringshare_del(bd->client.icccm.class);
4511 if (bd->client.icccm.title)
4512 eina_stringshare_del(bd->client.icccm.title);
4513 if (bd->client.icccm.icon_name)
4514 eina_stringshare_del(bd->client.icccm.icon_name);
4515 if (bd->client.icccm.machine)
4516 eina_stringshare_del(bd->client.icccm.machine);
4517 if (bd->client.icccm.window_role)
4518 eina_stringshare_del(bd->client.icccm.window_role);
4520 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
4524 for (i = 0; i < bd->client.icccm.command.argc; i++)
4525 free(bd->client.icccm.command.argv[i]);
4526 free(bd->client.icccm.command.argv);
4528 if (bd->client.netwm.name)
4529 eina_stringshare_del(bd->client.netwm.name);
4530 if (bd->client.netwm.icon_name)
4531 eina_stringshare_del(bd->client.netwm.icon_name);
4532 e_object_del(E_OBJECT(bd->shape));
4533 if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
4534 if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
4535 if (bd->icon_object) evas_object_del(bd->icon_object);
4536 evas_object_del(bd->bg_object);
4537 e_canvas_del(bd->bg_ecore_evas);
4538 ecore_evas_free(bd->bg_ecore_evas);
4539 ecore_x_window_free(bd->client.shell_win);
4540 e_focus_setdown(bd);
4541 e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
4542 e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
4543 ecore_x_window_free(bd->win);
4545 eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
4546 eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
4547 eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
4548 borders = eina_list_remove(borders, bd);
4549 focus_stack = eina_list_remove(focus_stack, bd);
4550 raise_stack = eina_list_remove(raise_stack, bd);
4552 e_container_border_remove(bd);
4558 _e_border_del_dangling_ref_check(void *data)
4564 printf("EEK EEK border still around 1 second after being deleted!\n");
4565 printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
4566 bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
4567 bd->client.icccm.name, bd->client.icccm.class);
4568 // e_object_breadcrumb_debug(E_OBJECT(bd));
4575 _e_border_del(E_Border *bd)
4577 E_Event_Border_Remove *ev;
4586 focus_next = eina_list_remove(focus_next, bd);
4588 if (bd->fullscreen) bd->desk->fullscreen_borders--;
4590 if ((drag_border) && (drag_border->data == bd))
4592 e_object_del(E_OBJECT(drag_border));
4595 if (bd->border_menu) e_menu_deactivate(bd->border_menu);
4597 if (bd->border_locks_dialog)
4599 e_object_del(E_OBJECT(bd->border_locks_dialog));
4600 bd->border_locks_dialog = NULL;
4602 if (bd->border_remember_dialog)
4604 e_object_del(E_OBJECT(bd->border_remember_dialog));
4605 bd->border_remember_dialog = NULL;
4607 if (bd->border_border_dialog)
4609 e_object_del(E_OBJECT(bd->border_border_dialog));
4610 bd->border_border_dialog = NULL;
4612 if (bd->border_prop_dialog)
4614 e_object_del(E_OBJECT(bd->border_prop_dialog));
4615 bd->border_prop_dialog = NULL;
4618 e_int_border_menu_del(bd);
4620 if (bd->raise_timer)
4622 ecore_timer_del(bd->raise_timer);
4623 bd->raise_timer = NULL;
4625 if (!bd->already_unparented)
4627 ecore_x_window_reparent(bd->client.win,
4628 bd->zone->container->manager->root,
4629 bd->x + bd->client_inset.l,
4630 bd->y + bd->client_inset.t);
4631 ecore_x_window_save_set_del(bd->client.win);
4632 bd->already_unparented = 1;
4633 // bd->client.win = 0;
4635 bd->already_unparented = 1;
4637 if ((!bd->new_client) && (!stopping))
4639 ev = E_NEW(E_Event_Border_Remove, 1);
4641 e_object_ref(E_OBJECT(bd));
4642 // e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
4643 ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
4648 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
4649 if (bd->parent->modal == bd)
4650 bd->parent->modal = NULL;
4653 EINA_LIST_FREE(bd->transients, child)
4655 child->parent = NULL;
4660 bd->leader->group = eina_list_remove(bd->leader->group, bd);
4661 if (bd->leader->modal == bd)
4662 bd->leader->modal = NULL;
4665 EINA_LIST_FREE(bd->group, child)
4667 child->leader = NULL;
4671 #ifdef PRINT_LOTS_OF_DEBUG
4673 _e_border_print(E_Border *bd,
4678 printf("*Window Info*"
4682 "\tBorderless: %s\n",
4683 bd, bd->client.icccm.name, bd->client.icccm.title,
4684 bd->borderless ? "TRUE" : "FALSE");
4690 _e_border_cb_window_show_request(void *data __UNUSED__,
4691 int ev_type __UNUSED__,
4695 Ecore_X_Event_Window_Show_Request *e;
4698 bd = e_border_find_by_client_window(e->win);
4699 if (!bd) return ECORE_CALLBACK_PASS_ON;
4702 if (!bd->lock_client_iconify)
4703 e_border_uniconify(bd);
4707 /* FIXME: make border "urgent" for a bit - it wants attention */
4708 /* e_border_show(bd); */
4709 if (!bd->lock_client_stacking)
4712 return ECORE_CALLBACK_PASS_ON;
4716 _e_border_cb_window_destroy(void *data __UNUSED__,
4717 int ev_type __UNUSED__,
4721 Ecore_X_Event_Window_Destroy *e;
4724 bd = e_border_find_by_client_window(e->win);
4725 if (!bd) return ECORE_CALLBACK_PASS_ON;
4726 e_border_hide(bd, 0);
4727 e_object_del(E_OBJECT(bd));
4728 return ECORE_CALLBACK_PASS_ON;
4732 _e_border_cb_window_hide(void *data __UNUSED__,
4733 int ev_type __UNUSED__,
4737 Ecore_X_Event_Window_Hide *e;
4740 // printf("HIDE: %x, event %x\n", e->win, e->event_win);
4741 // not interested in hide events from windows other than the window in question
4742 if (e->win != e->event_win) return ECORE_CALLBACK_PASS_ON;
4743 bd = e_border_find_by_client_window(e->win);
4744 // printf(" bd = %p\n", bd);
4745 if (!bd) return ECORE_CALLBACK_PASS_ON;
4746 // printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
4747 if (bd->ignore_first_unmap > 0)
4749 bd->ignore_first_unmap--;
4750 return ECORE_CALLBACK_PASS_ON;
4752 /* Don't delete hidden or iconified windows */
4753 if ((bd->iconic) || ((!bd->visible) && (!bd->new_client)) ||
4754 (bd->await_hide_event > 0))
4756 // printf(" Don't delete hidden or iconified windows\n");
4757 // printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
4758 // bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
4759 if (bd->await_hide_event > 0)
4761 bd->await_hide_event--;
4765 // printf(" hide really\n");
4766 /* Only hide the border if it is visible */
4767 if (bd->visible) e_border_hide(bd, 1);
4772 // printf(" hide2\n");
4773 e_border_hide(bd, 0);
4774 e_object_del(E_OBJECT(bd));
4776 return ECORE_CALLBACK_PASS_ON;
4780 _e_border_cb_window_reparent(void *data __UNUSED__,
4781 int ev_type __UNUSED__,
4782 void *ev __UNUSED__)
4786 Ecore_X_Event_Window_Reparent *e;
4789 bd = e_border_find_by_client_window(e->win);
4791 if (e->parent == bd->client.shell_win) return 1;
4792 if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
4796 e_border_hide(bd, 0);
4797 e_object_del(E_OBJECT(bd));
4799 return ECORE_CALLBACK_PASS_ON;
4803 _e_border_cb_window_configure_request(void *data __UNUSED__,
4804 int ev_type __UNUSED__,
4808 Ecore_X_Event_Window_Configure_Request *e;
4811 bd = e_border_find_by_client_window(e->win);
4814 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
4815 if (!e_util_container_window_find(e->win))
4816 ecore_x_window_configure(e->win, e->value_mask,
4817 e->x, e->y, e->w, e->h, e->border,
4818 e->abovewin, e->detail);
4819 return ECORE_CALLBACK_PASS_ON;
4822 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
4823 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
4829 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
4831 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
4833 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
4834 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
4840 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
4841 w = e->w + bd->client_inset.l + bd->client_inset.r;
4842 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
4843 h = e->h + bd->client_inset.t + bd->client_inset.b;
4844 if ((!bd->lock_client_location) && (!bd->lock_client_size))
4846 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4848 bd->saved.x = x - bd->zone->x;
4849 bd->saved.y = y - bd->zone->y;
4854 e_border_move_resize(bd, x, y, w, h);
4856 else if (!bd->lock_client_location)
4858 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4860 bd->saved.x = x - bd->zone->x;
4861 bd->saved.y = y - bd->zone->y;
4864 e_border_move(bd, x, y);
4866 else if (!bd->lock_client_size)
4868 if ((bd->shaded) || (bd->shading))
4874 if ((bd->shade.dir == E_DIRECTION_UP) ||
4875 (bd->shade.dir == E_DIRECTION_DOWN))
4877 e_border_resize(bd, w, bd->h);
4882 e_border_resize(bd, bd->w, h);
4888 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4894 e_border_resize(bd, w, h);
4900 if (!bd->lock_client_location)
4902 if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
4904 bd->saved.x = x - bd->zone->x;
4905 bd->saved.y = y - bd->zone->y;
4908 e_border_move(bd, x, y);
4912 else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
4913 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
4919 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
4920 w = e->w + bd->client_inset.l + bd->client_inset.r;
4921 if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
4922 h = e->h + bd->client_inset.t + bd->client_inset.b;
4923 if (!bd->lock_client_size)
4925 if ((bd->shaded) || (bd->shading))
4931 if ((bd->shade.dir == E_DIRECTION_UP) ||
4932 (bd->shade.dir == E_DIRECTION_DOWN))
4934 e_border_resize(bd, w, bd->h);
4939 e_border_resize(bd, bd->w, h);
4945 if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
4950 zx = zy = zw = zh = 0;
4953 * This code does resize and move a window on a
4954 * X configure request into an useful geometry.
4955 * This is really useful for size jumping file dialogs.
4960 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
4962 if (e_config->geometry_auto_resize_limit == 1)
4971 e_border_resize(bd, w, h);
4973 if (e_config->geometry_auto_move == 1)
4975 /* z{x,y,w,h} are only set here; FIXME! */
4978 // move window horizontal if resize to not useful geometry
4979 if (bd->x + bd->w > zx + zw)
4980 rx = zx + zw - bd->w;
4981 else if (bd->x < zx)
4984 // move window vertical if resize to not useful geometry
4985 if (bd->y + bd->h > zy + zh)
4986 ry = zy + zh - bd->h;
4987 else if (bd->y < zy)
4990 e_border_move(bd, rx, ry);
4996 if (!bd->lock_client_stacking)
4998 if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
4999 (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
5003 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
5005 obd = e_border_find_by_client_window(e->abovewin);
5008 e_border_stack_above(bd, obd);
5012 ecore_x_window_configure(bd->win,
5013 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
5014 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
5016 e->abovewin, ECORE_X_WINDOW_STACK_ABOVE);
5017 /* FIXME: need to rebuiuld border list from current stacking */
5020 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
5022 obd = e_border_find_by_client_window(e->abovewin);
5025 e_border_stack_below(bd, obd);
5029 ecore_x_window_configure(bd->win,
5030 ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING |
5031 ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE,
5033 e->abovewin, ECORE_X_WINDOW_STACK_BELOW);
5034 /* FIXME: need to rebuiuld border list from current stacking */
5037 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
5041 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
5045 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
5050 else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
5052 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
5056 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
5060 else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
5064 else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
5068 else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
5075 /* FIXME: need to send synthetic stacking event too as well as move/resize */
5076 _e_border_client_move_resize_send(bd);
5077 return ECORE_CALLBACK_PASS_ON;
5081 _e_border_cb_window_resize_request(void *data __UNUSED__,
5082 int ev_type __UNUSED__,
5086 Ecore_X_Event_Window_Resize_Request *e;
5089 bd = e_border_find_by_client_window(e->win);
5092 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
5093 ecore_x_window_resize(e->win, e->w, e->h);
5094 return ECORE_CALLBACK_PASS_ON;
5099 w = e->w + bd->client_inset.l + bd->client_inset.r;
5100 h = e->h + bd->client_inset.t + bd->client_inset.b;
5101 if ((bd->shaded) || (bd->shading))
5107 if ((bd->shade.dir == E_DIRECTION_UP) ||
5108 (bd->shade.dir == E_DIRECTION_DOWN))
5110 e_border_resize(bd, w, bd->h);
5115 e_border_resize(bd, bd->w, h);
5120 e_border_resize(bd, w, h);
5123 _e_border_client_move_resize_send(bd);
5124 return ECORE_CALLBACK_PASS_ON;
5128 _e_border_cb_window_gravity(void *data __UNUSED__,
5129 int ev_type __UNUSED__,
5130 void *ev __UNUSED__)
5133 // Ecore_X_Event_Window_Gravity *e;
5136 // bd = e_border_find_by_client_window(e->win);
5137 // if (!bd) return 1;
5142 _e_border_cb_window_stack_request(void *data __UNUSED__,
5143 int ev_type __UNUSED__,
5147 Ecore_X_Event_Window_Stack_Request *e;
5150 bd = e_border_find_by_client_window(e->win);
5153 if (e_stolen_win_get(e->win)) return ECORE_CALLBACK_PASS_ON;
5154 if (!e_util_container_window_find(e->win))
5159 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
5161 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
5162 if (tmp) ecore_x_window_raise(tmp->win);
5163 ecore_x_window_raise(e->win);
5165 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
5167 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
5168 if (tmp) ecore_x_window_lower(tmp->win);
5169 ecore_x_window_lower(e->win);
5172 return ECORE_CALLBACK_PASS_ON;
5174 if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
5176 else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
5178 return ECORE_CALLBACK_PASS_ON;
5182 _e_border_cb_window_property(void *data __UNUSED__,
5183 int ev_type __UNUSED__,
5187 Ecore_X_Event_Window_Property *e;
5190 bd = e_border_find_by_client_window(e->win);
5191 if (!bd) return ECORE_CALLBACK_PASS_ON;
5192 if (e->atom == ECORE_X_ATOM_WM_NAME)
5194 if ((!bd->client.netwm.name) &&
5195 (!bd->client.netwm.fetch.name))
5197 bd->client.icccm.fetch.title = 1;
5201 else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
5203 bd->client.netwm.fetch.name = 1;
5206 else if (e->atom == ECORE_X_ATOM_WM_CLASS)
5208 bd->client.icccm.fetch.name_class = 1;
5211 else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
5213 if ((!bd->client.netwm.icon_name) &&
5214 (!bd->client.netwm.fetch.icon_name))
5216 bd->client.icccm.fetch.icon_name = 1;
5220 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
5222 bd->client.netwm.fetch.icon_name = 1;
5225 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
5227 bd->client.icccm.fetch.machine = 1;
5230 else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
5232 bd->client.icccm.fetch.protocol = 1;
5235 else if (e->atom == ECORE_X_ATOM_WM_HINTS)
5237 bd->client.icccm.fetch.hints = 1;
5240 else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
5242 bd->client.icccm.fetch.size_pos_hints = 1;
5245 else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
5248 if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
5249 (!bd->client.netwm.fetch.type))
5252 bd->client.mwm.fetch.hints = 1;
5258 else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
5260 bd->client.icccm.fetch.transient_for = 1;
5263 else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
5265 bd->client.icccm.fetch.client_leader = 1;
5268 else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
5270 bd->client.icccm.fetch.window_role = 1;
5273 else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
5275 bd->client.netwm.fetch.icon = 1;
5278 else if (e->atom == ATM__QTOPIA_SOFT_MENU)
5280 bd->client.qtopia.fetch.soft_menu = 1;
5283 else if (e->atom == ATM__QTOPIA_SOFT_MENUS)
5285 bd->client.qtopia.fetch.soft_menus = 1;
5288 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
5290 bd->client.vkbd.fetch.state = 1;
5293 else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
5295 bd->client.vkbd.fetch.vkbd = 1;
5298 else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT)
5300 bd->client.illume.conformant.fetch.conformant = 1;
5303 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE)
5305 bd->client.illume.quickpanel.fetch.state = 1;
5308 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL)
5310 bd->client.illume.quickpanel.fetch.quickpanel = 1;
5313 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR)
5315 bd->client.illume.quickpanel.fetch.priority.major = 1;
5318 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR)
5320 bd->client.illume.quickpanel.fetch.priority.minor = 1;
5323 else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE)
5325 bd->client.illume.quickpanel.fetch.zone = 1;
5328 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED)
5330 bd->client.illume.drag.fetch.locked = 1;
5333 else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG)
5335 bd->client.illume.drag.fetch.drag = 1;
5339 else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
5341 bd->client.netwm.fetch.user_time = 1;
5344 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
5346 bd->client.netwm.fetch.strut = 1;
5349 else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
5351 bd->client.netwm.fetch.strut = 1;
5355 else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
5357 //printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
5359 else if (e->atom == ECORE_X_ATOM_E_VIDEO_POSITION)
5361 bd->client.e.fetch.video_position = 1;
5364 else if (e->atom == ECORE_X_ATOM_E_VIDEO_PARENT)
5366 bd->client.e.fetch.video_parent = 1;
5370 return ECORE_CALLBACK_PASS_ON;
5374 _e_border_cb_window_colormap(void *data __UNUSED__,
5375 int ev_type __UNUSED__,
5379 Ecore_X_Event_Window_Colormap *e;
5382 bd = e_border_find_by_client_window(e->win);
5383 if (!bd) return ECORE_CALLBACK_PASS_ON;
5384 return ECORE_CALLBACK_PASS_ON;
5388 _e_border_cb_window_shape(void *data __UNUSED__,
5389 int ev_type __UNUSED__,
5393 Ecore_X_Event_Window_Shape *e;
5396 bd = e_border_find_by_client_window(e->win);
5398 if (e->type == ECORE_X_SHAPE_INPUT)
5402 bd->need_shape_merge = 1;
5403 // YYY bd->shaped_input = 1;
5404 bd->changes.shape_input = 1;
5408 return ECORE_CALLBACK_PASS_ON;
5413 bd->changes.shape = 1;
5415 return ECORE_CALLBACK_PASS_ON;
5417 bd = e_border_find_by_window(e->win);
5420 bd->need_shape_export = 1;
5422 return ECORE_CALLBACK_PASS_ON;
5424 bd = e_border_find_by_frame_window(e->win);
5427 bd->need_shape_merge = 1;
5429 return ECORE_CALLBACK_PASS_ON;
5431 return ECORE_CALLBACK_PASS_ON;
5435 _e_border_cb_window_focus_in(void *data __UNUSED__,
5436 int ev_type __UNUSED__,
5440 Ecore_X_Event_Window_Focus_In *e;
5443 bd = e_border_find_by_client_window(e->win);
5444 if (!bd) return ECORE_CALLBACK_PASS_ON;
5445 #ifdef INOUTDEBUG_FOCUS
5450 const char *modes[] = {
5452 "MODE_WHILE_GRABBED",
5456 const char *details[] = {
5460 "DETAIL_NON_LINEAR",
5461 "DETAIL_NON_LINEAR_VIRTUAL",
5463 "DETAIL_POINTER_ROOT",
5464 "DETAIL_DETAIL_NONE"
5468 ct[strlen(ct) - 1] = 0;
5469 printf("FF ->IN %i 0x%x %s md=%s dt=%s\n",
5474 details[e->detail]);
5476 printf("%s cb focus in %d %d\n",
5477 e_border_name_get(bd),
5478 bd->client.icccm.accepts_focus,
5479 bd->client.icccm.take_focus);
5482 _e_border_pri_raise(bd);
5483 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
5485 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
5487 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
5489 if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return ECORE_CALLBACK_PASS_ON;
5492 /* ignore focus in from !take_focus windows, we just gave it em */
5493 /* if (!bd->client.icccm.take_focus)
5494 * return ECORE_CALLBACK_PASS_ON; */
5496 /* should be equal, maybe some clients dont reply with the proper timestamp ? */
5497 if (e->time >= focus_time)
5498 e_border_focus_set(bd, 1, 0);
5499 return ECORE_CALLBACK_PASS_ON;
5503 _e_border_cb_window_focus_out(void *data __UNUSED__,
5504 int ev_type __UNUSED__,
5508 Ecore_X_Event_Window_Focus_Out *e;
5511 bd = e_border_find_by_client_window(e->win);
5512 if (!bd) return ECORE_CALLBACK_PASS_ON;
5513 #ifdef INOUTDEBUG_FOCUS
5518 const char *modes[] = {
5520 "MODE_WHILE_GRABBED",
5524 const char *details[] = {
5528 "DETAIL_NON_LINEAR",
5529 "DETAIL_NON_LINEAR_VIRTUAL",
5531 "DETAIL_POINTER_ROOT",
5532 "DETAIL_DETAIL_NONE"
5536 ct[strlen(ct) - 1] = 0;
5537 printf("FF <-OUT %i 0x%x %s md=%s dt=%s\n",
5542 details[e->detail]);
5544 printf("%s cb focus out %d %d\n",
5545 e_border_name_get(bd),
5546 bd->client.icccm.accepts_focus,
5547 bd->client.icccm.take_focus);
5550 _e_border_pri_norm(bd);
5551 if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
5553 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
5554 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)
5555 return ECORE_CALLBACK_PASS_ON;
5556 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
5557 return ECORE_CALLBACK_PASS_ON;
5559 else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
5561 if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return ECORE_CALLBACK_PASS_ON;
5562 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
5563 return ECORE_CALLBACK_PASS_ON;
5564 else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL)
5565 return ECORE_CALLBACK_PASS_ON;
5566 else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR)
5567 return ECORE_CALLBACK_PASS_ON;
5568 else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL)
5569 return ECORE_CALLBACK_PASS_ON;
5571 else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
5573 /* for firefox/thunderbird (xul) menu walking */
5574 /* NB: why did i disable this before? */
5575 if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON;
5576 else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER)
5577 return ECORE_CALLBACK_PASS_ON;
5579 else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
5581 if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return ECORE_CALLBACK_PASS_ON;
5582 else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR)
5583 return ECORE_CALLBACK_PASS_ON;
5585 e_border_focus_set(bd, 0, 0);
5586 return ECORE_CALLBACK_PASS_ON;
5590 _e_border_cb_client_message(void *data __UNUSED__,
5591 int ev_type __UNUSED__,
5592 void *ev __UNUSED__)
5596 Ecore_X_Event_Client_Message *e;
5599 bd = e_border_find_by_client_window(e->win);
5606 _e_border_cb_window_state_request(void *data __UNUSED__,
5607 int ev_type __UNUSED__,
5611 Ecore_X_Event_Window_State_Request *e;
5615 bd = e_border_find_by_client_window(e->win);
5616 if (!bd) return ECORE_CALLBACK_PASS_ON;
5618 for (i = 0; i < 2; i++)
5619 e_hints_window_state_update(bd, e->state[i], e->action);
5621 return ECORE_CALLBACK_PASS_ON;
5625 _e_border_cb_window_move_resize_request(void *data __UNUSED__,
5626 int ev_type __UNUSED__,
5630 Ecore_X_Event_Window_Move_Resize_Request *e;
5633 bd = e_border_find_by_client_window(e->win);
5634 if (!bd) return ECORE_CALLBACK_PASS_ON;
5636 if ((bd->shaded) || (bd->shading) ||
5637 (bd->fullscreen) || (bd->moving) ||
5638 (bd->resize_mode != RESIZE_NONE))
5639 return ECORE_CALLBACK_PASS_ON;
5641 if ((e->button >= 1) && (e->button <= 3))
5643 bd->mouse.last_down[e->button - 1].mx = e->x;
5644 bd->mouse.last_down[e->button - 1].my = e->y;
5645 bd->mouse.last_down[e->button - 1].x = bd->x;
5646 bd->mouse.last_down[e->button - 1].y = bd->y;
5647 bd->mouse.last_down[e->button - 1].w = bd->w;
5648 bd->mouse.last_down[e->button - 1].h = bd->h;
5652 bd->moveinfo.down.x = bd->x;
5653 bd->moveinfo.down.y = bd->y;
5654 bd->moveinfo.down.w = bd->w;
5655 bd->moveinfo.down.h = bd->h;
5657 bd->mouse.current.mx = e->x;
5658 bd->mouse.current.my = e->y;
5659 bd->moveinfo.down.button = e->button;
5660 bd->moveinfo.down.mx = e->x;
5661 bd->moveinfo.down.my = e->y;
5664 if (!bd->lock_user_stacking)
5667 if (e->direction == MOVE)
5669 bd->cur_mouse_action = e_action_find("window_move");
5670 if (bd->cur_mouse_action)
5672 if ((!bd->cur_mouse_action->func.end_mouse) &&
5673 (!bd->cur_mouse_action->func.end))
5674 bd->cur_mouse_action = NULL;
5675 if (bd->cur_mouse_action)
5677 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5678 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
5681 return ECORE_CALLBACK_PASS_ON;
5684 if (!_e_border_resize_begin(bd))
5685 return ECORE_CALLBACK_PASS_ON;
5687 switch(e->direction)
5690 bd->resize_mode = RESIZE_TL;
5691 GRAV_SET(bd, ECORE_X_GRAVITY_SE);
5695 bd->resize_mode = RESIZE_T;
5696 GRAV_SET(bd, ECORE_X_GRAVITY_S);
5700 bd->resize_mode = RESIZE_TR;
5701 GRAV_SET(bd, ECORE_X_GRAVITY_SW);
5705 bd->resize_mode = RESIZE_R;
5706 GRAV_SET(bd, ECORE_X_GRAVITY_W);
5710 bd->resize_mode = RESIZE_BR;
5711 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
5715 bd->resize_mode = RESIZE_B;
5716 GRAV_SET(bd, ECORE_X_GRAVITY_N);
5720 bd->resize_mode = RESIZE_BL;
5721 GRAV_SET(bd, ECORE_X_GRAVITY_NE);
5725 bd->resize_mode = RESIZE_L;
5726 GRAV_SET(bd, ECORE_X_GRAVITY_E);
5730 return ECORE_CALLBACK_PASS_ON;
5733 bd->cur_mouse_action = e_action_find("window_resize");
5734 if (bd->cur_mouse_action)
5736 if ((!bd->cur_mouse_action->func.end_mouse) &&
5737 (!bd->cur_mouse_action->func.end))
5738 bd->cur_mouse_action = NULL;
5740 if (bd->cur_mouse_action)
5741 e_object_ref(E_OBJECT(bd->cur_mouse_action));
5743 return ECORE_CALLBACK_PASS_ON;
5747 _e_border_cb_desktop_change(void *data __UNUSED__,
5748 int ev_type __UNUSED__,
5752 Ecore_X_Event_Desktop_Change *e;
5755 bd = e_border_find_by_client_window(e->win);
5758 if (e->desk == 0xffffffff)
5760 else if ((int)e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
5764 desk = e_desk_at_pos_get(bd->zone, e->desk);
5766 e_border_desk_set(bd, desk);
5771 ecore_x_netwm_desktop_set(e->win, e->desk);
5773 return ECORE_CALLBACK_PASS_ON;
5777 _e_border_cb_sync_alarm(void *data __UNUSED__,
5778 int ev_type __UNUSED__,
5782 Ecore_X_Event_Sync_Alarm *e;
5783 unsigned int serial;
5786 bd = e_border_find_by_alarm(e->alarm);
5787 if (!bd) return ECORE_CALLBACK_PASS_ON;
5789 if (bd->client.netwm.sync.wait)
5790 bd->client.netwm.sync.wait--;
5792 if (ecore_x_sync_counter_query(bd->client.netwm.sync.counter, &serial))
5794 E_Border_Pending_Move_Resize *pnd = NULL;
5796 /* skip pending for which we didn't get a reply */
5797 while (bd->pending_move_resize)
5799 pnd = bd->pending_move_resize->data;
5800 bd->pending_move_resize = eina_list_remove(bd->pending_move_resize, pnd);
5802 if (serial == pnd->serial)
5814 bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
5815 bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
5820 bd->changes.size = 1;
5821 bd->changes.pos = 1;
5824 evas_render(bd->bg_evas);
5826 ecore_x_pointer_xy_get(e_manager_current_get()->root,
5827 &bd->mouse.current.mx,
5828 &bd->mouse.current.my);
5830 bd->client.netwm.sync.send_time = ecore_loop_time_get();
5831 _e_border_resize_handle(bd);
5833 return ECORE_CALLBACK_PASS_ON;
5837 _e_border_cb_efreet_cache_update(void *data __UNUSED__,
5838 int ev_type __UNUSED__,
5839 void *ev __UNUSED__)
5844 /* mark all borders for desktop/icon updates */
5845 EINA_LIST_FOREACH(borders, l, bd)
5849 efreet_desktop_free(bd->desktop);
5852 bd->changes.icon = 1;
5856 e_init_status_set(_("Desktop files scan done"));
5859 return ECORE_CALLBACK_PASS_ON;
5863 _e_border_cb_config_icon_theme(void *data __UNUSED__,
5864 int ev_type __UNUSED__,
5865 void *ev __UNUSED__)
5870 /* mark all borders for desktop/icon updates */
5871 EINA_LIST_FOREACH(borders, l, bd)
5873 bd->changes.icon = 1;
5876 return ECORE_CALLBACK_PASS_ON;
5880 _e_border_cb_pointer_warp(void *data __UNUSED__,
5881 int ev_type __UNUSED__,
5884 E_Event_Pointer_Warp *e;
5887 if (!bdmove) return ECORE_CALLBACK_PASS_ON;
5888 e_border_move(bdmove, bdmove->x + (e->curr.x - e->prev.x), bdmove->y + (e->curr.y - e->prev.y));
5889 return ECORE_CALLBACK_PASS_ON;
5893 _e_border_cb_signal_bind(void *data,
5894 Evas_Object *obj __UNUSED__,
5895 const char *emission,
5901 if (e_dnd_active()) return;
5902 e_bindings_signal_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd),
5907 _e_border_cb_mouse_in(void *data,
5908 int type __UNUSED__,
5911 Ecore_X_Event_Mouse_In *ev;
5916 #ifdef INOUTDEBUG_MOUSE
5921 const char *modes[] = {
5923 "MODE_WHILE_GRABBED",
5927 const char *details[] = {
5931 "DETAIL_NON_LINEAR",
5932 "DETAIL_NON_LINEAR_VIRTUAL",
5934 "DETAIL_POINTER_ROOT",
5935 "DETAIL_DETAIL_NONE"
5939 ct[strlen(ct) - 1] = 0;
5940 printf("@@ ->IN 0x%x 0x%x %s md=%s dt=%s\n",
5941 ev->win, ev->event_win,
5944 details[ev->detail]);
5947 if (grabbed) return ECORE_CALLBACK_PASS_ON;
5948 if (ev->event_win == bd->win)
5950 e_focus_event_mouse_in(bd);
5953 if ((ev->win != bd->win) &&
5954 (ev->win != bd->event_win) &&
5955 (ev->event_win != bd->win) &&
5956 (ev->event_win != bd->event_win))
5957 return ECORE_CALLBACK_PASS_ON;
5959 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
5961 bd->mouse.current.mx = ev->root.x;
5962 bd->mouse.current.my = ev->root.y;
5963 if (!bd->bg_evas_in)
5965 evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
5966 bd->bg_evas_in = EINA_TRUE;
5968 return ECORE_CALLBACK_PASS_ON;
5972 _e_border_cb_mouse_out(void *data,
5973 int type __UNUSED__,
5976 Ecore_X_Event_Mouse_Out *ev;
5981 #ifdef INOUTDEBUG_MOUSE
5986 const char *modes[] = {
5988 "MODE_WHILE_GRABBED",
5992 const char *details[] = {
5996 "DETAIL_NON_LINEAR",
5997 "DETAIL_NON_LINEAR_VIRTUAL",
5999 "DETAIL_POINTER_ROOT",
6000 "DETAIL_DETAIL_NONE"
6004 ct[strlen(ct) - 1] = 0;
6005 printf("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s\n",
6006 ev->win, ev->event_win,
6009 details[ev->detail]);
6012 if (grabbed) return ECORE_CALLBACK_PASS_ON;
6014 if (ev->event_win == bd->win)
6017 return ECORE_CALLBACK_PASS_ON;
6018 if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
6019 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
6020 return ECORE_CALLBACK_PASS_ON;
6021 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
6022 return ECORE_CALLBACK_PASS_ON;
6023 if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
6024 (ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
6025 return ECORE_CALLBACK_PASS_ON;
6026 e_focus_event_mouse_out(bd);
6030 if ((ev->win != bd->win) &&
6031 (ev->win != bd->event_win) &&
6032 (ev->event_win != bd->win) &&
6033 (ev->event_win != bd->event_win))
6034 return ECORE_CALLBACK_PASS_ON;
6036 if (ev->win != bd->event_win) return ECORE_CALLBACK_PASS_ON;
6038 bd->mouse.current.mx = ev->root.x;
6039 bd->mouse.current.my = ev->root.y;
6042 if (!((evas_event_down_count_get(bd->bg_evas) > 0) &&
6043 (!((ev->mode == ECORE_X_EVENT_MODE_GRAB) &&
6044 (ev->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR)))))
6046 if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
6047 evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
6048 evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
6049 bd->bg_evas_in = EINA_FALSE;
6052 return ECORE_CALLBACK_PASS_ON;
6056 _e_border_cb_mouse_wheel(void *data,
6057 int type __UNUSED__,
6060 Ecore_Event_Mouse_Wheel *ev;
6065 if ((ev->event_window == bd->win) ||
6066 (ev->event_window == bd->event_win))
6068 bd->mouse.current.mx = ev->root.x;
6069 bd->mouse.current.my = ev->root.y;
6070 if (!bd->cur_mouse_action)
6071 e_bindings_wheel_event_handle(E_BINDING_CONTEXT_BORDER,
6074 evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
6075 return ECORE_CALLBACK_PASS_ON;
6079 _e_border_cb_mouse_down(void *data,
6080 int type __UNUSED__,
6083 Ecore_Event_Mouse_Button *ev;
6088 if ((ev->event_window == bd->win) ||
6089 (ev->event_window == bd->event_win))
6091 if ((ev->buttons >= 1) && (ev->buttons <= 3))
6093 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
6094 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
6095 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
6096 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
6097 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
6098 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
6102 bd->moveinfo.down.x = bd->x + bd->fx.x;
6103 bd->moveinfo.down.y = bd->y + bd->fx.y;
6104 bd->moveinfo.down.w = bd->w;
6105 bd->moveinfo.down.h = bd->h;
6107 bd->mouse.current.mx = ev->root.x;
6108 bd->mouse.current.my = ev->root.y;
6109 if (!bd->cur_mouse_action)
6111 bd->cur_mouse_action =
6112 e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_BORDER,
6114 if (bd->cur_mouse_action)
6116 if ((!bd->cur_mouse_action->func.end_mouse) &&
6117 (!bd->cur_mouse_action->func.end))
6118 bd->cur_mouse_action = NULL;
6119 if (bd->cur_mouse_action)
6120 e_object_ref(E_OBJECT(bd->cur_mouse_action));
6123 e_focus_event_mouse_down(bd);
6125 if (ev->window != ev->event_window)
6129 if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
6133 if ((ev->buttons >= 1) && (ev->buttons <= 3))
6135 bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
6136 bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
6137 bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
6138 bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
6139 bd->mouse.last_down[ev->buttons - 1].w = bd->w;
6140 bd->mouse.last_down[ev->buttons - 1].h = bd->h;
6144 bd->moveinfo.down.x = bd->x + bd->fx.x;
6145 bd->moveinfo.down.y = bd->y + bd->fx.y;
6146 bd->moveinfo.down.w = bd->w;
6147 bd->moveinfo.down.h = bd->h;
6149 bd->mouse.current.mx = ev->root.x;
6150 bd->mouse.current.my = ev->root.y;
6155 else if (bd->resize_mode != RESIZE_NONE)
6161 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
6163 if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
6164 if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
6165 evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
6167 return ECORE_CALLBACK_PASS_ON;
6171 _e_border_cb_mouse_up(void *data,
6172 int type __UNUSED__,
6175 Ecore_Event_Mouse_Button *ev;
6180 if ((ev->event_window == bd->win) ||
6181 (ev->event_window == bd->event_win))
6183 if ((ev->buttons >= 1) && (ev->buttons <= 3))
6185 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
6186 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
6187 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
6188 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
6190 bd->mouse.current.mx = ev->root.x;
6191 bd->mouse.current.my = ev->root.y;
6192 /* also we dont pass the same params that went in - then again that */
6193 /* should be ok as we are just ending the action if it has an end */
6194 if (bd->cur_mouse_action)
6196 if (bd->cur_mouse_action->func.end_mouse)
6197 bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
6198 else if (bd->cur_mouse_action->func.end)
6199 bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
6200 e_object_unref(E_OBJECT(bd->cur_mouse_action));
6201 bd->cur_mouse_action = NULL;
6205 if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd), ev))
6206 e_focus_event_mouse_up(bd);
6209 if (ev->window != bd->event_win) return ECORE_CALLBACK_PASS_ON;
6210 if ((ev->buttons >= 1) && (ev->buttons <= 3))
6212 bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
6213 bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
6214 bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
6215 bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
6217 bd->mouse.current.mx = ev->root.x;
6218 bd->mouse.current.my = ev->root.y;
6222 evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
6223 return ECORE_CALLBACK_PASS_ON;
6227 _e_border_cb_mouse_move(void *data,
6228 int type __UNUSED__,
6231 Ecore_Event_Mouse_Move *ev;
6236 if ((ev->window != bd->event_win) &&
6237 (ev->event_window != bd->win)) return ECORE_CALLBACK_PASS_ON;
6238 bd->mouse.current.mx = ev->root.x;
6239 bd->mouse.current.my = ev->root.y;
6242 int x, y, new_x, new_y;
6244 Eina_List *skiplist = NULL;
6246 // FIXME: remove? sync what for when only moving?
6247 if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
6248 bd->client.netwm.sync.wait = 0;
6249 if ((bd->client.netwm.sync.request) &&
6250 (bd->client.netwm.sync.alarm) &&
6251 (bd->client.netwm.sync.wait > 1)) return ECORE_CALLBACK_PASS_ON;
6253 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
6255 x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
6256 (bd->mouse.current.mx - bd->moveinfo.down.mx);
6257 y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
6258 (bd->mouse.current.my - bd->moveinfo.down.my);
6262 x = bd->moveinfo.down.x +
6263 (bd->mouse.current.mx - bd->moveinfo.down.mx);
6264 y = bd->moveinfo.down.y +
6265 (bd->mouse.current.my - bd->moveinfo.down.my);
6269 skiplist = eina_list_append(skiplist, bd);
6270 e_resist_container_border_position(bd->zone->container, skiplist,
6271 bd->x, bd->y, bd->w, bd->h,
6273 &new_x, &new_y, &new_w, &new_h);
6274 eina_list_free(skiplist);
6275 bd->shelf_fix.x = 0;
6276 bd->shelf_fix.y = 0;
6277 bd->shelf_fix.modified = 0;
6278 e_border_move(bd, new_x, new_y);
6279 e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
6281 else if (bd->resize_mode != RESIZE_NONE)
6283 if ((bd->client.netwm.sync.request) &&
6284 (bd->client.netwm.sync.alarm))
6286 if ((ecore_loop_time_get() - bd->client.netwm.sync.send_time) > 0.5)
6288 E_Border_Pending_Move_Resize *pnd;
6290 if (bd->pending_move_resize)
6292 bd->changes.pos = 1;
6293 bd->changes.size = 1;
6295 _e_border_client_move_resize_send(bd);
6297 EINA_LIST_FREE(bd->pending_move_resize, pnd)
6300 bd->client.netwm.sync.wait = 0;
6302 /* sync.wait is incremented when resize_handle sends
6303 * sync-request and decremented by sync-alarm cb. so
6304 * we resize here either on initial resize, timeout or
6305 * when no new resize-request was added by sync-alarm cb.
6307 if (!bd->client.netwm.sync.wait)
6308 _e_border_resize_handle(bd);
6311 _e_border_resize_handle(bd);
6317 if ((bd->drag.x == -1) && (bd->drag.y == -1))
6319 bd->drag.x = ev->root.x;
6320 bd->drag.y = ev->root.y;
6326 dx = bd->drag.x - ev->root.x;
6327 dy = bd->drag.y - ev->root.y;
6328 if (((dx * dx) + (dy * dy)) >
6329 (e_config->drag_resist * e_config->drag_resist))
6332 if (bd->icon_object)
6334 Evas_Object *o = NULL;
6335 Evas_Coord x, y, w, h;
6336 const char *drag_types[] = { "enlightenment/border" };
6338 e_object_ref(E_OBJECT(bd));
6339 evas_object_geometry_get(bd->icon_object,
6341 drag_border = e_drag_new(bd->zone->container,
6342 bd->x + bd->fx.x + x,
6343 bd->y + bd->fx.y + y,
6344 drag_types, 1, bd, -1,
6346 _e_border_cb_drag_finished);
6347 o = e_border_icon_add(bd, drag_border->evas);
6350 /* FIXME: fallback icon for drag */
6351 o = evas_object_rectangle_add(drag_border->evas);
6352 evas_object_color_set(o, 255, 255, 255, 255);
6354 e_drag_object_set(drag_border, o);
6356 e_drag_resize(drag_border, w, h);
6357 e_drag_start(drag_border, bd->drag.x, bd->drag.y);
6363 evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
6365 return ECORE_CALLBACK_PASS_ON;
6369 _e_border_cb_grab_replay(void *data __UNUSED__,
6373 Ecore_Event_Mouse_Button *ev;
6375 if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE;
6377 if ((e_config->pass_click_on) || (e_config->always_click_to_raise) ||
6378 (e_config->always_click_to_focus))
6382 bd = e_border_find_by_window(ev->event_window);
6385 if (bd->cur_mouse_action)
6386 return ECORE_CALLBACK_DONE;
6387 if (ev->event_window == bd->win)
6389 if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_BORDER,
6390 E_OBJECT(bd), ev, NULL))
6391 return ECORE_CALLBACK_PASS_ON;
6395 return ECORE_CALLBACK_DONE;
6399 _e_border_cb_drag_finished(E_Drag *drag,
6400 int dropped __UNUSED__)
6405 e_object_unref(E_OBJECT(bd));
6410 _e_border_post_move_resize_job(void *data)
6414 bd = (E_Border *)data;
6420 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
6421 ecore_x_window_move(tmp->win,
6423 bd->client_inset.l +
6425 tmp->client.e.state.video_position.x,
6427 bd->client_inset.t +
6429 tmp->client.e.state.video_position.y);
6431 if (bd->client.e.state.video)
6435 parent = bd->client.e.state.video_parent_border;
6436 ecore_x_window_move(bd->win,
6438 parent->client_inset.l +
6440 bd->client.e.state.video_position.x,
6442 parent->client_inset.t +
6444 bd->client.e.state.video_position.y);
6446 else if ((bd->post_move) && (bd->post_resize))
6448 ecore_x_window_move_resize(bd->win,
6453 else if (bd->post_move)
6455 ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
6457 else if (bd->post_resize)
6459 ecore_x_window_resize(bd->win, bd->w, bd->h);
6462 if (bd->client.e.state.video)
6464 fprintf(stderr, "%x: [%i, %i] [%i, %i]\n",
6466 bd->client.e.state.video_parent_border->x +
6467 bd->client.e.state.video_parent_border->client_inset.l +
6468 bd->client.e.state.video_parent_border->fx.x +
6469 bd->client.e.state.video_position.x,
6470 bd->client.e.state.video_parent_border->y +
6471 bd->client.e.state.video_parent_border->client_inset.t +
6472 bd->client.e.state.video_parent_border->fx.y +
6473 bd->client.e.state.video_position.y,
6481 bd->post_job = NULL;
6487 bd->post_resize = 0;
6488 bd->post_job = NULL;
6489 return ECORE_CALLBACK_CANCEL;
6493 _e_border_container_layout_hook(E_Container *con)
6495 _e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
6499 _e_border_eval0(E_Border *bd)
6501 int change_urgent = 0;
6504 if (e_object_is_del(E_OBJECT(bd)))
6506 fprintf(stderr, "ERROR: _e_border_eval(%p) with deleted border!\n", bd);
6511 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
6513 bd->changes.border = 0;
6515 /* fetch any info queued to be fetched */
6516 if (bd->client.netwm.fetch.state)
6518 e_hints_window_state_get(bd);
6519 bd->client.netwm.fetch.state = 0;
6522 if (bd->client.icccm.fetch.client_leader)
6524 /* TODO: What do to if the client leader isn't mapped yet? */
6525 E_Border *bd_leader = NULL;
6527 bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
6528 if (bd->client.icccm.client_leader)
6529 bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
6532 if (bd->leader != bd_leader)
6534 bd->leader->group = eina_list_remove(bd->leader->group, bd);
6535 if (bd->leader->modal == bd) bd->leader->modal = NULL;
6541 /* If this border is the leader of the group, don't register itself */
6542 if ((bd_leader) && (bd_leader != bd))
6544 bd_leader->group = eina_list_append(bd_leader->group, bd);
6545 bd->leader = bd_leader;
6546 /* Only set the window modal to the leader it there is no parent */
6547 if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
6548 ((!bd->parent) || (bd->parent->modal != bd)))
6550 bd->leader->modal = bd;
6551 if (bd->leader->focused)
6552 e_border_focus_set(bd, 1, 1);
6558 EINA_LIST_FOREACH(bd->leader->group, l, child)
6560 if ((child != bd) && (child->focused))
6561 e_border_focus_set(bd, 1, 1);
6566 bd->client.icccm.fetch.client_leader = 0;
6569 if (bd->client.icccm.fetch.title)
6571 char *title = ecore_x_icccm_title_get(bd->client.win);
6572 eina_stringshare_replace(&bd->client.icccm.title, title);
6573 if (title) free(title);
6576 edje_object_part_text_set(bd->bg_object, "e.text.title",
6577 bd->client.icccm.title);
6578 bd->client.icccm.fetch.title = 0;
6581 if (bd->client.netwm.fetch.name)
6584 ecore_x_netwm_name_get(bd->client.win, &name);
6585 eina_stringshare_replace(&bd->client.netwm.name, name);
6586 if (name) free(name);
6589 edje_object_part_text_set(bd->bg_object, "e.text.title",
6590 bd->client.netwm.name);
6591 bd->client.netwm.fetch.name = 0;
6594 if (bd->client.icccm.fetch.name_class)
6596 const char *pname, *pclass;
6597 char *nname, *nclass;
6599 ecore_x_icccm_name_class_get(bd->client.win, &nname, &nclass);
6600 pname = bd->client.icccm.name;
6601 pclass = bd->client.icccm.class;
6602 bd->client.icccm.name = eina_stringshare_add(nname);
6603 bd->client.icccm.class = eina_stringshare_add(nclass);
6604 if (nname) free(nname);
6605 if (nclass) free(nclass);
6607 if (!((bd->client.icccm.name == pname) &&
6608 (bd->client.icccm.class == pclass)))
6609 bd->changes.icon = 1;
6611 if (pname) eina_stringshare_del(pname);
6612 if (pclass) eina_stringshare_del(pclass);
6613 bd->client.icccm.fetch.name_class = 0;
6614 bd->changes.icon = 1;
6617 if (bd->client.icccm.fetch.state)
6619 bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
6620 bd->client.icccm.fetch.state = 0;
6623 if (bd->client.e.fetch.state)
6625 e_hints_window_e_state_get(bd);
6626 bd->client.e.fetch.state = 0;
6629 if (bd->client.netwm.fetch.type)
6631 e_hints_window_type_get(bd);
6632 if ((!bd->lock_border) || (!bd->client.border.name))
6633 bd->client.border.changed = 1;
6635 if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
6637 if (!bd->client.netwm.state.skip_pager)
6639 bd->client.netwm.state.skip_pager = 1;
6640 bd->client.netwm.update.state = 1;
6642 if (!bd->client.netwm.state.skip_taskbar)
6644 bd->client.netwm.state.skip_taskbar = 1;
6645 bd->client.netwm.update.state = 1;
6648 bd->client.netwm.fetch.type = 0;
6650 if (bd->client.icccm.fetch.machine)
6652 char *machine = ecore_x_icccm_client_machine_get(bd->client.win);
6654 if ((!machine) && (bd->client.icccm.client_leader))
6655 machine = ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
6657 eina_stringshare_replace(&bd->client.icccm.machine, machine);
6658 if (machine) free(machine);
6660 bd->client.icccm.fetch.machine = 0;
6663 if (bd->client.icccm.fetch.command)
6665 if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
6669 for (i = 0; i < bd->client.icccm.command.argc; i++)
6670 free(bd->client.icccm.command.argv[i]);
6671 free(bd->client.icccm.command.argv);
6673 bd->client.icccm.command.argc = 0;
6674 bd->client.icccm.command.argv = NULL;
6675 ecore_x_icccm_command_get(bd->client.win,
6676 &(bd->client.icccm.command.argc),
6677 &(bd->client.icccm.command.argv));
6678 if ((bd->client.icccm.client_leader) &&
6679 (!bd->client.icccm.command.argv))
6680 ecore_x_icccm_command_get(bd->client.icccm.client_leader,
6681 &(bd->client.icccm.command.argc),
6682 &(bd->client.icccm.command.argv));
6683 bd->client.icccm.fetch.command = 0;
6686 if (bd->client.icccm.fetch.hints)
6688 Eina_Bool accepts_focus, is_urgent;
6690 accepts_focus = EINA_TRUE;
6691 is_urgent = EINA_FALSE;
6692 bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
6693 if (ecore_x_icccm_hints_get(bd->client.win,
6695 &bd->client.icccm.initial_state,
6696 &bd->client.icccm.icon_pixmap,
6697 &bd->client.icccm.icon_mask,
6698 &bd->client.icccm.icon_window,
6699 &bd->client.icccm.window_group,
6702 bd->client.icccm.accepts_focus = accepts_focus;
6703 if (bd->client.icccm.urgent != is_urgent)
6705 bd->client.icccm.urgent = is_urgent;
6707 /* If this is a new window, set the state as requested. */
6708 if ((bd->new_client) &&
6709 (bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
6711 e_border_iconify(bd);
6712 e_border_hide(bd, 1);
6715 bd->client.icccm.fetch.hints = 0;
6718 if (bd->client.icccm.fetch.size_pos_hints)
6720 Eina_Bool request_pos;
6722 request_pos = EINA_FALSE;
6723 if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
6725 &bd->client.icccm.gravity,
6726 &bd->client.icccm.min_w,
6727 &bd->client.icccm.min_h,
6728 &bd->client.icccm.max_w,
6729 &bd->client.icccm.max_h,
6730 &bd->client.icccm.base_w,
6731 &bd->client.icccm.base_h,
6732 &bd->client.icccm.step_w,
6733 &bd->client.icccm.step_h,
6734 &bd->client.icccm.min_aspect,
6735 &bd->client.icccm.max_aspect))
6737 bd->client.icccm.request_pos = request_pos;
6742 if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
6743 if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
6744 if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
6745 if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
6746 if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
6747 if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
6748 // if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
6749 // if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
6750 // if doing a resize, fix it up
6751 if (bd->resize_mode != RESIZE_NONE)
6753 int x, y, w, h, new_w, new_h;
6761 e_border_resize_limit(bd, &new_w, &new_h);
6762 if ((bd->resize_mode == RESIZE_TL) ||
6763 (bd->resize_mode == RESIZE_L) ||
6764 (bd->resize_mode == RESIZE_BL))
6766 if ((bd->resize_mode == RESIZE_TL) ||
6767 (bd->resize_mode == RESIZE_T) ||
6768 (bd->resize_mode == RESIZE_TR))
6770 e_border_move_resize(bd, x, y, new_w, new_h);
6772 bd->client.icccm.fetch.size_pos_hints = 0;
6775 if (bd->client.icccm.fetch.protocol)
6778 Ecore_X_WM_Protocol *proto;
6780 proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
6783 for (i = 0; i < num; i++)
6785 if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
6786 bd->client.icccm.delete_request = 1;
6787 else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
6788 bd->client.icccm.take_focus = 1;
6789 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
6790 bd->client.netwm.ping = 1;
6791 else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
6793 bd->client.netwm.sync.request = 1;
6794 if (!ecore_x_netwm_sync_counter_get(bd->client.win,
6795 &bd->client.netwm.sync.counter))
6796 bd->client.netwm.sync.request = 0;
6801 if (bd->client.netwm.ping)
6805 if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
6806 bd->ping_poller = NULL;
6808 bd->client.icccm.fetch.protocol = 0;
6810 if (bd->client.icccm.fetch.transient_for)
6812 /* TODO: What do to if the transient for isn't mapped yet? */
6813 E_Border *bd_parent = NULL;
6815 bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
6816 if (bd->client.icccm.transient_for)
6817 bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
6818 /* If we already have a parent, remove it */
6821 if (bd_parent != bd->parent)
6823 bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
6824 if (bd->parent->modal == bd) bd->parent->modal = NULL;
6830 if ((bd_parent) && (bd_parent != bd) &&
6831 (eina_list_data_find(bd->transients, bd_parent) != bd_parent))
6833 bd_parent->transients = eina_list_append(bd_parent->transients, bd);
6834 bd->parent = bd_parent;
6835 e_border_layer_set(bd, bd->parent->layer);
6836 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
6837 bd->parent->modal = bd;
6839 if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
6840 (bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
6843 bd->client.icccm.fetch.transient_for = 0;
6846 if (bd->client.icccm.fetch.window_role)
6848 char *role = ecore_x_icccm_window_role_get(bd->client.win);
6849 eina_stringshare_replace(&bd->client.icccm.window_role, role);
6850 if (role) free(role);
6852 bd->client.icccm.fetch.window_role = 0;
6855 if (bd->client.icccm.fetch.icon_name)
6857 char *icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
6858 eina_stringshare_replace(&bd->client.icccm.icon_name, icon_name);
6859 if (icon_name) free(icon_name);
6861 bd->client.icccm.fetch.icon_name = 0;
6864 if (bd->client.netwm.fetch.icon_name)
6867 ecore_x_netwm_icon_name_get(bd->client.win, &icon_name);
6868 eina_stringshare_replace(&bd->client.netwm.icon_name, icon_name);
6869 if (icon_name) free(icon_name);
6871 bd->client.netwm.fetch.icon_name = 0;
6874 if (bd->client.netwm.fetch.icon)
6876 if (bd->client.netwm.icons)
6880 for (i = 0; i < bd->client.netwm.num_icons; i++)
6881 free(bd->client.netwm.icons[i].data);
6882 free(bd->client.netwm.icons);
6884 if (!ecore_x_netwm_icons_get(bd->client.win,
6885 &bd->client.netwm.icons, &bd->client.netwm.num_icons))
6887 bd->client.netwm.icons = NULL;
6888 bd->client.netwm.num_icons = 0;
6891 bd->changes.icon = 1;
6892 bd->client.netwm.fetch.icon = 0;
6894 if (bd->client.netwm.fetch.user_time)
6896 ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
6897 bd->client.netwm.fetch.user_time = 0;
6899 if (bd->client.netwm.fetch.strut)
6901 if (!ecore_x_netwm_strut_partial_get(bd->client.win,
6902 &bd->client.netwm.strut.left,
6903 &bd->client.netwm.strut.right,
6904 &bd->client.netwm.strut.top,
6905 &bd->client.netwm.strut.bottom,
6906 &bd->client.netwm.strut.left_start_y,
6907 &bd->client.netwm.strut.left_end_y,
6908 &bd->client.netwm.strut.right_start_y,
6909 &bd->client.netwm.strut.right_end_y,
6910 &bd->client.netwm.strut.top_start_x,
6911 &bd->client.netwm.strut.top_end_x,
6912 &bd->client.netwm.strut.bottom_start_x,
6913 &bd->client.netwm.strut.bottom_end_x))
6915 ecore_x_netwm_strut_get(bd->client.win,
6916 &bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
6917 &bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
6919 bd->client.netwm.strut.left_start_y = 0;
6920 bd->client.netwm.strut.left_end_y = 0;
6921 bd->client.netwm.strut.right_start_y = 0;
6922 bd->client.netwm.strut.right_end_y = 0;
6923 bd->client.netwm.strut.top_start_x = 0;
6924 bd->client.netwm.strut.top_end_x = 0;
6925 bd->client.netwm.strut.bottom_start_x = 0;
6926 bd->client.netwm.strut.bottom_end_x = 0;
6928 bd->client.netwm.fetch.strut = 0;
6930 if (bd->client.qtopia.fetch.soft_menu)
6932 e_hints_window_qtopia_soft_menu_get(bd);
6933 bd->client.qtopia.fetch.soft_menu = 0;
6936 if (bd->client.qtopia.fetch.soft_menus)
6938 e_hints_window_qtopia_soft_menus_get(bd);
6939 bd->client.qtopia.fetch.soft_menus = 0;
6942 if (bd->client.vkbd.fetch.state)
6944 e_hints_window_virtual_keyboard_state_get(bd);
6945 bd->client.vkbd.fetch.state = 0;
6948 if (bd->client.vkbd.fetch.vkbd)
6950 e_hints_window_virtual_keyboard_get(bd);
6951 bd->client.vkbd.fetch.vkbd = 0;
6954 if (bd->client.illume.conformant.fetch.conformant)
6956 bd->client.illume.conformant.conformant =
6957 ecore_x_e_illume_conformant_get(bd->client.win);
6958 bd->client.illume.conformant.fetch.conformant = 0;
6960 if (bd->client.illume.quickpanel.fetch.state)
6962 bd->client.illume.quickpanel.state =
6963 ecore_x_e_illume_quickpanel_state_get(bd->client.win);
6964 bd->client.illume.quickpanel.fetch.state = 0;
6966 if (bd->client.illume.quickpanel.fetch.quickpanel)
6968 bd->client.illume.quickpanel.quickpanel =
6969 ecore_x_e_illume_quickpanel_get(bd->client.win);
6970 bd->client.illume.quickpanel.fetch.quickpanel = 0;
6972 if (bd->client.illume.quickpanel.fetch.priority.major)
6974 bd->client.illume.quickpanel.priority.major =
6975 ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win);
6976 bd->client.illume.quickpanel.fetch.priority.major = 0;
6978 if (bd->client.illume.quickpanel.fetch.priority.minor)
6980 bd->client.illume.quickpanel.priority.minor =
6981 ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win);
6982 bd->client.illume.quickpanel.fetch.priority.minor = 0;
6984 if (bd->client.illume.quickpanel.fetch.zone)
6986 bd->client.illume.quickpanel.zone =
6987 ecore_x_e_illume_quickpanel_zone_get(bd->client.win);
6988 bd->client.illume.quickpanel.fetch.zone = 0;
6990 if (bd->client.illume.drag.fetch.drag)
6992 bd->client.illume.drag.drag =
6993 ecore_x_e_illume_drag_get(bd->client.win);
6994 bd->client.illume.drag.fetch.drag = 0;
6996 if (bd->client.illume.drag.fetch.locked)
6998 bd->client.illume.drag.locked =
6999 ecore_x_e_illume_drag_locked_get(bd->client.win);
7000 bd->client.illume.drag.fetch.locked = 0;
7002 if (bd->changes.shape)
7004 Ecore_X_Rectangle *rects;
7007 bd->changes.shape = 0;
7008 rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
7013 /* This doesn't fix the race, but makes it smaller. we detect
7014 * this and if cw and ch != client w/h then mark this as needing
7015 * a shape change again to fixup next event loop.
7017 ecore_x_window_size_get(bd->client.win, &cw, &ch);
7018 if ((cw != bd->client.w) || (ch != bd->client.h))
7019 bd->changes.shape = 1;
7021 (rects[0].x == 0) &&
7022 (rects[0].y == 0) &&
7023 ((int)rects[0].width == cw) &&
7024 ((int)rects[0].height == ch))
7026 if (bd->client.shaped)
7028 bd->client.shaped = 0;
7029 if (!bd->bordername)
7030 bd->client.border.changed = 1;
7035 if (!bd->client.shaped)
7037 bd->client.shaped = 1;
7038 if (!bd->bordername)
7039 bd->client.border.changed = 1;
7046 // FIXME: no rects i think can mean... totally empty window
7047 bd->client.shaped = 0;
7048 if (!bd->bordername)
7049 bd->client.border.changed = 1;
7051 bd->need_shape_merge = 1;
7053 if (bd->changes.shape_input)
7055 Ecore_X_Rectangle *rects;
7058 bd->changes.shape_input = 0;
7059 rects = ecore_x_window_shape_input_rectangles_get(bd->client.win, &num);
7064 /* This doesn't fix the race, but makes it smaller. we detect
7065 * this and if cw and ch != client w/h then mark this as needing
7066 * a shape change again to fixup next event loop.
7068 ecore_x_window_size_get(bd->client.win, &cw, &ch);
7069 if ((cw != bd->client.w) || (ch != bd->client.h))
7070 bd->changes.shape_input = 1;
7072 (rects[0].x == 0) &&
7073 (rects[0].y == 0) &&
7074 ((int)rects[0].width == cw) &&
7075 ((int)rects[0].height == ch))
7077 if (bd->shaped_input)
7079 bd->shaped_input = 0;
7080 if (!bd->bordername)
7081 bd->client.border.changed = 1;
7086 if (!bd->shaped_input)
7088 bd->shaped_input = 1;
7089 if (!bd->bordername)
7090 bd->client.border.changed = 1;
7097 bd->shaped_input = 1;
7098 if (!bd->bordername)
7099 bd->client.border.changed = 1;
7101 bd->need_shape_merge = 1;
7103 if (bd->client.mwm.fetch.hints)
7107 bd->client.mwm.exists =
7108 ecore_x_mwm_hints_get(bd->client.win,
7109 &bd->client.mwm.func,
7110 &bd->client.mwm.decor,
7111 &bd->client.mwm.input);
7112 pb = bd->client.mwm.borderless;
7113 bd->client.mwm.borderless = 0;
7114 if (bd->client.mwm.exists)
7116 if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
7117 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
7118 (!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
7119 bd->client.mwm.borderless = 1;
7121 if (bd->client.mwm.borderless != pb)
7123 if ((!bd->lock_border) || (!bd->client.border.name))
7124 bd->client.border.changed = 1;
7126 bd->client.mwm.fetch.hints = 0;
7129 if (bd->client.e.fetch.video_parent)
7131 /* unlinking child/parent */
7132 if (bd->client.e.state.video_parent_border != NULL)
7134 bd->client.e.state.video_parent_border->client.e.state.video_child = eina_list_remove(bd->client.e.state.video_parent_border->client.e.state.video_child,
7138 ecore_x_window_prop_card32_get(bd->client.win,
7139 ECORE_X_ATOM_E_VIDEO_PARENT,
7140 &bd->client.e.state.video_parent,
7143 /* linking child/parent */
7144 if (bd->client.e.state.video_parent != 0)
7149 EINA_LIST_FOREACH(borders, l, tmp)
7150 if (tmp->client.win == bd->client.e.state.video_parent)
7152 fprintf(stderr, "child added to parent \\o/\n");
7153 bd->client.e.state.video_parent_border = tmp;
7154 tmp->client.e.state.video_child = eina_list_append(tmp->client.e.state.video_child,
7156 if (bd->desk != tmp->desk)
7157 e_border_desk_set(bd, tmp->desk);
7162 fprintf(stderr, "new parent %x => %p\n", bd->client.e.state.video_parent, bd->client.e.state.video_parent_border);
7164 if (bd->client.e.state.video_parent_border) bd->client.e.fetch.video_parent = 0;
7167 if (bd->client.e.fetch.video_position && bd->client.e.fetch.video_parent == 0)
7171 ecore_x_window_prop_card32_get(bd->client.win,
7172 ECORE_X_ATOM_E_VIDEO_POSITION,
7175 bd->client.e.state.video_position.x = xy[0];
7176 bd->client.e.state.video_position.y = xy[1];
7177 bd->client.e.state.video_position.updated = 1;
7178 bd->client.e.fetch.video_position = 0;
7179 bd->x = bd->client.e.state.video_position.x;
7180 bd->y = bd->client.e.state.video_position.y;
7182 fprintf(stderr, "internal position has been updated [%i, %i]\n", bd->client.e.state.video_position.x, bd->client.e.state.video_position.y);
7184 if (bd->client.netwm.update.state)
7186 e_hints_window_state_set(bd);
7187 /* Some stats might change the border, like modal */
7188 if (((!bd->lock_border) || (!bd->client.border.name)) &&
7189 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
7191 bd->client.border.changed = 1;
7195 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
7197 bd->parent->modal = bd;
7198 if (bd->parent->focused)
7199 e_border_focus_set(bd, 1, 1);
7202 else if (bd->leader)
7204 if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
7206 bd->leader->modal = bd;
7207 if (bd->leader->focused)
7208 e_border_focus_set(bd, 1, 1);
7214 EINA_LIST_FOREACH(bd->leader->group, l, child)
7216 if ((child != bd) && (child->focused))
7217 e_border_focus_set(bd, 1, 1);
7222 bd->client.netwm.update.state = 0;
7227 E_Event_Border_Add *ev;
7229 ev = E_NEW(E_Event_Border_Add, 1);
7231 e_object_ref(E_OBJECT(bd));
7232 // e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
7233 ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
7235 if ((!bd->lock_border) || (!bd->client.border.name))
7236 bd->client.border.changed = 1;
7239 /* PRE_POST_FETCH calls e_remember apply for new client */
7240 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
7241 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
7242 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
7244 if (bd->need_reparent)
7247 ecore_x_window_save_set_add(bd->client.win);
7248 ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
7251 if ((bd->new_client) && (bd->internal) &&
7252 (bd->internal_ecore_evas))
7253 ecore_evas_show(bd->internal_ecore_evas);
7254 ecore_x_window_show(bd->client.win);
7256 bd->need_reparent = 0;
7259 if ((bd->client.border.changed) && (!bd->shaded) &&
7260 (!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
7262 const char *bordername;
7265 bordername = "borderless";
7266 else if (bd->bordername)
7267 bordername = bd->bordername;
7268 else if ((bd->client.mwm.borderless) || (bd->borderless))
7269 bordername = "borderless";
7270 else if (((bd->client.icccm.transient_for != 0) ||
7271 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
7272 (bd->client.icccm.min_w == bd->client.icccm.max_w) &&
7273 (bd->client.icccm.min_h == bd->client.icccm.max_h))
7274 bordername = "noresize_dialog";
7275 else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
7276 (bd->client.icccm.min_h == bd->client.icccm.max_h))
7277 bordername = "noresize";
7278 else if (bd->client.shaped)
7279 bordername = "shaped";
7280 else if ((!bd->client.icccm.accepts_focus) &&
7281 (!bd->client.icccm.take_focus))
7282 bordername = "nofocus";
7283 else if (bd->client.icccm.urgent)
7284 bordername = "urgent";
7285 else if ((bd->client.icccm.transient_for != 0) ||
7286 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
7287 bordername = "dialog";
7288 else if (bd->client.netwm.state.modal)
7289 bordername = "modal";
7290 else if ((bd->client.netwm.state.skip_taskbar) ||
7291 (bd->client.netwm.state.skip_pager))
7292 bordername = "skipped";
7293 else if ((bd->internal) && (bd->client.icccm.class) &&
7294 (!strncmp(bd->client.icccm.class, "e_fwin", 6)))
7295 bordername = "internal_fileman";
7297 bordername = e_config->theme_default_border_style;
7298 if (!bordername) bordername = "default";
7300 if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
7306 bd->changes.border = 1;
7307 eina_stringshare_replace(&bd->client.border.name, bordername);
7311 bd->w -= (bd->client_inset.l + bd->client_inset.r);
7312 bd->h -= (bd->client_inset.t + bd->client_inset.b);
7313 bd->changes.size = 1;
7314 evas_object_del(bd->bg_object);
7316 o = edje_object_add(bd->bg_evas);
7317 snprintf(buf, sizeof(buf), "e/widgets/border/%s/border", bd->client.border.name);
7318 ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
7319 if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
7321 ok = e_theme_edje_object_set(o, "base/theme/borders",
7322 "e/widgets/border/default/border");
7325 /* Reset default border style to default */
7326 eina_stringshare_replace(&e_config->theme_default_border_style, "default");
7327 e_config_save_queue();
7334 const char *shape_option, *argb_option;
7339 if ((e_config->use_composite) && (!bd->client.argb))
7341 argb_option = edje_object_data_get(o, "argb");
7342 if ((argb_option) && (!strcmp(argb_option, "1")))
7345 if (use_argb != bd->argb)
7346 _e_border_frame_replace(bd, use_argb);
7353 shape_option = edje_object_data_get(o, "shaped");
7354 if ((shape_option) && (!strcmp(shape_option, "1")))
7358 if (bd->client.netwm.name)
7359 edje_object_part_text_set(o, "e.text.title",
7360 bd->client.netwm.name);
7361 else if (bd->client.icccm.title)
7362 edje_object_part_text_set(o, "e.text.title",
7363 bd->client.icccm.title);
7368 bd->bg_object = NULL;
7371 _e_border_client_inset_calc(bd);
7373 bd->w += (bd->client_inset.l + bd->client_inset.r);
7374 bd->h += (bd->client_inset.t + bd->client_inset.b);
7375 ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
7376 bd->changes.size = 1;
7377 /* really needed ? */
7378 ecore_x_window_move(bd->client.shell_win,
7380 bd->client_inset.t);
7382 if (bd->maximized != E_MAXIMIZE_NONE)
7384 E_Maximize maximized = bd->maximized;
7386 /* to force possible resizes */
7387 bd->maximized = E_MAXIMIZE_NONE;
7389 _e_border_maximize(bd, maximized);
7391 /* restore maximized state */
7392 bd->maximized = maximized;
7394 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
7395 bd->maximized & E_MAXIMIZE_VERTICAL);
7399 edje_object_signal_callback_add(bd->bg_object, "*", "*",
7400 _e_border_cb_signal_bind, bd);
7403 edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
7404 if (bd->icon_object)
7405 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
7408 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
7410 edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
7412 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
7413 if (bd->client.icccm.urgent)
7414 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
7415 // FIXME: in eval -do differently
7416 // edje_object_message_signal_process(bd->bg_object);
7417 // e_border_frame_recalc(bd);
7419 evas_object_move(bd->bg_object, 0, 0);
7420 evas_object_resize(bd->bg_object, bd->w, bd->h);
7421 evas_object_show(bd->bg_object);
7424 bd->client.border.changed = 0;
7426 if (bd->icon_object)
7430 evas_object_show(bd->icon_object);
7431 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
7434 evas_object_hide(bd->icon_object);
7438 if (rem_change) e_remember_update(bd);
7442 E_Event_Border_Urgent_Change *ev;
7444 if (bd->client.icccm.urgent)
7445 edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
7447 edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
7449 ev = E_NEW(E_Event_Border_Urgent_Change, 1);
7451 e_object_ref(E_OBJECT(bd));
7452 ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
7453 _e_border_event_border_urgent_change_free, NULL);
7456 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
7459 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
7461 _e_border_latest_stacked_focus (E_Border* bd)
7463 Eina_List *l = NULL;
7467 root_w = bd->zone->w;
7468 root_h = bd->zone->h;
7471 bl = e_container_border_list_last(bd->zone->container);
7472 while ((temp_bd = e_container_border_list_prev(bl)))
7474 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
7475 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
7477 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
7478 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
7479 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
7480 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
7481 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
7482 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
7483 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
7491 /* this border is the top of the latest stack */
7492 e_border_focus_set (temp_bd, 1, 1);
7498 e_container_border_list_free(bl);
7502 _e_border_check_stack (E_Border *bd)
7504 Eina_List* l = NULL;
7505 E_Border* temp_bd = NULL;;
7506 E_Border* top_bd = NULL;
7507 int passed_focus = 0;
7509 int root_w = bd->zone->w;
7510 int root_h = bd->zone->h;
7513 bl = e_container_border_list_last(bd->zone->container);
7514 while ((temp_bd = e_container_border_list_prev(bl)))
7516 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
7517 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
7519 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
7520 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
7521 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
7522 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
7523 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
7524 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
7525 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
7531 e_border_focus_set_with_pointer(bd);
7538 e_border_focus_set_with_pointer(top_bd);
7547 if ((bd->client.icccm.accepts_focus) || (bd->client.icccm.take_focus))
7549 if (!bd->lock_focus_out)
7551 e_border_focus_latest_set(bd);
7563 if (temp_bd == focused)
7569 e_container_border_list_free(bl);
7573 _e_border_focus_top_stack_set (E_Border* bd)
7575 Eina_List *l = NULL;
7579 root_w = bd->zone->w;
7580 root_h = bd->zone->h;
7583 bl = e_container_border_list_last(bd->zone->container);
7584 while ((temp_bd = e_container_border_list_prev(bl)))
7586 if ((temp_bd->x >= root_w) || (temp_bd->y >= root_h)) continue;
7587 if (((temp_bd->x + temp_bd->w) <= 0) || ((temp_bd->y + temp_bd->h) <= 0)) continue;
7589 if ((!temp_bd->iconic) && (temp_bd->visible) && (temp_bd->desk == bd->desk) &&
7590 (temp_bd->client.icccm.accepts_focus || temp_bd->client.icccm.take_focus) &&
7591 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DOCK) &&
7592 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_TOOLBAR) &&
7593 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_MENU) &&
7594 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_SPLASH) &&
7595 (temp_bd->client.netwm.type != ECORE_X_WINDOW_TYPE_DESKTOP))
7597 if (!temp_bd->focused)
7599 /* this border is the top of the latest stack */
7600 e_border_focus_set (temp_bd, 1, 1);
7605 e_container_border_list_free(bl);
7610 _e_border_eval(E_Border *bd)
7612 E_Event_Border_Property *event;
7613 E_Border_Pending_Move_Resize *pnd;
7617 if (e_object_is_del(E_OBJECT(bd)))
7619 fprintf(stderr, "ERROR: _e_border_eval(%p) with deleted border! - %d\n", bd, bd->new_client);
7624 _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
7628 int zx = 0, zy = 0, zw = 0, zh = 0;
7631 e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
7634 * Limit maximum size of windows to useful geometry
7636 // TODO: temoporary limited maximize algorithm
7648 if ((rw != bd->w) || (rh != bd->h))
7652 e_border_resize (bd, bd->w, bd->h);
7658 bd->x -= bd->client_inset.l;
7659 bd->y -= bd->client_inset.t;
7660 bd->changes.pos = 1;
7663 else if ((!bd->placed) && (bd->client.icccm.request_pos))
7666 Ecore_X_Window_Attributes *att;
7669 att = &bd->client.initial_attributes;
7670 bw = att->border * 2;
7671 switch (bd->client.icccm.gravity)
7673 case ECORE_X_GRAVITY_N:
7674 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
7678 case ECORE_X_GRAVITY_NE:
7679 bd->x = (att->x - (bw)) - (bd->client_inset.l);
7683 case ECORE_X_GRAVITY_E:
7684 bd->x = (att->x - (bw)) - (bd->client_inset.l);
7685 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
7688 case ECORE_X_GRAVITY_SE:
7689 bd->x = (att->x - (bw)) - (bd->client_inset.l);
7690 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7693 case ECORE_X_GRAVITY_S:
7694 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
7695 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7698 case ECORE_X_GRAVITY_SW:
7700 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7703 case ECORE_X_GRAVITY_W:
7705 bd->y = (att->y - (bw)) - (bd->client_inset.t);
7708 case ECORE_X_GRAVITY_CENTER:
7709 bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
7710 bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
7713 case ECORE_X_GRAVITY_NW:
7720 * This ensures that windows that like to open with a x/y
7721 * position smaller than returned by e_zone_useful_geometry_get()
7722 * are moved to useful positions.
7724 if (e_config->geometry_auto_move == 1)
7733 if (bd->x + bd->w > zx + zw)
7734 bd->x = zx + zw - bd->w;
7736 if (bd->y + bd->h > zy + zh)
7737 bd->y = zy + zh - bd->h;
7740 if (bd->zone && e_container_zone_at_point_get(bd->zone->container, bd->x, bd->y))
7742 bd->changes.pos = 1;
7748 bd->changes.pos = 1;
7754 /* FIXME: special placement for dialogs etc. etc. etc goes
7756 /* FIXME: what if parent is not on this desktop - or zone? */
7757 if ((bd->parent) && (bd->parent->visible))
7759 bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
7760 bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
7761 bd->changes.pos = 1;
7765 else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
7767 /* TODO: Place in center of group */
7770 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
7772 bd->x = zx + ((zw - bd->w) / 2);
7773 bd->y = zy + ((zh - bd->h) / 2);
7774 bd->changes.pos = 1;
7780 Eina_List *skiplist = NULL;
7784 new_x = zx + (rand() % (zw - bd->w));
7788 new_y = zy + (rand() % (zh - bd->h));
7792 if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART) || (e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
7794 skiplist = eina_list_append(skiplist, bd);
7795 e_place_zone_region_smart(bd->zone, skiplist,
7796 bd->x, bd->y, bd->w, bd->h,
7798 eina_list_free(skiplist);
7800 else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
7802 e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
7807 e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
7808 bd->client_inset.t, &new_x, &new_y);
7812 bd->changes.pos = 1;
7815 EINA_LIST_FREE(bd->pending_move_resize, pnd)
7817 if ((!bd->lock_client_location) && (pnd->move))
7821 bd->changes.pos = 1;
7823 if (pnd->without_border)
7825 bd->x -= bd->client_inset.l;
7826 bd->y -= bd->client_inset.t;
7829 if ((!bd->lock_client_size) && (pnd->resize))
7831 bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
7832 bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
7833 bd->client.w = pnd->w;
7834 bd->client.h = pnd->h;
7835 bd->changes.size = 1;
7841 /* Recreate state */
7842 e_hints_window_init(bd);
7843 if ((bd->client.e.state.centered) &&
7845 ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
7847 bd->x = zx + (zw - bd->w) / 2;
7848 bd->y = zy + (zh - bd->h) / 2;
7849 bd->changes.pos = 1;
7853 _e_border_client_move_resize_send(bd);
7855 /* if the explicit geometry request asks for the app to be
7856 * in another zone - well move it there */
7860 zone = e_container_zone_at_point_get(bd->zone->container,
7861 bd->x + (bd->w / 2),
7862 bd->y + (bd->h / 2));
7864 zone = e_container_zone_at_point_get(bd->zone->container,
7868 zone = e_container_zone_at_point_get(bd->zone->container,
7872 zone = e_container_zone_at_point_get(bd->zone->container,
7876 zone = e_container_zone_at_point_get(bd->zone->container,
7879 if ((zone) && (zone != bd->zone))
7880 e_border_zone_set(bd, zone);
7884 _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
7886 /* effect changes to the window border itself */
7887 if ((bd->changes.shading))
7889 /* show at start of unshade (but don't hide until end of shade) */
7891 ecore_x_window_raise(bd->client.shell_win);
7892 bd->changes.shading = 0;
7895 if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
7898 ecore_x_window_lower(bd->client.shell_win);
7900 ecore_x_window_raise(bd->client.shell_win);
7901 bd->changes.shaded = 0;
7904 else if ((bd->changes.shaded) && (bd->changes.pos))
7907 ecore_x_window_lower(bd->client.shell_win);
7909 ecore_x_window_raise(bd->client.shell_win);
7910 bd->changes.size = 1;
7911 bd->changes.shaded = 0;
7914 else if ((bd->changes.shaded) && (bd->changes.size))
7917 ecore_x_window_lower(bd->client.shell_win);
7919 ecore_x_window_raise(bd->client.shell_win);
7920 bd->changes.shaded = 0;
7923 else if (bd->changes.shaded)
7926 ecore_x_window_lower(bd->client.shell_win);
7928 ecore_x_window_raise(bd->client.shell_win);
7929 bd->changes.size = 1;
7930 bd->changes.shaded = 0;
7934 if (bd->changes.size)
7936 int x = 0, y = 0, xx = 0, yy = 0;
7938 if ((bd->shaded) && (!bd->shading))
7940 evas_obscured_clear(bd->bg_evas);
7944 xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
7945 yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
7947 evas_obscured_clear(bd->bg_evas);
7948 evas_obscured_rectangle_add(bd->bg_evas,
7949 bd->client_inset.l, bd->client_inset.t, xx, yy);
7953 if (bd->shade.dir == E_DIRECTION_UP)
7955 y = yy - bd->client.h;
7957 else if (bd->shade.dir == E_DIRECTION_LEFT)
7959 x = xx - bd->client.w;
7964 if (bd->client.e.state.video)
7966 if (bd->client.e.state.video_position.updated)
7968 ecore_x_window_move(bd->win,
7969 bd->client.e.state.video_parent_border->x +
7970 bd->client.e.state.video_parent_border->client_inset.l +
7971 bd->client.e.state.video_parent_border->fx.x +
7972 bd->client.e.state.video_position.x,
7973 bd->client.e.state.video_parent_border->y +
7974 bd->client.e.state.video_parent_border->client_inset.t +
7975 bd->client.e.state.video_parent_border->fx.y +
7976 bd->client.e.state.video_position.y);
7977 bd->client.e.state.video_position.updated = 0;
7980 else if (!bd->changes.pos)
7982 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
7983 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
7984 bd->post_resize = 1;
7991 ecore_x_window_move_resize(bd->win,
7996 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
7997 ecore_x_window_move(tmp->win,
7998 bd->x + bd->fx.x + bd->client_inset.l + tmp->client.e.state.video_position.x,
7999 bd->y + bd->fx.y + bd->client_inset.t + tmp->client.e.state.video_position.y);
8002 ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
8004 if ((!bd->shaded) || (bd->shading))
8005 ecore_x_window_move_resize(bd->client.shell_win,
8006 bd->client_inset.l, bd->client_inset.t, xx, yy);
8008 if (bd->internal_ecore_evas)
8009 ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
8010 else if (!bd->client.e.state.video)
8011 ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
8013 ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
8014 evas_object_resize(bd->bg_object, bd->w, bd->h);
8015 e_container_shape_resize(bd->shape, bd->w, bd->h);
8016 if (bd->changes.pos)
8017 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
8019 _e_border_client_move_resize_send(bd);
8021 bd->changes.pos = 0;
8022 bd->changes.size = 0;
8025 else if (bd->changes.pos)
8027 if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
8028 bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
8031 e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
8033 _e_border_client_move_resize_send(bd);
8035 bd->changes.pos = 0;
8039 if (bd->changes.reset_gravity)
8041 GRAV_SET(bd, ECORE_X_GRAVITY_NW);
8042 bd->changes.reset_gravity = 0;
8046 if (bd->need_shape_merge)
8048 _e_border_shape_input_rectangle_set(bd);
8049 if ((bd->shaped) || (bd->client.shaped))
8051 Ecore_X_Window twin, twin2;
8054 twin = ecore_x_window_override_new
8055 (bd->zone->container->scratch_win, 0, 0, bd->w, bd->h);
8057 ecore_x_window_shape_window_set(twin, bd->bg_win);
8060 Ecore_X_Rectangle rects[4];
8064 rects[0].width = bd->w;
8065 rects[0].height = bd->client_inset.t;
8067 rects[1].y = bd->client_inset.t;
8068 rects[1].width = bd->client_inset.l;
8069 rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
8070 rects[2].x = bd->w - bd->client_inset.r;
8071 rects[2].y = bd->client_inset.t;
8072 rects[2].width = bd->client_inset.r;
8073 rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
8075 rects[3].y = bd->h - bd->client_inset.b;
8076 rects[3].width = bd->w;
8077 rects[3].height = bd->client_inset.b;
8078 ecore_x_window_shape_rectangles_set(twin, rects, 4);
8080 twin2 = ecore_x_window_override_new
8081 (bd->zone->container->scratch_win, 0, 0,
8082 bd->w - bd->client_inset.l - bd->client_inset.r,
8083 bd->h - bd->client_inset.t - bd->client_inset.b);
8086 if ((bd->shading) || (bd->shaded))
8088 if (bd->shade.dir == E_DIRECTION_UP)
8089 y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
8090 else if (bd->shade.dir == E_DIRECTION_LEFT)
8091 x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
8093 ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
8095 ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
8096 bd->w - bd->client_inset.l - bd->client_inset.r,
8097 bd->h - bd->client_inset.t - bd->client_inset.b);
8098 ecore_x_window_shape_window_add_xy(twin, twin2,
8100 bd->client_inset.t);
8101 ecore_x_window_free(twin2);
8102 ecore_x_window_shape_window_set(bd->win, twin);
8103 ecore_x_window_free(twin);
8106 ecore_x_window_shape_mask_set(bd->win, 0);
8107 // bd->need_shape_export = 1;
8108 bd->need_shape_merge = 0;
8111 if (bd->need_shape_export)
8113 Ecore_X_Rectangle *rects, *orects;
8116 rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
8122 if ((num == bd->shape_rects_num) && (bd->shape_rects))
8126 orects = bd->shape_rects;
8128 for (i = 0; i < num; i++)
8132 rects[i].width -= rects[i].x;
8135 if ((rects[i].x + (int)rects[i].width) > bd->w)
8136 rects[i].width = rects[i].width - rects[i].x;
8139 rects[i].height -= rects[i].y;
8142 if ((rects[i].y + (int)rects[i].height) > bd->h)
8143 rects[i].height = rects[i].height - rects[i].y;
8145 if ((orects[i].x != rects[i].x) ||
8146 (orects[i].y != rects[i].y) ||
8147 (orects[i].width != rects[i].width) ||
8148 (orects[i].height != rects[i].height))
8157 if (bd->client.shaped)
8158 e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
8160 e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
8161 E_FREE(bd->shape_rects);
8162 bd->shape_rects = rects;
8163 bd->shape_rects_num = num;
8164 e_container_shape_rects_set(bd->shape, rects, num);
8171 E_FREE(bd->shape_rects);
8172 bd->shape_rects = NULL;
8173 bd->shape_rects_num = 0;
8174 e_container_shape_rects_set(bd->shape, NULL, 0);
8176 bd->need_shape_export = 0;
8179 if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
8183 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
8184 if ((!bd->placed) && (!bd->re_manage) &&
8185 (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
8186 (!((bd->client.icccm.transient_for != 0) ||
8187 (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
8188 (!bdmove) && (!bdresize))
8190 /* Set this window into moving state */
8192 bd->cur_mouse_action = e_action_find("window_move");
8193 if (bd->cur_mouse_action)
8195 if ((!bd->cur_mouse_action->func.end_mouse) &&
8196 (!bd->cur_mouse_action->func.end))
8197 bd->cur_mouse_action = NULL;
8198 if (bd->cur_mouse_action)
8200 bd->x = x - (bd->w >> 1);
8201 bd->y = y - (bd->client_inset.t >> 1);
8203 bd->changes.pos = 1;
8205 _e_border_client_move_resize_send(bd);
8212 if (bd->cur_mouse_action)
8214 bd->moveinfo.down.x = bd->x + bd->fx.x;
8215 bd->moveinfo.down.y = bd->y + bd->fx.y;
8216 bd->moveinfo.down.w = bd->w;
8217 bd->moveinfo.down.h = bd->h;
8218 bd->mouse.current.mx = x;
8219 bd->mouse.current.my = y;
8220 bd->moveinfo.down.button = 0;
8221 bd->moveinfo.down.mx = x;
8222 bd->moveinfo.down.my = y;
8225 e_object_ref(E_OBJECT(bd->cur_mouse_action));
8226 bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
8227 if (e_config->border_raise_on_mouse_action)
8229 e_border_focus_set(bd, 1, 1);
8231 bd->changes.visible = 0;
8235 if (bd->changes.icon)
8239 efreet_desktop_free(bd->desktop);
8242 if (bd->icon_object)
8244 evas_object_del(bd->icon_object);
8245 bd->icon_object = NULL;
8247 if (bd->remember && bd->remember->prop.desktop_file)
8249 const char *desktop = bd->remember->prop.desktop_file;
8251 bd->desktop = efreet_desktop_get(desktop);
8253 bd->desktop = efreet_util_desktop_name_find(desktop);
8257 if ((bd->client.icccm.name) && (bd->client.icccm.class))
8258 bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
8259 bd->client.icccm.class);
8263 /* libreoffice and maybe others match window class
8264 with .desktop file name */
8265 if (bd->client.icccm.class)
8268 snprintf(buf, sizeof(buf), "%s.desktop", bd->client.icccm.class);
8269 bd->desktop = efreet_util_desktop_file_id_find(buf);
8274 bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
8275 bd->client.netwm.pid);
8276 if (bd->desktop) efreet_desktop_ref(bd->desktop);
8278 if (!bd->desktop && bd->client.icccm.name)
8280 /* this works for most cases as fallback. useful when app is
8282 bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
8284 if (!bd->desktop && bd->client.icccm.transient_for)
8286 E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
8287 if (bd2 && bd2->desktop)
8289 efreet_desktop_ref(bd2->desktop);
8290 bd->desktop = bd2->desktop;
8295 ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
8296 bd->desktop->orig_path);
8299 bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
8300 if ((bd->focused) && (bd->icon_object))
8301 edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
8304 evas_object_show(bd->icon_object);
8305 edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
8308 evas_object_hide(bd->icon_object);
8311 E_Event_Border_Icon_Change *ev;
8313 ev = E_NEW(E_Event_Border_Icon_Change, 1);
8315 e_object_ref(E_OBJECT(bd));
8316 // e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
8317 ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
8318 _e_border_event_border_icon_change_free, NULL);
8320 bd->changes.icon = 0;
8325 bd->changes.stack = 0;
8326 bd->changes.prop = 0;
8328 if ((bd->take_focus) || (bd->want_focus))
8331 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8332 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
8333 (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK) ||
8336 if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || (bd->want_focus))
8340 #ifdef _F_FOCUS_WINDOW_IF_TOP_STACK_
8341 if (e_config->focus_setting == E_FOCUS_NEW_WINDOW_IF_TOP_STACK)
8342 _e_border_check_stack(bd);
8345 e_border_focus_set_with_pointer(bd);
8347 else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
8349 if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
8350 ((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
8351 (e_border_find_by_client_window(bd->client.icccm.transient_for) ==
8352 e_border_focused_get())))
8354 e_border_focus_set_with_pointer(bd);
8359 /* focus window by default when it is the only one on desk */
8360 E_Border *bd2 = NULL;
8362 EINA_LIST_FOREACH(focus_stack, l, bd2)
8364 if (bd == bd2) continue;
8365 if ((!bd2->iconic) && (bd2->visible) &&
8366 ((bd->desk == bd2->desk) || bd2->sticky))
8371 e_border_focus_set_with_pointer(bd);
8375 if (bd->need_maximize)
8378 max = bd->maximized;
8379 bd->maximized = E_MAXIMIZE_NONE;
8380 e_border_maximize(bd, max);
8381 bd->need_maximize = 0;
8384 if (bd->need_fullscreen)
8386 e_border_fullscreen(bd, e_config->fullscreen_policy);
8387 bd->need_fullscreen = 0;
8391 e_remember_update(bd);
8393 if (send_event) // FIXME: send only if a property changed - above need to
8394 { // check on that. for now - always send.
8395 event = E_NEW(E_Event_Border_Property, 1);
8397 e_object_ref(E_OBJECT(bd));
8398 ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
8400 _e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
8404 _e_border_moveinfo_gather(E_Border *bd,
8407 if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
8408 else if (e_util_glob_match(source, "mouse,*,2"))
8409 bd->moveinfo.down.button = 2;
8410 else if (e_util_glob_match(source, "mouse,*,3"))
8411 bd->moveinfo.down.button = 3;
8412 else bd->moveinfo.down.button = 0;
8413 if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
8415 bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
8416 bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
8420 bd->moveinfo.down.mx = bd->mouse.current.mx;
8421 bd->moveinfo.down.my = bd->mouse.current.my;
8426 _e_border_resize_handle(E_Border *bd)
8429 int new_x, new_y, new_w, new_h;
8431 Eina_List *skiplist = NULL;
8438 if ((bd->resize_mode == RESIZE_TR) ||
8439 (bd->resize_mode == RESIZE_R) ||
8440 (bd->resize_mode == RESIZE_BR))
8442 if ((bd->moveinfo.down.button >= 1) &&
8443 (bd->moveinfo.down.button <= 3))
8444 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
8445 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8447 w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
8449 else if ((bd->resize_mode == RESIZE_TL) ||
8450 (bd->resize_mode == RESIZE_L) ||
8451 (bd->resize_mode == RESIZE_BL))
8453 if ((bd->moveinfo.down.button >= 1) &&
8454 (bd->moveinfo.down.button <= 3))
8455 w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
8456 (bd->mouse.current.mx - bd->moveinfo.down.mx);
8458 w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
8461 if ((bd->resize_mode == RESIZE_TL) ||
8462 (bd->resize_mode == RESIZE_T) ||
8463 (bd->resize_mode == RESIZE_TR))
8465 if ((bd->moveinfo.down.button >= 1) &&
8466 (bd->moveinfo.down.button <= 3))
8467 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
8468 (bd->mouse.current.my - bd->moveinfo.down.my);
8470 h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
8472 else if ((bd->resize_mode == RESIZE_BL) ||
8473 (bd->resize_mode == RESIZE_B) ||
8474 (bd->resize_mode == RESIZE_BR))
8476 if ((bd->moveinfo.down.button >= 1) &&
8477 (bd->moveinfo.down.button <= 3))
8478 h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
8479 (bd->mouse.current.my - bd->moveinfo.down.my);
8481 h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
8487 if ((bd->resize_mode == RESIZE_TL) ||
8488 (bd->resize_mode == RESIZE_L) ||
8489 (bd->resize_mode == RESIZE_BL))
8491 if ((bd->resize_mode == RESIZE_TL) ||
8492 (bd->resize_mode == RESIZE_T) ||
8493 (bd->resize_mode == RESIZE_TR))
8496 skiplist = eina_list_append(skiplist, bd);
8497 e_resist_container_border_position(bd->zone->container, skiplist,
8498 bd->x, bd->y, bd->w, bd->h,
8500 &new_x, &new_y, &new_w, &new_h);
8501 eina_list_free(skiplist);
8505 e_border_resize_limit(bd, &new_w, &new_h);
8506 if ((bd->resize_mode == RESIZE_TL) ||
8507 (bd->resize_mode == RESIZE_L) ||
8508 (bd->resize_mode == RESIZE_BL))
8509 new_x += (w - new_w);
8510 if ((bd->resize_mode == RESIZE_TL) ||
8511 (bd->resize_mode == RESIZE_T) ||
8512 (bd->resize_mode == RESIZE_TR))
8513 new_y += (h - new_h);
8515 e_border_move_resize(bd, new_x, new_y, new_w, new_h);
8519 _e_border_shade_animator(void *data)
8521 E_Border *bd = data;
8523 double dur = bd->client.h / e_config->border_shade_speed;
8525 dt = ecore_loop_time_get() - bd->shade.start;
8528 if (val < 0.0) val = 0.0;
8529 else if (val > 1.0) val = 1.0;
8531 if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
8534 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL, 0.0, 0.0);
8535 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8537 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
8540 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE, 0.0, 0.0);
8541 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8543 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
8546 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE, 0.0, 0.0);
8547 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8549 else if (e_config->border_shade_transition == E_TRANSITION_LINEAR)
8552 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
8553 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8555 else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE_LOTS)
8558 ecore_animator_pos_map(val, ECORE_POS_MAP_ACCELERATE_FACTOR, 1.7, 0.0);
8559 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8561 else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE_LOTS)
8564 ecore_animator_pos_map(val, ECORE_POS_MAP_DECELERATE_FACTOR, 1.7, 0.0);
8565 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8567 else if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL_LOTS)
8570 ecore_animator_pos_map(val, ECORE_POS_MAP_SINUSOIDAL_FACTOR, 1.7, 0.0);
8571 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8573 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE)
8576 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 3.0);
8577 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8579 else if (e_config->border_shade_transition == E_TRANSITION_BOUNCE_LOTS)
8582 ecore_animator_pos_map(val, ECORE_POS_MAP_BOUNCE, 1.2, 5.0);
8583 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8588 ecore_animator_pos_map(val, ECORE_POS_MAP_LINEAR, 0.0, 0.0);
8589 if (!bd->shaded) bd->shade.val = 1.0 - bd->shade.val;
8592 /* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
8593 if (bd->shade.val < 0.001) bd->shade.val = 0.0;
8594 else if (bd->shade.val > .999)
8595 bd->shade.val = 1.0;
8597 if (bd->shade.dir == E_DIRECTION_UP)
8598 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
8599 else if (bd->shade.dir == E_DIRECTION_DOWN)
8601 bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
8602 bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
8603 bd->changes.pos = 1;
8605 else if (bd->shade.dir == E_DIRECTION_LEFT)
8606 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
8607 else if (bd->shade.dir == E_DIRECTION_RIGHT)
8609 bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
8610 bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
8611 bd->changes.pos = 1;
8614 if ((bd->shaped) || (bd->client.shaped))
8616 bd->need_shape_merge = 1;
8617 bd->need_shape_export = 1;
8619 if (bd->shaped_input)
8621 bd->need_shape_merge = 1;
8623 bd->changes.size = 1;
8629 E_Event_Border_Resize *ev;
8632 bd->shaded = !(bd->shaded);
8633 bd->changes.size = 1;
8634 bd->changes.shaded = 1;
8635 bd->changes.shading = 1;
8637 bd->shade.anim = NULL;
8640 edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
8642 edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
8643 edje_object_message_signal_process(bd->bg_object);
8644 e_border_frame_recalc(bd);
8646 ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
8647 ev = E_NEW(E_Event_Border_Resize, 1);
8649 e_object_ref(E_OBJECT(bd));
8650 // e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
8651 ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
8652 return ECORE_CALLBACK_CANCEL;
8654 return ECORE_CALLBACK_RENEW;
8658 _e_border_event_border_resize_free(void *data __UNUSED__,
8661 E_Event_Border_Resize *e;
8664 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
8665 e_object_unref(E_OBJECT(e->border));
8670 _e_border_event_border_move_free(void *data __UNUSED__,
8673 E_Event_Border_Move *e;
8676 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
8677 e_object_unref(E_OBJECT(e->border));
8682 _e_border_event_border_add_free(void *data __UNUSED__,
8685 E_Event_Border_Add *e;
8688 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
8689 e_object_unref(E_OBJECT(e->border));
8694 _e_border_event_border_remove_free(void *data __UNUSED__,
8697 E_Event_Border_Remove *e;
8700 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
8701 e_object_unref(E_OBJECT(e->border));
8706 _e_border_event_border_show_free(void *data __UNUSED__,
8709 E_Event_Border_Show *e;
8712 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
8713 e_object_unref(E_OBJECT(e->border));
8718 _e_border_event_border_hide_free(void *data __UNUSED__,
8721 E_Event_Border_Hide *e;
8724 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
8725 e_object_unref(E_OBJECT(e->border));
8730 _e_border_event_border_iconify_free(void *data __UNUSED__,
8733 E_Event_Border_Iconify *e;
8736 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
8737 e_object_unref(E_OBJECT(e->border));
8742 _e_border_event_border_uniconify_free(void *data __UNUSED__,
8745 E_Event_Border_Uniconify *e;
8748 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
8749 e_object_unref(E_OBJECT(e->border));
8754 _e_border_event_border_stick_free(void *data __UNUSED__,
8757 E_Event_Border_Stick *e;
8760 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
8761 e_object_unref(E_OBJECT(e->border));
8766 _e_border_event_border_unstick_free(void *data __UNUSED__,
8769 E_Event_Border_Unstick *e;
8772 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
8773 e_object_unref(E_OBJECT(e->border));
8778 _e_border_event_border_zone_set_free(void *data __UNUSED__,
8781 E_Event_Border_Zone_Set *e;
8784 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
8785 e_object_unref(E_OBJECT(e->border));
8786 e_object_unref(E_OBJECT(e->zone));
8791 _e_border_event_border_desk_set_free(void *data __UNUSED__,
8794 E_Event_Border_Desk_Set *e;
8797 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
8798 e_object_unref(E_OBJECT(e->border));
8799 e_object_unref(E_OBJECT(e->desk));
8804 _e_border_event_border_stack_free(void *data __UNUSED__,
8807 E_Event_Border_Stack *e;
8810 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
8811 e_object_unref(E_OBJECT(e->border));
8814 // e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
8815 e_object_unref(E_OBJECT(e->stack));
8821 _e_border_event_border_icon_change_free(void *data __UNUSED__,
8824 E_Event_Border_Icon_Change *e;
8827 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
8828 e_object_unref(E_OBJECT(e->border));
8833 _e_border_event_border_urgent_change_free(void *data __UNUSED__,
8836 E_Event_Border_Urgent_Change *e;
8839 e_object_unref(E_OBJECT(e->border));
8844 _e_border_event_border_focus_in_free(void *data __UNUSED__,
8847 E_Event_Border_Focus_In *e;
8850 e_object_unref(E_OBJECT(e->border));
8855 _e_border_event_border_focus_out_free(void *data __UNUSED__,
8858 E_Event_Border_Focus_Out *e;
8861 e_object_unref(E_OBJECT(e->border));
8866 _e_border_event_border_property_free(void *data __UNUSED__,
8869 E_Event_Border_Property *e;
8872 e_object_unref(E_OBJECT(e->border));
8877 _e_border_event_border_fullscreen_free(void *data __UNUSED__,
8880 E_Event_Border_Fullscreen *e;
8883 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_fullscreen_event");
8884 e_object_unref(E_OBJECT(e->border));
8889 _e_border_event_border_unfullscreen_free(void *data __UNUSED__,
8892 E_Event_Border_Unfullscreen *e;
8895 // e_object_breadcrumb_del(E_OBJECT(e->border), "border_unfullscreen_event");
8896 e_object_unref(E_OBJECT(e->border));
8901 _e_border_zone_update(E_Border *bd)
8907 /* still within old zone - leave it there */
8908 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
8909 bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
8911 /* find a new zone */
8912 con = bd->zone->container;
8913 EINA_LIST_FOREACH(con->zones, l, zone)
8915 if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
8916 zone->x, zone->y, zone->w, zone->h))
8918 e_border_zone_set(bd, zone);
8925 _e_border_resize_begin(E_Border *bd)
8927 if (!bd->lock_user_stacking)
8929 if (e_config->border_raise_on_mouse_action)
8932 if ((bd->shaded) || (bd->shading) ||
8933 (bd->fullscreen) || (bd->lock_user_size))
8936 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
8942 if (bd->client.netwm.sync.request)
8944 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
8945 bd->client.netwm.sync.serial = 1;
8946 bd->client.netwm.sync.wait = 0;
8947 bd->client.netwm.sync.send_time = ecore_loop_time_get();
8950 _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
8957 _e_border_resize_end(E_Border *bd)
8961 e_grabinput_release(bd->win, bd->win);
8964 if (bd->client.netwm.sync.alarm)
8966 E_Border_Pending_Move_Resize *pnd;
8968 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
8969 bd->client.netwm.sync.alarm = 0;
8970 /* resize to last geometry if sync alarm for it was not yet handled */
8971 if (bd->pending_move_resize)
8974 bd->changes.pos = 1;
8975 bd->changes.size = 1;
8976 _e_border_client_move_resize_send(bd);
8979 EINA_LIST_FREE(bd->pending_move_resize, pnd)
8983 _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
8987 /* If this border was maximized, we need to unset Maximized state or
8988 * on restart, E still thinks it's maximized */
8989 if (bd->maximized != E_MAXIMIZE_NONE)
8990 e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
8991 bd->maximized & E_MAXIMIZE_NONE);
8996 _e_border_resize_update(E_Border *bd)
8998 _e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
9002 _e_border_move_begin(E_Border *bd)
9004 if (!bd->lock_user_stacking)
9006 if (e_config->border_raise_on_mouse_action)
9009 if ((bd->fullscreen) || (bd->lock_user_location))
9012 if (grabbed && !e_grabinput_get(bd->win, 0, bd->win))
9018 if (bd->client.netwm.sync.request)
9020 bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
9021 bd->client.netwm.sync.serial = 0;
9022 bd->client.netwm.sync.wait = 0;
9023 bd->client.netwm.sync.time = ecore_loop_time_get();
9026 _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
9033 _e_border_move_end(E_Border *bd)
9037 e_grabinput_release(bd->win, bd->win);
9041 if (bd->client.netwm.sync.alarm)
9043 ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
9044 bd->client.netwm.sync.alarm = 0;
9047 _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
9054 _e_border_move_update(E_Border *bd)
9056 _e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
9060 _e_border_cb_ping_poller(void *data)
9070 edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
9073 ecore_timer_del(bd->kill_timer);
9074 bd->kill_timer = NULL;
9080 /* if time between last ping and now is greater
9081 * than half the ping interval... */
9082 if ((ecore_loop_time_get() - bd->ping) >
9083 ((e_config->ping_clients_interval *
9084 ecore_poller_poll_interval_get(ECORE_POLLER_CORE)) / 2.0))
9089 edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
9090 /* FIXME: if below dialog is up - hide it now */
9092 if (bd->delete_requested)
9094 /* FIXME: pop up dialog saying app is hung - kill client, or pid */
9095 e_border_act_kill_begin(bd);
9099 bd->ping_poller = NULL;
9101 return ECORE_CALLBACK_CANCEL;
9105 _e_border_cb_kill_timer(void *data)
9110 // dont wait until it's hung -
9113 if (bd->client.netwm.pid > 1)
9114 kill(bd->client.netwm.pid, SIGKILL);
9116 bd->kill_timer = NULL;
9117 return ECORE_CALLBACK_CANCEL;
9121 _e_border_pointer_resize_begin(E_Border *bd)
9123 switch (bd->resize_mode)
9126 e_pointer_type_push(bd->pointer, bd, "resize_tl");
9130 e_pointer_type_push(bd->pointer, bd, "resize_t");
9134 e_pointer_type_push(bd->pointer, bd, "resize_tr");
9138 e_pointer_type_push(bd->pointer, bd, "resize_r");
9142 e_pointer_type_push(bd->pointer, bd, "resize_br");
9146 e_pointer_type_push(bd->pointer, bd, "resize_b");
9150 e_pointer_type_push(bd->pointer, bd, "resize_bl");
9154 e_pointer_type_push(bd->pointer, bd, "resize_l");
9160 _e_border_pointer_resize_end(E_Border *bd)
9162 switch (bd->resize_mode)
9165 e_pointer_type_pop(bd->pointer, bd, "resize_tl");
9169 e_pointer_type_pop(bd->pointer, bd, "resize_t");
9173 e_pointer_type_pop(bd->pointer, bd, "resize_tr");
9177 e_pointer_type_pop(bd->pointer, bd, "resize_r");
9181 e_pointer_type_pop(bd->pointer, bd, "resize_br");
9185 e_pointer_type_pop(bd->pointer, bd, "resize_b");
9189 e_pointer_type_pop(bd->pointer, bd, "resize_bl");
9193 e_pointer_type_pop(bd->pointer, bd, "resize_l");
9199 _e_border_pointer_move_begin(E_Border *bd)
9201 e_pointer_type_push(bd->pointer, bd, "move");
9205 _e_border_pointer_move_end(E_Border *bd)
9207 e_pointer_type_pop(bd->pointer, bd, "move");
9210 static Eina_List *_e_border_hooks = NULL;
9211 static int _e_border_hooks_delete = 0;
9212 static int _e_border_hooks_walking = 0;
9215 _e_border_hooks_clean(void)
9220 EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
9224 _e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
9231 _e_border_hook_call(E_Border_Hook_Point hookpoint,
9237 _e_border_hooks_walking++;
9238 EINA_LIST_FOREACH(_e_border_hooks, l, bh)
9240 if (bh->delete_me) continue;
9241 if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
9243 _e_border_hooks_walking--;
9244 if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
9245 _e_border_hooks_clean();
9248 EAPI E_Border_Hook *
9249 e_border_hook_add(E_Border_Hook_Point hookpoint,
9250 void (*func)(void *data,
9256 bh = E_NEW(E_Border_Hook, 1);
9257 if (!bh) return NULL;
9258 bh->hookpoint = hookpoint;
9261 _e_border_hooks = eina_list_append(_e_border_hooks, bh);
9266 e_border_hook_del(E_Border_Hook *bh)
9269 if (_e_border_hooks_walking == 0)
9271 _e_border_hooks = eina_list_remove(_e_border_hooks, bh);
9275 _e_border_hooks_delete++;
9279 e_border_focus_track_freeze(void)
9281 focus_track_frozen++;
9285 e_border_focus_track_thaw(void)
9287 focus_track_frozen--;
9291 e_border_under_pointer_get(E_Desk *desk,
9294 E_Border *bd = NULL, *cbd;
9298 /* We need to ensure that we can get the container window for the
9299 * zone of either the given desk or the desk of the excluded
9300 * window, so return if neither is given */
9302 ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
9304 ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
9308 EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
9311 /* If a border was specified which should be excluded from the list
9312 * (because it will be closed shortly for example), skip */
9313 if ((exclude) && (cbd == exclude)) continue;
9314 if ((desk) && (cbd->desk != desk)) continue;
9315 if (!E_INSIDE(x, y, cbd->x, cbd->y, cbd->w, cbd->h))
9317 /* If the layer is higher, the position of the window is higher
9318 * (always on top vs always below) */
9319 if (!bd || (cbd->layer > bd->layer))
9329 _e_border_pointer_warp_to_center_timer(void *data __UNUSED__)
9336 ecore_x_pointer_xy_get(warp_to_win, &x, &y);
9337 if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
9338 (y - warp_y) > 5 || (y - warp_y) < -5)
9340 /* User moved the mouse, so stop warping */
9345 /* We just use the same warp speed as configured
9346 * for the windowlist */
9347 spd = e_config->winlist_warp_speed;
9350 warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
9351 warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
9352 if (warp_x == x && warp_y == y)
9359 ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
9360 return ECORE_CALLBACK_RENEW;
9363 ecore_timer_del(warp_timer);
9365 return ECORE_CALLBACK_CANCEL;
9369 e_border_pointer_warp_to_center(E_Border *bd)
9373 /* Do not slide pointer when disabled (probably breaks focus
9374 * on sloppy/mouse focus but requested by users). */
9375 if (!e_config->pointer_slide) return 0;
9376 /* Only warp the pointer if it is not already in the area of
9377 * the given border */
9378 ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
9379 if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
9380 (y >= bd->y) && (y <= (bd->y + bd->h)))
9383 warp_to_x = bd->x + (bd->w / 2);
9384 if (warp_to_x < (bd->zone->x + 1))
9385 warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
9386 else if (warp_to_x > (bd->zone->x + bd->zone->w))
9387 warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
9389 warp_to_y = bd->y + (bd->h / 2);
9390 if (warp_to_y < (bd->zone->y + 1))
9391 warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
9392 else if (warp_to_y > (bd->zone->y + bd->zone->h))
9393 warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
9396 warp_to_win = bd->zone->container->win;
9397 ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
9399 warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void *)bd);
9404 e_border_comp_hidden_set(E_Border *bd,
9411 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
9413 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9416 ecore_x_window_hide(tmp->win);
9418 ecore_x_window_show(tmp->win);
9421 if (bd->comp_hidden == hidden) return;
9423 bd->comp_hidden = hidden;
9425 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
9427 ecore_x_composite_window_events_disable(bd->win);
9428 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
9432 _e_border_shape_input_rectangle_set(bd);
9433 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
9438 e_border_tmp_input_hidden_push(E_Border *bd)
9444 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
9446 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9447 e_border_tmp_input_hidden_push(tmp);
9449 bd->tmp_input_hidden++;
9450 if (bd->tmp_input_hidden != 1) return;
9452 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
9454 ecore_x_composite_window_events_disable(bd->win);
9455 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
9459 _e_border_shape_input_rectangle_set(bd);
9460 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
9465 e_border_tmp_input_hidden_pop(E_Border *bd)
9471 E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
9473 EINA_LIST_FOREACH(bd->client.e.state.video_child, l, tmp)
9474 e_border_tmp_input_hidden_pop(tmp);
9476 bd->tmp_input_hidden--;
9477 if (bd->tmp_input_hidden != 0) return;
9479 if ((bd->comp_hidden) || (bd->tmp_input_hidden > 0))
9481 ecore_x_composite_window_events_disable(bd->win);
9482 ecore_x_window_ignore_set(bd->win, EINA_TRUE);
9486 _e_border_shape_input_rectangle_set(bd);
9487 ecore_x_window_ignore_set(bd->win, EINA_FALSE);
9490 /*vim:ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0*/