enlightenment/src/bin/e_border.c

7758 lines
208 KiB
C
Raw Normal View History

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
//#define INOUTDEBUG_MOUSE 1
//#define INOUTDEBUG_FOCUS 1
/* These are compatible with netwm */
#define RESIZE_TL 0
#define RESIZE_T 1
#define RESIZE_TR 2
#define RESIZE_R 3
#define RESIZE_BR 4
#define RESIZE_B 5
#define RESIZE_BL 6
#define RESIZE_L 7
#define MOVE 8
#define RESIZE_NONE 11
/* local subsystem functions */
static void _e_border_free(E_Border *bd);
static void _e_border_del(E_Border *bd);
/* FIXME: these likely belong in a separate icccm/client handler */
2005-02-07 05:51:09 -08:00
/* and the border needs to become a dumb object that just does what its */
/* told to do */
static int _e_border_cb_window_show_request(void *data, int ev_type, void *ev);
static int _e_border_cb_window_destroy(void *data, int ev_type, void *ev);
static int _e_border_cb_window_hide(void *data, int ev_type, void *ev);
static int _e_border_cb_window_reparent(void *data, int ev_type, void *ev);
static int _e_border_cb_window_configure_request(void *data, int ev_type, void *ev);
2005-01-06 01:08:20 -08:00
static int _e_border_cb_window_resize_request(void *data, int ev_type, void *ev);
static int _e_border_cb_window_gravity(void *data, int ev_type, void *ev);
static int _e_border_cb_window_stack_request(void *data, int ev_type, void *ev);
static int _e_border_cb_window_property(void *data, int ev_type, void *ev);
static int _e_border_cb_window_colormap(void *data, int ev_type, void *ev);
static int _e_border_cb_window_shape(void *data, int ev_type, void *ev);
static int _e_border_cb_window_focus_in(void *data, int ev_type, void *ev);
static int _e_border_cb_window_focus_out(void *data, int ev_type, void *ev);
2005-06-06 08:22:05 -07:00
static int _e_border_cb_client_message(void *data, int ev_type, void *ev);
static int _e_border_cb_window_state_request(void *data, int ev_type, void *ev);
static int _e_border_cb_window_move_resize_request(void *data, int ev_type, void *ev);
2005-05-16 08:43:15 -07:00
static int _e_border_cb_desktop_change(void *data, int ev_type, void *ev);
2005-06-06 08:22:05 -07:00
static int _e_border_cb_sync_alarm(void *data, int ev_type, void *ev);
static int _e_border_cb_efreet_desktop_list_change(void *data, int ev_type, void *ev);
static int _e_border_cb_efreet_desktop_change(void *data, int ev_type, void *ev);
static int _e_border_cb_config_icon_theme(void *data, int ev_type, void *ev);
static int _e_border_cb_pointer_warp(void *data, int ev_type, void *ev);
static void _e_border_cb_signal_bind(void *data, Evas_Object *obj, const char *emission, const char *source);
static int _e_border_cb_mouse_in(void *data, int type, void *event);
static int _e_border_cb_mouse_out(void *data, int type, void *event);
static int _e_border_cb_mouse_wheel(void *data, int type, void *event);
static int _e_border_cb_mouse_down(void *data, int type, void *event);
static int _e_border_cb_mouse_up(void *data, int type, void *event);
static int _e_border_cb_mouse_move(void *data, int type, void *event);
static int _e_border_cb_grab_replay(void *data, int type, void *event);
static void _e_border_cb_drag_finished(E_Drag *drag, int dropped);
static void _e_border_eval(E_Border *bd);
static void _e_border_eval0(E_Border *bd);
static void _e_border_container_layout_hook(E_Container *con);
static void _e_border_moveinfo_gather(E_Border *bd, const char *source);
static void _e_border_resize_handle(E_Border *bd);
static int _e_border_shade_animator(void *data);
static void _e_border_event_border_add_free(void *data, void *ev);
static void _e_border_event_border_remove_free(void *data, void *ev);
static void _e_border_event_border_zone_set_free(void *data, void *ev);
static void _e_border_event_border_desk_set_free(void *data, void *ev);
static void _e_border_event_border_stack_free(void *data, void *ev);
static void _e_border_event_border_icon_change_free(void *data, void *ev);
static void _e_border_event_border_urgent_change_free(void *data, void *ev);
static void _e_border_event_border_focus_in_free(void *data, void *ev);
static void _e_border_event_border_focus_out_free(void *data, void *ev);
static void _e_border_event_border_resize_free(void *data, void *ev);
static void _e_border_event_border_move_free(void *data, void *ev);
static void _e_border_event_border_show_free(void *data, void *ev);
static void _e_border_event_border_hide_free(void *data, void *ev);
static void _e_border_event_border_iconify_free(void *data, void *ev);
static void _e_border_event_border_uniconify_free(void *data, void *ev);
2005-02-10 07:21:23 -08:00
static void _e_border_event_border_stick_free(void *data, void *ev);
static void _e_border_event_border_unstick_free(void *data, void *ev);
static void _e_border_event_border_property_free(void *data, void *ev);
static void _e_border_zone_update(E_Border *bd);
static int _e_border_resize_begin(E_Border *bd);
static int _e_border_resize_end(E_Border *bd);
2005-02-07 05:51:09 -08:00
static void _e_border_resize_update(E_Border *bd);
static int _e_border_move_begin(E_Border *bd);
static int _e_border_move_end(E_Border *bd);
static void _e_border_move_update(E_Border *bd);
e: 1. configure/build changes to allow cross-compiling painlessly 2. pager module namespace changes - this was still dirty afdter the namespace cleanup, so clean it up 3. add a powersave subsystem - doesnt have an "automatic" way to turn on and off right now, this i think is best provided by modules (that do things like monitor acpi status's (eg close lid of laptop), AC power status etc. etc. this allows e to nicely defer "power" expensive actions to avoid disk spinups etc. 4. move to use the new ecore poller system - discussed long ago as part of power management/saving issues. now it exists 5. add a canvas idle flush call that helsp cope with the new shm greedy software x11 engine stuff 6. use the new powersave subsystem where appropriate 7. fix non-zeroed/initted memory access in e_fm_main 8. fix mem leak for e menus 9. remove ipc handlers for changed/removed config values 10. use animaotr not timer for menu scrolls - then menu scrolls obey the fps config 11. fix up timer/poll happienss of cursor idle stuff 12. remove avoid damage from popups for now - causing problems 13. change battery and temp readouts to b e shorter so they fit 14. pager can emit signals on focus change for mini-windows now 15. temperature module now uses a slave process and uses stdin/out to talk to it and get output - this makes e smoother as in my expereicne i found getting the temp on my laptop actually took like 200ms so e "hang" for 200ms while reading the acpi files - so now the subprocess does it and just writesa back to e when it gets it. ecore: 1. add ecore_pollers. see the documentation on them in doxygen comments :) 2. fix timers to only go off when they have to - bug there that made e's select time out a LOT more than it needed to. defensive coding hid the problem. now fixed. e should be much more power friendly now. 3. formatting/niceness in ecore_exe stuff 4. some comments on comments with SIGIO ideas vs. select 5. add call to be able to add an idle enterer at the start of the list of them, not just the end (as has been the default) 6. fix ecore_evas to support auto evas idler calls after 0.5 secs of idle in all canvases - and to do it right 7. if argb destination - set the shape EVENT shape (to mask out events in transparent regions much like shape does withotu translucency) 8. in ecore_x add support for the event shape evas: 1. fix cache to work properly and not just always fill up (as it seemed to like to think cahce useage dropped below 0 when it didnt and thus just over-fill) 2. software x11 engine now ONLY uses shm segments - no ximages over the socket. this ximage hack was there to avoid the 2 round trips involved in setting up an shm image - now i mitigated that wih an shm image cache pool. it keeps shm images around and repurposes them for new update regions if appropriate. this means many fewer shm creates (about 1/100th the number) and since we recycle the memory less 0 memory page filling by the kernel - in the end, i recorded about a 10-20% speedup over the old software x11 engine. simple tests i have seen up to 120% speedups. idle flush now does something - it frees all the cached shm segments. it has a hard-coded limit of 4mb worth of shm segments (or 32 segments - whichever comes first) to keep around. once can never complain much about speedups methinks :). also evas will defer sync until the NEXT frame is written - this means evas can calculate the next frame of data while x dma's/copies the images to the screen at the same time (if you hve a dual core or multi-cpu machnike or your xserver is able to use DMA to copy image data to the screen/video ram then this should see a decent speedup). SVN revision: 33448
2008-01-10 23:33:57 -08:00
static int _e_border_cb_ping_poller(void *data);
static int _e_border_cb_kill_timer(void *data);
static void _e_border_pointer_resize_begin(E_Border *bd);
static void _e_border_pointer_resize_end(E_Border *bd);
static void _e_border_pointer_move_begin(E_Border *bd);
static void _e_border_pointer_move_end(E_Border *bd);
static void _e_border_hook_call(E_Border_Hook_Point hookpoint, void *bd);
static void _e_border_client_move_resize_send(E_Border *bd);
/* local subsystem globals */
static Eina_List *handlers = NULL;
static Eina_List *borders = NULL;
static Eina_Hash *borders_hash = NULL;
static E_Border *focused = NULL;
static E_Border *resize = NULL;
static E_Border *move = NULL;
static E_Drag *drag_border = NULL;
2005-06-06 08:22:05 -07:00
static int grabbed = 0;
static Eina_List *focus_stack = NULL;
static Eina_List *raise_stack = NULL;
static Ecore_X_Screen_Size screen_size = { -1, -1 };
2007-08-04 21:41:55 -07:00
static int focus_track_frozen = 0;
static int warp_to = 0;
static int warp_to_x = 0;
static int warp_to_y = 0;
static int warp_x = 0;
static int warp_y = 0;
static Ecore_X_Window warp_to_win;
static Ecore_Timer *warp_timer = NULL;
2006-01-07 02:39:46 -08:00
EAPI int E_EVENT_BORDER_ADD = 0;
EAPI int E_EVENT_BORDER_REMOVE = 0;
EAPI int E_EVENT_BORDER_ZONE_SET = 0;
EAPI int E_EVENT_BORDER_DESK_SET = 0;
EAPI int E_EVENT_BORDER_RESIZE = 0;
EAPI int E_EVENT_BORDER_MOVE = 0;
EAPI int E_EVENT_BORDER_SHOW = 0;
EAPI int E_EVENT_BORDER_HIDE = 0;
EAPI int E_EVENT_BORDER_ICONIFY = 0;
EAPI int E_EVENT_BORDER_UNICONIFY = 0;
EAPI int E_EVENT_BORDER_STICK = 0;
EAPI int E_EVENT_BORDER_UNSTICK = 0;
EAPI int E_EVENT_BORDER_STACK = 0;
EAPI int E_EVENT_BORDER_ICON_CHANGE = 0;
EAPI int E_EVENT_BORDER_URGENT_CHANGE = 0;
EAPI int E_EVENT_BORDER_FOCUS_IN = 0;
EAPI int E_EVENT_BORDER_FOCUS_OUT = 0;
EAPI int E_EVENT_BORDER_PROPERTY = 0;
#define GRAV_SET(bd, grav) \
ecore_x_window_gravity_set(bd->bg_win, grav); \
ecore_x_window_gravity_set(bd->client.shell_win, grav); \
ecore_x_window_gravity_set(bd->client.win, grav);
/* externally accessible functions */
2006-01-07 02:39:46 -08:00
EAPI int
e_border_init(void)
{
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_border_cb_window_show_request, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _e_border_cb_window_destroy, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _e_border_cb_window_hide, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_REPARENT, _e_border_cb_window_reparent, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, _e_border_cb_window_configure_request, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, _e_border_cb_window_resize_request, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_GRAVITY, _e_border_cb_window_gravity, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, _e_border_cb_window_stack_request, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _e_border_cb_window_property, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_COLORMAP, _e_border_cb_window_colormap, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHAPE, _e_border_cb_window_shape, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _e_border_cb_window_focus_in, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _e_border_cb_window_focus_out, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _e_border_cb_client_message, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, _e_border_cb_window_state_request, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, _e_border_cb_window_move_resize_request, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_DESKTOP_CHANGE, _e_border_cb_desktop_change, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(ECORE_X_EVENT_SYNC_ALARM, _e_border_cb_sync_alarm, NULL));
ecore_x_passive_grab_replay_func_set(_e_border_cb_grab_replay, NULL);
handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_POINTER_WARP, _e_border_cb_pointer_warp, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_LIST_CHANGE, _e_border_cb_efreet_desktop_list_change, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(EFREET_EVENT_DESKTOP_CHANGE, _e_border_cb_efreet_desktop_change, NULL));
handlers = eina_list_append(handlers, ecore_event_handler_add(E_EVENT_CONFIG_ICON_THEME, _e_border_cb_config_icon_theme, NULL));
if (!borders_hash) borders_hash = eina_hash_string_superfast_new(NULL);
E_EVENT_BORDER_ADD = ecore_event_type_new();
E_EVENT_BORDER_REMOVE = ecore_event_type_new();
E_EVENT_BORDER_DESK_SET = ecore_event_type_new();
E_EVENT_BORDER_ZONE_SET = ecore_event_type_new();
E_EVENT_BORDER_RESIZE = ecore_event_type_new();
E_EVENT_BORDER_MOVE = ecore_event_type_new();
E_EVENT_BORDER_SHOW = ecore_event_type_new();
E_EVENT_BORDER_HIDE = ecore_event_type_new();
E_EVENT_BORDER_ICONIFY = ecore_event_type_new();
E_EVENT_BORDER_UNICONIFY = ecore_event_type_new();
2005-02-10 07:21:23 -08:00
E_EVENT_BORDER_STICK = ecore_event_type_new();
E_EVENT_BORDER_UNSTICK = ecore_event_type_new();
E_EVENT_BORDER_STACK = ecore_event_type_new();
E_EVENT_BORDER_ICON_CHANGE = ecore_event_type_new();
E_EVENT_BORDER_URGENT_CHANGE = ecore_event_type_new();
E_EVENT_BORDER_FOCUS_IN = ecore_event_type_new();
E_EVENT_BORDER_FOCUS_OUT = ecore_event_type_new();
E_EVENT_BORDER_PROPERTY = ecore_event_type_new();
2005-02-07 05:51:09 -08:00
e_init_undone();
return 1;
}
2006-01-07 02:39:46 -08:00
EAPI int
e_border_shutdown(void)
{
E_FREE_LIST(handlers, ecore_event_handler_del);
2005-02-07 05:51:09 -08:00
if (borders_hash) eina_hash_free(borders_hash);
borders_hash = NULL;
return 1;
}
2006-01-07 02:39:46 -08:00
EAPI E_Border *
e_border_new(E_Container *con, Ecore_X_Window win, int first_map, int internal)
{
E_Border *bd, *bd2;
Ecore_X_Window_Attributes *att;
unsigned int managed, desk[2];
int deskx, desky;
2005-02-07 05:51:09 -08:00
bd = E_OBJECT_ALLOC(E_Border, E_BORDER_TYPE, _e_border_free);
if (!bd) return NULL;
ecore_x_window_shadow_tree_flush();
e_object_del_func_set(E_OBJECT(bd), E_OBJECT_CLEANUP_FUNC(_e_border_del));
2005-02-07 05:51:09 -08:00
bd->w = 1;
bd->h = 1;
/* FIXME: ewww - round trip */
bd->client.argb = ecore_x_window_argb_get(win);
if (bd->client.argb)
bd->win = ecore_x_window_manager_argb_new(con->win, 0, 0, bd->w, bd->h);
else
{
bd->win = ecore_x_window_override_new(con->win, 0, 0, bd->w, bd->h);
ecore_x_window_shape_events_select(bd->win, 1);
}
e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
e_focus_setup(bd);
bd->bg_ecore_evas = e_canvas_new(e_config->evas_engine_borders, bd->win,
0, 0, bd->w, bd->h, 1, 0,
&(bd->bg_win));
e_canvas_add(bd->bg_ecore_evas);
bd->event_win = ecore_x_window_input_new(bd->win, 0, 0, bd->w, bd->h);
bd->bg_evas = ecore_evas_get(bd->bg_ecore_evas);
ecore_x_window_shape_events_select(bd->bg_win, 1);
ecore_evas_name_class_set(bd->bg_ecore_evas, "E", "Frame_Window");
ecore_evas_title_set(bd->bg_ecore_evas, "Enlightenment Frame");
if (bd->client.argb)
bd->client.shell_win = ecore_x_window_manager_argb_new(bd->win, 0, 0, 1, 1);
else
bd->client.shell_win = ecore_x_window_override_new(bd->win, 0, 0, 1, 1);
ecore_x_window_container_manage(bd->client.shell_win);
if (!internal) ecore_x_window_client_manage(win);
/* FIXME: Round trip. XCB */
2005-01-06 01:08:20 -08:00
/* fetch needed to avoid grabbing the server as window may vanish */
att = &bd->client.initial_attributes;
if ((!ecore_x_window_attributes_get(win, att)) || (att->input_only))
{
2005-05-26 05:38:53 -07:00
// printf("##- ATTR FETCH FAILED/INPUT ONLY FOR 0x%x - ABORT MANAGE\n", win);
e_canvas_del(bd->bg_ecore_evas);
ecore_evas_free(bd->bg_ecore_evas);
ecore_x_window_free(bd->client.shell_win);
e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
ecore_x_window_free(bd->win);
free(bd);
return NULL;
}
/* printf("##- ON MAP CLIENT 0x%x SIZE %ix%i %i:%i\n",
* bd->client.win, bd->client.w, bd->client.h, att->x, att->y); */
/* FIXME: if first_map is 1 then we should ignore the first hide event
* or ensure the window is alreayd hidden and events flushed before we
* create a border for it */
if (first_map)
{
// printf("##- FIRST MAP\n");
bd->x = att->x;
bd->y = att->y;
bd->changes.pos = 1;
bd->re_manage = 1;
// needed to be 1 for internal windw and on restart.
// bd->ignore_first_unmap = 2;
}
bd->client.win = win;
bd->zone = e_zone_current_get(con);
_e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd);
bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd));
bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd));
bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_cb_mouse_down, bd));
bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, _e_border_cb_mouse_up, bd));
bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE, _e_border_cb_mouse_move, bd));
bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_EVENT_MOUSE_WHEEL, _e_border_cb_mouse_wheel, bd));
2005-02-07 05:51:09 -08:00
bd->client.icccm.title = NULL;
bd->client.icccm.name = NULL;
bd->client.icccm.class = NULL;
bd->client.icccm.icon_name = NULL;
bd->client.icccm.machine = NULL;
bd->client.icccm.min_w = 1;
bd->client.icccm.min_h = 1;
bd->client.icccm.max_w = 32767;
bd->client.icccm.max_h = 32767;
bd->client.icccm.base_w = 0;
bd->client.icccm.base_h = 0;
bd->client.icccm.step_w = -1;
bd->client.icccm.step_h = -1;
bd->client.icccm.min_aspect = 0.0;
bd->client.icccm.max_aspect = 0.0;
bd->client.icccm.accepts_focus = 1;
2005-02-07 05:51:09 -08:00
bd->client.netwm.pid = 0;
bd->client.netwm.name = NULL;
bd->client.netwm.icon_name = NULL;
bd->client.netwm.desktop = 0;
bd->client.netwm.state.modal = 0;
bd->client.netwm.state.sticky = 0;
bd->client.netwm.state.shaded = 0;
bd->client.netwm.state.hidden = 0;
bd->client.netwm.state.maximized_v = 0;
bd->client.netwm.state.maximized_h = 0;
bd->client.netwm.state.skip_taskbar = 0;
bd->client.netwm.state.skip_pager = 0;
bd->client.netwm.state.fullscreen = 0;
bd->client.netwm.state.stacking = E_STACKING_NONE;
bd->client.netwm.action.move = 0;
bd->client.netwm.action.resize = 0;
bd->client.netwm.action.minimize = 0;
bd->client.netwm.action.shade = 0;
bd->client.netwm.action.stick = 0;
bd->client.netwm.action.maximized_h = 0;
bd->client.netwm.action.maximized_v = 0;
bd->client.netwm.action.fullscreen = 0;
bd->client.netwm.action.change_desktop = 0;
bd->client.netwm.action.close = 0;
bd->client.netwm.type = ECORE_X_WINDOW_TYPE_UNKNOWN;
{
int at_num = 0, i;
Ecore_X_Atom *atoms;
atoms = ecore_x_window_prop_list(bd->client.win, &at_num);
bd->client.icccm.fetch.command = 1;
if (atoms)
{
/* icccm */
for (i = 0; i < at_num; i++)
{
if (atoms[i] == ECORE_X_ATOM_WM_NAME)
bd->client.icccm.fetch.title = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_CLASS)
bd->client.icccm.fetch.name_class = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_ICON_NAME)
bd->client.icccm.fetch.icon_name = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_MACHINE)
bd->client.icccm.fetch.machine = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_HINTS)
bd->client.icccm.fetch.hints = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_NORMAL_HINTS)
bd->client.icccm.fetch.size_pos_hints = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_PROTOCOLS)
bd->client.icccm.fetch.protocol = 1;
else if (atoms[i] == ECORE_X_ATOM_MOTIF_WM_HINTS)
bd->client.mwm.fetch.hints = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_TRANSIENT_FOR)
{
bd->client.icccm.fetch.transient_for = 1;
bd->client.netwm.fetch.type = 1;
}
else if (atoms[i] == ECORE_X_ATOM_WM_CLIENT_LEADER)
bd->client.icccm.fetch.client_leader = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_WINDOW_ROLE)
bd->client.icccm.fetch.window_role = 1;
else if (atoms[i] == ECORE_X_ATOM_WM_STATE)
bd->client.icccm.fetch.state = 1;
}
/* netwm, loop again, netwm will ignore some icccm, so we
* have to be sure that netwm is checked after */
for (i = 0; i < at_num; i++)
{
if (atoms[i] == ECORE_X_ATOM_NET_WM_NAME)
{
/* Ignore icccm */
bd->client.icccm.fetch.title = 0;
bd->client.netwm.fetch.name = 1;
}
else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON_NAME)
{
/* Ignore icccm */
bd->client.icccm.fetch.icon_name = 0;
bd->client.netwm.fetch.icon_name = 1;
}
else if (atoms[i] == ECORE_X_ATOM_NET_WM_ICON)
{
bd->client.netwm.fetch.icon = 1;
}
2005-06-03 05:23:34 -07:00
else if (atoms[i] == ECORE_X_ATOM_NET_WM_USER_TIME)
{
bd->client.netwm.fetch.user_time = 1;
}
else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT)
{
printf("ECORE_X_ATOM_NET_WM_STRUT\n");
2005-06-03 05:23:34 -07:00
bd->client.netwm.fetch.strut = 1;
}
else if (atoms[i] == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
{
printf("ECORE_X_ATOM_NET_WM_STRUT_PARTIAL\n");
2005-06-03 05:23:34 -07:00
bd->client.netwm.fetch.strut = 1;
}
else if (atoms[i] == ECORE_X_ATOM_NET_WM_WINDOW_TYPE)
{
/* Ignore mwm
bd->client.mwm.fetch.hints = 0;
*/
bd->client.netwm.fetch.type = 1;
}
else if (atoms[i] == ECORE_X_ATOM_NET_WM_STATE)
{
bd->client.netwm.fetch.state = 1;
}
}
2008-07-16 10:06:23 -07:00
/* other misc atoms */
for (i = 0; i < at_num; i++)
{
2008-07-16 10:06:23 -07:00
/* loop to check for own atoms */
if (atoms[i] == E_ATOM_WINDOW_STATE)
{
bd->client.e.fetch.state = 1;
}
2008-07-16 10:06:23 -07:00
/* loop to check for qtopia atoms */
if (atoms[i] == _QTOPIA_SOFT_MENU)
bd->client.qtopia.fetch.soft_menu = 1;
else if (atoms[i] == _QTOPIA_SOFT_MENUS)
bd->client.qtopia.fetch.soft_menus = 1;
2008-07-16 10:06:23 -07:00
/* loop to check for vkbd atoms */
else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
2008-07-16 10:06:23 -07:00
bd->client.vkbd.fetch.state = 1;
else if (atoms[i] == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
2008-07-16 10:06:23 -07:00
bd->client.vkbd.fetch.vkbd = 1;
}
free(atoms);
}
}
bd->client.border.changed = 1;
bd->client.w = att->w;
bd->client.h = att->h;
2005-02-07 05:51:09 -08:00
bd->w = bd->client.w;
bd->h = bd->client.h;
bd->resize_mode = RESIZE_NONE;
bd->layer = 100;
bd->saved.layer = bd->layer;
bd->changes.icon = 1;
bd->changes.size = 1;
bd->changes.shape = 1;
2005-01-06 01:08:20 -08:00
/* just to friggin make java happy - we're DELAYING the reparent until
* eval time...
*/
/* ecore_x_window_reparent(win, bd->client.shell_win, 0, 0); */
bd->need_reparent = 1;
ecore_x_window_border_width_set(win, 0);
2005-04-28 03:34:47 -07:00
ecore_x_window_show(bd->event_win);
ecore_x_window_show(bd->client.shell_win);
bd->shape = e_container_shape_add(con);
if (e_config->focus_setting != E_FOCUS_NONE)
bd->take_focus = 1;
bd->new_client = 1;
bd->changed = 1;
2005-02-07 05:51:09 -08:00
bd->zone = e_zone_current_get(con);
bd->desk = e_desk_current_get(bd->zone);
e_container_border_add(bd);
borders = eina_list_append(borders, bd);
bd2 = eina_hash_find(borders_hash, e_util_winid_str_get(bd->client.win));
if (bd2)
{
printf("EEEEK! 2 borders with same client window id in them! very bad!\n");
printf("optimisations failing due to bizarre client behavior. will\n");
printf("work around.\n");
printf("bd=%p, bd->references=%i, bd->deleted=%i, bd->client.win=%x\n",
bd2, bd2->e_obj_inherit.references, bd2->e_obj_inherit.deleted,
bd2->client.win);
eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd2);
eina_hash_del(borders_hash, e_util_winid_str_get(bd2->bg_win), bd2);
eina_hash_del(borders_hash, e_util_winid_str_get(bd2->win), bd2);
}
eina_hash_add(borders_hash, e_util_winid_str_get(bd->client.win), bd);
eina_hash_add(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
eina_hash_add(borders_hash, e_util_winid_str_get(bd->win), bd);
managed = 1;
ecore_x_window_prop_card32_set(win, E_ATOM_MANAGED, &managed, 1);
ecore_x_window_prop_card32_set(win, E_ATOM_CONTAINER, &bd->zone->container->num, 1);
ecore_x_window_prop_card32_set(win, E_ATOM_ZONE, &bd->zone->num, 1);
e_desk_xy_get(bd->desk, &deskx, &desky);
desk[0] = deskx;
desk[1] = desky;
ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2);
focus_stack = eina_list_append(focus_stack, bd);
bd->pointer = e_pointer_window_new(bd->win, 0);
return bd;
}
EAPI void
e_border_res_change_geometry_save(E_Border *bd)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->pre_res_change.valid) return;
bd->pre_res_change.valid = 1;
bd->pre_res_change.x = bd->x;
bd->pre_res_change.y = bd->y;
bd->pre_res_change.w = bd->w;
bd->pre_res_change.h = bd->h;
bd->pre_res_change.saved.x = bd->saved.x;
bd->pre_res_change.saved.y = bd->saved.y;
bd->pre_res_change.saved.w = bd->saved.w;
bd->pre_res_change.saved.h = bd->saved.h;
}
EAPI void
e_border_res_change_geometry_restore(E_Border *bd)
{
struct {
unsigned char valid : 1;
int x, y, w, h;
struct {
int x, y, w, h;
} saved;
} pre_res_change;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (!bd->pre_res_change.valid) return;
if (bd->new_client) return;
ecore_x_window_shadow_tree_flush();
memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change));
if (bd->fullscreen)
{
e_border_unfullscreen(bd);
e_border_fullscreen(bd, e_config->fullscreen_policy);
}
else if (bd->maximized != E_MAXIMIZE_NONE)
{
E_Maximize max;
max = bd->maximized;
e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
e_border_maximize(bd, max);
}
else
{
int x, y, w, h, zx, zy, zw, zh;
bd->saved.x = bd->pre_res_change.saved.x;
bd->saved.y = bd->pre_res_change.saved.y;
bd->saved.w = bd->pre_res_change.saved.w;
bd->saved.h = bd->pre_res_change.saved.h;
e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
if (bd->saved.w > zw)
bd->saved.w = zw;
if ((bd->saved.x + bd->saved.w) > (zx + zw))
bd->saved.x = zx + zw - bd->saved.w;
if (bd->saved.h > zh)
bd->saved.h = zh;
if ((bd->saved.y + bd->saved.h) > (zy + zh))
bd->saved.y = zy + zh - bd->saved.h;
x = bd->pre_res_change.x;
y = bd->pre_res_change.y;
w = bd->pre_res_change.w;
h = bd->pre_res_change.h;
if (w > zw)
w = zw;
if (h > zh)
h = zh;
if ((x + w) > (zx + zw))
x = zx + zw - w;
if ((y + h) > (zy + zh))
y = zy + zh - h;
e_border_move_resize(bd, x, y, w, h);
}
memcpy(&bd->pre_res_change, &pre_res_change, sizeof(pre_res_change));
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_zone_set(E_Border *bd, E_Zone *zone)
{
E_Event_Border_Zone_Set *ev;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if (bd->zone == zone) return;
if (!zone) return;
/* if the window does not lie in the new zone, move it so that it does */
if (!E_INTERSECTS(bd->x, bd->y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
{
int x, y;
/* first guess -- get offset from old zone, and apply to new zone */
x = zone->x + (bd->x - bd->zone->x);
y = zone->y + (bd->y - bd->zone->y);
/* keep window from hanging off bottom and left */
if (x + bd->w > zone->x + zone->w) x += (zone->x + zone->w) - (x + bd->w);
if (y + bd->h > zone->y + zone->h) y += (zone->y + zone->h) - (y + bd->h);
/* make sure to and left are on screen (if the window is larger than the zone, it will hang off the bottom / right) */
if (x < zone->x) x = zone->x;
if (y < zone->y) y = zone->y;
if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h))
{
/* still not in zone at all, so just move it to closest edge */
if (x < zone->x) x = zone->x;
if (x >= zone->x + zone->w) x = zone->x + zone->w - bd->w;
if (y < zone->y) y = zone->y;
if (y >= zone->y + zone->h) y = zone->y + zone->h - bd->h;
}
e_border_move(bd, x, y);
}
bd->zone = zone;
if (bd->desk->zone != bd->zone)
e_border_desk_set(bd, e_desk_current_get(bd->zone));
ev = E_NEW(E_Event_Border_Zone_Set, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_zone_set_event");
ev->zone = zone;
e_object_ref(E_OBJECT(zone));
ecore_event_add(E_EVENT_BORDER_ZONE_SET, ev, _e_border_event_border_zone_set_free, NULL);
ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_ZONE, &bd->zone->num, 1);
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_desk_set(E_Border *bd, E_Desk *desk)
{
E_Event_Border_Desk_Set *ev;
2005-02-07 05:51:09 -08:00
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
E_OBJECT_CHECK(desk);
E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE);
if (bd->desk == desk) return;
ecore_x_window_shadow_tree_flush();
bd->desk = desk;
2005-02-18 02:28:54 -08:00
e_border_zone_set(bd, desk->zone);
_e_border_hook_call(E_BORDER_HOOK_SET_DESK, bd);
2005-05-16 08:43:15 -07:00
e_hints_window_desktop_set(bd);
ev = E_NEW(E_Event_Border_Desk_Set, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_desk_set_event");
ev->desk = desk;
e_object_ref(E_OBJECT(desk));
2005-02-07 05:51:09 -08:00
ecore_event_add(E_EVENT_BORDER_DESK_SET, ev, _e_border_event_border_desk_set_free, NULL);
if ((bd->desk->visible) || (bd->sticky))
e_border_show(bd);
else
e_border_hide(bd, 1);
if (e_config->transient.desktop)
{
Eina_List *l;
E_Border *child;
EINA_LIST_FOREACH(bd->transients, l, child)
{
e_border_desk_set(child, bd->desk);
}
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_show(E_Border *bd)
{
E_Event_Border_Show *ev;
unsigned int visible;
2005-02-07 05:51:09 -08:00
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->visible) return;
ecore_x_window_shadow_tree_flush();
e_container_shape_show(bd->shape);
if (!bd->need_reparent)
ecore_x_window_show(bd->client.win);
e_hints_window_visible_set(bd);
bd->visible = 1;
bd->changes.visible = 1;
visible = 1;
ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
2005-02-07 05:51:09 -08:00
ev = E_NEW(E_Event_Border_Show, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_show_event");
ecore_event_add(E_EVENT_BORDER_SHOW, ev, _e_border_event_border_show_free, NULL);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_hide(E_Border *bd, int manage)
{
unsigned int visible;
2005-02-07 05:51:09 -08:00
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (!bd->visible) return;
ecore_x_window_shadow_tree_flush();
if (bd->moving)
2005-07-26 21:51:42 -07:00
_e_border_move_end(bd);
2005-06-23 21:10:18 -07:00
if (bd->resize_mode != RESIZE_NONE)
{
_e_border_pointer_resize_end(bd);
2005-06-23 21:10:18 -07:00
bd->resize_mode = RESIZE_NONE;
_e_border_resize_end(bd);
}
e_container_shape_hide(bd->shape);
if (!bd->iconic) e_hints_window_hidden_set(bd);
bd->visible = 0;
bd->changes.visible = 1;
if (!bd->need_reparent)
{
if (bd->focused)
{
e_border_focus_set(bd, 0, 1);
if (manage != 2)
{
if ((e_config->focus_policy == E_FOCUS_CLICK) &&
(e_config->focus_revert_on_hide_or_close))
e_desk_last_focused_focus(bd->desk);
}
}
if (manage == 1)
{
/* Make sure that this border isn't deleted */
bd->await_hide_event++;
}
if (manage != 2)
ecore_x_window_hide(bd->client.win);
}
visible = 0;
ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1);
if (!manage)
ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1);
if (!stopping)
{
E_Event_Border_Hide *ev;
ev = E_NEW(E_Event_Border_Hide, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_hide_event");
ecore_event_add(E_EVENT_BORDER_HIDE, ev, _e_border_event_border_hide_free, NULL);
}
bd->post_show = 0;
}
static void
_e_border_client_move_resize_send(E_Border *bd)
{
if (bd->internal_ecore_evas)
ecore_evas_managed_move(bd->internal_ecore_evas,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t);
ecore_x_icccm_move_resize_send(bd->client.win,
bd->x + bd->fx.x + bd->client_inset.l,
bd->y + bd->fx.y + bd->client_inset.t,
bd->client.w,
bd->client.h);
}
static void
_e_border_move_internal(E_Border *bd, int x, int y, Eina_Bool without_border)
{
E_Event_Border_Move *ev;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->fullscreen) ||
(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN) && (!e_config->allow_manip)))
return;
ecore_x_window_shadow_tree_flush();
if (bd->new_client)
{
E_Border_Pending_Move_Resize *pnd;
2005-02-07 05:51:09 -08:00
pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
if (!pnd) return;
pnd->move = 1;
pnd->x = x;
pnd->y = y;
pnd->without_border = without_border;
bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
return;
}
if (without_border)
{
x -= bd->client_inset.l;
y -= bd->client_inset.t;
}
if ((x == bd->x) && (y == bd->y)) return;
bd->maximized = 0;
bd->pre_res_change.valid = 0;
bd->x = x;
bd->y = y;
bd->changed = 1;
bd->changes.pos = 1;
#if 0
2005-06-06 08:22:05 -07:00
if (bd->client.netwm.sync.request)
{
bd->client.netwm.sync.wait++;
ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
}
#endif
_e_border_client_move_resize_send(bd);
_e_border_move_update(bd);
ev = E_NEW(E_Event_Border_Move, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
ecore_event_add(E_EVENT_BORDER_MOVE, ev, _e_border_event_border_move_free, NULL);
2005-07-31 01:33:00 -07:00
_e_border_zone_update(bd);
}
/**
* Move window to coordinates that already account border decorations.
*
* This call will consider given position already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
*
* @see e_border_move_without_border()
*/
EAPI void
e_border_move(E_Border *bd, int x, int y)
{
_e_border_move_internal(bd, x, y, 0);
}
/**
* Move window to coordinates that do not account border decorations yet.
*
* This call will consider given position does not account border
* decoration, so these values (border->client_inset) will be
* accounted automatically. This is specially useful when it is a new
* client and has not be evaluated yet, in this case
* border->client_inset will be zeroed and no information is known. It
* will mark pending requests so border will be accounted on
* evalutation phase.
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
*
* @see e_border_move()
*/
EAPI void
e_border_move_without_border(E_Border *bd, int x, int y)
{
_e_border_move_internal(bd, x, y, 1);
}
EAPI void
e_border_center(E_Border *bd)
{
int x, y, w, h;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
e_zone_useful_geometry_get(bd->zone, &x, &y, &w, &h);
e_border_move(bd, x + (w - bd->w) / 2, y + (h - bd->h) / 2);
}
EAPI void
e_border_center_pos_get(E_Border *bd, int *x, int *y)
{
int zx, zy, zw, zh;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
if (x) *x = zx + (zw - bd->w) / 2;
if (y) *y = zy + (zh - bd->h) / 2;
}
EAPI void
e_border_fx_offset(E_Border *bd, int x, int y)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((x == bd->fx.x) && (y == bd->fx.y)) return;
bd->fx.x = x;
bd->fx.y = y;
bd->changed = 1;
bd->changes.pos = 1;
_e_border_client_move_resize_send(bd);
if (bd->moving) _e_border_move_update(bd);
}
static void
_e_border_move_resize_internal(E_Border *bd, int x, int y, int w, int h, Eina_Bool without_border, Eina_Bool move)
{
E_Event_Border_Move *mev;
E_Event_Border_Resize *rev;
2005-02-07 05:51:09 -08:00
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->fullscreen) ||
(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN) && (!e_config->allow_manip)))
return;
ecore_x_window_shadow_tree_flush();
if (bd->new_client)
{
E_Border_Pending_Move_Resize *pnd;
2005-02-07 05:51:09 -08:00
pnd = E_NEW(E_Border_Pending_Move_Resize, 1);
if (!pnd) return;
pnd->resize = 1;
pnd->without_border = without_border;
if (move)
{
pnd->move = 1;
pnd->x = x;
pnd->y = y;
}
pnd->w = w;
pnd->h = h;
bd->pending_move_resize = eina_list_append(bd->pending_move_resize, pnd);
return;
}
if (without_border)
{
x -= bd->client_inset.l;
y -= bd->client_inset.t;
w += (bd->client_inset.l + bd->client_inset.r);
h += (bd->client_inset.t + bd->client_inset.b);
}
if ((!move || ((x == bd->x) && (y == bd->y))) &&
(w == bd->w) && (h == bd->h))
return;
bd->maximized = 0;
bd->pre_res_change.valid = 0;
if (move)
{
bd->changes.pos = 1;
bd->x = x;
bd->y = y;
}
bd->w = w;
bd->h = h;
bd->client.w = bd->w - (bd->client_inset.l + bd->client_inset.r);
bd->client.h = bd->h - (bd->client_inset.t + bd->client_inset.b);
bd->changes.size = 1;
bd->changed = 1;
2005-08-12 20:22:24 -07:00
if ((bd->shaped) || (bd->client.shaped))
{
bd->need_shape_merge = 1;
bd->need_shape_export = 1;
}
2005-06-06 08:22:05 -07:00
if (bd->client.netwm.sync.request)
{
bd->client.netwm.sync.wait++;
ecore_x_netwm_sync_request_send(bd->client.win, bd->client.netwm.sync.serial++);
}
_e_border_client_move_resize_send(bd);
2005-02-07 05:51:09 -08:00
_e_border_resize_update(bd);
if (move)
{
mev = E_NEW(E_Event_Border_Move, 1);
mev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event");
ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL);
}
rev = E_NEW(E_Event_Border_Resize, 1);
rev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
ecore_event_add(E_EVENT_BORDER_RESIZE, rev, _e_border_event_border_resize_free, NULL);
2005-07-31 01:33:00 -07:00
_e_border_zone_update(bd);
}
/**
* Move and resize window to values that already account border decorations.
*
* This call will consider given values already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_move_resize_without_border()
*/
EAPI void
e_border_move_resize(E_Border *bd, int x, int y, int w, int h)
{
_e_border_move_resize_internal(bd, x, y, w, h, 0, 1);
}
/**
* Move and resize window to values that do not account border decorations yet.
*
* This call will consider given values already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm x horizontal position to place window.
* @parm y vertical position to place window.
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_move_resize()
*/
EAPI void
e_border_move_resize_without_border(E_Border *bd, int x, int y, int w, int h)
{
_e_border_move_resize_internal(bd, x, y, w, h, 1, 1);
}
/**
* Resize window to values that already account border decorations.
*
* This call will consider given size already accounts border
* decorations, so it will not be considered later. This will just
* work properly with borders that have being evaluated and border
* decorations are known (border->client_inset).
*
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_resize_without_border()
*/
EAPI void
e_border_resize(E_Border *bd, int w, int h)
{
_e_border_move_resize_internal(bd, 0, 0, w, h, 0, 0);
}
/**
* Resize window to values that do not account border decorations yet.
*
* This call will consider given size does not account border
* decoration, so these values (border->client_inset) will be
* accounted automatically. This is specially useful when it is a new
* client and has not be evaluated yet, in this case
* border->client_inset will be zeroed and no information is known. It
* will mark pending requests so border will be accounted on
* evalutation phase.
*
* @parm w horizontal window size.
* @parm h vertical window size.
*
* @see e_border_resize()
*/
EAPI void
e_border_resize_without_border(E_Border *bd, int w, int h)
{
_e_border_move_resize_internal(bd, 0, 0, w, h, 1, 0);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_layer_set(E_Border *bd, int layer)
{
int raise;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
ecore_x_window_shadow_tree_flush();
raise = e_config->transient.raise;
bd->saved.layer = bd->layer;
bd->layer = layer;
if (e_config->transient.layer)
{
Eina_List *l;
E_Border *child;
/* We need to set raise to one, else the child wont
* follow to the new layer. It should be like this,
* even if the user usually doesn't want to raise
* the transients.
*/
e_config->transient.raise = 1;
EINA_LIST_FOREACH(bd->transients, l, child)
{
child->layer = layer;
}
}
e_border_raise(bd);
e_config->transient.raise = raise;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_raise(E_Border *bd)
{
E_Event_Border_Stack *ev;
E_Border *last = NULL, *child;
Eina_List *l;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
ecore_x_window_shadow_tree_flush();
if (e_config->transient.raise)
{
EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
{
/* Don't stack iconic transients. If the user wants these shown,
* thats another option.
*/
if (!child->iconic)
{
if (last)
e_border_stack_below(child, last);
else
{
E_Border *above;
/* First raise the border to find out which border we will end up above */
above = e_container_border_raise(child);
if (above)
{
/* We ended up above a border, now we must stack this border to
* generate the stacking event, and to check if this transient
* has other transients etc.
*/
e_border_stack_above(child, above);
}
else
{
/* If we didn't end up above any border, we are on the bottom! */
e_border_lower(child);
}
}
last = child;
}
}
}
ev = E_NEW(E_Event_Border_Stack, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
if (last)
{
e_container_border_stack_below(bd, last);
ev->stack = last;
e_object_ref(E_OBJECT(last));
ev->type = E_STACKING_BELOW;
}
else
{
E_Border *above;
/* If we don't have any children, raise this border */
above = e_container_border_raise(bd);
e_border_raise_latest_set(bd);
if (above)
{
/* We ended up above a border */
ev->stack = above;
e_object_ref(E_OBJECT(above));
ev->type = E_STACKING_ABOVE;
}
else
{
/* No border to raise above, same as a lower! */
ev->stack = NULL;
ev->type = E_STACKING_ABOVE;
}
}
ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_lower(E_Border *bd)
{
E_Event_Border_Stack *ev;
E_Border *last = NULL, *child;
Eina_List *l;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
ecore_x_window_shadow_tree_flush();
if (e_config->transient.lower)
{
EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
{
/* Don't stack iconic transients. If the user wants these shown,
* thats another option.
*/
if (!child->iconic)
{
if (last)
e_border_stack_below(child, last);
else
{
E_Border *below;
/* First lower the border to find out which border we will end up below */
below = e_container_border_lower(child);
if (below)
{
/* We ended up below a border, now we must stack this border to
* generate the stacking event, and to check if this transient
* has other transients etc.
*/
e_border_stack_below(child, below);
}
else
{
/* If we didn't end up below any border, we are on top! */
e_border_raise(child);
}
}
last = child;
}
}
}
ev = E_NEW(E_Event_Border_Stack, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
if (last)
{
e_container_border_stack_below(bd, last);
ev->stack = last;
e_object_ref(E_OBJECT(last));
ev->type = E_STACKING_BELOW;
}
else
{
E_Border *below;
/* If we don't have any children, lower this border */
below = e_container_border_lower(bd);
if (below)
{
/* We ended up below a border */
ev->stack = below;
e_object_ref(E_OBJECT(below));
ev->type = E_STACKING_BELOW;
}
else
{
/* No border to hide under, same as a raise! */
ev->stack = NULL;
ev->type = E_STACKING_BELOW;
}
}
ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_stack_above(E_Border *bd, E_Border *above)
{
/* TODO: Should stack above allow the border to change level */
E_Event_Border_Stack *ev;
E_Border *last = NULL, *child;
Eina_List *l;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
ecore_x_window_shadow_tree_flush();
if (e_config->transient.raise)
{
EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
{
/* Don't stack iconic transients. If the user wants these shown,
* thats another option.
*/
if (!child->iconic)
{
if (last)
e_border_stack_below(child, last);
else
e_border_stack_above(child, above);
last = child;
}
}
}
ev = E_NEW(E_Event_Border_Stack, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
if (last)
{
e_container_border_stack_below(bd, last);
ev->stack = last;
e_object_ref(E_OBJECT(last));
ev->type = E_STACKING_BELOW;
}
else
{
e_container_border_stack_above(bd, above);
ev->stack = above;
e_object_ref(E_OBJECT(above));
ev->type = E_STACKING_ABOVE;
}
ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_stack_below(E_Border *bd, E_Border *below)
{
/* TODO: Should stack below allow the border to change level */
E_Event_Border_Stack *ev;
E_Border *last = NULL, *child;
Eina_List *l;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
ecore_x_window_shadow_tree_flush();
if (e_config->transient.lower)
{
EINA_LIST_REVERSE_FOREACH(bd->transients, l, child)
{
/* Don't stack iconic transients. If the user wants these shown,
* thats another option.
*/
if (!child->iconic)
{
if (last)
e_border_stack_below(child, last);
else
e_border_stack_below(child, below);
last = child;
}
}
}
ev = E_NEW(E_Event_Border_Stack, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
if (last)
{
e_container_border_stack_below(bd, last);
ev->stack = last;
e_object_ref(E_OBJECT(last));
ev->type = E_STACKING_BELOW;
}
else
{
e_container_border_stack_below(bd, below);
ev->stack = below;
e_object_ref(E_OBJECT(below));
ev->type = E_STACKING_BELOW;
}
ecore_event_add(E_EVENT_BORDER_STACK, ev, _e_border_event_border_stack_free, NULL);
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_focus_latest_set(E_Border *bd)
{
focus_stack = eina_list_remove(focus_stack, bd);
focus_stack = eina_list_prepend(focus_stack, bd);
}
EAPI void
e_border_raise_latest_set(E_Border *bd)
{
raise_stack = eina_list_remove(raise_stack, bd);
raise_stack = eina_list_prepend(raise_stack, bd);
}
/*
* Sets the focus to the given border if necessary
* There are 3 cases of different focus_policy-configurations:
*
* - E_FOCUS_CLICK: just set the focus, the most simple one
*
* - E_FOCUS_MOUSE: focus is where the mouse is, so try to
* warp the pointer to the window. If this fails (because
* the pointer is already in the window), just set the focus.
*
* - E_FOCUS_SLOPPY: focus is where the mouse is or on the
* last window which was focused, if the mouse is on the
* desktop. So, we need to look if there is another window
* under the pointer and warp to pointer to the right
* one if so (also, we set the focus afterwards). In case
* there is no window under pointer, the pointer is on the
* desktop and so we just set the focus.
*
*
* This function is to be called when setting the focus was not
* explicitly triggered by the user (by moving the mouse or
* clicking for example), but implicitly (by closing a window,
* the last focused window should get focus).
*
*/
EAPI void
e_border_focus_set_with_pointer(E_Border *bd)
{
/* note: this is here as it seems there are enough apps that do not even
* expect us to emulate a look of focus but not actually set x input
* focus as we do - so simply abort any focuse set on such windows */
/* be strict about accepting focus hint */
if ((!bd->client.icccm.accepts_focus) &&
(!bd->client.icccm.take_focus)) return;
if (bd->lock_focus_out) return;
/* Try to grab the pointer to make sure it's not "in use" */
/*
* this causes problems as the grab can cause an in/out event (by grab) that
* normally would be like a grab from a menu or something else and e gets into
* a slef-feeding loop. sorry - can't grab :(
if (!ecore_x_pointer_grab(bd->zone->container->win))
return;
*/
if (e_config->focus_policy == E_FOCUS_SLOPPY)
{
if (e_border_under_pointer_get(bd->desk, bd))
{
if (!e_border_pointer_warp_to_center(bd))
{
e_border_focus_set(bd, 1, 1);
}
}
else
{
e_border_focus_set(bd, 1, 1);
}
}
else if (e_config->focus_policy == E_FOCUS_CLICK)
{
e_border_focus_set(bd, 1, 1);
}
else
if (!e_border_pointer_warp_to_center(bd))
{
e_border_focus_set(bd, 1, 1);
}
ecore_x_pointer_ungrab();
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_focus_set(E_Border *bd, int focus, int set)
{
int focus_changed = 0;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
/* note: this is here as it seems there are enough apps that do not even
* expect us to emulate a look of focus but not actually set x input
* focus as we do - so simply abort any focuse set on such windows */
/* be strict about accepting focus hint */
if ((!bd->client.icccm.accepts_focus) &&
(!bd->client.icccm.take_focus))
return;
if ((set) && (focus) && (bd->lock_focus_out)) return;
/* dont focus an iconified window. that's silly! */
if ((focus) && (bd->iconic))
return;
if ((bd->modal) && (bd->modal != bd))
{
e_border_focus_set(bd->modal, focus, set);
return;
}
else if ((bd->leader) && (bd->leader->modal) && (bd->leader->modal != bd))
{
e_border_focus_set(bd->leader->modal, focus, set);
return;
}
if ((focus) && (set) && (!bd->focused))
{
if ((bd->client.icccm.accepts_focus) &&
(bd->client.icccm.take_focus))
{
if ((bd->visible) && (bd->changes.visible))
{
//// e_border_focus_latest_set(bd);
bd->want_focus = 1;
bd->changed = 1;
return;
}
e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
return;
}
else if ((!bd->client.icccm.accepts_focus) &&
(bd->client.icccm.take_focus))
{
if ((bd->visible) && (bd->changes.visible))
{
//// e_border_focus_latest_set(bd);
bd->want_focus = 1;
bd->changed = 1;
return;
}
e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
return;
}
}
if ((bd->visible) && (bd->changes.visible))
{
if ((bd->want_focus) && (set) && (!focus))
bd->want_focus = 0;
}
2008-08-06 23:45:02 -07:00
if ((!bd->visible) && (focus))
2008-08-06 23:16:35 -07:00
{
//// e_border_focus_latest_set(bd);
// bd->want_focus = 1;
// bd->changed = 1;
2008-08-06 23:16:35 -07:00
return;
}
2004-11-25 07:39:11 -08:00
if ((focus) && (!bd->focused))
{
if ((bd->visible) && (bd->changes.visible))
{
//// e_border_focus_latest_set(bd);
bd->want_focus = 1;
bd->changed = 1;
return;
}
// if (bd->visible)
// {
// if (focus_track_frozen == 0)
// {
//// e_border_focus_latest_set(bd);
// }
// }
e_border_focus_latest_set(bd);
edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
2005-11-11 00:03:49 -08:00
if (bd->icon_object)
edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
e_focus_event_focus_in(bd);
}
2004-11-25 07:39:11 -08:00
else if ((!focus) && (bd->focused))
{
edje_object_signal_emit(bd->bg_object, "e,state,unfocused", "e");
2005-11-11 00:03:49 -08:00
if (bd->icon_object)
edje_object_signal_emit(bd->icon_object, "e,state,unfocused", "e");
e_focus_event_focus_out(bd);
/* FIXME: Sometimes we should leave the window fullscreen! */
// if (bd->fullscreen)
// e_border_unfullscreen(bd);
if (bd->raise_timer)
{
ecore_timer_del(bd->raise_timer);
bd->raise_timer = NULL;
}
}
if (((bd->focused) && (!focus)) || ((!bd->focused) && (focus)))
focus_changed = 1;
bd->focused = focus;
if (set)
{
if (bd->focused)
{
if (bd->internal)
e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
else
{
if ((!bd->client.icccm.accepts_focus) &&
(!bd->client.icccm.take_focus))
e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_NO_INPUT);
else if ((bd->client.icccm.accepts_focus) &&
(bd->client.icccm.take_focus))
e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_LOCALLY_ACTIVE);
else if ((!bd->client.icccm.accepts_focus) &&
(bd->client.icccm.take_focus))
e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_GLOBALLY_ACTIVE);
else if ((bd->client.icccm.accepts_focus) &&
(!bd->client.icccm.take_focus))
e_grabinput_focus(bd->client.win, E_FOCUS_METHOD_PASSIVE);
}
}
else
{
// ecore_x_window_focus(bd->zone->container->manager->root);
// ecore_x_window_focus(bd->zone->container->bg_win);
e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE);
}
}
if ((bd->focused) && (focused != bd))
2005-04-29 03:03:11 -07:00
{
if (focused)
{
if ((!e_object_is_del(E_OBJECT(focused))) &&
(e_object_ref_get(E_OBJECT(focused)) > 0))
{
E_Event_Border_Focus_Out *ev;
edje_object_signal_emit(focused->bg_object, "e,state,unfocused", "e");
if (focused->icon_object)
edje_object_signal_emit(focused->icon_object, "e,state,unfocused", "e");
e_focus_event_focus_out(focused);
ev = E_NEW(E_Event_Border_Focus_Out, 1);
ev->border = focused;
e_object_ref(E_OBJECT(focused));
ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
_e_border_event_border_focus_out_free, NULL);
/* FIXME: Sometimes we should leave the window fullscreen! */
// if (focused->fullscreen) e_border_unfullscreen(focused);
focused->focused = 0;
// e_border_focus_set(focused, 0, 0);
if (focused->raise_timer)
{
ecore_timer_del(focused->raise_timer);
focused->raise_timer = NULL;
}
focused = NULL;
}
}
e_hints_active_window_set(bd->zone->container->manager, bd);
2005-04-29 03:03:11 -07:00
}
#if 0
/* i'm pretty sure this case is handled above -- this was resulting in the "passive"
* event getting sent twice when going from a window to the desktop. --rephorm */
/*
else if ((!bd->focused) && (focused == bd))
2005-04-29 03:03:11 -07:00
{
if (focused)
{
// printf("unfocus previous 2\n");
edje_object_signal_emit(focused->bg_object, "e,state,unfocused", "e");
2005-11-11 00:03:49 -08:00
if (focused->icon_object)
edje_object_signal_emit(focused->icon_object, "e,state,unfocused", "e");
e_focus_event_focus_out(focused);
// FIXME: Sometimes we should leave the window fullscreen!
if (focused->fullscreen) e_border_unfullscreen(focused);
focused->focused = 0;
// e_border_focus_set(focused, 0, 0);
if (focused->raise_timer)
{
ecore_timer_del(focused->raise_timer);
focused->raise_timer = NULL;
}
}
e_hints_active_window_set(bd->zone->container->manager, NULL);
2005-04-29 03:03:11 -07:00
}
*/
#endif
if (focus_changed)
{
if (bd->focused)
{
E_Event_Border_Focus_In *ev;
focused = bd;
// Let send the focus event iff the focus is set explicitly,
// not via callback
ev = E_NEW(E_Event_Border_Focus_In, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev,
_e_border_event_border_focus_in_free, NULL);
}
else
{
E_Event_Border_Focus_Out *ev;
focused = NULL;
// Let send the focus event iff the focus is set explicitly,
// not via callback
ev = E_NEW(E_Event_Border_Focus_Out, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev,
_e_border_event_border_focus_out_free, NULL);
}
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_shade(E_Border *bd, E_Direction dir)
{
E_Event_Border_Resize *ev;
2005-02-07 05:51:09 -08:00
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->shaded) || (bd->shading) ||
((bd->maximized) && (!e_config->allow_manip)) ||
(bd->fullscreen)) return;
2005-10-15 21:25:57 -07:00
if ((bd->client.border.name) &&
(!strcmp("borderless", bd->client.border.name))) return;
ecore_x_window_shadow_tree_flush();
2005-02-07 05:51:09 -08:00
bd->shade.x = bd->x;
bd->shade.y = bd->y;
bd->shade.dir = dir;
2005-02-07 05:51:09 -08:00
e_hints_window_shaded_set(bd, 1);
e_hints_window_shade_direction_set(bd, dir);
if (e_config->border_shade_animate)
{
bd->shade.start = ecore_loop_time_get();
bd->shading = 1;
bd->changes.shading = 1;
bd->changed = 1;
2005-02-07 05:51:09 -08:00
if (bd->shade.dir == E_DIRECTION_UP ||
bd->shade.dir == E_DIRECTION_LEFT)
ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
else
ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
edje_object_signal_emit(bd->bg_object, "e,state,shading", "e");
}
else
{
if (bd->shade.dir == E_DIRECTION_UP)
{
bd->h = bd->client_inset.t + bd->client_inset.b;
}
else if (bd->shade.dir == E_DIRECTION_DOWN)
{
bd->h = bd->client_inset.t + bd->client_inset.b;
bd->y = bd->y + bd->client.h;
bd->changes.pos = 1;
}
else if (bd->shade.dir == E_DIRECTION_LEFT)
{
bd->w = bd->client_inset.l + bd->client_inset.r;
}
else if (bd->shade.dir == E_DIRECTION_RIGHT)
{
bd->w = bd->client_inset.l + bd->client_inset.r;
bd->x = bd->x + bd->client.w;
bd->changes.pos = 1;
}
if ((bd->shaped) || (bd->client.shaped))
{
bd->need_shape_merge = 1;
bd->need_shape_export = 1;
}
bd->changes.size = 1;
bd->shaded = 1;
bd->changes.shaded = 1;
bd->changed = 1;
if ((bd->shaped) || (bd->client.shaped))
{
bd->need_shape_merge = 1;
bd->need_shape_export = 1;
}
edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
e_border_frame_recalc(bd);
ev = E_NEW(E_Event_Border_Resize, 1);
ev->border = bd;
/* The resize is added in the animator when animation complete */
/* For non-animated, we add it immediately with the new size */
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_unshade(E_Border *bd, E_Direction dir)
{
E_Event_Border_Resize *ev;
2005-02-07 05:51:09 -08:00
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((!bd->shaded) || (bd->shading) ||
((bd->maximized) && (!e_config->allow_manip)) ||
(bd->fullscreen)) return;
ecore_x_window_shadow_tree_flush();
bd->shade.dir = dir;
2005-02-07 05:51:09 -08:00
e_hints_window_shaded_set(bd, 0);
e_hints_window_shade_direction_set(bd, dir);
if (bd->shade.dir == E_DIRECTION_UP ||
bd->shade.dir == E_DIRECTION_LEFT)
{
bd->shade.x = bd->x;
bd->shade.y = bd->y;
}
else
{
bd->shade.x = bd->x - bd->client.w;
bd->shade.y = bd->y - bd->client.h;
}
if (e_config->border_shade_animate)
{
bd->shade.start = ecore_loop_time_get();
bd->shading = 1;
bd->changes.shading = 1;
bd->changed = 1;
if (bd->shade.dir == E_DIRECTION_UP)
{
ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
ecore_x_window_move_resize(bd->client.win, 0,
bd->h - (bd->client_inset.t + bd->client_inset.b) -
bd->client.h,
bd->client.w, bd->client.h);
}
else if (bd->shade.dir == E_DIRECTION_LEFT)
{
ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_SW);
ecore_x_window_move_resize(bd->client.win,
bd->w - (bd->client_inset.l + bd->client_inset.r) -
bd->client.h,
0, bd->client.w, bd->client.h);
}
else
ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NE);
bd->shade.anim = ecore_animator_add(_e_border_shade_animator, bd);
edje_object_signal_emit(bd->bg_object, "e,state,unshading", "e");
}
else
{
if (bd->shade.dir == E_DIRECTION_UP)
{
bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
}
else if (bd->shade.dir == E_DIRECTION_DOWN)
{
bd->h = bd->client_inset.t + bd->client.h + bd->client_inset.b;
bd->y = bd->y - bd->client.h;
bd->changes.pos = 1;
}
else if (bd->shade.dir == E_DIRECTION_LEFT)
{
bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
}
else if (bd->shade.dir == E_DIRECTION_RIGHT)
{
bd->w = bd->client_inset.l + bd->client.w + bd->client_inset.r;
bd->x = bd->x - bd->client.w;
bd->changes.pos = 1;
}
if ((bd->shaped) || (bd->client.shaped))
{
bd->need_shape_merge = 1;
bd->need_shape_export = 1;
}
bd->changes.size = 1;
bd->shaded = 0;
bd->changes.shaded = 1;
bd->changed = 1;
if ((bd->shaped) || (bd->client.shaped))
{
bd->need_shape_merge = 1;
bd->need_shape_export = 1;
}
edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
e_border_frame_recalc(bd);
ev = E_NEW(E_Event_Border_Resize, 1);
ev->border = bd;
/* The resize is added in the animator when animation complete */
/* For non-animated, we add it immediately with the new size */
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_maximize(E_Border *bd, E_Maximize max)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2005-02-07 05:51:09 -08:00
if (!(max & E_MAXIMIZE_DIRECTION)) max |= E_MAXIMIZE_BOTH;
if ((bd->shaded) || (bd->shading)) return;
ecore_x_window_shadow_tree_flush();
if (bd->fullscreen)
e_border_unfullscreen(bd);
/* Only allow changes in vertical/ horizontal maximization */
if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) ||
((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return;
if (bd->new_client)
{
bd->need_maximize = 1;
bd->maximized &= ~E_MAXIMIZE_TYPE;
bd->maximized |= max;
return;
}
{
int x1, y1, x2, y2;
int w, h, pw, ph;
bd->pre_res_change.valid = 0;
if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL))
{
/* Horisontal hasn't been set */
bd->saved.x = bd->x - bd->zone->x;
bd->saved.w = bd->w;
}
if (!(bd->maximized & E_MAXIMIZE_VERTICAL))
{
/* Vertical hasn't been set */
bd->saved.y = bd->y - bd->zone->y;
bd->saved.h = bd->h;
}
bd->saved.zone = bd->zone->num;
2005-08-10 21:44:08 -07:00
e_hints_window_size_set(bd);
e_border_raise(bd);
switch (max & E_MAXIMIZE_TYPE)
2005-06-16 15:23:25 -07:00
{
case E_MAXIMIZE_NONE:
/* Ignore */
max = E_MAXIMIZE_NONE;
break;
case E_MAXIMIZE_FULLSCREEN:
if (bd->bg_object)
{
Evas_Coord cx, cy, cw, ch;
edje_object_message_signal_process(bd->bg_object);
edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
edje_object_message_signal_process(bd->bg_object);
evas_object_resize(bd->bg_object, 1000, 1000);
edje_object_calc_force(bd->bg_object);
edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
bd->client_inset.l = cx;
bd->client_inset.r = 1000 - (cx + cw);
bd->client_inset.t = cy;
bd->client_inset.b = 1000 - (cy + ch);
ecore_x_netwm_frame_size_set(bd->client.win,
bd->client_inset.l, bd->client_inset.r,
bd->client_inset.t, bd->client_inset.b);
ecore_x_e_frame_size_set(bd->client.win,
bd->client_inset.l, bd->client_inset.r,
bd->client_inset.t, bd->client_inset.b);
}
w = bd->zone->w;
h = bd->zone->h;
e_border_resize_limit(bd, &w, &h);
/* center x-direction */
x1 = bd->zone->x + (bd->zone->w - w) / 2;
/* center y-direction */
y1 = bd->zone->y + (bd->zone->h - h) / 2;
if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
e_border_move_resize(bd, x1, y1, w, h);
else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
e_border_move_resize(bd, bd->x, y1, bd->w, h);
else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
e_border_move_resize(bd, x1, bd->y, w, bd->h);
break;
case E_MAXIMIZE_SMART:
case E_MAXIMIZE_EXPAND:
x1 = bd->zone->x;
y1 = bd->zone->y;
x2 = bd->zone->x + bd->zone->w;
y2 = bd->zone->y + bd->zone->h;
/* walk through all shelves */
e_maximize_border_shelf_fit(bd, &x1, &y1, &x2, &y2, max);
/* walk through docks and toolbars */
e_maximize_border_dock_fit(bd, &x1, &y1, &x2, &y2);
w = x2 - x1;
h = y2 - y1;
pw = w;
ph = h;
e_border_resize_limit(bd, &w, &h);
/* center x-direction */
x1 = x1 + (pw - w) / 2;
/* center y-direction */
y1 = y1 + (ph - h) / 2;
if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
e_border_move_resize(bd, x1, y1, w, h);
else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
e_border_move_resize(bd, bd->x, y1, bd->w, h);
else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
e_border_move_resize(bd, x1, bd->y, w, bd->h);
edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
break;
case E_MAXIMIZE_FILL:
x1 = bd->zone->x;
y1 = bd->zone->y;
x2 = bd->zone->x + bd->zone->w;
y2 = bd->zone->y + bd->zone->h;
/* walk through all shelves */
e_maximize_border_shelf_fill(bd, &x1, &y1, &x2, &y2, max);
/* walk through all windows */
e_maximize_border_border_fill(bd, &x1, &y1, &x2, &y2, max);
w = x2 - x1;
h = y2 - y1;
pw = w;
ph = h;
e_border_resize_limit(bd, &w, &h);
/* center x-direction */
x1 = x1 + (pw - w) / 2;
/* center y-direction */
y1 = y1 + (ph - h) / 2;
if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)
e_border_move_resize(bd, x1, y1, w, h);
else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_VERTICAL)
e_border_move_resize(bd, bd->x, y1, bd->w, h);
else if ((max & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_HORIZONTAL)
e_border_move_resize(bd, x1, bd->y, w, bd->h);
break;
2005-06-16 15:23:25 -07:00
}
/* Remove previous type */
bd->maximized &= ~E_MAXIMIZE_TYPE;
/* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */
bd->maximized |= max;
e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
bd->maximized & E_MAXIMIZE_VERTICAL);
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_unmaximize(E_Border *bd, E_Maximize max)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (!(max & E_MAXIMIZE_DIRECTION))
{
printf("BUG: Unmaximize call without direction!\n");
return;
}
if ((bd->shaded) || (bd->shading)) return;
ecore_x_window_shadow_tree_flush();
/* Remove directions not used */
max &= (bd->maximized & E_MAXIMIZE_DIRECTION);
/* Can only remove existing maximization directions */
if (!max) return;
if (bd->maximized & E_MAXIMIZE_TYPE)
{
bd->pre_res_change.valid = 0;
bd->need_maximize = 0;
if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
{
if (bd->bg_object)
{
Evas_Coord cx, cy, cw, ch;
edje_object_message_signal_process(bd->bg_object);
edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e");
edje_object_message_signal_process(bd->bg_object);
evas_object_resize(bd->bg_object, 1000, 1000);
edje_object_calc_force(bd->bg_object);
edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
bd->client_inset.l = cx;
bd->client_inset.r = 1000 - (cx + cw);
bd->client_inset.t = cy;
bd->client_inset.b = 1000 - (cy + ch);
ecore_x_netwm_frame_size_set(bd->client.win,
bd->client_inset.l, bd->client_inset.r,
bd->client_inset.t, bd->client_inset.b);
ecore_x_e_frame_size_set(bd->client.win,
bd->client_inset.l, bd->client_inset.r,
bd->client_inset.t, bd->client_inset.b);
}
bd->maximized = E_MAXIMIZE_NONE;
e_border_move_resize(bd, bd->zone->x + bd->saved.x, bd->zone->y + bd->saved.y, bd->saved.w, bd->saved.h);
bd->saved.x = bd->saved.y = bd->saved.w = bd->saved.h = 0;
e_hints_window_size_unset(bd);
}
else
{
int w, h, x, y;
w = bd->w;
h = bd->h;
x = bd->x;
y = bd->y;
if (max & E_MAXIMIZE_VERTICAL)
{
/* Remove vertical */
h = bd->saved.h;
y = bd->saved.y + bd->zone->y;
bd->saved.h = bd->saved.y = 0;
bd->maximized &= ~E_MAXIMIZE_VERTICAL;
}
if (max & E_MAXIMIZE_HORIZONTAL)
{
/* Remove horizontal */
w = bd->saved.w;
x = bd->saved.x + bd->zone->x;
bd->saved.w = bd->saved.x = 0;
bd->maximized &= ~E_MAXIMIZE_HORIZONTAL;
}
e_border_resize_limit(bd, &w, &h);
e_border_move_resize(bd, x, y, w, h);
if (!(bd->maximized & E_MAXIMIZE_DIRECTION))
{
bd->maximized = E_MAXIMIZE_NONE;
e_hints_window_size_unset(bd);
edje_object_signal_emit(bd->bg_object, "e,action,unmaximize", "e");
}
else
e_hints_window_size_set(bd);
}
e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL,
bd->maximized & E_MAXIMIZE_VERTICAL);
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_fullscreen(E_Border *bd, E_Fullscreen policy)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->shaded) || (bd->shading)) return;
ecore_x_window_shadow_tree_flush();
if (bd->maximized)
e_border_unmaximize(bd, E_MAXIMIZE_BOTH);
if (bd->new_client)
{
bd->need_fullscreen = 1;
return;
}
if (!bd->fullscreen)
{
bd->pre_res_change.valid = 0;
bd->saved.x = bd->x - bd->zone->x;
bd->saved.y = bd->y - bd->zone->y;
bd->saved.w = bd->client.w;
bd->saved.h = bd->client.h;
bd->saved.zone = bd->zone->num;
2005-08-10 21:44:08 -07:00
e_hints_window_size_set(bd);
bd->client_inset.l = 0;
bd->client_inset.r = 0;
bd->client_inset.t = 0;
bd->client_inset.b = 0;
bd->desk->fullscreen_borders++;
/* e_zone_fullscreen_set(bd->zone, 1); */
if (!e_config->allow_above_fullscreen)
e_border_layer_set(bd, 200);
if ((eina_list_count(bd->zone->container->zones) > 1) || (policy == E_FULLSCREEN_RESIZE) || (!ecore_x_randr_query()))
{
e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
}
else if (policy == E_FULLSCREEN_ZOOM)
{
Ecore_X_Screen_Size *sizes;
int num_sizes, i;
screen_size = ecore_x_randr_current_screen_size_get(bd->zone->container->manager->root);
sizes = ecore_x_randr_screen_sizes_get(bd->zone->container->manager->root, &num_sizes);
if (sizes)
{
Ecore_X_Screen_Size best_size = { -1, -1 };
int best_dist = INT_MAX, dist;
for (i = 0; i < num_sizes; i++)
{
if ((sizes[i].width > bd->w) && (sizes[i].height > bd->h))
{
dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h);
if (dist < best_dist)
{
best_size = sizes[i];
best_dist = dist;
}
}
}
if (((best_size.width != -1) && (best_size.height != -1)) &&
((best_size.width != screen_size.width) ||
(best_size.height != screen_size.height)))
{
ecore_x_randr_screen_size_set(bd->zone->container->manager->root,
best_size);
e_border_move_resize(bd, 0, 0, best_size.width, best_size.height);
}
else
{
screen_size.width = -1;
screen_size.height = -1;
e_border_move_resize(bd, 0, 0, bd->zone->w, bd->zone->h);
}
free(sizes);
}
else
e_border_move_resize(bd, bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h);
}
bd->fullscreen = 1;
e_hints_window_fullscreen_set(bd, 1);
2005-08-10 21:44:08 -07:00
e_hints_window_size_unset(bd);
bd->client.border.changed = 1;
bd->changed = 1;
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_unfullscreen(E_Border *bd)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->shaded) || (bd->shading)) return;
ecore_x_window_shadow_tree_flush();
if (bd->fullscreen)
{
bd->pre_res_change.valid = 0;
bd->fullscreen = 0;
bd->need_fullscreen = 0;
bd->desk->fullscreen_borders--;
if ((screen_size.width != -1) && (screen_size.height != -1))
{
ecore_x_randr_screen_size_set(bd->zone->container->manager->root, screen_size);
screen_size.width = -1;
screen_size.height = -1;
}
e_border_move_resize(bd,
bd->saved.x + bd->zone->x,
bd->saved.y + bd->zone->y,
bd->saved.w, bd->saved.h);
e_border_layer_set(bd, bd->saved.layer);
e_hints_window_fullscreen_set(bd, 0);
bd->client.border.changed = 1;
bd->changed = 1;
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_iconify(E_Border *bd)
{
E_Event_Border_Iconify *ev;
unsigned int iconic;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->fullscreen) || (bd->shading)) return;
ecore_x_window_shadow_tree_flush();
if (!bd->iconic)
{
bd->iconic = 1;
e_border_hide(bd, 1);
edje_object_signal_emit(bd->bg_object, "e,action,iconify", "e");
}
iconic = 1;
e_hints_window_iconic_set(bd);
ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
ev = E_NEW(E_Event_Border_Iconify, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_iconify_event");
ecore_event_add(E_EVENT_BORDER_ICONIFY, ev, _e_border_event_border_iconify_free, NULL);
if (e_config->transient.iconify)
{
Eina_List *l;
E_Border *child;
EINA_LIST_FOREACH(bd->transients, l, child)
{
e_border_iconify(child);
}
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_uniconify(E_Border *bd)
{
E_Desk *desk;
E_Event_Border_Uniconify *ev;
unsigned int iconic;
2005-02-07 05:51:09 -08:00
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->fullscreen) || (bd->shading)) return;
ecore_x_window_shadow_tree_flush();
if (bd->iconic)
{
bd->iconic = 0;
desk = e_desk_current_get(bd->desk->zone);
2005-02-18 02:28:54 -08:00
e_border_desk_set(bd, desk);
e_border_show(bd);
e_border_raise(bd);
edje_object_signal_emit(bd->bg_object, "e,action,uniconify", "e");
}
iconic = 0;
ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &iconic, 1);
ev = E_NEW(E_Event_Border_Uniconify, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_uniconify_event");
ecore_event_add(E_EVENT_BORDER_UNICONIFY, ev, _e_border_event_border_uniconify_free, NULL);
if (e_config->transient.iconify)
{
Eina_List *l;
E_Border *child;
EINA_LIST_FOREACH(bd->transients, l, child)
{
e_border_uniconify(child);
}
}
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_stick(E_Border *bd)
{
2005-02-10 07:21:23 -08:00
E_Event_Border_Stick *ev;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2005-05-25 03:09:34 -07:00
if (bd->sticky) return;
bd->sticky = 1;
e_hints_window_sticky_set(bd, 1);
e_border_show(bd);
2005-02-10 07:21:23 -08:00
if (e_config->transient.desktop)
{
Eina_List *l;
E_Border *child;
EINA_LIST_FOREACH(bd->transients, l, child)
{
child->sticky = 1;
e_hints_window_sticky_set(child, 1);
e_border_show(child);
}
}
edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
2005-02-10 07:21:23 -08:00
ev = E_NEW(E_Event_Border_Stick, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_stick_event");
2005-02-10 07:21:23 -08:00
ecore_event_add(E_EVENT_BORDER_STICK, ev, _e_border_event_border_stick_free, NULL);
e_remember_update(bd);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_unstick(E_Border *bd)
{
2005-02-10 07:21:23 -08:00
E_Event_Border_Unstick *ev;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
2005-03-07 04:42:31 -08:00
/* Set the desk before we unstick the border */
2005-05-25 03:09:34 -07:00
if (!bd->sticky) return;
bd->sticky = 0;
e_hints_window_sticky_set(bd, 0);
2005-02-10 07:21:23 -08:00
if (e_config->transient.desktop)
{
Eina_List *l;
E_Border *child;
EINA_LIST_FOREACH(bd->transients, l, child)
{
child->sticky = 0;
e_hints_window_sticky_set(child, 0);
}
}
edje_object_signal_emit(bd->bg_object, "e,state,unsticky", "e");
2005-02-10 07:21:23 -08:00
ev = E_NEW(E_Event_Border_Unstick, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_unstick_event");
2005-02-10 07:21:23 -08:00
ecore_event_add(E_EVENT_BORDER_UNSTICK, ev, _e_border_event_border_unstick_free, NULL);
e_border_desk_set(bd, e_desk_current_get(bd->zone));
e_remember_update(bd);
}
EAPI void
e_border_pinned_set(E_Border *bd, int set)
{
int layer;
int stacking;
if (bd)
{
bd->borderless = set;
bd->user_skip_winlist = set;
if (set)
{
layer = 50;
stacking = E_STACKING_BELOW;
}
else
{
layer = 100;
stacking = E_STACKING_NONE;
}
e_border_layer_set(bd, layer);
e_hints_window_stacking_set(bd, stacking);
bd->client.border.changed = 1;
bd->changed = 1;
}
}
2006-01-07 02:39:46 -08:00
EAPI E_Border *
e_border_find_by_client_window(Ecore_X_Window win)
{
E_Border *bd;
bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
(bd->client.win == win))
return bd;
return NULL;
}
EAPI E_Border *
e_border_find_all_by_client_window(Ecore_X_Window win)
{
E_Border *bd;
bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
if ((bd) && (bd->client.win == win))
return bd;
return NULL;
}
2006-01-07 02:39:46 -08:00
EAPI E_Border *
e_border_find_by_frame_window(Ecore_X_Window win)
{
E_Border *bd;
bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
(bd->bg_win == win))
return bd;
return NULL;
}
2006-01-07 02:39:46 -08:00
EAPI E_Border *
e_border_find_by_window(Ecore_X_Window win)
{
E_Border *bd;
bd = eina_hash_find(borders_hash, e_util_winid_str_get(win));
if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
(bd->win == win))
return bd;
return NULL;
}
2006-01-07 02:39:46 -08:00
EAPI E_Border *
2005-06-06 08:22:05 -07:00
e_border_find_by_alarm(Ecore_X_Sync_Alarm alarm)
{
Eina_List *l;
E_Border *bd;
EINA_LIST_FOREACH(borders, l, bd)
2005-06-06 08:22:05 -07:00
{
if ((bd) && (!e_object_is_del(E_OBJECT(bd))) &&
(bd->client.netwm.sync.alarm == alarm))
return bd;
}
return NULL;
}
2006-01-07 02:39:46 -08:00
EAPI E_Border *
e_border_focused_get(void)
{
return focused;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_idler_before(void)
{
Eina_List *ml, *cl;
E_Manager *man;
E_Container *con;
if (!borders)
return;
EINA_LIST_FOREACH(e_manager_list(), ml, man)
{
EINA_LIST_FOREACH(man->containers, cl, con)
{
E_Border_List *bl;
E_Border *bd;
// pass 1 - eval0. fetch properties on new or on change and
// call hooks to decide what to do - maybe move/resize
bl = e_container_border_list_last(con);
while ((bd = e_container_border_list_prev(bl)))
{
if (bd->changed) _e_border_eval0(bd);
}
e_container_border_list_free(bl);
// layout hook - this is where a hook gets to figure out what to
// do if anything.
_e_border_container_layout_hook(con);
// pass 2 - show windows needing show
bl = e_container_border_list_last(con);
while ((bd = e_container_border_list_prev(bl)))
{
if ((bd->changes.visible) && (bd->visible) &&
(!bd->new_client) && (!bd->changes.pos) &&
(!bd->changes.size))
{
ecore_evas_show(bd->bg_ecore_evas);
if ((1) &&
((bd->changes.pos && !bd->changes.size) ||
(!bd->changes.pos && bd->changes.size) ||
(bd->post_job)))
{
bd->post_show = 1;
}
else
{
ecore_x_window_show(bd->win);
}
bd->changes.visible = 0;
}
}
e_container_border_list_free(bl);
// pass 3 - hide windows needing hide and eval (main eval)
bl = e_container_border_list_first(con);
while ((bd = e_container_border_list_next(bl)))
{
if (e_object_is_del(E_OBJECT(bd))) continue;
if ((bd->changes.visible) && (!bd->visible))
{
ecore_x_window_hide(bd->win);
ecore_evas_hide(bd->bg_ecore_evas);
bd->changes.visible = 0;
}
if (bd->changed) _e_border_eval(bd);
if ((bd->changes.visible) && (bd->visible) &&
(!bd->new_client))
{
ecore_evas_show(bd->bg_ecore_evas);
if ((1) &&
((bd->changes.pos && !bd->changes.size) ||
(!bd->changes.pos && bd->changes.size) ||
(bd->post_job)))
{
bd->post_show = 1;
}
else
{
ecore_x_window_show(bd->win);
}
bd->changes.visible = 0;
}
}
e_container_border_list_free(bl);
}
}
}
EAPI Eina_List *
e_border_client_list()
{
/* FIXME: This should be a somewhat ordered list */
return borders;
}
static Ecore_X_Window action_input_win = 0;
static E_Border *action_border = NULL;
static Ecore_Event_Handler *action_handler_key = NULL;
static Ecore_Event_Handler *action_handler_mouse = NULL;
static Ecore_Timer *action_timer = NULL;
static Ecore_X_Rectangle action_orig;
static int
_e_border_action_input_win_del(void)
{
if (!action_input_win)
return 0;
e_grabinput_release(action_input_win, action_input_win);
ecore_x_window_free(action_input_win);
action_input_win = 0;
return 1;
}
static int
_e_border_action_input_win_new(E_Border *bd)
{
if (!action_input_win)
{
Ecore_X_Window parent = bd->zone->container->win;
action_input_win = ecore_x_window_input_new(parent, 0, 0, 1, 1);
if (!action_input_win)
return 0;
}
ecore_x_window_show(action_input_win);
if (e_grabinput_get(action_input_win, 0, action_input_win))
return 1;
_e_border_action_input_win_del();
return 0;
}
static void
_e_border_action_finish(void)
{
_e_border_action_input_win_del();
if (action_timer)
{
ecore_timer_del(action_timer);
action_timer = NULL;
}
if (action_handler_key)
{
ecore_event_handler_del(action_handler_key);
action_handler_key = NULL;
}
if (action_handler_mouse)
{
ecore_event_handler_del(action_handler_mouse);
action_handler_mouse = NULL;
}
action_border = NULL;
}
static void
_e_border_action_init(E_Border *bd)
{
action_orig.x = bd->x;
action_orig.y = bd->y;
action_orig.width = bd->w;
action_orig.height = bd->h;
action_border = bd;
}
static void
_e_border_action_restore_orig(E_Border *bd)
{
if (action_border != bd)
return;
e_border_move_resize(bd, action_orig.x, action_orig.y, action_orig.width, action_orig.height);
}
static int
_e_border_key_down_modifier_apply(int modifier, int value)
{
if (modifier & ECORE_EVENT_MODIFIER_CTRL)
return value * 2;
else if (modifier & ECORE_EVENT_MODIFIER_ALT)
{
value /= 2;
if (value)
return value;
else
return 1;
}
return value;
}
static int
_e_border_action_move_timeout(void *data)
{
_e_border_move_end(action_border);
_e_border_action_finish();
return 0;
}
static void
_e_border_action_move_timeout_add(void)
{
if (action_timer)
ecore_timer_del(action_timer);
action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_move_timeout, NULL);
}
static int
_e_border_move_key_down(void *data, int type, void *event)
{
Ecore_Event_Key *ev = event;
int x, y;
if (ev->event_window != action_input_win)
return 1;
if (!action_border)
{
fputs("ERROR: no action_border!\n", stderr);
goto stop;
}
x = action_border->x;
y = action_border->y;
if (strcmp(ev->key, "Up") == 0)
y -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
else if (strcmp(ev->key, "Down") == 0)
y += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dy);
else if (strcmp(ev->key, "Left") == 0)
x -= _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
else if (strcmp(ev->key, "Right") == 0)
x += _e_border_key_down_modifier_apply(ev->modifiers, e_config->border_keyboard.move.dx);
else if (strcmp(ev->key, "Return") == 0)
goto stop;
else if (strcmp(ev->key, "Escape") == 0)
{
_e_border_action_restore_orig(action_border);
goto stop;
}
else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
(strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
goto stop;
e_border_move(action_border, x, y);
_e_border_action_move_timeout_add();
return 1;
stop:
_e_border_move_end(action_border);
_e_border_action_finish();
return 0;
}
static int
_e_border_move_mouse_down(void *data, int type, void *event)
{
Ecore_Event_Mouse_Button *ev = event;
if (ev->event_window != action_input_win)
return 1;
if (!action_border)
fputs("ERROR: no action_border!\n", stderr);
_e_border_move_end(action_border);
_e_border_action_finish();
return 0;
}
EAPI void
e_border_act_move_keyboard(E_Border *bd)
{
if (!bd)
return;
if (!_e_border_move_begin(bd))
return;
if (!_e_border_action_input_win_new(bd))
{
_e_border_move_end(bd);
return;
}
_e_border_action_init(bd);
_e_border_action_move_timeout_add();
_e_border_move_update(bd);
if (action_handler_key)
ecore_event_handler_del(action_handler_key);
action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_move_key_down, NULL);
if (action_handler_mouse)
ecore_event_handler_del(action_handler_mouse);
action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_move_mouse_down, NULL);
}
static int
_e_border_action_resize_timeout(void *data)
{
_e_border_resize_end(action_border);
_e_border_action_finish();
return 0;
}
static void
_e_border_action_resize_timeout_add(void)
{
if (action_timer)
ecore_timer_del(action_timer);
action_timer = ecore_timer_add(e_config->border_keyboard.timeout, _e_border_action_resize_timeout, NULL);
}
static int
_e_border_resize_key_down(void *data, int type, void *event)
{
Ecore_Event_Key *ev = event;
int w, h, dx, dy;
if (ev->event_window != action_input_win)
return 1;
if (!action_border)
{
fputs("ERROR: no action_border!\n", stderr);
goto stop;
}
w = action_border->w;
h = action_border->h;
dx = e_config->border_keyboard.resize.dx;
if (dx < action_border->client.icccm.step_w)
dx = action_border->client.icccm.step_w;
dy = e_config->border_keyboard.resize.dy;
if (dy < action_border->client.icccm.step_h)
dy = action_border->client.icccm.step_h;
if (strcmp(ev->key, "Up") == 0)
h -= _e_border_key_down_modifier_apply(ev->modifiers, dy);
else if (strcmp(ev->key, "Down") == 0)
h += _e_border_key_down_modifier_apply(ev->modifiers, dy);
else if (strcmp(ev->key, "Left") == 0)
w -= _e_border_key_down_modifier_apply(ev->modifiers, dx);
else if (strcmp(ev->key, "Right") == 0)
w += _e_border_key_down_modifier_apply(ev->modifiers, dx);
else if (strcmp(ev->key, "Return") == 0)
goto stop;
else if (strcmp(ev->key, "Escape") == 0)
{
_e_border_action_restore_orig(action_border);
goto stop;
}
else if ((strncmp(ev->key, "Control", sizeof("Control") - 1) != 0) &&
(strncmp(ev->key, "Alt", sizeof("Alt") - 1) != 0))
goto stop;
e_border_resize_limit(action_border, &w, &h);
e_border_resize(action_border, w, h);
_e_border_action_resize_timeout_add();
return 1;
stop:
_e_border_resize_end(action_border);
_e_border_action_finish();
return 0;
}
static int
_e_border_resize_mouse_down(void *data, int type, void *event)
{
Ecore_Event_Mouse_Button *ev = event;
if (ev->event_window != action_input_win)
return 1;
if (!action_border)
fputs("ERROR: no action_border!\n", stderr);
_e_border_resize_end(action_border);
_e_border_action_finish();
return 0;
}
EAPI void
e_border_act_resize_keyboard(E_Border *bd)
{
if (!bd)
return;
if (!_e_border_resize_begin(bd))
return;
if (!_e_border_action_input_win_new(bd))
{
_e_border_resize_end(bd);
return;
}
_e_border_action_init(bd);
_e_border_action_resize_timeout_add();
_e_border_resize_update(bd);
if (action_handler_key)
ecore_event_handler_del(action_handler_key);
action_handler_key = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _e_border_resize_key_down, NULL);
if (action_handler_mouse)
ecore_event_handler_del(action_handler_mouse);
action_handler_mouse = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_border_resize_mouse_down, NULL);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_act_move_begin(E_Border *bd, Ecore_Event_Mouse_Button *ev)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->lock_user_location) return;
if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
if (!_e_border_move_begin(bd))
return;
e_zone_flip_win_disable();
bd->moving = 1;
_e_border_pointer_move_begin(bd);
if (ev)
{
char source[256];
snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
_e_border_moveinfo_gather(bd, source);
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_act_move_end(E_Border *bd, Ecore_Event_Mouse_Button *ev)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (!bd->moving) return;
bd->moving = 0;
_e_border_pointer_move_end(bd);
e_zone_flip_win_restore();
_e_border_move_end(bd);
e_zone_flip_coords_handle(bd->zone, -1, -1);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_act_resize_begin(E_Border *bd, Ecore_Event_Mouse_Button *ev)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->lock_user_size) return;
if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
if (!_e_border_resize_begin(bd))
return;
if (bd->mouse.current.mx < (bd->x + bd-> w / 2))
{
if (bd->mouse.current.my < (bd->y + bd->h / 2))
{
bd->resize_mode = RESIZE_TL;
GRAV_SET(bd, ECORE_X_GRAVITY_SE);
}
else
{
bd->resize_mode = RESIZE_BL;
GRAV_SET(bd, ECORE_X_GRAVITY_NE);
}
}
else
{
if (bd->mouse.current.my < (bd->y + bd->h / 2))
{
bd->resize_mode = RESIZE_TR;
GRAV_SET(bd, ECORE_X_GRAVITY_SW);
}
else
{
bd->resize_mode = RESIZE_BR;
GRAV_SET(bd, ECORE_X_GRAVITY_NW);
}
}
_e_border_pointer_resize_begin(bd);
if (ev)
{
char source[256];
snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons);
_e_border_moveinfo_gather(bd, source);
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_act_resize_end(E_Border *bd, Ecore_Event_Mouse_Button *ev)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->resize_mode != RESIZE_NONE)
{
_e_border_pointer_resize_end(bd);
bd->resize_mode = RESIZE_NONE;
_e_border_resize_end(bd);
bd->changes.reset_gravity = 1;
bd->changed = 1;
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_act_menu_begin(E_Border *bd, Ecore_Event_Mouse_Button *ev, int key)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (ev)
{
e_int_border_menu_show(bd,
bd->x + bd->fx.x + ev->x - bd->zone->container->x,
bd->y + bd->fx.y + ev->y - bd->zone->container->y, key,
ev->timestamp);
}
else
{
int x, y;
ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
e_int_border_menu_show(bd, x, y, key, 0);
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_act_close_begin(E_Border *bd)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->lock_close) return;
if (bd->client.icccm.delete_request)
{
bd->delete_requested = 1;
ecore_x_window_delete_request_send(bd->client.win);
if (bd->client.netwm.ping)
e_border_ping(bd);
}
2005-06-29 01:49:54 -07:00
else if (e_config->kill_if_close_not_possible)
{
printf("KILL win %x (dead)\n", bd->client.win);
e_border_act_kill_begin(bd);
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_act_kill_begin(E_Border *bd)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->internal) return;
if (bd->lock_close) return;
2005-06-29 01:49:54 -07:00
if ((bd->client.netwm.pid > 1) && (e_config->kill_process))
{
kill(bd->client.netwm.pid, SIGINT);
2005-06-29 01:49:54 -07:00
bd->kill_timer = ecore_timer_add(e_config->kill_timer_wait,
_e_border_cb_kill_timer, bd);
}
else
{
if (!bd->internal) ecore_x_kill(bd->client.win);
}
}
2006-01-07 02:39:46 -08:00
EAPI Evas_Object *
e_border_icon_add(E_Border *bd, Evas *evas)
{
Evas_Object *o;
E_OBJECT_CHECK_RETURN(bd, NULL);
E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL);
o = NULL;
2005-11-11 00:03:49 -08:00
if (bd->internal)
{
o = edje_object_add(evas);
if (!bd->internal_icon)
e_util_edje_icon_set(o, "enlightenment");
else
{
if (!bd->internal_icon_key)
{
char *ext;
ext = strrchr(bd->internal_icon, '.');
if ((ext) && ((!strcmp(ext, ".edj"))))
{
if (!edje_object_file_set(o, bd->internal_icon, "icon"))
e_util_edje_icon_set(o, "enlightenment");
}
else if (ext)
{
evas_object_del(o);
o = e_icon_add(evas);
e_icon_file_set(o, bd->internal_icon);
}
else
{
evas_object_del(o);
o = e_icon_add(evas);
if (!e_util_icon_theme_set(o, bd->internal_icon))
e_util_icon_theme_set(o, "enlightenment");
}
}
else
{
edje_object_file_set(o, bd->internal_icon,
bd->internal_icon_key);
}
}
return o;
2005-11-11 00:03:49 -08:00
}
if ((e_config->use_app_icon) && (bd->icon_preference != E_ICON_PREF_USER))
{
if (bd->client.netwm.icons)
{
o = e_icon_add(evas);
e_icon_data_set(o, bd->client.netwm.icons[0].data,
bd->client.netwm.icons[0].width,
bd->client.netwm.icons[0].height);
e_icon_alpha_set(o, 1);
return o;
}
}
if (!o)
2005-06-03 12:10:25 -07:00
{
if ((bd->desktop) && (bd->icon_preference != E_ICON_PREF_NETWM))
{
o = e_util_desktop_icon_add(bd->desktop, 24, evas);
if (o)
return o;
}
else if (bd->client.netwm.icons)
{
o = e_icon_add(evas);
e_icon_data_set(o, bd->client.netwm.icons[0].data,
bd->client.netwm.icons[0].width,
bd->client.netwm.icons[0].height);
e_icon_alpha_set(o, 1);
return o;
}
2005-11-11 00:03:49 -08:00
}
o = e_icon_add(evas);
e_util_icon_theme_set(o, "unknown");
return o;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_button_bindings_ungrab_all(void)
{
Eina_List *l;
E_Border *bd;
EINA_LIST_FOREACH(borders, l, bd)
{
e_focus_setdown(bd);
e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_button_bindings_grab_all(void)
{
Eina_List *l;
E_Border *bd;
EINA_LIST_FOREACH(borders, l, bd)
{
e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win);
e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win);
e_focus_setup(bd);
}
}
EAPI Eina_List *
e_border_focus_stack_get(void)
{
return focus_stack;
}
EAPI Eina_List *
e_border_raise_stack_get(void)
{
return raise_stack;
}
EAPI Eina_List *
e_border_lost_windows_get(E_Zone *zone)
{
Eina_List *list = NULL, *l;
E_Border *bd;
int loss_overlap = 5;
E_OBJECT_CHECK_RETURN(zone, NULL);
E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL);
EINA_LIST_FOREACH(borders, l, bd)
{
if (bd->zone)
{
if ((bd->zone == zone) ||
(bd->zone->container == zone->container))
{
if (!E_INTERSECTS(bd->zone->x + loss_overlap,
bd->zone->y + loss_overlap,
bd->zone->w - (2 * loss_overlap),
bd->zone->h - (2 * loss_overlap),
bd->x, bd->y, bd->w, bd->h))
{
list = eina_list_append(list, bd);
}
else if ((!E_CONTAINS(bd->zone->x, bd->zone->y,
bd->zone->w, bd->zone->h,
bd->x, bd->y, bd->w, bd->h)) &&
(bd->shaped))
{
Ecore_X_Rectangle *rect;
int i, num;
rect = ecore_x_window_shape_rectangles_get(bd->win, &num);
if (rect)
{
int ok;
ok = 0;
for (i = 0; i < num; i++)
{
if (E_INTERSECTS(bd->zone->x + loss_overlap,
bd->zone->y + loss_overlap,
bd->zone->w - (2 * loss_overlap),
bd->zone->h - (2 * loss_overlap),
rect[i].x, rect[i].y,
rect[i].width, rect[i].height))
{
ok = 1;
break;
}
}
free(rect);
if (!ok)
list = eina_list_append(list, bd);
}
}
}
}
}
return list;
}
2006-01-07 02:39:46 -08:00
EAPI void
2005-06-23 21:10:18 -07:00
e_border_ping(E_Border *bd)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (!e_config->ping_clients) return;
2005-06-23 21:10:18 -07:00
bd->ping_ok = 0;
ecore_x_netwm_ping_send(bd->client.win);
bd->ping = ecore_loop_time_get();
e: 1. configure/build changes to allow cross-compiling painlessly 2. pager module namespace changes - this was still dirty afdter the namespace cleanup, so clean it up 3. add a powersave subsystem - doesnt have an "automatic" way to turn on and off right now, this i think is best provided by modules (that do things like monitor acpi status's (eg close lid of laptop), AC power status etc. etc. this allows e to nicely defer "power" expensive actions to avoid disk spinups etc. 4. move to use the new ecore poller system - discussed long ago as part of power management/saving issues. now it exists 5. add a canvas idle flush call that helsp cope with the new shm greedy software x11 engine stuff 6. use the new powersave subsystem where appropriate 7. fix non-zeroed/initted memory access in e_fm_main 8. fix mem leak for e menus 9. remove ipc handlers for changed/removed config values 10. use animaotr not timer for menu scrolls - then menu scrolls obey the fps config 11. fix up timer/poll happienss of cursor idle stuff 12. remove avoid damage from popups for now - causing problems 13. change battery and temp readouts to b e shorter so they fit 14. pager can emit signals on focus change for mini-windows now 15. temperature module now uses a slave process and uses stdin/out to talk to it and get output - this makes e smoother as in my expereicne i found getting the temp on my laptop actually took like 200ms so e "hang" for 200ms while reading the acpi files - so now the subprocess does it and just writesa back to e when it gets it. ecore: 1. add ecore_pollers. see the documentation on them in doxygen comments :) 2. fix timers to only go off when they have to - bug there that made e's select time out a LOT more than it needed to. defensive coding hid the problem. now fixed. e should be much more power friendly now. 3. formatting/niceness in ecore_exe stuff 4. some comments on comments with SIGIO ideas vs. select 5. add call to be able to add an idle enterer at the start of the list of them, not just the end (as has been the default) 6. fix ecore_evas to support auto evas idler calls after 0.5 secs of idle in all canvases - and to do it right 7. if argb destination - set the shape EVENT shape (to mask out events in transparent regions much like shape does withotu translucency) 8. in ecore_x add support for the event shape evas: 1. fix cache to work properly and not just always fill up (as it seemed to like to think cahce useage dropped below 0 when it didnt and thus just over-fill) 2. software x11 engine now ONLY uses shm segments - no ximages over the socket. this ximage hack was there to avoid the 2 round trips involved in setting up an shm image - now i mitigated that wih an shm image cache pool. it keeps shm images around and repurposes them for new update regions if appropriate. this means many fewer shm creates (about 1/100th the number) and since we recycle the memory less 0 memory page filling by the kernel - in the end, i recorded about a 10-20% speedup over the old software x11 engine. simple tests i have seen up to 120% speedups. idle flush now does something - it frees all the cached shm segments. it has a hard-coded limit of 4mb worth of shm segments (or 32 segments - whichever comes first) to keep around. once can never complain much about speedups methinks :). also evas will defer sync until the NEXT frame is written - this means evas can calculate the next frame of data while x dma's/copies the images to the screen at the same time (if you hve a dual core or multi-cpu machnike or your xserver is able to use DMA to copy image data to the screen/video ram then this should see a decent speedup). SVN revision: 33448
2008-01-10 23:33:57 -08:00
if (bd->ping_poller) ecore_poller_del(bd->ping_poller);
bd->ping_poller = ecore_poller_add(ECORE_POLLER_CORE,
e_config->ping_clients_interval,
_e_border_cb_ping_poller, bd);
2005-06-23 21:10:18 -07:00
}
2006-01-07 02:39:46 -08:00
EAPI void
2005-06-23 21:10:18 -07:00
e_border_move_cancel(void)
{
if (move) _e_border_move_end(move);
2005-06-23 21:10:18 -07:00
}
2006-01-07 02:39:46 -08:00
EAPI void
2005-06-23 21:10:18 -07:00
e_border_resize_cancel(void)
{
if (resize)
{
resize->resize_mode = RESIZE_NONE;
_e_border_resize_end(resize);
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_frame_recalc(E_Border *bd)
{
Evas_Coord cx, cy, cw, ch;
if (!bd->bg_object) return;
bd->w -= (bd->client_inset.l + bd->client_inset.r);
bd->h -= (bd->client_inset.t + bd->client_inset.b);
evas_object_resize(bd->bg_object, 1000, 1000);
edje_object_calc_force(bd->bg_object);
edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch);
bd->client_inset.l = cx;
bd->client_inset.r = 1000 - (cx + cw);
bd->client_inset.t = cy;
bd->client_inset.b = 1000 - (cy + ch);
ecore_x_netwm_frame_size_set(bd->client.win,
bd->client_inset.l, bd->client_inset.r,
bd->client_inset.t, bd->client_inset.b);
ecore_x_e_frame_size_set(bd->client.win,
bd->client_inset.l, bd->client_inset.r,
bd->client_inset.t, bd->client_inset.b);
bd->w += (bd->client_inset.l + bd->client_inset.r);
bd->h += (bd->client_inset.t + bd->client_inset.b);
bd->changed = 1;
bd->changes.size = 1;
if ((bd->shaped) || (bd->client.shaped))
{
bd->need_shape_merge = 1;
bd->need_shape_export = 1;
}
_e_border_client_move_resize_send(bd);
}
EAPI Eina_List *
2005-07-08 01:43:27 -07:00
e_border_immortal_windows_get(void)
{
Eina_List *list = NULL, *l;
E_Border *bd;
2005-07-08 01:43:27 -07:00
EINA_LIST_FOREACH(borders, l, bd)
2005-07-08 01:43:27 -07:00
{
if (bd->lock_life)
list = eina_list_append(list, bd);
2005-07-08 01:43:27 -07:00
}
return list;
}
2006-01-07 02:39:46 -08:00
EAPI const char *
e_border_name_get(const E_Border *bd)
{
E_OBJECT_CHECK_RETURN(bd, "");
E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, "");
if (bd->client.netwm.name)
return bd->client.netwm.name;
else if (bd->client.icccm.title)
return bd->client.icccm.title;
return "";
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_signal_move_begin(E_Border *bd, const char *sig, const char *src)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
if (!_e_border_move_begin(bd)) return;
bd->moving = 1;
_e_border_pointer_move_begin(bd);
e_zone_flip_win_disable();
_e_border_moveinfo_gather(bd, sig);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_signal_move_end(E_Border *bd, const char *sig, const char *src)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (!bd->moving) return;
bd->moving = 0;
_e_border_pointer_move_end(bd);
e_zone_flip_win_restore();
_e_border_move_end(bd);
e_zone_flip_coords_handle(bd->zone, -1, -1);
}
2006-01-07 02:39:46 -08:00
EAPI int
e_border_resizing_get(E_Border *bd)
{
E_OBJECT_CHECK_RETURN(bd, 0);
E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, 0);
if (bd->resize_mode == RESIZE_NONE) return 0;
return 1;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_signal_resize_begin(E_Border *bd, const char *dir, const char *sig, const char *src)
{
Ecore_X_Gravity grav = ECORE_X_GRAVITY_NW;
int resize_mode = RESIZE_BR;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return;
if (!_e_border_resize_begin(bd))
return;
if (!strcmp(dir, "tl"))
{
resize_mode = RESIZE_TL;
grav = ECORE_X_GRAVITY_SE;
}
else if (!strcmp(dir, "t"))
{
resize_mode = RESIZE_T;
grav = ECORE_X_GRAVITY_S;
}
else if (!strcmp(dir, "tr"))
{
resize_mode = RESIZE_TR;
grav = ECORE_X_GRAVITY_SW;
}
else if (!strcmp(dir, "r"))
{
resize_mode = RESIZE_R;
grav = ECORE_X_GRAVITY_W;
}
else if (!strcmp(dir, "br"))
{
resize_mode = RESIZE_BR;
grav = ECORE_X_GRAVITY_NW;
}
else if (!strcmp(dir, "b"))
{
resize_mode = RESIZE_B;
grav = ECORE_X_GRAVITY_N;
}
else if (!strcmp(dir, "bl"))
{
resize_mode = RESIZE_BL;
grav = ECORE_X_GRAVITY_NE;
}
else if (!strcmp(dir, "l"))
{
resize_mode = RESIZE_L;
grav = ECORE_X_GRAVITY_E;
}
bd->resize_mode = resize_mode;
_e_border_pointer_resize_begin(bd);
_e_border_moveinfo_gather(bd, sig);
GRAV_SET(bd, grav);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_signal_resize_end(E_Border *bd, const char *dir, const char *sig, const char *src)
{
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
if (bd->resize_mode == RESIZE_NONE) return;
_e_border_resize_handle(bd);
_e_border_pointer_resize_end(bd);
bd->resize_mode = RESIZE_NONE;
_e_border_resize_end(bd);
bd->changes.reset_gravity = 1;
bd->changed = 1;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_border_resize_limit(E_Border *bd, int *w, int *h)
{
double a;
E_OBJECT_CHECK(bd);
E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE);
*w -= bd->client_inset.l + bd->client_inset.r;
*h -= bd->client_inset.t + bd->client_inset.b;
if (*h < 1) *h = 1;
if (*w < 1) *w = 1;
if ((bd->client.icccm.base_w >= 0) &&
(bd->client.icccm.base_h >= 0))
{
int tw, th;
tw = *w - bd->client.icccm.base_w;
th = *h - bd->client.icccm.base_h;
if (tw < 1) tw = 1;
if (th < 1) th = 1;
a = (double)(tw) / (double)(th);
if ((bd->client.icccm.min_aspect != 0.0) &&
(a < bd->client.icccm.min_aspect))
{
th = tw / bd->client.icccm.max_aspect;
*h = th + bd->client.icccm.base_h;
}
else if ((bd->client.icccm.max_aspect != 0.0) &&
(a > bd->client.icccm.max_aspect))
{
tw = th * bd->client.icccm.max_aspect;
*w = tw + bd->client.icccm.base_w;
}
}
else
{
a = (double)*w / (double)*h;
if ((bd->client.icccm.min_aspect != 0.0) &&
(a < bd->client.icccm.min_aspect))
*h = *w / bd->client.icccm.min_aspect;
else if ((bd->client.icccm.max_aspect != 0.0) &&
(a > bd->client.icccm.max_aspect))
*w = *h * bd->client.icccm.max_aspect;
}
if (bd->client.icccm.step_w > 0)
{
if (bd->client.icccm.base_w >= 0)
*w = bd->client.icccm.base_w +
(((*w - bd->client.icccm.base_w) / bd->client.icccm.step_w) *
bd->client.icccm.step_w);
else
*w = bd->client.icccm.min_w +
(((*w - bd->client.icccm.min_w) / bd->client.icccm.step_w) *
bd->client.icccm.step_w);
}
if (bd->client.icccm.step_h > 0)
{
if (bd->client.icccm.base_h >= 0)
*h = bd->client.icccm.base_h +
(((*h - bd->client.icccm.base_h) / bd->client.icccm.step_h) *
bd->client.icccm.step_h);
else
*h = bd->client.icccm.min_h +
(((*h - bd->client.icccm.min_h) / bd->client.icccm.step_h) *
bd->client.icccm.step_h);
}
if (*h < 1) *h = 1;
if (*w < 1) *w = 1;
if (*w > bd->client.icccm.max_w) *w = bd->client.icccm.max_w;
else if (*w < bd->client.icccm.min_w) *w = bd->client.icccm.min_w;
if (*h > bd->client.icccm.max_h) *h = bd->client.icccm.max_h;
else if (*h < bd->client.icccm.min_h) *h = bd->client.icccm.min_h;
*w += bd->client_inset.l + bd->client_inset.r;
*h += bd->client_inset.t + bd->client_inset.b;
}
/* local subsystem functions */
static void
_e_border_free(E_Border *bd)
{
if (bd->post_job)
{
ecore_idle_enterer_del(bd->post_job);
bd->post_job = NULL;
}
if (bd->pointer)
{
e_object_del(E_OBJECT(bd->pointer));
bd->pointer = NULL;
}
if (bd->focused)
{
if (e_config->focus_revert_on_hide_or_close)
e_desk_last_focused_focus(bd->desk);
}
if (resize == bd)
_e_border_resize_end(bd);
if (move == bd)
_e_border_move_end(bd);
/* TODO: Other states to end before dying? */
2005-06-27 21:00:17 -07:00
if (bd->cur_mouse_action)
{
e_object_unref(E_OBJECT(bd->cur_mouse_action));
bd->cur_mouse_action = NULL;
}
2005-09-05 08:24:07 -07:00
E_FREE(bd->shape_rects);
bd->shape_rects_num = 0;
/*
if (bd->dangling_ref_check)
{
ecore_timer_del(bd->dangling_ref_check);
bd->dangling_ref_check = NULL;
}
*/
if (bd->kill_timer)
{
ecore_timer_del(bd->kill_timer);
bd->kill_timer = NULL;
}
e: 1. configure/build changes to allow cross-compiling painlessly 2. pager module namespace changes - this was still dirty afdter the namespace cleanup, so clean it up 3. add a powersave subsystem - doesnt have an "automatic" way to turn on and off right now, this i think is best provided by modules (that do things like monitor acpi status's (eg close lid of laptop), AC power status etc. etc. this allows e to nicely defer "power" expensive actions to avoid disk spinups etc. 4. move to use the new ecore poller system - discussed long ago as part of power management/saving issues. now it exists 5. add a canvas idle flush call that helsp cope with the new shm greedy software x11 engine stuff 6. use the new powersave subsystem where appropriate 7. fix non-zeroed/initted memory access in e_fm_main 8. fix mem leak for e menus 9. remove ipc handlers for changed/removed config values 10. use animaotr not timer for menu scrolls - then menu scrolls obey the fps config 11. fix up timer/poll happienss of cursor idle stuff 12. remove avoid damage from popups for now - causing problems 13. change battery and temp readouts to b e shorter so they fit 14. pager can emit signals on focus change for mini-windows now 15. temperature module now uses a slave process and uses stdin/out to talk to it and get output - this makes e smoother as in my expereicne i found getting the temp on my laptop actually took like 200ms so e "hang" for 200ms while reading the acpi files - so now the subprocess does it and just writesa back to e when it gets it. ecore: 1. add ecore_pollers. see the documentation on them in doxygen comments :) 2. fix timers to only go off when they have to - bug there that made e's select time out a LOT more than it needed to. defensive coding hid the problem. now fixed. e should be much more power friendly now. 3. formatting/niceness in ecore_exe stuff 4. some comments on comments with SIGIO ideas vs. select 5. add call to be able to add an idle enterer at the start of the list of them, not just the end (as has been the default) 6. fix ecore_evas to support auto evas idler calls after 0.5 secs of idle in all canvases - and to do it right 7. if argb destination - set the shape EVENT shape (to mask out events in transparent regions much like shape does withotu translucency) 8. in ecore_x add support for the event shape evas: 1. fix cache to work properly and not just always fill up (as it seemed to like to think cahce useage dropped below 0 when it didnt and thus just over-fill) 2. software x11 engine now ONLY uses shm segments - no ximages over the socket. this ximage hack was there to avoid the 2 round trips involved in setting up an shm image - now i mitigated that wih an shm image cache pool. it keeps shm images around and repurposes them for new update regions if appropriate. this means many fewer shm creates (about 1/100th the number) and since we recycle the memory less 0 memory page filling by the kernel - in the end, i recorded about a 10-20% speedup over the old software x11 engine. simple tests i have seen up to 120% speedups. idle flush now does something - it frees all the cached shm segments. it has a hard-coded limit of 4mb worth of shm segments (or 32 segments - whichever comes first) to keep around. once can never complain much about speedups methinks :). also evas will defer sync until the NEXT frame is written - this means evas can calculate the next frame of data while x dma's/copies the images to the screen at the same time (if you hve a dual core or multi-cpu machnike or your xserver is able to use DMA to copy image data to the screen/video ram then this should see a decent speedup). SVN revision: 33448
2008-01-10 23:33:57 -08:00
if (bd->ping_poller)
{
e: 1. configure/build changes to allow cross-compiling painlessly 2. pager module namespace changes - this was still dirty afdter the namespace cleanup, so clean it up 3. add a powersave subsystem - doesnt have an "automatic" way to turn on and off right now, this i think is best provided by modules (that do things like monitor acpi status's (eg close lid of laptop), AC power status etc. etc. this allows e to nicely defer "power" expensive actions to avoid disk spinups etc. 4. move to use the new ecore poller system - discussed long ago as part of power management/saving issues. now it exists 5. add a canvas idle flush call that helsp cope with the new shm greedy software x11 engine stuff 6. use the new powersave subsystem where appropriate 7. fix non-zeroed/initted memory access in e_fm_main 8. fix mem leak for e menus 9. remove ipc handlers for changed/removed config values 10. use animaotr not timer for menu scrolls - then menu scrolls obey the fps config 11. fix up timer/poll happienss of cursor idle stuff 12. remove avoid damage from popups for now - causing problems 13. change battery and temp readouts to b e shorter so they fit 14. pager can emit signals on focus change for mini-windows now 15. temperature module now uses a slave process and uses stdin/out to talk to it and get output - this makes e smoother as in my expereicne i found getting the temp on my laptop actually took like 200ms so e "hang" for 200ms while reading the acpi files - so now the subprocess does it and just writesa back to e when it gets it. ecore: 1. add ecore_pollers. see the documentation on them in doxygen comments :) 2. fix timers to only go off when they have to - bug there that made e's select time out a LOT more than it needed to. defensive coding hid the problem. now fixed. e should be much more power friendly now. 3. formatting/niceness in ecore_exe stuff 4. some comments on comments with SIGIO ideas vs. select 5. add call to be able to add an idle enterer at the start of the list of them, not just the end (as has been the default) 6. fix ecore_evas to support auto evas idler calls after 0.5 secs of idle in all canvases - and to do it right 7. if argb destination - set the shape EVENT shape (to mask out events in transparent regions much like shape does withotu translucency) 8. in ecore_x add support for the event shape evas: 1. fix cache to work properly and not just always fill up (as it seemed to like to think cahce useage dropped below 0 when it didnt and thus just over-fill) 2. software x11 engine now ONLY uses shm segments - no ximages over the socket. this ximage hack was there to avoid the 2 round trips involved in setting up an shm image - now i mitigated that wih an shm image cache pool. it keeps shm images around and repurposes them for new update regions if appropriate. this means many fewer shm creates (about 1/100th the number) and since we recycle the memory less 0 memory page filling by the kernel - in the end, i recorded about a 10-20% speedup over the old software x11 engine. simple tests i have seen up to 120% speedups. idle flush now does something - it frees all the cached shm segments. it has a hard-coded limit of 4mb worth of shm segments (or 32 segments - whichever comes first) to keep around. once can never complain much about speedups methinks :). also evas will defer sync until the NEXT frame is written - this means evas can calculate the next frame of data while x dma's/copies the images to the screen at the same time (if you hve a dual core or multi-cpu machnike or your xserver is able to use DMA to copy image data to the screen/video ram then this should see a decent speedup). SVN revision: 33448
2008-01-10 23:33:57 -08:00
ecore_poller_del(bd->ping_poller);
bd->ping_poller = NULL;
}
E_FREE_LIST(bd->pending_move_resize, free);
if (bd->shade.anim) ecore_animator_del(bd->shade.anim);
if (bd->border_menu) e_menu_deactivate(bd->border_menu);
if (bd->border_locks_dialog)
{
e_object_del(E_OBJECT(bd->border_locks_dialog));
bd->border_locks_dialog = NULL;
}
if (bd->border_remember_dialog)
{
e_object_del(E_OBJECT(bd->border_remember_dialog));
bd->border_remember_dialog = NULL;
}
if (bd->border_border_dialog)
{
e_object_del(E_OBJECT(bd->border_border_dialog));
bd->border_border_dialog = NULL;
}
if (bd->border_prop_dialog)
{
e_object_del(E_OBJECT(bd->border_prop_dialog));
bd->border_prop_dialog = NULL;
}
e_int_border_menu_del(bd);
if (focused == bd)
{
// ecore_x_window_focus(bd->zone->container->manager->root);
e_grabinput_focus(bd->zone->container->bg_win, E_FOCUS_METHOD_PASSIVE);
e_hints_active_window_set(bd->zone->container->manager, NULL);
focused = NULL;
}
E_FREE_LIST(bd->handlers, ecore_event_handler_del);
if (bd->remember)
{
E_Remember *rem;
rem = bd->remember;
bd->remember = NULL;
e_remember_unuse(rem);
}
if (!bd->already_unparented)
{
ecore_x_window_reparent(bd->client.win, bd->zone->container->manager->root,
bd->x + bd->client_inset.l, bd->y + bd->client_inset.t);
ecore_x_window_save_set_del(bd->client.win);
bd->already_unparented = 1;
}
if (bd->group) eina_list_free(bd->group);
if (bd->transients) eina_list_free(bd->transients);
if (bd->stick_desks) eina_list_free(bd->stick_desks);
if (bd->client.netwm.icons)
{
int i;
for (i = 0; i < bd->client.netwm.num_icons; i++)
free(bd->client.netwm.icons[i].data);
free(bd->client.netwm.icons);
}
if (bd->client.netwm.extra_types)
free(bd->client.netwm.extra_types);
if (bd->client.border.name) eina_stringshare_del(bd->client.border.name);
if (bd->bordername) eina_stringshare_del(bd->bordername);
if (bd->client.icccm.title) free(bd->client.icccm.title);
if (bd->client.icccm.name) free(bd->client.icccm.name);
if (bd->client.icccm.class) free(bd->client.icccm.class);
if (bd->client.icccm.icon_name) free(bd->client.icccm.icon_name);
if (bd->client.icccm.machine) free(bd->client.icccm.machine);
if (bd->client.icccm.window_role) free(bd->client.icccm.window_role);
if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
{
int i;
for (i = 0; i < bd->client.icccm.command.argc; i++)
free(bd->client.icccm.command.argv[i]);
free(bd->client.icccm.command.argv);
}
2005-05-29 23:24:14 -07:00
if (bd->client.netwm.name) free(bd->client.netwm.name);
if (bd->client.netwm.icon_name) free(bd->client.netwm.icon_name);
e_object_del(E_OBJECT(bd->shape));
if (bd->internal_icon) eina_stringshare_del(bd->internal_icon);
if (bd->internal_icon_key) eina_stringshare_del(bd->internal_icon_key);
if (bd->icon_object) evas_object_del(bd->icon_object);
evas_object_del(bd->bg_object);
e_canvas_del(bd->bg_ecore_evas);
ecore_evas_free(bd->bg_ecore_evas);
ecore_x_window_free(bd->client.shell_win);
e_focus_setdown(bd);
e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
e_bindings_wheel_ungrab(E_BINDING_CONTEXT_BORDER, bd->win);
ecore_x_window_free(bd->win);
2005-02-07 05:51:09 -08:00
eina_hash_del(borders_hash, e_util_winid_str_get(bd->client.win), bd);
eina_hash_del(borders_hash, e_util_winid_str_get(bd->bg_win), bd);
eina_hash_del(borders_hash, e_util_winid_str_get(bd->win), bd);
borders = eina_list_remove(borders, bd);
focus_stack = eina_list_remove(focus_stack, bd);
raise_stack = eina_list_remove(raise_stack, bd);
2006-08-26 01:38:53 -07:00
e_container_border_remove(bd);
free(bd);
}
/*
static int
_e_border_del_dangling_ref_check(void *data)
{
E_Border *bd;
bd = data;
printf("---\n");
printf("EEK EEK border still around 1 second after being deleted!\n");
printf("%p, %i, \"%s\" [\"%s\" \"%s\"]\n",
bd, e_object_ref_get(E_OBJECT(bd)), bd->client.icccm.title,
bd->client.icccm.name, bd->client.icccm.class);
// e_object_breadcrumb_debug(E_OBJECT(bd));
printf("---\n");
return 1;
}
*/
static void
_e_border_del(E_Border *bd)
{
E_Event_Border_Remove *ev;
E_Border *child;
if (bd->fullscreen) bd->desk->fullscreen_borders--;
if ((drag_border) && (drag_border->data == bd))
{
e_object_del(E_OBJECT(drag_border));
drag_border = NULL;
}
if (bd->border_menu) e_menu_deactivate(bd->border_menu);
if (bd->border_locks_dialog)
{
e_object_del(E_OBJECT(bd->border_locks_dialog));
bd->border_locks_dialog = NULL;
}
if (bd->border_remember_dialog)
{
e_object_del(E_OBJECT(bd->border_remember_dialog));
bd->border_remember_dialog = NULL;
}
if (bd->border_border_dialog)
{
e_object_del(E_OBJECT(bd->border_border_dialog));
bd->border_border_dialog = NULL;
}
if (bd->border_prop_dialog)
{
e_object_del(E_OBJECT(bd->border_prop_dialog));
bd->border_prop_dialog = NULL;
}
e_int_border_menu_del(bd);
if (bd->raise_timer)
{
ecore_timer_del(bd->raise_timer);
bd->raise_timer = NULL;
}
if (!bd->already_unparented)
{
ecore_x_window_reparent(bd->client.win,
bd->zone->container->manager->root,
bd->x + bd->client_inset.l,
bd->y + bd->client_inset.t);
ecore_x_window_save_set_del(bd->client.win);
bd->already_unparented = 1;
// bd->client.win = 0;
}
bd->already_unparented = 1;
if ((!bd->new_client) && (!stopping))
{
ev = E_NEW(E_Event_Border_Remove, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_remove_event");
ecore_event_add(E_EVENT_BORDER_REMOVE, ev, _e_border_event_border_remove_free, NULL);
}
if (bd->parent)
{
bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
if (bd->parent->modal == bd)
{
bd->parent->modal = NULL;
if (bd->focused)
e_border_focus_set(bd->parent, 1, 1);
}
bd->parent = NULL;
}
EINA_LIST_FREE(bd->transients, child)
{
child->parent = NULL;
}
if (bd->leader)
{
bd->leader->group = eina_list_remove(bd->leader->group, bd);
if (bd->leader->modal == bd)
{
bd->leader->modal = NULL;
/* TODO Should we focus leader when this window closes? */
#if 0
if (bd->focused)
e_border_focus_set(bd->leader, 1, 1);
#endif
}
bd->leader = NULL;
}
EINA_LIST_FREE(bd->group, child)
{
child->leader = NULL;
}
}
static int
_e_border_cb_window_show_request(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Show_Request *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
if (bd->iconic)
{
if (!bd->lock_client_iconify)
e_border_uniconify(bd);
}
else
{
2005-06-29 03:58:27 -07:00
/* FIXME: make border "urgent" for a bit - it wants attention */
/* e_border_show(bd); */
if (!bd->lock_client_stacking)
e_border_raise(bd);
}
return 1;
}
static int
_e_border_cb_window_destroy(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Destroy *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
e_border_hide(bd, 0);
e_object_del(E_OBJECT(bd));
return 1;
}
static int
_e_border_cb_window_hide(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Hide *e;
2005-02-07 05:51:09 -08:00
bd = data;
e = ev;
2009-03-23 06:39:24 -07:00
// printf("HIDE: %x, event %x\n", e->win, e->event_win);
// not interested in hide events from windows other than the window in question
if (e->win != e->event_win) return 1;
bd = e_border_find_by_client_window(e->win);
2009-03-23 06:39:24 -07:00
// printf(" bd = %p\n", bd);
if (!bd) return 1;
2009-03-23 06:39:24 -07:00
// printf(" bd->ignore_first_unmap = %i\n", bd->ignore_first_unmap);
if (bd->ignore_first_unmap > 0)
{
bd->ignore_first_unmap--;
return 1;
}
/* Don't delete hidden or iconified windows */
if ((bd->iconic) || ((!bd->visible) && (!bd->new_client)) ||
(bd->await_hide_event > 0))
{
2009-03-23 06:39:24 -07:00
// printf(" Don't delete hidden or iconified windows\n");
// printf(" bd->iconic = %i, bd->visible = %i, bd->new_client = %i, bd->await_hide_event = %i\n",
// bd->iconic, bd->visible, bd->new_client, bd->await_hide_event);
if (bd->await_hide_event > 0)
{
bd->await_hide_event--;
}
else
{
2009-03-23 06:39:24 -07:00
// printf(" hide really\n");
/* Only hide the border if it is visible */
if (bd->visible) e_border_hide(bd, 1);
}
}
else
{
2009-03-23 06:39:24 -07:00
// printf(" hide2\n");
e_border_hide(bd, 0);
if (e_config->focus_revert_on_hide_or_close)
{
E_Border *pbd;
E_Container *con;
E_Zone *zone;
E_Desk *desk;
con = e_container_current_get(e_manager_current_get());
zone = e_zone_current_get(con);
desk = e_desk_current_get(zone);
/* When using pointer focus, the border under the
* pointer (if any) gets focused, in sloppy/click
* focus the last focused window on the current
* desk gets focus */
if (e_config->focus_policy == E_FOCUS_MOUSE)
{
pbd = e_border_under_pointer_get(desk, bd);
if (pbd)
e_border_focus_set(pbd, 1, 1);
}
else
e_desk_last_focused_focus(desk);
}
e_object_del(E_OBJECT(bd));
}
return 1;
}
static int
_e_border_cb_window_reparent(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Reparent *e;
2005-02-07 05:51:09 -08:00
bd = data;
e = ev;
return 1;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
if (e->parent == bd->client.shell_win) return 1;
if (ecore_x_window_parent_get(e->win) == bd->client.shell_win)
{
return 1;
}
e_border_hide(bd, 0);
e_object_del(E_OBJECT(bd));
return 1;
}
static int
_e_border_cb_window_configure_request(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Configure_Request *e;
2005-02-07 05:51:09 -08:00
bd = data;
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd)
{
if (e_stolen_win_get(e->win)) return 1;
2005-08-22 20:50:02 -07:00
if (!e_util_container_window_find(e->win))
ecore_x_window_configure(e->win, e->value_mask,
e->x, e->y, e->w, e->h, e->border,
e->abovewin, e->detail);
return 1;
}
2005-05-11 06:13:43 -07:00
if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X) ||
(e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y))
{
2005-05-11 06:13:43 -07:00
int x, y;
2005-02-07 05:51:09 -08:00
2005-05-11 06:13:43 -07:00
x = bd->x;
y = bd->y;
2005-05-11 06:13:43 -07:00
if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_X)
x = e->x;
if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_Y)
y = e->y;
if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
(e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
{
int w, h;
2005-02-07 05:51:09 -08:00
h = bd->h;
w = bd->w;
if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
w = e->w + bd->client_inset.l + bd->client_inset.r;
if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
h = e->h + bd->client_inset.t + bd->client_inset.b;
if ((!bd->lock_client_location) && (!bd->lock_client_size))
{
if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
{
bd->saved.x = x - bd->zone->x;
bd->saved.y = y - bd->zone->y;
bd->saved.w = w;
bd->saved.h = h;
}
else
e_border_move_resize(bd, x, y, w, h);
}
else if (!bd->lock_client_location)
{
if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
{
bd->saved.x = x - bd->zone->x;
bd->saved.y = y - bd->zone->y;
}
else
e_border_move(bd, x, y);
}
else if (!bd->lock_client_size)
2005-07-28 03:30:54 -07:00
{
if ((bd->shaded) || (bd->shading))
{
int pw, ph;
pw = bd->client.w;
ph = bd->client.h;
if ((bd->shade.dir == E_DIRECTION_UP) ||
(bd->shade.dir == E_DIRECTION_DOWN))
{
e_border_resize(bd, w, bd->h);
bd->client.h = ph;
}
else
{
e_border_resize(bd, bd->w, h);
bd->client.w = pw;
}
}
else
{
if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
{
bd->saved.w = w;
bd->saved.h = h;
}
else
e_border_resize(bd, w, h);
}
2005-07-28 03:30:54 -07:00
}
}
2005-05-11 06:13:43 -07:00
else
{
if (!bd->lock_client_location)
{
if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
{
bd->saved.x = x - bd->zone->x;
bd->saved.y = y - bd->zone->y;
}
else
e_border_move(bd, x, y);
}
}
2005-05-11 06:13:43 -07:00
}
else if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W) ||
(e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H))
{
int w, h;
h = bd->h;
w = bd->w;
if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_W)
w = e->w + bd->client_inset.l + bd->client_inset.r;
if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_H)
h = e->h + bd->client_inset.t + bd->client_inset.b;
if (!bd->lock_client_size)
2005-07-28 03:30:54 -07:00
{
if ((bd->shaded) || (bd->shading))
{
int pw, ph;
pw = bd->client.w;
ph = bd->client.h;
if ((bd->shade.dir == E_DIRECTION_UP) ||
(bd->shade.dir == E_DIRECTION_DOWN))
{
e_border_resize(bd, w, bd->h);
bd->client.h = ph;
}
else
{
e_border_resize(bd, bd->w, h);
bd->client.w = pw;
}
}
else
{
if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_NONE)
e_border_resize(bd, w, h);
}
2005-07-28 03:30:54 -07:00
}
2005-05-11 06:13:43 -07:00
}
if (!bd->lock_client_stacking)
2005-05-11 06:13:43 -07:00
{
if ((e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE) &&
(e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING))
2005-05-11 06:13:43 -07:00
{
E_Border *obd;
if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
{
obd = e_border_find_by_client_window(e->abovewin);
if (obd)
e_border_stack_above(bd, obd);
}
else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
{
obd = e_border_find_by_client_window(e->abovewin);
if (obd)
e_border_stack_below(bd, obd);
}
else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
{
/* FIXME: do */
}
else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
{
/* FIXME: do */
}
else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
{
/* FIXME: do */
}
2005-05-11 06:13:43 -07:00
}
else if (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE)
2005-05-11 06:13:43 -07:00
{
if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
{
e_border_raise(bd);
}
else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
{
e_border_lower(bd);
}
else if (e->detail == ECORE_X_WINDOW_STACK_TOP_IF)
{
/* FIXME: do */
}
else if (e->detail == ECORE_X_WINDOW_STACK_BOTTOM_IF)
{
/* FIXME: do */
}
else if (e->detail == ECORE_X_WINDOW_STACK_OPPOSITE)
{
/* FIXME: do */
}
}
}
_e_border_client_move_resize_send(bd);
return 1;
}
2005-01-06 01:08:20 -08:00
static int
_e_border_cb_window_resize_request(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Resize_Request *e;
2005-02-07 05:51:09 -08:00
2005-01-06 01:08:20 -08:00
bd = data;
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd)
{
if (e_stolen_win_get(e->win)) return 1;
2005-01-06 01:08:20 -08:00
ecore_x_window_resize(e->win, e->w, e->h);
return 1;
}
{
int w, h;
2005-02-07 05:51:09 -08:00
2005-01-06 01:08:20 -08:00
h = bd->h;
w = bd->w;
w = e->w + bd->client_inset.l + bd->client_inset.r;
h = e->h + bd->client_inset.t + bd->client_inset.b;
2005-07-28 03:30:54 -07:00
if ((bd->shaded) || (bd->shading))
{
int pw, ph;
pw = bd->client.w;
ph = bd->client.h;
if ((bd->shade.dir == E_DIRECTION_UP) ||
(bd->shade.dir == E_DIRECTION_DOWN))
{
e_border_resize(bd, w, bd->h);
bd->client.h = ph;
}
else
{
e_border_resize(bd, bd->w, h);
bd->client.w = pw;
}
}
else
e_border_resize(bd, w, h);
2005-01-06 01:08:20 -08:00
}
_e_border_client_move_resize_send(bd);
2005-01-06 01:08:20 -08:00
return 1;
}
static int
_e_border_cb_window_gravity(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Gravity *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
return 1;
}
static int
_e_border_cb_window_stack_request(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Stack_Request *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
2005-08-22 20:50:02 -07:00
if (!bd)
{
if (e_stolen_win_get(e->win)) return 1;
2005-08-22 20:50:02 -07:00
if (!e_util_container_window_find(e->win))
{
if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
ecore_x_window_raise(e->win);
else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
ecore_x_window_lower(e->win);
}
return 1;
}
if (e->detail == ECORE_X_WINDOW_STACK_ABOVE)
e_border_raise(bd);
else if (e->detail == ECORE_X_WINDOW_STACK_BELOW)
e_border_lower(bd);
return 1;
}
static int
_e_border_cb_window_property(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Property *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
if (e->atom == ECORE_X_ATOM_WM_NAME)
{
if ((!bd->client.netwm.name) &&
(!bd->client.netwm.fetch.name))
{
bd->client.icccm.fetch.title = 1;
bd->changed = 1;
}
}
else if (e->atom == ECORE_X_ATOM_NET_WM_NAME)
{
bd->client.netwm.fetch.name = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_CLASS)
{
bd->client.icccm.fetch.name_class = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_ICON_NAME)
{
if ((!bd->client.netwm.icon_name) &&
(!bd->client.netwm.fetch.icon_name))
{
bd->client.icccm.fetch.icon_name = 1;
bd->changed = 1;
}
}
else if (e->atom == ECORE_X_ATOM_NET_WM_ICON_NAME)
{
bd->client.netwm.fetch.icon_name = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
{
bd->client.icccm.fetch.machine = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_PROTOCOLS)
{
bd->client.icccm.fetch.protocol = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_HINTS)
{
bd->client.icccm.fetch.hints = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_NORMAL_HINTS)
{
bd->client.icccm.fetch.size_pos_hints = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_MOTIF_WM_HINTS)
{
/*
if ((bd->client.netwm.type == ECORE_X_WINDOW_TYPE_UNKNOWN) &&
(!bd->client.netwm.fetch.type))
{
*/
bd->client.mwm.fetch.hints = 1;
bd->changed = 1;
/*
}
*/
}
else if (e->atom == ECORE_X_ATOM_WM_TRANSIENT_FOR)
{
bd->client.icccm.fetch.transient_for = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_CLIENT_LEADER)
{
bd->client.icccm.fetch.client_leader = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_WM_WINDOW_ROLE)
{
bd->client.icccm.fetch.window_role = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_NET_WM_ICON)
{
bd->client.netwm.fetch.icon = 1;
bd->changed = 1;
}
else if (e->atom == _QTOPIA_SOFT_MENU)
{
bd->client.qtopia.fetch.soft_menu = 1;
bd->changed = 1;
}
else if (e->atom == _QTOPIA_SOFT_MENUS)
{
bd->client.qtopia.fetch.soft_menus = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
2008-07-16 10:06:23 -07:00
{
bd->client.vkbd.fetch.state = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD)
2008-07-16 10:06:23 -07:00
{
bd->client.vkbd.fetch.vkbd = 1;
bd->changed = 1;
}
/*
2005-06-03 05:23:34 -07:00
else if (e->atom == ECORE_X_ATOM_NET_WM_USER_TIME)
{
bd->client.netwm.fetch.user_time = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT)
{
bd->client.netwm.fetch.strut = 1;
bd->changed = 1;
}
else if (e->atom == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL)
{
bd->client.netwm.fetch.strut = 1;
bd->changed = 1;
}
*/
2005-06-06 08:22:05 -07:00
else if (e->atom == ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER)
{
printf("ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER\n");
}
return 1;
}
static int
_e_border_cb_window_colormap(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Colormap *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
return 1;
}
static int
_e_border_cb_window_shape(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Shape *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (bd)
{
bd->changes.shape = 1;
bd->changed = 1;
return 1;
}
bd = e_border_find_by_window(e->win);
if (bd)
{
bd->need_shape_export = 1;
bd->changed = 1;
return 1;
}
bd = e_border_find_by_frame_window(e->win);
if (bd)
{
bd->need_shape_merge = 1;
bd->changed = 1;
return 1;
}
return 1;
}
static int
_e_border_cb_window_focus_in(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Focus_In *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
#ifdef INOUTDEBUG_FOCUS
{
time_t t;
char *ct;
const char *modes[] = {
"MODE_NORMAL",
"MODE_WHILE_GRABBED",
"MODE_GRAB",
"MODE_UNGRAB"
};
const char *details[] = {
"DETAIL_ANCESTOR",
"DETAIL_VIRTUAL",
"DETAIL_INFERIOR",
"DETAIL_NON_LINEAR",
"DETAIL_NON_LINEAR_VIRTUAL",
"DETAIL_POINTER",
"DETAIL_POINTER_ROOT",
"DETAIL_DETAIL_NONE"
};
t = time(NULL);
ct = ctime(&t);
ct[strlen(ct) - 1] = 0;
printf("FF ->IN %i 0x%x %s md=%s dt=%s\n",
e->time,
e->win,
ct,
modes[e->mode],
details[e->detail]);
}
#endif
if (e->mode == ECORE_X_EVENT_MODE_GRAB)
{
if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return 1;
}
else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
{
if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return 1;
}
e_border_focus_set(bd, 1, 0);
return 1;
}
static int
_e_border_cb_window_focus_out(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Focus_Out *e;
2005-02-07 05:51:09 -08:00
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
#ifdef INOUTDEBUG_FOCUS
{
time_t t;
char *ct;
const char *modes[] = {
"MODE_NORMAL",
"MODE_WHILE_GRABBED",
"MODE_GRAB",
"MODE_UNGRAB"
};
const char *details[] = {
"DETAIL_ANCESTOR",
"DETAIL_VIRTUAL",
"DETAIL_INFERIOR",
"DETAIL_NON_LINEAR",
"DETAIL_NON_LINEAR_VIRTUAL",
"DETAIL_POINTER",
"DETAIL_POINTER_ROOT",
"DETAIL_DETAIL_NONE"
};
t = time(NULL);
ct = ctime(&t);
ct[strlen(ct) - 1] = 0;
printf("FF <-OUT %i 0x%x %s md=%s dt=%s\n",
e->time,
e->win,
ct,
modes[e->mode],
details[e->detail]);
}
#endif
if (e->mode == ECORE_X_EVENT_MODE_NORMAL)
{
if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL) return 1;
}
else if (e->mode == ECORE_X_EVENT_MODE_GRAB)
{
if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_VIRTUAL) return 1;
}
else if (e->mode == ECORE_X_EVENT_MODE_UNGRAB)
{
/* for firefox/thunderbird (xul) menu walking */
/* NB: why did i disable this before? */
if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_POINTER) return 1;
}
else if (e->mode == ECORE_X_EVENT_MODE_WHILE_GRABBED)
{
if (e->detail == ECORE_X_EVENT_DETAIL_ANCESTOR) return 1;
else if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return 1;
}
e_border_focus_set(bd, 0, 0);
return 1;
}
2005-06-06 08:22:05 -07:00
static int
_e_border_cb_client_message(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Client_Message *e;
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
return 1;
}
static int
_e_border_cb_window_state_request(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_State_Request *e;
2005-06-07 08:35:18 -07:00
int i;
e = ev;
bd = e_border_find_by_client_window(e->win);
2005-06-07 08:35:18 -07:00
if (!bd) return 1;
for (i = 0; i < 2; i++)
e_hints_window_state_update(bd, e->state[i], e->action);
2005-05-16 08:43:15 -07:00
return 1;
}
static int
_e_border_cb_window_move_resize_request(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Window_Move_Resize_Request *e;
e = ev;
bd = e_border_find_by_client_window(e->win);
if (!bd) return 1;
if ((bd->shaded) || (bd->shading) ||
(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN) && (!e_config->allow_manip)) ||
(bd->fullscreen) || (bd->moving) ||
(bd->resize_mode != RESIZE_NONE))
return 1;
if ((e->button >= 1) && (e->button <= 3))
{
bd->mouse.last_down[e->button - 1].mx = e->x;
bd->mouse.last_down[e->button - 1].my = e->y;
bd->mouse.last_down[e->button - 1].x = bd->x;
bd->mouse.last_down[e->button - 1].y = bd->y;
bd->mouse.last_down[e->button - 1].w = bd->w;
bd->mouse.last_down[e->button - 1].h = bd->h;
}
else
{
bd->moveinfo.down.x = bd->x;
bd->moveinfo.down.y = bd->y;
bd->moveinfo.down.w = bd->w;
bd->moveinfo.down.h = bd->h;
}
bd->mouse.current.mx = e->x;
bd->mouse.current.my = e->y;
bd->moveinfo.down.button = e->button;
bd->moveinfo.down.mx = e->x;
bd->moveinfo.down.my = e->y;
2005-06-06 08:22:05 -07:00
grabbed = 1;
if (!bd->lock_user_stacking)
e_border_raise(bd);
if (e->direction == MOVE)
{
bd->cur_mouse_action = e_action_find("window_move");
2005-06-27 21:00:17 -07:00
if (bd->cur_mouse_action)
{
if ((!bd->cur_mouse_action->func.end_mouse) &&
(!bd->cur_mouse_action->func.end))
bd->cur_mouse_action = NULL;
if (bd->cur_mouse_action)
{
e_object_ref(E_OBJECT(bd->cur_mouse_action));
bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
}
}
return 1;
}
if (!_e_border_resize_begin(bd))
return 1;
switch(e->direction)
{
case RESIZE_TL:
bd->resize_mode = RESIZE_TL;
GRAV_SET(bd, ECORE_X_GRAVITY_SE);
break;
case RESIZE_T:
bd->resize_mode = RESIZE_T;
GRAV_SET(bd, ECORE_X_GRAVITY_S);
break;
case RESIZE_TR:
bd->resize_mode = RESIZE_TR;
GRAV_SET(bd, ECORE_X_GRAVITY_SW);
break;
case RESIZE_R:
bd->resize_mode = RESIZE_R;
GRAV_SET(bd, ECORE_X_GRAVITY_W);
break;
case RESIZE_BR:
bd->resize_mode = RESIZE_BR;
GRAV_SET(bd, ECORE_X_GRAVITY_NW);
case RESIZE_B:
bd->resize_mode = RESIZE_B;
GRAV_SET(bd, ECORE_X_GRAVITY_N);
break;
case RESIZE_BL:
bd->resize_mode = RESIZE_BL;
GRAV_SET(bd, ECORE_X_GRAVITY_NE);
break;
case RESIZE_L:
bd->resize_mode = RESIZE_L;
GRAV_SET(bd, ECORE_X_GRAVITY_E);
break;
default:
return 1;
}
bd->cur_mouse_action = e_action_find("window_resize");
if (bd->cur_mouse_action)
{
if ((!bd->cur_mouse_action->func.end_mouse) &&
(!bd->cur_mouse_action->func.end))
bd->cur_mouse_action = NULL;
2005-06-27 21:00:17 -07:00
if (bd->cur_mouse_action)
e_object_ref(E_OBJECT(bd->cur_mouse_action));
}
return 1;
}
2005-05-16 08:43:15 -07:00
static int
_e_border_cb_desktop_change(void *data, int ev_type, void *ev)
{
E_Border *bd;
Ecore_X_Event_Desktop_Change *e;
e = ev;
bd = e_border_find_by_client_window(e->win);
if (bd)
{
if (e->desk == 0xffffffff)
2005-05-16 08:43:15 -07:00
e_border_stick(bd);
else if (e->desk < (bd->zone->desk_x_count * bd->zone->desk_y_count))
{
E_Desk *desk;
desk = e_desk_at_pos_get(bd->zone, e->desk);
if (desk)
e_border_desk_set(bd, desk);
2005-05-16 08:43:15 -07:00
}
}
else
{
2005-05-16 08:43:15 -07:00
ecore_x_netwm_desktop_set(e->win, e->desk);
}
return 1;
}
static int
2005-06-06 08:22:05 -07:00
_e_border_cb_sync_alarm(void *data, int ev_type, void *ev)
{
E_Border *bd;
2005-06-06 08:22:05 -07:00
Ecore_X_Event_Sync_Alarm *e;
2005-02-07 05:51:09 -08:00
e = ev;
2005-06-06 08:22:05 -07:00
bd = e_border_find_by_alarm(e->alarm);
if (!bd) return 1;
2005-06-06 08:22:05 -07:00
bd->client.netwm.sync.wait--;
bd->client.netwm.sync.send_time = ecore_loop_time_get();
if (bd->client.netwm.sync.wait <= 0)
_e_border_resize_handle(bd);
return 1;
}
static int
_e_border_cb_efreet_desktop_list_change(void *data, int ev_type, void *ev)
{
Eina_List *l;
E_Border *bd;
/* mark all borders for desktop/icon updates */
EINA_LIST_FOREACH(borders, l, bd)
{
if (!bd->desktop)
{
bd->changes.icon = 1;
bd->changed = 1;
}
}
e_init_status_set(_("Desktop files scan done"));
e_init_done();
return 1;
}
static int
_e_border_cb_efreet_desktop_change(void *data, int ev_type, void *ev)
{
Efreet_Event_Desktop_Change *event;
Eina_List *l;
E_Border *bd;
event = ev;
e_init_status_set(_("Desktop file scan"));
switch (event->change)
{
case EFREET_DESKTOP_CHANGE_ADD:
/* If a desktop is added, make the borders without icon retry */
EINA_LIST_FOREACH(borders, l, bd)
{
if (!bd->desktop)
{
bd->changes.icon = 1;
bd->changed = 1;
}
}
break;
case EFREET_DESKTOP_CHANGE_REMOVE:
/* If a desktop is removed, drop the .desktop pointer */
EINA_LIST_FOREACH(borders, l, bd)
{
if (bd->desktop == event->current)
{
efreet_desktop_free(bd->desktop);
bd->desktop = NULL;
bd->changes.icon = 1;
bd->changed = 1;
}
}
break;
case EFREET_DESKTOP_CHANGE_UPDATE:
/* If a desktop is updated, point to the new desktop and update the icon */
EINA_LIST_FOREACH(borders, l, bd)
{
if (bd->desktop == event->previous)
{
efreet_desktop_free(bd->desktop);
efreet_desktop_ref(event->current);
bd->desktop = event->current;
bd->changes.icon = 1;
bd->changed = 1;
}
else if (bd->desktop == NULL)
{
bd->changes.icon = 1;
bd->changed = 1;
}
}
break;
}
return 1;
}
static int
_e_border_cb_config_icon_theme(void *data, int ev_type, void *ev)
{
Eina_List *l;
E_Border *bd;
/* mark all borders for desktop/icon updates */
EINA_LIST_FOREACH(borders, l, bd)
{
bd->changes.icon = 1;
bd->changed = 1;
}
return 1;
}
/* FIXME:
* Using '2' is bad, may change in zone flip code.
* Calculate pos from e->x and e->y
*/
static int
_e_border_cb_pointer_warp(void *data, int ev_type, void *ev)
{
E_Event_Pointer_Warp *e;
e = ev;
if (!move) return 1;
e_border_move(move, move->x + (e->curr.x - e->prev.x), move->y + (e->curr.y - e->prev.y));
return 1;
}
static void
_e_border_cb_signal_bind(void *data, Evas_Object *obj, const char *emission, const char *source)
{
E_Border *bd;
bd = data;
if (e_dnd_active()) return;
e_bindings_signal_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd),
2007-01-12 05:14:54 -08:00
emission, source);
}
static int
_e_border_cb_mouse_in(void *data, int type, void *event)
{
Ecore_X_Event_Mouse_In *ev;
E_Border *bd;
2005-02-07 05:51:09 -08:00
ev = event;
bd = data;
#ifdef INOUTDEBUG_MOUSE
{
time_t t;
char *ct;
2005-02-07 05:51:09 -08:00
const char *modes[] = {
"MODE_NORMAL",
"MODE_WHILE_GRABBED",
"MODE_GRAB",
"MODE_UNGRAB"
};
const char *details[] = {
"DETAIL_ANCESTOR",
"DETAIL_VIRTUAL",
"DETAIL_INFERIOR",
"DETAIL_NON_LINEAR",
"DETAIL_NON_LINEAR_VIRTUAL",
"DETAIL_POINTER",
"DETAIL_POINTER_ROOT",
"DETAIL_DETAIL_NONE"
};
t = time(NULL);
ct = ctime(&t);
ct[strlen(ct) - 1] = 0;
printf("@@ ->IN 0x%x 0x%x %s md=%s dt=%s\n",
ev->win, ev->event_win,
ct,
modes[ev->mode],
details[ev->detail]);
}
2005-02-07 05:51:09 -08:00
#endif
if (grabbed) return 1;
if (ev->event_win == bd->win)
{
e_focus_event_mouse_in(bd);
}
#if 0
if ((ev->win != bd->win) &&
(ev->win != bd->event_win) &&
(ev->event_win != bd->win) &&
(ev->event_win != bd->event_win))
return 1;
#else
if (ev->win != bd->event_win) return 1;
#endif
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
evas_event_feed_mouse_in(bd->bg_evas, ev->time, NULL);
return 1;
}
static int
_e_border_cb_mouse_out(void *data, int type, void *event)
{
Ecore_X_Event_Mouse_Out *ev;
E_Border *bd;
ev = event;
bd = data;
#ifdef INOUTDEBUG_MOUSE
{
time_t t;
char *ct;
2005-02-07 05:51:09 -08:00
const char *modes[] = {
"MODE_NORMAL",
"MODE_WHILE_GRABBED",
"MODE_GRAB",
"MODE_UNGRAB"
};
const char *details[] = {
"DETAIL_ANCESTOR",
"DETAIL_VIRTUAL",
"DETAIL_INFERIOR",
"DETAIL_NON_LINEAR",
"DETAIL_NON_LINEAR_VIRTUAL",
"DETAIL_POINTER",
"DETAIL_POINTER_ROOT",
"DETAIL_DETAIL_NONE"
};
t = time(NULL);
ct = ctime(&t);
ct[strlen(ct) - 1] = 0;
printf("@@ <-OUT 0x%x 0x%x %s md=%s dt=%s\n",
ev->win, ev->event_win,
ct,
modes[ev->mode],
details[ev->detail]);
}
2005-02-07 05:51:09 -08:00
#endif
if (grabbed) return 1;
#if 0
if (ev->event_win == bd->win)
{
if (bd->fullscreen)
return 1;
if ((ev->mode == ECORE_X_EVENT_MODE_UNGRAB) &&
(ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
return 1;
if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
return 1;
if ((ev->mode == ECORE_X_EVENT_MODE_NORMAL) &&
(ev->detail == ECORE_X_EVENT_DETAIL_INFERIOR))
return 1;
e_focus_event_mouse_out(bd);
}
#endif
#if 0
if ((ev->win != bd->win) &&
(ev->win != bd->event_win) &&
(ev->event_win != bd->win) &&
(ev->event_win != bd->event_win))
return 1;
#else
if (ev->win != bd->event_win) return 1;
#endif
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
if (ev->mode == ECORE_X_EVENT_MODE_GRAB)
evas_event_feed_mouse_cancel(bd->bg_evas, ev->time, NULL);
evas_event_feed_mouse_out(bd->bg_evas, ev->time, NULL);
return 1;
}
static int
_e_border_cb_mouse_wheel(void *data, int type, void *event)
{
Ecore_Event_Mouse_Wheel *ev;
E_Border *bd;
ev = event;
bd = data;
if (ev->event_window == bd->win)
{
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
if (!bd->cur_mouse_action)
e_bindings_wheel_event_handle(E_BINDING_CONTEXT_BORDER,
E_OBJECT(bd), ev);
}
evas_event_feed_mouse_wheel(bd->bg_evas, ev->direction, ev->z, ev->timestamp, NULL);
return 1;
}
static int
_e_border_cb_mouse_down(void *data, int type, void *event)
{
Ecore_Event_Mouse_Button *ev;
E_Border *bd;
2005-02-07 05:51:09 -08:00
ev = event;
bd = data;
if (ev->event_window == bd->win)
{
if ((ev->buttons >= 1) && (ev->buttons <= 3))
{
bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
bd->mouse.last_down[ev->buttons - 1].w = bd->w;
bd->mouse.last_down[ev->buttons - 1].h = bd->h;
}
else
{
bd->moveinfo.down.x = bd->x + bd->fx.x;
bd->moveinfo.down.y = bd->y + bd->fx.y;
bd->moveinfo.down.w = bd->w;
bd->moveinfo.down.h = bd->h;
}
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
if (!bd->cur_mouse_action)
{
bd->cur_mouse_action =
e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_BORDER,
E_OBJECT(bd), ev);
2005-06-27 21:00:17 -07:00
if (bd->cur_mouse_action)
{
if ((!bd->cur_mouse_action->func.end_mouse) &&
(!bd->cur_mouse_action->func.end))
bd->cur_mouse_action = NULL;
if (bd->cur_mouse_action)
e_object_ref(E_OBJECT(bd->cur_mouse_action));
}
}
e_focus_event_mouse_down(bd);
}
if (ev->window != ev->event_window)
2005-07-10 00:34:39 -07:00
{
return 1;
}
if ((ev->window != bd->event_win) && (ev->event_window != bd->win))
{
return 1;
}
if ((ev->buttons >= 1) && (ev->buttons <= 3))
{
bd->mouse.last_down[ev->buttons - 1].mx = ev->root.x;
bd->mouse.last_down[ev->buttons - 1].my = ev->root.y;
bd->mouse.last_down[ev->buttons - 1].x = bd->x + bd->fx.x;
bd->mouse.last_down[ev->buttons - 1].y = bd->y + bd->fx.y;
bd->mouse.last_down[ev->buttons - 1].w = bd->w;
bd->mouse.last_down[ev->buttons - 1].h = bd->h;
}
else
{
bd->moveinfo.down.x = bd->x + bd->fx.x;
bd->moveinfo.down.y = bd->y + bd->fx.y;
bd->moveinfo.down.w = bd->w;
bd->moveinfo.down.h = bd->h;
}
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
/*
if (bd->moving)
{
}
2005-02-07 05:51:09 -08:00
else if (bd->resize_mode != RESIZE_NONE)
{
}
else
*/
{
Evas_Button_Flags flags = EVAS_BUTTON_NONE;
2005-02-07 05:51:09 -08:00
if (ev->double_click) flags |= EVAS_BUTTON_DOUBLE_CLICK;
if (ev->triple_click) flags |= EVAS_BUTTON_TRIPLE_CLICK;
evas_event_feed_mouse_down(bd->bg_evas, ev->buttons, flags, ev->timestamp, NULL);
}
return 1;
}
static int
_e_border_cb_mouse_up(void *data, int type, void *event)
2005-02-07 05:51:09 -08:00
{
Ecore_Event_Mouse_Button *ev;
E_Border *bd;
2005-02-07 05:51:09 -08:00
ev = event;
bd = data;
if (ev->event_window == bd->win)
{
if ((ev->buttons >= 1) && (ev->buttons <= 3))
{
bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
}
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
/* also we dont pass the same params that went in - then again that */
/* should be ok as we are just ending the action if it has an end */
if (bd->cur_mouse_action)
{
if (bd->cur_mouse_action->func.end_mouse)
bd->cur_mouse_action->func.end_mouse(E_OBJECT(bd), "", ev);
else if (bd->cur_mouse_action->func.end)
bd->cur_mouse_action->func.end(E_OBJECT(bd), "");
2005-06-27 21:00:17 -07:00
e_object_unref(E_OBJECT(bd->cur_mouse_action));
bd->cur_mouse_action = NULL;
}
else
{
if (!e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd), ev))
e_focus_event_mouse_up(bd);
}
}
if (ev->window != bd->event_win) return 1;
if ((ev->buttons >= 1) && (ev->buttons <= 3))
{
bd->mouse.last_up[ev->buttons - 1].mx = ev->root.x;
bd->mouse.last_up[ev->buttons - 1].my = ev->root.y;
bd->mouse.last_up[ev->buttons - 1].x = bd->x + bd->fx.x;
bd->mouse.last_up[ev->buttons - 1].y = bd->y + bd->fx.y;
}
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
bd->drag.start = 0;
evas_event_feed_mouse_up(bd->bg_evas, ev->buttons, EVAS_BUTTON_NONE, ev->timestamp, NULL);
return 1;
}
static int
_e_border_cb_mouse_move(void *data, int type, void *event)
{
Ecore_Event_Mouse_Move *ev;
E_Border *bd;
2005-02-07 05:51:09 -08:00
ev = event;
bd = data;
if ((ev->window != bd->event_win) &&
(ev->event_window != bd->win)) return 1;
bd->mouse.current.mx = ev->root.x;
bd->mouse.current.my = ev->root.y;
if (bd->moving)
{
int x, y, new_x, new_y;
2005-02-07 05:51:09 -08:00
int new_w, new_h;
Eina_List *skiplist = NULL;
2005-02-07 05:51:09 -08:00
#if 0
if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
2005-06-06 08:22:05 -07:00
bd->client.netwm.sync.wait = 0;
if ((bd->client.netwm.sync.request) &&
(bd->client.netwm.sync.alarm) &&
(bd->client.netwm.sync.wait > 1)) return 1;
#endif
2005-06-06 08:22:05 -07:00
if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
{
x = bd->mouse.last_down[bd->moveinfo.down.button - 1].x +
(bd->mouse.current.mx - bd->moveinfo.down.mx);
y = bd->mouse.last_down[bd->moveinfo.down.button - 1].y +
(bd->mouse.current.my - bd->moveinfo.down.my);
}
else
{
x = bd->moveinfo.down.x +
(bd->mouse.current.mx - bd->moveinfo.down.mx);
y = bd->moveinfo.down.y +
(bd->mouse.current.my - bd->moveinfo.down.my);
}
new_x = x;
new_y = y;
skiplist = eina_list_append(skiplist, bd);
e_resist_container_border_position(bd->zone->container, skiplist,
bd->x, bd->y, bd->w, bd->h,
x, y, bd->w, bd->h,
2005-02-07 05:51:09 -08:00
&new_x, &new_y, &new_w, &new_h);
eina_list_free(skiplist);
bd->shelf_fix.x = 0;
bd->shelf_fix.y = 0;
bd->shelf_fix.modified = 0;
e_border_move(bd, new_x, new_y);
e_zone_flip_coords_handle(bd->zone, ev->root.x, ev->root.y);
}
else if (bd->resize_mode != RESIZE_NONE)
{
#if 0
/* FIXME: it seems we send sync requests we dont get replies to */
/* ie our sync wait > 1 often - try eclipse - its slow enough to */
/* REALLY show how bad this is */
printf("SYNC %i - %3.3f\n", bd->client.netwm.sync.wait,
ecore_loop_time_get() - bd->client.netwm.sync.time);
if ((ecore_loop_time_get() - bd->client.netwm.sync.time) > 0.5)
2005-06-06 08:22:05 -07:00
bd->client.netwm.sync.wait = 0;
if ((bd->client.netwm.sync.request) &&
(bd->client.netwm.sync.alarm) &&
(bd->client.netwm.sync.wait > 1)) return 1;
#endif
_e_border_resize_handle(bd);
}
else
{
if (bd->drag.start)
{
if ((bd->drag.x == -1) && (bd->drag.y == -1))
{
bd->drag.x = ev->root.x;
bd->drag.y = ev->root.y;
}
else
{
int dx, dy;
dx = bd->drag.x - ev->root.x;
dy = bd->drag.y - ev->root.y;
if (((dx * dx) + (dy * dy)) >
(e_config->drag_resist * e_config->drag_resist))
{
/* start drag! */
if (bd->icon_object)
{
Evas_Object *o = NULL;
Evas_Coord x, y, w, h;
const char *drag_types[] = { "enlightenment/border" };
e_object_ref(E_OBJECT(bd));
evas_object_geometry_get(bd->icon_object,
&x, &y, &w, &h);
drag_border = e_drag_new(bd->zone->container,
bd->x + bd->fx.x + x,
bd->y + bd->fx.y + y,
drag_types, 1, bd, -1,
NULL,
_e_border_cb_drag_finished);
o = e_border_icon_add(bd, drag_border->evas);
if (!o)
{
/* FIXME: fallback icon for drag */
o = evas_object_rectangle_add(drag_border->evas);
evas_object_color_set(o, 255, 255, 255, 255);
}
e_drag_object_set(drag_border, o);
e_drag_resize(drag_border, w, h);
e_drag_start(drag_border, bd->drag.x, bd->drag.y);
}
bd->drag.start = 0;
}
}
}
evas_event_feed_mouse_move(bd->bg_evas, ev->x, ev->y, ev->timestamp, NULL);
}
return 1;
}
2005-02-07 05:51:09 -08:00
static int
_e_border_cb_grab_replay(void *data, int type, void *event)
{
Ecore_Event_Mouse_Button *ev;
if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return 0;
ev = event;
if ((e_config->pass_click_on) || (e_config->always_click_to_raise) ||
(e_config->always_click_to_focus))
{
E_Border *bd;
bd = e_border_find_by_window(ev->event_window);
if (bd)
{
if (bd->cur_mouse_action)
return 0;
if (ev->event_window == bd->win)
{
if (!e_bindings_mouse_down_find(E_BINDING_CONTEXT_BORDER,
E_OBJECT(bd), ev, NULL))
return 1;
}
}
}
return 0;
}
static void
_e_border_cb_drag_finished(E_Drag *drag, int dropped)
{
E_Border *bd;
bd = drag->data;
e_object_unref(E_OBJECT(bd));
drag_border = NULL;
}
static int
_e_border_post_move_resize_job(void *data)
{
E_Border *bd;
bd = (E_Border *)data;
if ((bd->post_move) && (bd->post_resize))
{
ecore_x_window_move_resize(bd->win,
bd->x + bd->fx.x,
bd->y + bd->fx.y,
bd->w, bd->h);
}
else if (bd->post_move)
{
ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
}
else if (bd->post_resize)
{
ecore_x_window_resize(bd->win, bd->w, bd->h);
}
if (bd->post_show)
{
if (bd->visible) ecore_x_window_show(bd->win);
}
bd->post_show = 0;
bd->post_move = 0;
bd->post_resize = 0;
bd->post_job = NULL;
return 0;
}
static void
_e_border_container_layout_hook(E_Container *con)
{
_e_border_hook_call(E_BORDER_HOOK_CONTAINER_LAYOUT, con);
}
static void
_e_border_eval0(E_Border *bd)
{
int change_urgent = 0;
int rem_change = 0;
if (e_object_is_del(E_OBJECT(bd)))
{
fprintf(stderr, "ERROR: _e_border_eval(%p) with deleted border!\n", bd);
return;
}
_e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd);
/* fetch any info queued to be fetched */
if (bd->client.icccm.fetch.client_leader)
{
/* TODO: What do to if the client leader isn't mapped yet? */
E_Border *bd_leader = NULL;
bd->client.icccm.client_leader = ecore_x_icccm_client_leader_get(bd->client.win);
if (bd->client.icccm.client_leader)
bd_leader = e_border_find_by_client_window(bd->client.icccm.client_leader);
if (bd->leader)
{
if (bd->leader != bd_leader)
{
bd->leader->group = eina_list_remove(bd->leader->group, bd);
if (bd->leader->modal == bd) bd->leader->modal = NULL;
bd->leader = NULL;
}
else
bd_leader = NULL;
}
/* If this border is the leader of the group, don't register itself */
if ((bd_leader) && (bd_leader != bd))
{
bd_leader->group = eina_list_append(bd_leader->group, bd);
bd->leader = bd_leader;
/* Only set the window modal to the leader it there is no parent */
if ((e_config->modal_windows) && (bd->client.netwm.state.modal) &&
((!bd->parent) || (bd->parent->modal != bd)))
{
bd->leader->modal = bd;
if (bd->leader->focused)
e_border_focus_set(bd, 1, 1);
else
{
Eina_List *l;
E_Border *child;
EINA_LIST_FOREACH(bd->leader->group, l, child)
{
if ((child != bd) && (child->focused))
e_border_focus_set(bd, 1, 1);
}
}
}
}
bd->client.icccm.fetch.client_leader = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.title)
{
if (bd->client.icccm.title) free(bd->client.icccm.title);
bd->client.icccm.title = ecore_x_icccm_title_get(bd->client.win);
bd->client.icccm.fetch.title = 0;
if (bd->bg_object)
{
edje_object_part_text_set(bd->bg_object, "e.text.title",
bd->client.icccm.title);
}
rem_change = 1;
}
if (bd->client.netwm.fetch.name)
{
if (bd->client.netwm.name) free(bd->client.netwm.name);
2005-06-07 08:35:18 -07:00
ecore_x_netwm_name_get(bd->client.win, &bd->client.netwm.name);
bd->client.netwm.fetch.name = 0;
if (bd->bg_object)
{
edje_object_part_text_set(bd->bg_object, "e.text.title",
bd->client.netwm.name);
}
rem_change = 1;
}
if (bd->client.icccm.fetch.name_class)
{
int nc_change = 0;
char *pname, *pclass;
2005-02-07 05:51:09 -08:00
pname = bd->client.icccm.name;
pclass = bd->client.icccm.class;
ecore_x_icccm_name_class_get(bd->client.win, &bd->client.icccm.name, &bd->client.icccm.class);
if ((pname) && (bd->client.icccm.name) &&
(pclass) && (bd->client.icccm.class))
{
if (!((!strcmp(bd->client.icccm.name, pname)) &&
(!strcmp(bd->client.icccm.class, pclass))))
nc_change = 1;
}
else if (((!pname) || (!pclass)) &&
((bd->client.icccm.name) || (bd->client.icccm.class)))
nc_change = 1;
else if (((bd->client.icccm.name) || (bd->client.icccm.class)) &&
((!pname) || (!pclass)))
nc_change = 1;
if (pname) free(pname);
if (pclass) free(pclass);
if (nc_change)
bd->changes.icon = 1;
bd->client.icccm.fetch.name_class = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.state)
{
bd->client.icccm.state = ecore_x_icccm_state_get(bd->client.win);
bd->client.icccm.fetch.state = 0;
rem_change = 1;
}
if (bd->client.netwm.fetch.state)
{
e_hints_window_state_get(bd);
bd->client.netwm.fetch.state = 0;
rem_change = 1;
}
if (bd->client.e.fetch.state)
{
e_hints_window_e_state_get(bd);
bd->client.e.fetch.state = 0;
rem_change = 1;
}
if (bd->client.netwm.fetch.type)
{
e_hints_window_type_get(bd);
if ((!bd->lock_border) || (!bd->client.border.name))
bd->client.border.changed = 1;
if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DOCK)
{
if (!bd->client.netwm.state.skip_pager)
{
bd->client.netwm.state.skip_pager = 1;
bd->client.netwm.update.state = 1;
}
if (!bd->client.netwm.state.skip_taskbar)
{
bd->client.netwm.state.skip_taskbar = 1;
bd->client.netwm.update.state = 1;
}
}
bd->client.netwm.fetch.type = 0;
}
if (bd->client.icccm.fetch.machine)
{
if (bd->client.icccm.machine) free(bd->client.icccm.machine);
2005-06-09 21:19:46 -07:00
bd->client.icccm.machine = ecore_x_icccm_client_machine_get(bd->client.win);
if ((bd->client.icccm.client_leader) &&
(!bd->client.icccm.machine))
ecore_x_icccm_client_machine_get(bd->client.icccm.client_leader);
bd->client.icccm.fetch.machine = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.command)
{
if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv))
{
int i;
for (i = 0; i < bd->client.icccm.command.argc; i++)
free(bd->client.icccm.command.argv[i]);
free(bd->client.icccm.command.argv);
}
bd->client.icccm.command.argc = 0;
bd->client.icccm.command.argv = NULL;
ecore_x_icccm_command_get(bd->client.win,
&(bd->client.icccm.command.argc),
&(bd->client.icccm.command.argv));
if ((bd->client.icccm.client_leader) &&
(!bd->client.icccm.command.argv))
ecore_x_icccm_command_get(bd->client.icccm.client_leader,
&(bd->client.icccm.command.argc),
&(bd->client.icccm.command.argv));
bd->client.icccm.fetch.command = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.hints)
{
int accepts_focus = 1;
int is_urgent = 0;
2005-02-07 05:51:09 -08:00
bd->client.icccm.initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
if (ecore_x_icccm_hints_get(bd->client.win,
&accepts_focus,
&bd->client.icccm.initial_state,
&bd->client.icccm.icon_pixmap,
&bd->client.icccm.icon_mask,
&bd->client.icccm.icon_window,
&bd->client.icccm.window_group,
&is_urgent))
{
bd->client.icccm.accepts_focus = accepts_focus;
if (bd->client.icccm.urgent != is_urgent)
change_urgent = 1;
bd->client.icccm.urgent = is_urgent;
/* If this is a new window, set the state as requested. */
if ((bd->new_client) &&
(bd->client.icccm.initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC))
{
e_border_iconify(bd);
e_border_hide(bd, 1);
}
}
bd->client.icccm.fetch.hints = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.size_pos_hints)
{
int request_pos = 0;
2005-02-07 05:51:09 -08:00
if (ecore_x_icccm_size_pos_hints_get(bd->client.win,
&request_pos,
&bd->client.icccm.gravity,
&bd->client.icccm.min_w,
&bd->client.icccm.min_h,
&bd->client.icccm.max_w,
&bd->client.icccm.max_h,
&bd->client.icccm.base_w,
&bd->client.icccm.base_h,
&bd->client.icccm.step_w,
&bd->client.icccm.step_h,
&bd->client.icccm.min_aspect,
&bd->client.icccm.max_aspect))
{
bd->client.icccm.request_pos = request_pos;
}
else
{
}
if (bd->client.icccm.min_w > 32767) bd->client.icccm.min_w = 32767;
if (bd->client.icccm.min_h > 32767) bd->client.icccm.min_h = 32767;
if (bd->client.icccm.max_w > 32767) bd->client.icccm.max_w = 32767;
if (bd->client.icccm.max_h > 32767) bd->client.icccm.max_h = 32767;
if (bd->client.icccm.base_w > 32767) bd->client.icccm.base_w = 32767;
if (bd->client.icccm.base_h > 32767) bd->client.icccm.base_h = 32767;
// if (bd->client.icccm.step_w < 1) bd->client.icccm.step_w = 1;
// if (bd->client.icccm.step_h < 1) bd->client.icccm.step_h = 1;
2005-02-07 05:51:09 -08:00
bd->client.icccm.fetch.size_pos_hints = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.protocol)
{
int i, num;
Ecore_X_WM_Protocol *proto;
2005-02-07 05:51:09 -08:00
proto = ecore_x_window_prop_protocol_list_get(bd->client.win, &num);
if (proto)
{
for (i = 0; i < num; i++)
{
if (proto[i] == ECORE_X_WM_PROTOCOL_DELETE_REQUEST)
2005-06-06 08:22:05 -07:00
bd->client.icccm.delete_request = 1;
else if (proto[i] == ECORE_X_WM_PROTOCOL_TAKE_FOCUS)
bd->client.icccm.take_focus = 1;
else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_PING)
2005-06-06 08:22:05 -07:00
bd->client.netwm.ping = 1;
else if (proto[i] == ECORE_X_NET_WM_PROTOCOL_SYNC_REQUEST)
{
2005-06-06 08:22:05 -07:00
bd->client.netwm.sync.request = 1;
if (!ecore_x_netwm_sync_counter_get(bd->client.win,
&bd->client.netwm.sync.counter))
bd->client.netwm.sync.request = 0;
}
}
free(proto);
}
if (bd->client.netwm.ping)
e_border_ping(bd);
else
{
e: 1. configure/build changes to allow cross-compiling painlessly 2. pager module namespace changes - this was still dirty afdter the namespace cleanup, so clean it up 3. add a powersave subsystem - doesnt have an "automatic" way to turn on and off right now, this i think is best provided by modules (that do things like monitor acpi status's (eg close lid of laptop), AC power status etc. etc. this allows e to nicely defer "power" expensive actions to avoid disk spinups etc. 4. move to use the new ecore poller system - discussed long ago as part of power management/saving issues. now it exists 5. add a canvas idle flush call that helsp cope with the new shm greedy software x11 engine stuff 6. use the new powersave subsystem where appropriate 7. fix non-zeroed/initted memory access in e_fm_main 8. fix mem leak for e menus 9. remove ipc handlers for changed/removed config values 10. use animaotr not timer for menu scrolls - then menu scrolls obey the fps config 11. fix up timer/poll happienss of cursor idle stuff 12. remove avoid damage from popups for now - causing problems 13. change battery and temp readouts to b e shorter so they fit 14. pager can emit signals on focus change for mini-windows now 15. temperature module now uses a slave process and uses stdin/out to talk to it and get output - this makes e smoother as in my expereicne i found getting the temp on my laptop actually took like 200ms so e "hang" for 200ms while reading the acpi files - so now the subprocess does it and just writesa back to e when it gets it. ecore: 1. add ecore_pollers. see the documentation on them in doxygen comments :) 2. fix timers to only go off when they have to - bug there that made e's select time out a LOT more than it needed to. defensive coding hid the problem. now fixed. e should be much more power friendly now. 3. formatting/niceness in ecore_exe stuff 4. some comments on comments with SIGIO ideas vs. select 5. add call to be able to add an idle enterer at the start of the list of them, not just the end (as has been the default) 6. fix ecore_evas to support auto evas idler calls after 0.5 secs of idle in all canvases - and to do it right 7. if argb destination - set the shape EVENT shape (to mask out events in transparent regions much like shape does withotu translucency) 8. in ecore_x add support for the event shape evas: 1. fix cache to work properly and not just always fill up (as it seemed to like to think cahce useage dropped below 0 when it didnt and thus just over-fill) 2. software x11 engine now ONLY uses shm segments - no ximages over the socket. this ximage hack was there to avoid the 2 round trips involved in setting up an shm image - now i mitigated that wih an shm image cache pool. it keeps shm images around and repurposes them for new update regions if appropriate. this means many fewer shm creates (about 1/100th the number) and since we recycle the memory less 0 memory page filling by the kernel - in the end, i recorded about a 10-20% speedup over the old software x11 engine. simple tests i have seen up to 120% speedups. idle flush now does something - it frees all the cached shm segments. it has a hard-coded limit of 4mb worth of shm segments (or 32 segments - whichever comes first) to keep around. once can never complain much about speedups methinks :). also evas will defer sync until the NEXT frame is written - this means evas can calculate the next frame of data while x dma's/copies the images to the screen at the same time (if you hve a dual core or multi-cpu machnike or your xserver is able to use DMA to copy image data to the screen/video ram then this should see a decent speedup). SVN revision: 33448
2008-01-10 23:33:57 -08:00
if (bd->ping_poller) ecore_timer_del(bd->ping_poller);
bd->ping_poller = NULL;
}
bd->client.icccm.fetch.protocol = 0;
}
if (bd->client.icccm.fetch.transient_for)
{
/* TODO: What do to if the transient for isn't mapped yet? */
E_Border *bd_parent = NULL;
bd->client.icccm.transient_for = ecore_x_icccm_transient_for_get(bd->client.win);
if (bd->client.icccm.transient_for)
bd_parent = e_border_find_by_client_window(bd->client.icccm.transient_for);
/* If we already have a parent, remove it */
if (bd->parent)
{
if (bd_parent != bd->parent)
{
bd->parent->transients = eina_list_remove(bd->parent->transients, bd);
if (bd->parent->modal == bd) bd->parent->modal = NULL;
bd->parent = NULL;
}
else
bd_parent = NULL;
}
if ((bd_parent) && (bd_parent != bd))
{
bd_parent->transients = eina_list_append(bd_parent->transients, bd);
bd->parent = bd_parent;
e_border_layer_set(bd, bd->parent->layer);
if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
bd->parent->modal = bd;
if (e_config->focus_setting == E_FOCUS_NEW_DIALOG ||
(bd->parent->focused && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED)))
bd->take_focus = 1;
}
bd->client.icccm.fetch.transient_for = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.window_role)
{
if (bd->client.icccm.window_role) free(bd->client.icccm.window_role);
bd->client.icccm.window_role = ecore_x_icccm_window_role_get(bd->client.win);
bd->client.icccm.fetch.window_role = 0;
rem_change = 1;
}
if (bd->client.icccm.fetch.icon_name)
{
if (bd->client.icccm.icon_name) free(bd->client.icccm.icon_name);
bd->client.icccm.icon_name = ecore_x_icccm_icon_name_get(bd->client.win);
bd->client.icccm.fetch.icon_name = 0;
rem_change = 1;
}
if (bd->client.netwm.fetch.icon_name)
{
if (bd->client.netwm.icon_name) free(bd->client.netwm.icon_name);
ecore_x_netwm_icon_name_get(bd->client.win, &bd->client.netwm.icon_name);
bd->client.netwm.fetch.icon_name = 0;
rem_change = 1;
}
if (bd->client.netwm.fetch.icon)
{
if (bd->client.netwm.icons)
{
int i;
for (i = 0; i < bd->client.netwm.num_icons; i++)
free(bd->client.netwm.icons[i].data);
free(bd->client.netwm.icons);
}
if (!ecore_x_netwm_icons_get(bd->client.win,
&bd->client.netwm.icons, &bd->client.netwm.num_icons))
{
bd->client.netwm.icons = NULL;
bd->client.netwm.num_icons = 0;
}
else
bd->changes.icon = 1;
bd->client.netwm.fetch.icon = 0;
}
if (bd->client.netwm.fetch.user_time)
{
ecore_x_netwm_user_time_get(bd->client.win, &bd->client.netwm.user_time);
bd->client.netwm.fetch.user_time = 0;
}
if (bd->client.netwm.fetch.strut)
{
if (!ecore_x_netwm_strut_partial_get(bd->client.win,
&bd->client.netwm.strut.left,
&bd->client.netwm.strut.right,
&bd->client.netwm.strut.top,
&bd->client.netwm.strut.bottom,
&bd->client.netwm.strut.left_start_y,
&bd->client.netwm.strut.left_end_y,
&bd->client.netwm.strut.right_start_y,
&bd->client.netwm.strut.right_end_y,
&bd->client.netwm.strut.top_start_x,
&bd->client.netwm.strut.top_end_x,
&bd->client.netwm.strut.bottom_start_x,
&bd->client.netwm.strut.bottom_end_x))
{
ecore_x_netwm_strut_get(bd->client.win,
&bd->client.netwm.strut.left, &bd->client.netwm.strut.right,
&bd->client.netwm.strut.top, &bd->client.netwm.strut.bottom);
bd->client.netwm.strut.left_start_y = 0;
bd->client.netwm.strut.left_end_y = 0;
bd->client.netwm.strut.right_start_y = 0;
bd->client.netwm.strut.right_end_y = 0;
bd->client.netwm.strut.top_start_x = 0;
bd->client.netwm.strut.top_end_x = 0;
bd->client.netwm.strut.bottom_start_x = 0;
bd->client.netwm.strut.bottom_end_x = 0;
}
bd->client.netwm.fetch.strut = 0;
}
if (bd->client.qtopia.fetch.soft_menu)
{
e_hints_window_qtopia_soft_menu_get(bd);
bd->client.qtopia.fetch.soft_menu = 0;
rem_change = 1;
}
if (bd->client.qtopia.fetch.soft_menus)
{
e_hints_window_qtopia_soft_menus_get(bd);
bd->client.qtopia.fetch.soft_menus = 0;
rem_change = 1;
}
2008-07-16 10:06:23 -07:00
if (bd->client.vkbd.fetch.state)
{
e_hints_window_virtual_keyboard_state_get(bd);
bd->client.vkbd.fetch.state = 0;
rem_change = 1;
}
if (bd->client.vkbd.fetch.vkbd)
{
e_hints_window_virtual_keyboard_get(bd);
bd->client.vkbd.fetch.vkbd = 0;
rem_change = 1;
}
if (bd->changes.shape)
{
Ecore_X_Rectangle *rects;
int num;
bd->changes.shape = 0;
rects = ecore_x_window_shape_rectangles_get(bd->client.win, &num);
if (rects)
{
int cw = 0, ch = 0;
/* This doesnt fix the race, but makes it smaller. we detect
* this and if cw and ch != client w/h then mark this as needing
* a shape change again to fixup next event loop.
*/
ecore_x_window_size_get(bd->client.win, &cw, &ch);
if ((cw != bd->client.w) || (ch != bd->client.h))
bd->changes.shape = 1;
if ((num == 1) &&
(rects[0].x == 0) &&
(rects[0].y == 0) &&
(rects[0].width == cw) &&
(rects[0].height == ch))
{
if (bd->client.shaped)
{
bd->client.shaped = 0;
if (!bd->bordername)
bd->client.border.changed = 1;
}
}
else
{
if (!bd->client.shaped)
{
bd->client.shaped = 1;
if (!bd->bordername)
bd->client.border.changed = 1;
}
}
free(rects);
}
else
{
bd->client.shaped = 0;
if (!bd->bordername)
bd->client.border.changed = 1;
}
bd->need_shape_merge = 1;
}
if (bd->client.mwm.fetch.hints)
{
int pb;
bd->client.mwm.exists =
ecore_x_mwm_hints_get(bd->client.win,
&bd->client.mwm.func,
&bd->client.mwm.decor,
&bd->client.mwm.input);
pb = bd->client.mwm.borderless;
bd->client.mwm.borderless = 0;
if (bd->client.mwm.exists)
{
if ((!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_ALL)) &&
(!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_TITLE)) &&
(!(bd->client.mwm.decor & ECORE_X_MWM_HINT_DECOR_BORDER)))
bd->client.mwm.borderless = 1;
}
if (bd->client.mwm.borderless != pb)
{
if ((!bd->lock_border) || (!bd->client.border.name))
bd->client.border.changed = 1;
}
bd->client.mwm.fetch.hints = 0;
rem_change = 1;
}
if (bd->client.netwm.update.state)
{
e_hints_window_state_set(bd);
/* Some stats might change the border, like modal */
if (((!bd->lock_border) || (!bd->client.border.name)) &&
(!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
{
bd->client.border.changed = 1;
}
if (bd->parent)
{
if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
{
bd->parent->modal = bd;
if (bd->parent->focused)
e_border_focus_set(bd, 1, 1);
}
}
else if (bd->leader)
{
if ((e_config->modal_windows) && (bd->client.netwm.state.modal))
{
bd->leader->modal = bd;
if (bd->leader->focused)
e_border_focus_set(bd, 1, 1);
else
{
Eina_List *l;
E_Border *child;
EINA_LIST_FOREACH(bd->leader->group, l, child)
{
if ((child != bd) && (child->focused))
e_border_focus_set(bd, 1, 1);
}
}
}
}
bd->client.netwm.update.state = 0;
}
if (bd->new_client)
{
E_Event_Border_Add *ev;
ev = E_NEW(E_Event_Border_Add, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_add_event");
ecore_event_add(E_EVENT_BORDER_ADD, ev, _e_border_event_border_add_free, NULL);
if ((!bd->lock_border) || (!bd->client.border.name))
bd->client.border.changed = 1;
}
/* PRE_POST_FETCH calls e_remember apply for new client */
2008-07-16 10:06:23 -07:00
_e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_POST_FETCH, bd);
_e_border_hook_call(E_BORDER_HOOK_EVAL_POST_FETCH, bd);
_e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_BORDER_ASSIGN, bd);
if (bd->need_reparent)
{
ecore_x_window_save_set_add(bd->client.win);
ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0);
if (bd->visible)
ecore_x_window_show(bd->client.win);
bd->need_reparent = 0;
}
if ((bd->client.border.changed) && (!bd->shaded) &&
(!(((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN))))
{
Evas_Object *o;
char buf[4096];
const char *bordername;
Evas_Coord cx, cy, cw, ch;
int l, r, t, b;
int ok;
if (bd->fullscreen)
bordername = "borderless";
else if (bd->bordername)
bordername = bd->bordername;
else if ((bd->client.mwm.borderless) || (bd->borderless))
bordername = "borderless";
else if (((bd->client.icccm.transient_for != 0) ||
(bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)) &&
(bd->client.icccm.min_w == bd->client.icccm.max_w) &&
(bd->client.icccm.min_h == bd->client.icccm.max_h))
bordername = "noresize_dialog";
else if ((bd->client.icccm.min_w == bd->client.icccm.max_w) &&
(bd->client.icccm.min_h == bd->client.icccm.max_h))
bordername = "noresize";
else if (bd->client.shaped)
bordername = "shaped";
else if ((!bd->client.icccm.accepts_focus) &&
(!bd->client.icccm.take_focus))
bordername = "nofocus";
else if (bd->client.icccm.urgent)
bordername = "urgent";
else if ((bd->client.icccm.transient_for != 0) ||
(bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
bordername = "dialog";
else if (bd->client.netwm.state.modal)
bordername = "modal";
else if ((bd->client.netwm.state.skip_taskbar) ||
(bd->client.netwm.state.skip_pager))
bordername = "skipped";
else
bordername = e_config->theme_default_border_style;
if (!bordername) bordername = "default";
if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername)))
{
if (bd->client.border.name) eina_stringshare_del(bd->client.border.name);
bd->client.border.name = eina_stringshare_add(bordername);
if (bd->bg_object)
{
bd->w -= (bd->client_inset.l + bd->client_inset.r);
bd->h -= (bd->client_inset.t + bd->client_inset.b);
bd->client_inset.l = 0;
bd->client_inset.r = 0;
bd->client_inset.t = 0;
bd->client_inset.b = 0;
bd->changes.size = 1;
evas_object_del(bd->bg_object);
}
o = edje_object_add(bd->bg_evas);
snprintf(buf, sizeof(buf), "e/widgets/border/%s/border",
bd->client.border.name);
ok = e_theme_edje_object_set(o, "base/theme/borders", buf);
if ((!ok) && (strcmp(bd->client.border.name, "borderless")))
{
ok = e_theme_edje_object_set(o, "base/theme/borders",
"e/widgets/border/default/border");
if (ok)
{
/* Reset default border style to default */
if (e_config->theme_default_border_style)
eina_stringshare_del(e_config->theme_default_border_style);
e_config->theme_default_border_style = eina_stringshare_add("default");
e_config_save_queue();
}
}
bd->shaped = 0;
if (ok)
{
const char *shape_option;
bd->bg_object = o;
shape_option = edje_object_data_get(o, "shaped");
2007-08-18 03:37:16 -07:00
if (shape_option && !strcmp(shape_option, "1"))
{
bd->shaped = 1;
}
if (bd->client.netwm.name)
edje_object_part_text_set(o, "e.text.title",
bd->client.netwm.name);
else if (bd->client.icccm.title)
edje_object_part_text_set(o, "e.text.title",
bd->client.icccm.title);
evas_object_resize(o, 1000, 1000);
edje_object_calc_force(o);
edje_object_part_geometry_get(o, "e.swallow.client", &cx, &cy, &cw, &ch);
l = cx;
r = 1000 - (cx + cw);
t = cy;
b = 1000 - (cy + ch);
}
else
{
evas_object_del(o);
bd->bg_object = NULL;
l = 0;
r = 0;
t = 0;
b = 0;
}
bd->client_inset.l = l;
bd->client_inset.r = r;
bd->client_inset.t = t;
bd->client_inset.b = b;
ecore_x_netwm_frame_size_set(bd->client.win, l, r, t, b);
ecore_x_e_frame_size_set(bd->client.win, l, r, t, b);
bd->w += (bd->client_inset.l + bd->client_inset.r);
bd->h += (bd->client_inset.t + bd->client_inset.b);
ecore_evas_shaped_set(bd->bg_ecore_evas, bd->shaped);
bd->changes.size = 1;
ecore_x_window_move(bd->client.shell_win, l, t);
if (bd->bg_object)
2005-11-11 00:03:49 -08:00
{
edje_object_signal_callback_add(bd->bg_object, "*", "*",
_e_border_cb_signal_bind, bd);
if (bd->focused)
{
edje_object_signal_emit(bd->bg_object, "e,state,focused", "e");
if (bd->icon_object)
edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
}
if (bd->shaded)
edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
if (bd->sticky)
edje_object_signal_emit(bd->bg_object, "e,state,sticky", "e");
if ((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN)
edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e");
else if ((bd->maximized & E_MAXIMIZE_TYPE) != E_MAXIMIZE_NONE)
edje_object_signal_emit(bd->bg_object, "e,action,maximize", "e");
if (bd->hung)
edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
if (bd->client.icccm.urgent)
edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
2007-11-06 00:46:54 -08:00
// FIXME: in eval -do differently
// edje_object_message_signal_process(bd->bg_object);
// e_border_frame_recalc(bd);
evas_object_move(bd->bg_object, 0, 0);
evas_object_resize(bd->bg_object, bd->w, bd->h);
evas_object_show(bd->bg_object);
2005-11-11 00:03:49 -08:00
}
}
bd->client.border.changed = 0;
if (bd->icon_object)
{
if (bd->bg_object)
{
evas_object_show(bd->icon_object);
edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
}
else
evas_object_hide(bd->icon_object);
}
}
if (rem_change)
e_remember_update(bd);
if (change_urgent)
{
if (bd->client.icccm.urgent)
edje_object_signal_emit(bd->bg_object, "e,state,urgent", "e");
else
edje_object_signal_emit(bd->bg_object, "e,state,not_urgent", "e");
E_Event_Border_Urgent_Change *ev;
ev = E_NEW(E_Event_Border_Urgent_Change, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
ecore_event_add(E_EVENT_BORDER_URGENT_CHANGE, ev,
_e_border_event_border_urgent_change_free, NULL);
}
_e_border_hook_call(E_BORDER_HOOK_EVAL_POST_BORDER_ASSIGN, bd);
}
static void
_e_border_eval(E_Border *bd)
{
E_Event_Border_Property *event;
E_Border_Pending_Move_Resize *pnd;
int rem_change = 0;
int send_event = 1;
int zx, zy, zw, zh;
if (e_object_is_del(E_OBJECT(bd)))
{
fprintf(stderr, "ERROR: _e_border_eval(%p) with deleted border!\n", bd);
return;
}
if (bd->zone)
e_zone_useful_geometry_get(bd->zone, &zx, &zy, &zw, &zh);
_e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd);
if (bd->new_client)
{
if (bd->re_manage)
{
bd->x -= bd->client_inset.l;
bd->y -= bd->client_inset.t;
bd->changes.pos = 1;
bd->placed = 1;
}
else if (!bd->placed)
{
if (bd->client.icccm.request_pos)
{
Ecore_X_Window_Attributes *att;
int bw;
2005-02-07 05:51:09 -08:00
att = &bd->client.initial_attributes;
bw = att->border * 2;
switch (bd->client.icccm.gravity)
{
case ECORE_X_GRAVITY_N:
bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
bd->y = att->y;
break;
case ECORE_X_GRAVITY_NE:
bd->x = (att->x - (bw)) - (bd->client_inset.l);
bd->y = att->y;
break;
case ECORE_X_GRAVITY_E:
bd->x = (att->x - (bw)) - (bd->client_inset.l);
bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
break;
case ECORE_X_GRAVITY_SE:
bd->x = (att->x - (bw)) - (bd->client_inset.l);
bd->y = (att->y - (bw)) - (bd->client_inset.t);
break;
case ECORE_X_GRAVITY_S:
bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
bd->y = (att->y - (bw)) - (bd->client_inset.t);
break;
case ECORE_X_GRAVITY_SW:
bd->x = att->x;
bd->y = (att->y - (bw)) - (bd->client_inset.t);
break;
case ECORE_X_GRAVITY_W:
bd->x = att->x;
bd->y = (att->y - (bw)) - (bd->client_inset.t);
break;
case ECORE_X_GRAVITY_CENTER:
bd->x = (att->x - (bw / 2)) - (bd->client_inset.l / 2);
bd->y = (att->y - (bw / 2)) - (bd->client_inset.t / 2);
break;
case ECORE_X_GRAVITY_NW:
default:
bd->x = att->x;
bd->y = att->y;
}
bd->changes.pos = 1;
bd->placed = 1;
}
else
{
/* FIXME: special placement for dialogs etc. etc. etc goes
* here */
/* FIXME: what if parent is not on this desktop - or zone? */
if ((bd->parent) && (bd->parent->visible))
{
bd->x = bd->parent->x + ((bd->parent->w - bd->w) / 2);
bd->y = bd->parent->y + ((bd->parent->h - bd->h) / 2);
bd->changes.pos = 1;
bd->placed = 1;
}
#if 0
else if ((bd->leader) && (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))
{
/* TODO: Place in center of group */
}
#endif
else if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
{
bd->x = zx + ((zw - bd->w) / 2);
bd->y = zy + ((zh - bd->h) / 2);
bd->changes.pos = 1;
bd->placed = 1;
}
if (!bd->placed)
{
Eina_List *skiplist = NULL;
int new_x, new_y;
2005-02-07 05:51:09 -08:00
if (zw > bd->w)
new_x = zx + (rand() % (zw - bd->w));
else
new_x = zx;
if (zh > bd->h)
new_y = zy + (rand() % (zh - bd->h));
else
new_y = zy;
if ((e_config->window_placement_policy == E_WINDOW_PLACEMENT_SMART)||(e_config->window_placement_policy == E_WINDOW_PLACEMENT_ANTIGADGET))
{
skiplist = eina_list_append(skiplist, bd);
e_place_zone_region_smart(bd->zone, skiplist,
bd->x, bd->y, bd->w, bd->h,
&new_x, &new_y);
eina_list_free(skiplist);
}
2005-09-22 10:10:02 -07:00
else if (e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL)
{
e_place_zone_manual(bd->zone, bd->w, bd->client_inset.t,
2005-09-22 10:10:02 -07:00
&new_x, &new_y);
}
else
{
e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h,
bd->client_inset.t, &new_x, &new_y);
}
bd->x = new_x;
bd->y = new_y;
bd->changes.pos = 1;
}
}
}
EINA_LIST_FREE(bd->pending_move_resize, pnd)
{
if ((!bd->lock_client_location) && (pnd->move))
{
bd->x = pnd->x;
bd->y = pnd->y;
bd->changes.pos = 1;
bd->placed = 1;
if (pnd->without_border)
{
bd->x -= bd->client_inset.l;
bd->y -= bd->client_inset.t;
}
}
if ((!bd->lock_client_size) && (pnd->resize))
{
bd->w = pnd->w + (bd->client_inset.l + bd->client_inset.r);
bd->h = pnd->h + (bd->client_inset.t + bd->client_inset.b);
bd->client.w = pnd->w;
bd->client.h = pnd->h;
bd->changes.size = 1;
}
free(pnd);
}
/* Recreate state */
e_hints_window_init(bd);
if ((bd->client.e.state.centered) &&
((!bd->remember) ||
((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS)))))
{
bd->x = zx + (zw - bd->w) / 2;
bd->y = zy + (zh - bd->h) / 2;
bd->changes.pos = 1;
bd->placed = 1;
}
2005-09-22 10:10:02 -07:00
_e_border_client_move_resize_send(bd);
/* if the explicit geometry request asks for the app to be
* in another zone - well move it there */
{
E_Zone *zone;
zone = e_container_zone_at_point_get(bd->zone->container,
bd->x + (bd->w / 2),
bd->y + (bd->h / 2));
if (!zone)
zone = e_container_zone_at_point_get(bd->zone->container,
bd->x,
bd->y);
if (!zone)
zone = e_container_zone_at_point_get(bd->zone->container,
bd->x + bd->w - 1,
bd->y);
if (!zone)
zone = e_container_zone_at_point_get(bd->zone->container,
bd->x + bd->w - 1,
bd->y + bd->h - 1);
if (!zone)
zone = e_container_zone_at_point_get(bd->zone->container,
bd->x,
bd->y + bd->h - 1);
if ((zone) && (zone != bd->zone))
{
e_border_zone_set(bd, zone);
/* e_zone_useful_geometry_get(zone, &zx, &zy, &zw, &zh); */
}
}
}
_e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd);
/* effect changes to the window border itself */
if ((bd->changes.shading))
{
/* show at start of unshade (but don't hide until end of shade) */
if (bd->shaded)
2005-04-28 03:09:00 -07:00
ecore_x_window_raise(bd->client.shell_win);
bd->changes.shading = 0;
rem_change = 1;
}
if ((bd->changes.shaded) && (bd->changes.pos) && (bd->changes.size))
{
if (bd->shaded)
2005-04-28 03:34:47 -07:00
ecore_x_window_lower(bd->client.shell_win);
else
2005-04-28 03:09:00 -07:00
ecore_x_window_raise(bd->client.shell_win);
bd->changes.shaded = 0;
rem_change = 1;
}
else if ((bd->changes.shaded) && (bd->changes.pos))
{
if (bd->shaded)
2005-04-28 03:34:47 -07:00
ecore_x_window_lower(bd->client.shell_win);
else
2005-04-28 03:09:00 -07:00
ecore_x_window_raise(bd->client.shell_win);
bd->changes.size = 1;
bd->changes.shaded = 0;
rem_change = 1;
}
else if ((bd->changes.shaded) && (bd->changes.size))
{
if (bd->shaded)
2005-04-28 03:34:47 -07:00
ecore_x_window_lower(bd->client.shell_win);
else
2005-04-28 03:09:00 -07:00
ecore_x_window_raise(bd->client.shell_win);
bd->changes.shaded = 0;
rem_change = 1;
}
else if (bd->changes.shaded)
{
if (bd->shaded)
2005-04-28 03:34:47 -07:00
ecore_x_window_lower(bd->client.shell_win);
else
2005-04-28 03:09:00 -07:00
ecore_x_window_raise(bd->client.shell_win);
bd->changes.size = 1;
bd->changes.shaded = 0;
rem_change = 1;
}
2005-02-07 05:51:09 -08:00
if (bd->changes.size)
{
int x = 0, y = 0, xx = 0, yy = 0;
if ((bd->shaded) && (!bd->shading))
{
evas_obscured_clear(bd->bg_evas);
}
else
{
xx = bd->w - (bd->client_inset.l + bd->client_inset.r);
yy = bd->h - (bd->client_inset.t + bd->client_inset.b);
evas_obscured_clear(bd->bg_evas);
evas_obscured_rectangle_add(bd->bg_evas,
bd->client_inset.l, bd->client_inset.t, xx, yy);
if (bd->shading)
{
if (bd->shade.dir == E_DIRECTION_UP)
{
y = yy - bd->client.h;
}
else if (bd->shade.dir == E_DIRECTION_LEFT)
{
x = xx - bd->client.w;
}
}
}
if (!bd->changes.pos)
{
if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job, bd);
bd->post_resize = 1;
}
else
{
ecore_x_window_move_resize(bd->win,
bd->x + bd->fx.x,
bd->y + bd->fx.y,
bd->w, bd->h);
}
ecore_x_window_move_resize(bd->event_win, 0, 0, bd->w, bd->h);
if ((!bd->shaded) || (bd->shading))
ecore_x_window_move_resize(bd->client.shell_win,
bd->client_inset.l, bd->client_inset.t, xx, yy);
if (bd->internal_ecore_evas)
ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h);
else
ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h);
ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h);
evas_object_resize(bd->bg_object, bd->w, bd->h);
e_container_shape_resize(bd->shape, bd->w, bd->h);
if (bd->changes.pos)
e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
_e_border_client_move_resize_send(bd);
bd->changes.pos = 0;
bd->changes.size = 0;
rem_change = 1;
}
else if (bd->changes.pos)
{
if (1)
{
if (bd->post_job) ecore_idle_enterer_del(bd->post_job);
bd->post_job = ecore_idle_enterer_add(_e_border_post_move_resize_job,
bd);
bd->post_move = 1;
}
else
{
ecore_x_window_move(bd->win, bd->x + bd->fx.x, bd->y + bd->fx.y);
}
e_container_shape_move(bd->shape, bd->x + bd->fx.x, bd->y + bd->fx.y);
_e_border_client_move_resize_send(bd);
bd->changes.pos = 0;
rem_change = 1;
}
if (bd->changes.reset_gravity)
{
GRAV_SET(bd, ECORE_X_GRAVITY_NW);
bd->changes.reset_gravity = 0;
rem_change = 1;
}
if (bd->need_shape_merge)
{
if ((bd->shaped) || (bd->client.shaped))
{
Ecore_X_Window twin, twin2;
int x, y;
twin = ecore_x_window_override_new(bd->win, 0, 0, bd->w, bd->h);
if (bd->shaped)
ecore_x_window_shape_window_set(twin, bd->bg_win);
else
{
Ecore_X_Rectangle rects[4];
rects[0].x = 0;
rects[0].y = 0;
rects[0].width = bd->w;
rects[0].height = bd->client_inset.t;
rects[1].x = 0;
rects[1].y = bd->client_inset.t;
rects[1].width = bd->client_inset.l;
rects[1].height = bd->h - bd->client_inset.t - bd->client_inset.b;
rects[2].x = bd->w - bd->client_inset.r;
rects[2].y = bd->client_inset.t;
rects[2].width = bd->client_inset.r;
rects[2].height = bd->h - bd->client_inset.t - bd->client_inset.b;
rects[3].x = 0;
rects[3].y = bd->h - bd->client_inset.b;
rects[3].width = bd->w;
rects[3].height = bd->client_inset.b;
ecore_x_window_shape_rectangles_set(twin, rects, 4);
}
twin2 = ecore_x_window_override_new(bd->win, 0, 0,
bd->w - bd->client_inset.l - bd->client_inset.r,
bd->h - bd->client_inset.t - bd->client_inset.b);
x = 0;
y = 0;
if ((bd->shading) || (bd->shaded))
{
2005-10-04 04:15:33 -07:00
if (bd->shade.dir == E_DIRECTION_UP)
y = bd->h - bd->client_inset.t - bd->client_inset.b - bd->client.h;
else if (bd->shade.dir == E_DIRECTION_LEFT)
x = bd->w - bd->client_inset.l - bd->client_inset.r - bd->client.w;
}
ecore_x_window_shape_window_set_xy(twin2, bd->client.win,
x, y);
ecore_x_window_shape_rectangle_clip(twin2, 0, 0,
bd->w - bd->client_inset.l - bd->client_inset.r,
bd->h - bd->client_inset.t - bd->client_inset.b);
ecore_x_window_shape_window_add_xy(twin, twin2,
bd->client_inset.l,
bd->client_inset.t);
ecore_x_window_free(twin2);
ecore_x_window_shape_window_set(bd->win, twin);
ecore_x_window_free(twin);
}
else
ecore_x_window_shape_mask_set(bd->win, 0);
// bd->need_shape_export = 1;
bd->need_shape_merge = 0;
}
if (bd->need_shape_export)
{
Ecore_X_Rectangle *rects, *orects;
int num;
rects = ecore_x_window_shape_rectangles_get(bd->win, &num);
if (rects)
{
int changed;
changed = 1;
if ((num == bd->shape_rects_num) && (bd->shape_rects))
{
int i;
orects = bd->shape_rects;
changed = 0;
for (i = 0; i < num; i++)
{
if (rects[i].x < 0)
{
rects[i].width -= rects[i].x;
rects[i].x = 0;
}
if ((rects[i].x + rects[i].width) > bd->w)
rects[i].width = rects[i].width - rects[i].x;
if (rects[i].y < 0)
{
rects[i].height -= rects[i].y;
rects[i].y = 0;
}
if ((rects[i].y + rects[i].height) > bd->h)
rects[i].height = rects[i].height - rects[i].y;
if ((orects[i].x != rects[i].x) ||
(orects[i].y != rects[i].y) ||
(orects[i].width != rects[i].width) ||
(orects[i].height != rects[i].height))
{
changed = 1;
break;
}
}
}
if (changed)
{
if (bd->client.shaped)
e_container_shape_solid_rect_set(bd->shape, 0, 0, 0, 0);
else
e_container_shape_solid_rect_set(bd->shape, bd->client_inset.l, bd->client_inset.t, bd->client.w, bd->client.h);
2005-09-05 08:24:07 -07:00
E_FREE(bd->shape_rects);
bd->shape_rects = rects;
bd->shape_rects_num = num;
e_container_shape_rects_set(bd->shape, rects, num);
}
else
free(rects);
}
else
{
2005-09-05 08:24:07 -07:00
E_FREE(bd->shape_rects);
bd->shape_rects = NULL;
bd->shape_rects_num = 0;
e_container_shape_rects_set(bd->shape, NULL, 0);
}
bd->need_shape_export = 0;
}
if ((bd->changes.visible) && (bd->visible) && (bd->new_client))
{
int x, y;
if ((!bd->placed) && (!bd->re_manage) &&
2005-09-22 10:10:02 -07:00
(e_config->window_placement_policy == E_WINDOW_PLACEMENT_MANUAL) &&
(!((bd->client.icccm.transient_for != 0) ||
(bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG))) &&
2005-09-22 10:10:02 -07:00
(!move) && (!resize))
{
/* Set this window into moving state */
bd->cur_mouse_action = e_action_find("window_move");
if (bd->cur_mouse_action)
{
if ((!bd->cur_mouse_action->func.end_mouse) &&
(!bd->cur_mouse_action->func.end))
2005-09-22 10:10:02 -07:00
bd->cur_mouse_action = NULL;
if (bd->cur_mouse_action)
{
ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
bd->x = x - (bd->w >> 1);
bd->y = y - (bd->client_inset.t >> 1);
bd->changed = 1;
bd->changes.pos = 1;
_e_border_client_move_resize_send(bd);
2005-09-22 10:10:02 -07:00
}
}
}
ecore_evas_show(bd->bg_ecore_evas);
if (bd->post_job)
{
bd->post_show = 1;
}
else
{
ecore_x_window_show(bd->win);
}
if (bd->cur_mouse_action)
{
bd->moveinfo.down.x = bd->x + bd->fx.x;
bd->moveinfo.down.y = bd->y + bd->fx.y;
bd->moveinfo.down.w = bd->w;
bd->moveinfo.down.h = bd->h;
bd->mouse.current.mx = x;
bd->mouse.current.my = y;
bd->moveinfo.down.button = 0;
bd->moveinfo.down.mx = x;
bd->moveinfo.down.my = y;
grabbed = 1;
e_object_ref(E_OBJECT(bd->cur_mouse_action));
bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL);
if (e_config->border_raise_on_mouse_action)
e_border_raise(bd);
e_border_focus_set(bd, 1, 1);
}
bd->changes.visible = 0;
rem_change = 1;
}
if (bd->changes.icon)
{
if (bd->icon_object)
{
evas_object_del(bd->icon_object);
bd->icon_object = NULL;
}
if (bd->remember && bd->remember->prop.desktop_file)
{
const char *desktop = bd->remember->prop.desktop_file;
bd->desktop = efreet_desktop_new(desktop);
if (!bd->desktop)
bd->desktop = efreet_util_desktop_name_find(desktop);
}
if (!bd->desktop)
{
if ((bd->client.icccm.name) && (bd->client.icccm.class))
bd->desktop = efreet_util_desktop_wm_class_find(bd->client.icccm.name,
bd->client.icccm.class);
}
if (!bd->desktop)
{
bd->desktop = e_exec_startup_id_pid_find(bd->client.netwm.startup_id,
bd->client.netwm.pid);
if (bd->desktop) efreet_desktop_ref(bd->desktop);
}
if (!bd->desktop && bd->client.icccm.name)
{
/* this works for most cases as fallback. useful when app is
run from a shell */
bd->desktop = efreet_util_desktop_exec_find(bd->client.icccm.name);
}
if (!bd->desktop && bd->client.icccm.transient_for)
{
E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for);
if (bd2 && bd2->desktop)
{
efreet_desktop_ref(bd2->desktop);
bd->desktop = bd2->desktop;
}
}
if (bd->desktop)
{
ecore_x_window_prop_string_set(bd->client.win, E_ATOM_DESKTOP_FILE,
bd->desktop->orig_path);
}
bd->icon_object = e_border_icon_add(bd, bd->bg_evas);
2005-11-11 00:03:49 -08:00
if ((bd->focused) && (bd->icon_object))
edje_object_signal_emit(bd->icon_object, "e,state,focused", "e");
if (bd->bg_object)
{
evas_object_show(bd->icon_object);
edje_object_part_swallow(bd->bg_object, "e.swallow.icon", bd->icon_object);
}
else
evas_object_hide(bd->icon_object);
{
E_Event_Border_Icon_Change *ev;
ev = E_NEW(E_Event_Border_Icon_Change, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_icon_change_event");
ecore_event_add(E_EVENT_BORDER_ICON_CHANGE, ev,
_e_border_event_border_icon_change_free, NULL);
}
bd->changes.icon = 0;
}
bd->new_client = 0;
bd->changed = 0;
bd->changes.stack = 0;
bd->changes.prop = 0;
bd->changes.border = 0;
if ((bd->take_focus) || (bd->want_focus))
{
bd->take_focus = 0;
if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) ||
(bd->want_focus))
{
bd->want_focus = 0;
if (!bd->lock_focus_out)
{
e_border_focus_set_with_pointer(bd);
}
}
else
{
if (bd->client.netwm.type == ECORE_X_WINDOW_TYPE_DIALOG)
{
if ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) ||
((e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED) &&
(e_border_find_by_client_window(bd->client.icccm.transient_for) ==
e_border_focused_get())))
{
if (!bd->lock_focus_out)
e_border_focus_set_with_pointer(bd);
}
}
}
}
if (bd->need_maximize)
{
E_Maximize max;
max = bd->maximized;
bd->maximized = E_MAXIMIZE_NONE;
e_border_maximize(bd, max);
bd->need_maximize = 0;
}
if (bd->need_fullscreen)
{
e_border_fullscreen(bd, e_config->fullscreen_policy);
bd->need_fullscreen = 0;
}
if (rem_change)
e_remember_update(bd);
if (send_event) // FIXME: send only if a property changed - above need to
// check on that. for now - always send.
{
event = E_NEW(E_Event_Border_Property, 1);
event->border = bd;
e_object_ref(E_OBJECT(bd));
ecore_event_add(E_EVENT_BORDER_PROPERTY, event, _e_border_event_border_property_free, NULL);
}
_e_border_hook_call(E_BORDER_HOOK_EVAL_END, bd);
}
static void
_e_border_moveinfo_gather(E_Border *bd, const char *source)
{
if (e_util_glob_match(source, "mouse,*,1")) bd->moveinfo.down.button = 1;
else if (e_util_glob_match(source, "mouse,*,2")) bd->moveinfo.down.button = 2;
else if (e_util_glob_match(source, "mouse,*,3")) bd->moveinfo.down.button = 3;
else bd->moveinfo.down.button = 0;
if ((bd->moveinfo.down.button >= 1) && (bd->moveinfo.down.button <= 3))
{
bd->moveinfo.down.mx = bd->mouse.last_down[bd->moveinfo.down.button - 1].mx;
bd->moveinfo.down.my = bd->mouse.last_down[bd->moveinfo.down.button - 1].my;
}
else
{
bd->moveinfo.down.mx = bd->mouse.current.mx;
bd->moveinfo.down.my = bd->mouse.current.my;
}
}
static void
_e_border_resize_handle(E_Border *bd)
{
int x, y, w, h;
2005-02-07 05:51:09 -08:00
int new_x, new_y, new_w, new_h;
int tw, th;
Eina_List *skiplist = NULL;
2005-02-07 05:51:09 -08:00
x = bd->x;
y = bd->y;
w = bd->w;
h = bd->h;
2005-02-07 05:51:09 -08:00
if ((bd->resize_mode == RESIZE_TR) ||
(bd->resize_mode == RESIZE_R) ||
(bd->resize_mode == RESIZE_BR))
{
if ((bd->moveinfo.down.button >= 1) &&
(bd->moveinfo.down.button <= 3))
w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w +
(bd->mouse.current.mx - bd->moveinfo.down.mx);
else
w = bd->moveinfo.down.w + (bd->mouse.current.mx - bd->moveinfo.down.mx);
}
else if ((bd->resize_mode == RESIZE_TL) ||
(bd->resize_mode == RESIZE_L) ||
(bd->resize_mode == RESIZE_BL))
{
if ((bd->moveinfo.down.button >= 1) &&
(bd->moveinfo.down.button <= 3))
w = bd->mouse.last_down[bd->moveinfo.down.button - 1].w -
(bd->mouse.current.mx - bd->moveinfo.down.mx);
else
w = bd->moveinfo.down.w - (bd->mouse.current.mx - bd->moveinfo.down.mx);
}
2005-02-07 05:51:09 -08:00
if ((bd->resize_mode == RESIZE_TL) ||
(bd->resize_mode == RESIZE_T) ||
(bd->resize_mode == RESIZE_TR))
{
if ((bd->moveinfo.down.button >= 1) &&
(bd->moveinfo.down.button <= 3))
h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h -
(bd->mouse.current.my - bd->moveinfo.down.my);
else
h = bd->moveinfo.down.h - (bd->mouse.current.my - bd->moveinfo.down.my);
}
else if ((bd->resize_mode == RESIZE_BL) ||
(bd->resize_mode == RESIZE_B) ||
(bd->resize_mode == RESIZE_BR))
{
if ((bd->moveinfo.down.button >= 1) &&
(bd->moveinfo.down.button <= 3))
h = bd->mouse.last_down[bd->moveinfo.down.button - 1].h +
(bd->mouse.current.my - bd->moveinfo.down.my);
else
h = bd->moveinfo.down.h + (bd->mouse.current.my - bd->moveinfo.down.my);
}
tw = bd->w;
th = bd->h;
2005-02-07 05:51:09 -08:00
if ((bd->resize_mode == RESIZE_TL) ||
(bd->resize_mode == RESIZE_L) ||
(bd->resize_mode == RESIZE_BL))
x += (tw - w);
if ((bd->resize_mode == RESIZE_TL) ||
(bd->resize_mode == RESIZE_T) ||
(bd->resize_mode == RESIZE_TR))
y += (th - h);
2005-02-07 05:51:09 -08:00
skiplist = eina_list_append(skiplist, bd);
e_resist_container_border_position(bd->zone->container, skiplist,
2005-04-18 01:39:05 -07:00
bd->x, bd->y, bd->w, bd->h,
x, y, w, h,
&new_x, &new_y, &new_w, &new_h);
eina_list_free(skiplist);
2005-02-07 05:51:09 -08:00
w = new_w;
h = new_h;
e_border_resize_limit(bd, &new_w, &new_h);
if ((bd->resize_mode == RESIZE_TL) ||
(bd->resize_mode == RESIZE_L) ||
(bd->resize_mode == RESIZE_BL))
new_x += (w - new_w);
if ((bd->resize_mode == RESIZE_TL) ||
(bd->resize_mode == RESIZE_T) ||
(bd->resize_mode == RESIZE_TR))
new_y += (h - new_h);
2005-02-07 05:51:09 -08:00
e_border_move_resize(bd, new_x, new_y, new_w, new_h);
}
static int
_e_border_shade_animator(void *data)
{
E_Border *bd = data;
double dt, val;
double dur = bd->client.h / e_config->border_shade_speed;
dt = ecore_loop_time_get() - bd->shade.start;
val = dt / dur;
if (val < 0.0) val = 0.0;
else if (val > 1.0) val = 1.0;
if (e_config->border_shade_transition == E_TRANSITION_SINUSOIDAL)
{
if (bd->shaded)
bd->shade.val = (1 - cos(val * M_PI)) / 2.0;
else
bd->shade.val = 0.5 + (cos(val * M_PI) / 2.0);
}
else if (e_config->border_shade_transition == E_TRANSITION_DECELERATE)
{
if (bd->shaded)
bd->shade.val = sin(val * M_PI / 2.0);
else
bd->shade.val = 1 - sin(val * M_PI / 2.0);
}
else if (e_config->border_shade_transition == E_TRANSITION_ACCELERATE)
{
if (bd->shaded)
bd->shade.val = 1 - cos(val * M_PI / 2.0);
else
bd->shade.val = cos(val * M_PI / 2.0);
}
else /* LINEAR if none of the others */
{
if (bd->shaded)
bd->shade.val = val;
else
bd->shade.val = 1 - val;
}
/* due to M_PI's innacuracy, cos(M_PI/2) != 0.0, so we need this */
if (bd->shade.val < 0.001) bd->shade.val = 0.0;
else if (bd->shade.val > .999) bd->shade.val = 1.0;
2005-10-04 04:15:33 -07:00
if (bd->shade.dir == E_DIRECTION_UP)
bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
else if (bd->shade.dir == E_DIRECTION_DOWN)
{
bd->h = bd->client_inset.t + bd->client_inset.b + bd->client.h * bd->shade.val;
bd->y = bd->shade.y + bd->client.h * (1 - bd->shade.val);
bd->changes.pos = 1;
}
else if (bd->shade.dir == E_DIRECTION_LEFT)
bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
else if (bd->shade.dir == E_DIRECTION_RIGHT)
{
bd->w = bd->client_inset.l + bd->client_inset.r + bd->client.w * bd->shade.val;
bd->x = bd->shade.x + bd->client.w * (1 - bd->shade.val);
bd->changes.pos = 1;
}
if ((bd->shaped) || (bd->client.shaped))
{
bd->need_shape_merge = 1;
bd->need_shape_export = 1;
}
bd->changes.size = 1;
bd->changed = 1;
/* we're done */
if ((bd->shaded && (bd->shade.val == 1)) ||
((!bd->shaded) && (bd->shade.val == 0)) )
{
E_Event_Border_Resize *ev;
bd->shading = 0;
bd->shaded = !(bd->shaded);
bd->changes.size = 1;
bd->changes.shaded = 1;
bd->changes.shading = 1;
bd->changed = 1;
bd->shade.anim = NULL;
if (bd->shaded)
edje_object_signal_emit(bd->bg_object, "e,state,shaded", "e");
else
edje_object_signal_emit(bd->bg_object, "e,state,unshaded", "e");
2007-11-06 00:46:54 -08:00
edje_object_message_signal_process(bd->bg_object);
e_border_frame_recalc(bd);
ecore_x_window_gravity_set(bd->client.win, ECORE_X_GRAVITY_NW);
ev = E_NEW(E_Event_Border_Resize, 1);
ev->border = bd;
e_object_ref(E_OBJECT(bd));
// e_object_breadcrumb_add(E_OBJECT(bd), "border_resize_event");
ecore_event_add(E_EVENT_BORDER_RESIZE, ev, _e_border_event_border_resize_free, NULL);
return 0;
}
return 1;
}
static void
_e_border_event_border_resize_free(void *data, void *ev)
{
E_Event_Border_Resize *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_resize_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_move_free(void *data, void *ev)
{
E_Event_Border_Move *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_move_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_add_free(void *data, void *ev)
{
E_Event_Border_Add *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_add_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_remove_free(void *data, void *ev)
{
E_Event_Border_Remove *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_remove_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_show_free(void *data, void *ev)
{
E_Event_Border_Show *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_show_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_hide_free(void *data, void *ev)
{
E_Event_Border_Hide *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_hide_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_iconify_free(void *data, void *ev)
{
E_Event_Border_Iconify *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_iconify_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_uniconify_free(void *data, void *ev)
{
E_Event_Border_Uniconify *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_uniconify_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
2005-02-10 07:21:23 -08:00
static void
_e_border_event_border_stick_free(void *data, void *ev)
{
E_Event_Border_Stick *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_stick_event");
2005-02-10 07:21:23 -08:00
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
2005-02-10 07:21:23 -08:00
}
static void
_e_border_event_border_unstick_free(void *data, void *ev)
{
E_Event_Border_Unstick *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_unstick_event");
2005-02-10 07:21:23 -08:00
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
2005-02-10 07:21:23 -08:00
}
static void
_e_border_event_border_zone_set_free(void *data, void *ev)
{
E_Event_Border_Zone_Set *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_zone_set_event");
e_object_unref(E_OBJECT(e->border));
e_object_unref(E_OBJECT(e->zone));
E_FREE(e);
}
static void
_e_border_event_border_desk_set_free(void *data, void *ev)
{
E_Event_Border_Desk_Set *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_desk_set_event");
e_object_unref(E_OBJECT(e->border));
e_object_unref(E_OBJECT(e->desk));
E_FREE(e);
}
static void
_e_border_event_border_stack_free(void *data, void *ev)
{
E_Event_Border_Stack *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_raise_event");
e_object_unref(E_OBJECT(e->border));
if (e->stack)
{
// e_object_breadcrumb_del(E_OBJECT(e->above), "border_raise_event.above");
e_object_unref(E_OBJECT(e->stack));
}
E_FREE(e);
}
static void
_e_border_event_border_icon_change_free(void *data, void *ev)
{
E_Event_Border_Icon_Change *e;
e = ev;
// e_object_breadcrumb_del(E_OBJECT(e->border), "border_icon_change_event");
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_urgent_change_free(void *data, void *ev)
{
E_Event_Border_Urgent_Change *e;
e = ev;
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_focus_in_free(void *data, void *ev)
{
E_Event_Border_Focus_In *e;
e = ev;
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_focus_out_free(void *data, void *ev)
{
E_Event_Border_Focus_Out *e;
e = ev;
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_event_border_property_free(void *data, void *ev)
{
E_Event_Border_Property *e;
e = ev;
e_object_unref(E_OBJECT(e->border));
E_FREE(e);
}
static void
_e_border_zone_update(E_Border *bd)
{
E_Container *con;
Eina_List *l;
E_Zone *zone;
/* still within old zone - leave it there */
if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
bd->zone->x, bd->zone->y, bd->zone->w, bd->zone->h))
return;
/* find a new zone */
con = bd->zone->container;
EINA_LIST_FOREACH(con->zones, l, zone)
{
if (E_INTERSECTS(bd->x, bd->y, bd->w, bd->h,
zone->x, zone->y, zone->w, zone->h))
{
e_border_zone_set(bd, zone);
return;
}
}
}
2005-02-07 05:51:09 -08:00
static int
2005-02-07 05:51:09 -08:00
_e_border_resize_begin(E_Border *bd)
{
if (!bd->lock_user_stacking)
{
if (e_config->border_raise_on_mouse_action)
e_border_raise(bd);
}
if ((bd->shaded) || (bd->shading) ||
(bd->fullscreen) || (bd->lock_user_size))
return 0;
if (((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN) &&
(!e_config->allow_manip))
2005-06-06 08:22:05 -07:00
if (grabbed)
2005-09-22 10:10:02 -07:00
e_grabinput_get(bd->win, 0, bd->win);
2005-06-06 08:22:05 -07:00
if (bd->client.netwm.sync.request)
{
bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
bd->client.netwm.sync.serial = 0;
bd->client.netwm.sync.wait = 0;
bd->client.netwm.sync.send_time = ecore_loop_time_get();
2005-06-06 08:22:05 -07:00
}
_e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd);
resize = bd;
return 1;
2005-02-07 05:51:09 -08:00
}
static int
2005-02-07 05:51:09 -08:00
_e_border_resize_end(E_Border *bd)
{
2005-06-06 08:22:05 -07:00
if (grabbed)
2005-09-22 10:10:02 -07:00
e_grabinput_release(bd->win, bd->win);
2005-06-06 08:22:05 -07:00
grabbed = 0;
if (bd->client.netwm.sync.alarm)
{
ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
bd->client.netwm.sync.alarm = 0;
}
_e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd);
resize = NULL;
/* If this border was maximized, we need to unset Maximized state or
* on restart, E still thinks it's maximized */
if (bd->maximized != E_MAXIMIZE_NONE)
e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE,
bd->maximized & E_MAXIMIZE_NONE);
return 1;
2005-02-07 05:51:09 -08:00
}
static void
_e_border_resize_update(E_Border *bd)
{
_e_border_hook_call(E_BORDER_HOOK_RESIZE_UPDATE, bd);
2005-02-07 05:51:09 -08:00
}
static int
_e_border_move_begin(E_Border *bd)
{
if (!bd->lock_user_stacking)
{
if (e_config->border_raise_on_mouse_action)
e_border_raise(bd);
}
if ((bd->fullscreen) || (bd->lock_user_location))
return 0;
if (((bd->maximized & E_MAXIMIZE_TYPE) == E_MAXIMIZE_FULLSCREEN) &&
(!e_config->allow_manip))
return 0;
2005-06-06 08:22:05 -07:00
if (grabbed)
2005-09-22 10:10:02 -07:00
e_grabinput_get(bd->win, 0, bd->win);
#if 0
2005-06-06 08:22:05 -07:00
if (bd->client.netwm.sync.request)
{
bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter);
bd->client.netwm.sync.serial = 0;
bd->client.netwm.sync.wait = 0;
bd->client.netwm.sync.time = ecore_loop_time_get();
2005-06-06 08:22:05 -07:00
}
#endif
_e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd);
move = bd;
return 1;
}
static int
_e_border_move_end(E_Border *bd)
{
2005-06-06 08:22:05 -07:00
if (grabbed)
2005-09-22 10:10:02 -07:00
e_grabinput_release(bd->win, bd->win);
2005-06-06 08:22:05 -07:00
grabbed = 0;
#if 0
2005-06-06 08:22:05 -07:00
if (bd->client.netwm.sync.alarm)
{
ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm);
bd->client.netwm.sync.alarm = 0;
}
#endif
_e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd);
move = NULL;
return 1;
}
static void
_e_border_move_update(E_Border *bd)
{
_e_border_hook_call(E_BORDER_HOOK_MOVE_UPDATE, bd);
}
static int
e: 1. configure/build changes to allow cross-compiling painlessly 2. pager module namespace changes - this was still dirty afdter the namespace cleanup, so clean it up 3. add a powersave subsystem - doesnt have an "automatic" way to turn on and off right now, this i think is best provided by modules (that do things like monitor acpi status's (eg close lid of laptop), AC power status etc. etc. this allows e to nicely defer "power" expensive actions to avoid disk spinups etc. 4. move to use the new ecore poller system - discussed long ago as part of power management/saving issues. now it exists 5. add a canvas idle flush call that helsp cope with the new shm greedy software x11 engine stuff 6. use the new powersave subsystem where appropriate 7. fix non-zeroed/initted memory access in e_fm_main 8. fix mem leak for e menus 9. remove ipc handlers for changed/removed config values 10. use animaotr not timer for menu scrolls - then menu scrolls obey the fps config 11. fix up timer/poll happienss of cursor idle stuff 12. remove avoid damage from popups for now - causing problems 13. change battery and temp readouts to b e shorter so they fit 14. pager can emit signals on focus change for mini-windows now 15. temperature module now uses a slave process and uses stdin/out to talk to it and get output - this makes e smoother as in my expereicne i found getting the temp on my laptop actually took like 200ms so e "hang" for 200ms while reading the acpi files - so now the subprocess does it and just writesa back to e when it gets it. ecore: 1. add ecore_pollers. see the documentation on them in doxygen comments :) 2. fix timers to only go off when they have to - bug there that made e's select time out a LOT more than it needed to. defensive coding hid the problem. now fixed. e should be much more power friendly now. 3. formatting/niceness in ecore_exe stuff 4. some comments on comments with SIGIO ideas vs. select 5. add call to be able to add an idle enterer at the start of the list of them, not just the end (as has been the default) 6. fix ecore_evas to support auto evas idler calls after 0.5 secs of idle in all canvases - and to do it right 7. if argb destination - set the shape EVENT shape (to mask out events in transparent regions much like shape does withotu translucency) 8. in ecore_x add support for the event shape evas: 1. fix cache to work properly and not just always fill up (as it seemed to like to think cahce useage dropped below 0 when it didnt and thus just over-fill) 2. software x11 engine now ONLY uses shm segments - no ximages over the socket. this ximage hack was there to avoid the 2 round trips involved in setting up an shm image - now i mitigated that wih an shm image cache pool. it keeps shm images around and repurposes them for new update regions if appropriate. this means many fewer shm creates (about 1/100th the number) and since we recycle the memory less 0 memory page filling by the kernel - in the end, i recorded about a 10-20% speedup over the old software x11 engine. simple tests i have seen up to 120% speedups. idle flush now does something - it frees all the cached shm segments. it has a hard-coded limit of 4mb worth of shm segments (or 32 segments - whichever comes first) to keep around. once can never complain much about speedups methinks :). also evas will defer sync until the NEXT frame is written - this means evas can calculate the next frame of data while x dma's/copies the images to the screen at the same time (if you hve a dual core or multi-cpu machnike or your xserver is able to use DMA to copy image data to the screen/video ram then this should see a decent speedup). SVN revision: 33448
2008-01-10 23:33:57 -08:00
_e_border_cb_ping_poller(void *data)
{
E_Border *bd;
bd = data;
if (bd->ping_ok)
{
if (bd->hung)
{
bd->hung = 0;
edje_object_signal_emit(bd->bg_object, "e,state,unhung", "e");
if (bd->kill_timer)
{
ecore_timer_del(bd->kill_timer);
bd->kill_timer = NULL;
}
}
}
else
{
if (!bd->hung)
{
bd->hung = 1;
edje_object_signal_emit(bd->bg_object, "e,state,hung", "e");
/* FIXME: if below dialog is up - hide it now */
}
if (bd->delete_requested)
{
/* FIXME: pop up dialog saying app is hung - kill client, or pid */
e_border_act_kill_begin(bd);
}
}
e: 1. configure/build changes to allow cross-compiling painlessly 2. pager module namespace changes - this was still dirty afdter the namespace cleanup, so clean it up 3. add a powersave subsystem - doesnt have an "automatic" way to turn on and off right now, this i think is best provided by modules (that do things like monitor acpi status's (eg close lid of laptop), AC power status etc. etc. this allows e to nicely defer "power" expensive actions to avoid disk spinups etc. 4. move to use the new ecore poller system - discussed long ago as part of power management/saving issues. now it exists 5. add a canvas idle flush call that helsp cope with the new shm greedy software x11 engine stuff 6. use the new powersave subsystem where appropriate 7. fix non-zeroed/initted memory access in e_fm_main 8. fix mem leak for e menus 9. remove ipc handlers for changed/removed config values 10. use animaotr not timer for menu scrolls - then menu scrolls obey the fps config 11. fix up timer/poll happienss of cursor idle stuff 12. remove avoid damage from popups for now - causing problems 13. change battery and temp readouts to b e shorter so they fit 14. pager can emit signals on focus change for mini-windows now 15. temperature module now uses a slave process and uses stdin/out to talk to it and get output - this makes e smoother as in my expereicne i found getting the temp on my laptop actually took like 200ms so e "hang" for 200ms while reading the acpi files - so now the subprocess does it and just writesa back to e when it gets it. ecore: 1. add ecore_pollers. see the documentation on them in doxygen comments :) 2. fix timers to only go off when they have to - bug there that made e's select time out a LOT more than it needed to. defensive coding hid the problem. now fixed. e should be much more power friendly now. 3. formatting/niceness in ecore_exe stuff 4. some comments on comments with SIGIO ideas vs. select 5. add call to be able to add an idle enterer at the start of the list of them, not just the end (as has been the default) 6. fix ecore_evas to support auto evas idler calls after 0.5 secs of idle in all canvases - and to do it right 7. if argb destination - set the shape EVENT shape (to mask out events in transparent regions much like shape does withotu translucency) 8. in ecore_x add support for the event shape evas: 1. fix cache to work properly and not just always fill up (as it seemed to like to think cahce useage dropped below 0 when it didnt and thus just over-fill) 2. software x11 engine now ONLY uses shm segments - no ximages over the socket. this ximage hack was there to avoid the 2 round trips involved in setting up an shm image - now i mitigated that wih an shm image cache pool. it keeps shm images around and repurposes them for new update regions if appropriate. this means many fewer shm creates (about 1/100th the number) and since we recycle the memory less 0 memory page filling by the kernel - in the end, i recorded about a 10-20% speedup over the old software x11 engine. simple tests i have seen up to 120% speedups. idle flush now does something - it frees all the cached shm segments. it has a hard-coded limit of 4mb worth of shm segments (or 32 segments - whichever comes first) to keep around. once can never complain much about speedups methinks :). also evas will defer sync until the NEXT frame is written - this means evas can calculate the next frame of data while x dma's/copies the images to the screen at the same time (if you hve a dual core or multi-cpu machnike or your xserver is able to use DMA to copy image data to the screen/video ram then this should see a decent speedup). SVN revision: 33448
2008-01-10 23:33:57 -08:00
bd->ping_poller = NULL;
e_border_ping(bd);
return 0;
}
static int
_e_border_cb_kill_timer(void *data)
{
E_Border *bd;
bd = data;
if (bd->hung)
{
if (bd->client.netwm.pid > 1)
kill(bd->client.netwm.pid, SIGKILL);
}
bd->kill_timer = NULL;
return 0;
}
static void
_e_border_pointer_resize_begin(E_Border *bd)
{
switch (bd->resize_mode)
{
case RESIZE_TL:
e_pointer_type_push(bd->pointer, bd, "resize_tl");
break;
case RESIZE_T:
e_pointer_type_push(bd->pointer, bd, "resize_t");
break;
case RESIZE_TR:
e_pointer_type_push(bd->pointer, bd, "resize_tr");
break;
case RESIZE_R:
e_pointer_type_push(bd->pointer, bd, "resize_r");
break;
case RESIZE_BR:
e_pointer_type_push(bd->pointer, bd, "resize_br");
break;
case RESIZE_B:
e_pointer_type_push(bd->pointer, bd, "resize_b");
break;
case RESIZE_BL:
e_pointer_type_push(bd->pointer, bd, "resize_bl");
break;
case RESIZE_L:
e_pointer_type_push(bd->pointer, bd, "resize_l");
break;
}
}
static void
_e_border_pointer_resize_end(E_Border *bd)
{
switch (bd->resize_mode)
{
case RESIZE_TL:
e_pointer_type_pop(bd->pointer, bd, "resize_tl");
break;
case RESIZE_T:
e_pointer_type_pop(bd->pointer, bd, "resize_t");
break;
case RESIZE_TR:
e_pointer_type_pop(bd->pointer, bd, "resize_tr");
break;
case RESIZE_R:
e_pointer_type_pop(bd->pointer, bd, "resize_r");
break;
case RESIZE_BR:
e_pointer_type_pop(bd->pointer, bd, "resize_br");
break;
case RESIZE_B:
e_pointer_type_pop(bd->pointer, bd, "resize_b");
break;
case RESIZE_BL:
e_pointer_type_pop(bd->pointer, bd, "resize_bl");
break;
case RESIZE_L:
e_pointer_type_pop(bd->pointer, bd, "resize_l");
break;
}
}
static void
_e_border_pointer_move_begin(E_Border *bd)
{
e_pointer_type_push(bd->pointer, bd, "move");
}
static void
_e_border_pointer_move_end(E_Border *bd)
{
e_pointer_type_pop(bd->pointer, bd, "move");
}
static Eina_List *_e_border_hooks = NULL;
static int _e_border_hooks_delete = 0;
static int _e_border_hooks_walking = 0;
static void
_e_border_hooks_clean(void)
{
Eina_List *l, *ln;
E_Border_Hook *bh;
EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh)
{
if (bh->delete_me)
{
_e_border_hooks = eina_list_remove_list(_e_border_hooks, l);
free(bh);
}
}
}
static void
_e_border_hook_call(E_Border_Hook_Point hookpoint, void *bd)
{
Eina_List *l;
E_Border_Hook *bh;
_e_border_hooks_walking++;
EINA_LIST_FOREACH(_e_border_hooks, l, bh)
{
if (bh->delete_me) continue;
if (bh->hookpoint == hookpoint) bh->func(bh->data, bd);
}
_e_border_hooks_walking--;
if ((_e_border_hooks_walking == 0) && (_e_border_hooks_delete > 0))
_e_border_hooks_clean();
}
EAPI E_Border_Hook *
e_border_hook_add(E_Border_Hook_Point hookpoint, void (*func) (void *data, void *bd), void *data)
{
E_Border_Hook *bh;
bh = E_NEW(E_Border_Hook, 1);
if (!bh) return NULL;
bh->hookpoint = hookpoint;
bh->func = func;
bh->data = data;
_e_border_hooks = eina_list_append(_e_border_hooks, bh);
return bh;
}
EAPI void
e_border_hook_del(E_Border_Hook *bh)
{
bh->delete_me = 1;
if (_e_border_hooks_walking == 0)
{
_e_border_hooks = eina_list_remove(_e_border_hooks, bh);
free(bh);
}
else
_e_border_hooks_delete++;
}
2007-08-04 21:41:55 -07:00
EAPI void
e_border_focus_track_freeze(void)
{
focus_track_frozen++;
}
EAPI void
e_border_focus_track_thaw(void)
{
focus_track_frozen--;
}
EAPI E_Border *
e_border_under_pointer_get(E_Desk *desk, E_Border *exclude)
{
E_Border *bd = NULL, *cbd;
Eina_List *l;
int x, y;
/* We need to ensure that we can get the container window for the
* zone of either the given desk or the desk of the excluded
* window, so return if neither is given */
if (desk)
ecore_x_pointer_xy_get(desk->zone->container->win, &x, &y);
else if (exclude)
ecore_x_pointer_xy_get(exclude->desk->zone->container->win, &x, &y);
2007-12-02 12:03:29 -08:00
else
return NULL;
EINA_LIST_FOREACH(e_border_raise_stack_get(), l, cbd)
{
if (!cbd) continue;
/* If a border was specified which should be excluded from the list
* (because it will be closed shortly for example), skip */
if ((exclude) && (cbd == exclude)) continue;
if ((desk) && (cbd->desk != desk)) continue;
if ((x < cbd->x) || (x > (cbd->x + cbd->w)) ||
(y < cbd->y) || (y > (cbd->y + cbd->h))) continue;
/* If the layer is higher, the position of the window is higher
* (always on top vs always below) */
if (!bd || (cbd->layer > bd->layer))
{
bd = cbd;
break;
}
}
return bd;
}
static int
_e_border_pointer_warp_to_center_timer(void *data)
{
if (warp_to)
{
int x, y;
double spd;
ecore_x_pointer_xy_get(warp_to_win, &x, &y);
if ((x - warp_x) > 5 || (x - warp_x) < -5 ||
(y - warp_y) > 5 || (y - warp_y) < -5)
{
/* User moved the mouse, so stop warping */
warp_to = 0;
goto cleanup;
}
/* We just use the same warp speed as configured
* for the windowlist */
spd = e_config->winlist_warp_speed;
x = warp_x;
y = warp_y;
warp_x = (x * (1.0 - spd)) + (warp_to_x * spd);
warp_y = (y * (1.0 - spd)) + (warp_to_y * spd);
if (warp_x == x && warp_y == y)
{
warp_x = warp_to_x;
warp_y = warp_to_y;
warp_to = 0;
goto cleanup;
}
ecore_x_pointer_warp(warp_to_win, warp_x, warp_y);
return 1;
}
cleanup:
ecore_timer_del(warp_timer);
warp_timer = NULL;
return 0;
}
EAPI int
e_border_pointer_warp_to_center(E_Border *bd)
{
int x, y;
/* Do not slide pointer when disabled (probably breaks focus
* on sloppy/mouse focus but requested by users). */
if (!e_config->pointer_slide) return 0;
/* Only warp the pointer if it is not already in the area of
* the given border */
ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y);
if ((x >= bd->x) && (x <= (bd->x + bd->w)) &&
(y >= bd->y) && (y <= (bd->y + bd->h)))
return 0;
warp_to_x = bd->x + (bd->w / 2);
if (warp_to_x < (bd->zone->x + 1))
warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2);
else if (warp_to_x > (bd->zone->x + bd->zone->w))
warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2;
warp_to_y = bd->y + (bd->h / 2);
if (warp_to_y < (bd->zone->y + 1))
warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2);
else if (warp_to_y > (bd->zone->y + bd->zone->h))
warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2;
warp_to = 1;
warp_to_win = bd->zone->container->win;
ecore_x_pointer_xy_get(bd->zone->container->win, &warp_x, &warp_y);
warp_timer = ecore_timer_add(0.01, _e_border_pointer_warp_to_center_timer, (const void*)bd);
return 1;
}