forked from enlightenment/enlightenment
1884 lines
46 KiB
C
1884 lines
46 KiB
C
#include "e.h"
|
|
|
|
/* Window border rendering, querying, setting & modification code */
|
|
|
|
/* globals local to window borders */
|
|
static Evas_List evases = NULL;
|
|
static Evas_List borders = NULL;
|
|
|
|
static int mouse_x, mouse_y, mouse_win_x, mouse_win_y;
|
|
static int mouse_buttons = 0;
|
|
|
|
static int border_mouse_x = 0;
|
|
static int border_mouse_y = 0;
|
|
static int border_mouse_buttons = 0;
|
|
|
|
static Eevent *current_ev = NULL;
|
|
|
|
static void e_idle(void *data);
|
|
static void e_map_request(Eevent * ev);
|
|
static void e_configure_request(Eevent * ev);
|
|
static void e_property(Eevent * ev);
|
|
static void e_unmap(Eevent * ev);
|
|
static void e_destroy(Eevent * ev);
|
|
static void e_circulate_request(Eevent * ev);
|
|
static void e_reparent(Eevent * ev);
|
|
static void e_shape(Eevent * ev);
|
|
static void e_focus_in(Eevent * ev);
|
|
static void e_focus_out(Eevent * ev);
|
|
static void e_colormap(Eevent * ev);
|
|
static void e_mouse_down(Eevent * ev);
|
|
static void e_mouse_up(Eevent * ev);
|
|
static void e_mouse_in(Eevent * ev);
|
|
static void e_mouse_out(Eevent * ev);
|
|
static void e_window_expose(Eevent * ev);
|
|
|
|
static void e_cb_mouse_in(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
|
|
static void e_cb_mouse_out(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
|
|
static void e_cb_mouse_down(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
|
|
static void e_cb_mouse_up(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
|
|
static void e_cb_mouse_move(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh);
|
|
|
|
static void e_cb_border_mouse_in(E_Border *b, Eevent *e);
|
|
static void e_cb_border_mouse_out(E_Border *b, Eevent *e);
|
|
static void e_cb_border_mouse_down(E_Border *b, Eevent *e);
|
|
static void e_cb_border_mouse_up(E_Border *b, Eevent *e);
|
|
static void e_cb_border_mouse_move(E_Border *b, Eevent *e);
|
|
static void e_cb_border_move_resize(E_Border *b);
|
|
static void e_cb_border_visibility(E_Border *b);
|
|
|
|
static void e_border_poll(int val, void *data);
|
|
|
|
/* what to dowhen we're idle */
|
|
static void
|
|
e_idle(void *data)
|
|
{
|
|
Evas_List l;
|
|
|
|
for (l = borders; l; l = l->next)
|
|
{
|
|
E_Border *b;
|
|
|
|
b = l->data;
|
|
e_border_update(b);
|
|
}
|
|
for (l = evases; l; l = l->next)
|
|
{
|
|
Evas evas;
|
|
|
|
evas = l->data;
|
|
evas_render(evas);
|
|
}
|
|
e_db_runtime_flush();
|
|
return;
|
|
UN(data);
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_map_request(Eevent * ev)
|
|
{
|
|
Ev_Window_Map_Request *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (!b)
|
|
{
|
|
b = e_border_adopt(e->win, 0);
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_configure_request(Eevent * ev)
|
|
{
|
|
Ev_Window_Configure_Request *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
int pl, pr, pt, pb;
|
|
|
|
pl = pr = pt = pb = 0;
|
|
if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
|
|
if (e->mask & EV_VALUE_X)
|
|
b->current.requested.x = e->x;
|
|
if (e->mask & EV_VALUE_Y)
|
|
b->current.requested.y = e->y;
|
|
if (e->mask & EV_VALUE_W)
|
|
b->current.requested.w = e->w + pl + pr;
|
|
if (e->mask & EV_VALUE_H)
|
|
b->current.requested.h = e->h + pt + pb;
|
|
if ((e->mask & EV_VALUE_SIBLING) && (e->mask & EV_VALUE_STACKING))
|
|
{
|
|
E_Border *b_rel;
|
|
|
|
b_rel = e_border_find_by_window(e->stack_win);
|
|
if (b_rel)
|
|
{
|
|
if (e->detail == EV_STACK_ABOVE) e_border_raise_above(b, b_rel);
|
|
else if (e->detail == EV_STACK_BELOW) e_border_lower_below(b, b_rel);
|
|
/* FIXME: need to handle & fix
|
|
* EV_STACK_TOP_IF
|
|
* EV_STACK_BOTTOM_IF
|
|
* EV_STACK_OPPOSITE
|
|
*/
|
|
else if (e->detail == EV_STACK_TOP_IF) e_border_raise(b);
|
|
else if (e->detail == EV_STACK_BOTTOM_IF) e_border_lower(b);
|
|
}
|
|
}
|
|
else if (e->mask & EV_VALUE_STACKING)
|
|
{
|
|
if (e->detail == EV_STACK_ABOVE) e_border_raise(b);
|
|
else if (e->detail == EV_STACK_BELOW) e_border_lower(b);
|
|
/* FIXME: need to handle & fix
|
|
* EV_STACK_TOP_IF
|
|
* EV_STACK_BOTTOM_IF
|
|
* EV_STACK_OPPOSITE
|
|
*/
|
|
else if (e->detail == EV_STACK_TOP_IF) e_border_raise(b);
|
|
else if (e->detail == EV_STACK_BOTTOM_IF) e_border_lower(b);
|
|
}
|
|
b->changed = 1;
|
|
e_border_adjust_limits(b);
|
|
}
|
|
else
|
|
{
|
|
if ((e->mask & EV_VALUE_X) && (e->mask & EV_VALUE_W))
|
|
e_window_move_resize(e->win, e->x, e->y, e->w, e->h);
|
|
else if ((e->mask & EV_VALUE_W))
|
|
e_window_resize(e->win, e->w, e->h);
|
|
else if ((e->mask & EV_VALUE_X))
|
|
e_window_move(e->win, e->x, e->y);
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_property(Eevent * ev)
|
|
{
|
|
Ev_Window_Property *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
e_icccm_handle_property_change(e->atom, b);
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_client_message(Eevent * ev)
|
|
{
|
|
Ev_Message *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
|
|
e_icccm_handle_client_message(e);
|
|
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_unmap(Eevent * ev)
|
|
{
|
|
Ev_Window_Unmap *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (b->win.client == e->win)
|
|
{
|
|
if (b->ignore_unmap > 0) b->ignore_unmap--;
|
|
else
|
|
{
|
|
e_action_stop_by_object(b, NULL,
|
|
mouse_win_x, mouse_win_y,
|
|
border_mouse_x, border_mouse_y);
|
|
OBJ_UNREF(b);
|
|
OBJ_IF_FREE(b)
|
|
{
|
|
e_window_reparent(e->win, 0, 0, 0);
|
|
e_icccm_release(e->win);
|
|
OBJ_FREE(b);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_destroy(Eevent * ev)
|
|
{
|
|
Ev_Window_Destroy *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (b->win.client == e->win)
|
|
{
|
|
e_action_stop_by_object(b, NULL,
|
|
mouse_win_x, mouse_win_y,
|
|
border_mouse_x, border_mouse_y);
|
|
OBJ_UNREF(b);
|
|
OBJ_IF_FREE(b)
|
|
{
|
|
e_window_reparent(e->win, 0, 0, 0);
|
|
e_icccm_release(e->win);
|
|
OBJ_FREE(b);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_circulate_request(Eevent * ev)
|
|
{
|
|
Ev_Window_Circulate_Request *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (e->lower) e_border_lower(b);
|
|
else e_border_raise(b);
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_reparent(Eevent * ev)
|
|
{
|
|
Ev_Window_Reparent *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
#if 0
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if ((b) && (e->parent_from == b->win.container))
|
|
{
|
|
if (b)
|
|
{
|
|
e_action_stop_by_object(b, NULL,
|
|
mouse_win_x, mouse_win_y,
|
|
border_mouse_x, border_mouse_y);
|
|
OBJ_UNREF(b);
|
|
OBJ_IF_FREE(b)
|
|
{
|
|
e_window_reparent(e->win, 0, 0, 0);
|
|
e_icccm_release(e->win);
|
|
OBJ_FREE(b);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_shape(Eevent * ev)
|
|
{
|
|
Ev_Window_Shape *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_focus_in(Eevent * ev)
|
|
{
|
|
Ev_Window_Focus_In *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
b->current.selected = 1;
|
|
b->changed = 1;
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_focus_out(Eevent * ev)
|
|
{
|
|
Ev_Window_Focus_Out *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
char *settings_db = PACKAGE_DATA_DIR"/data/config/behavior/default/settings.db";
|
|
E_DB_File *db;
|
|
int focus_mode;
|
|
char buf[4096];
|
|
|
|
b->current.selected = 0;
|
|
/* settings - click to focus would affect grabs */
|
|
db = e_db_open_read(settings_db);
|
|
sprintf(buf, "/focus/mode");
|
|
if ((db) && (e_db_int_get(db, buf, &focus_mode)) && (!b->current.selected))
|
|
{
|
|
if (focus_mode == 2) /* click to focus */
|
|
{
|
|
E_Grab *g;
|
|
|
|
g = NEW(E_Grab, 1);
|
|
ZERO(g, E_Grab, 1);
|
|
g->button = 0;
|
|
g->mods = 0;
|
|
g->any_mod = 1;
|
|
g->remove_after = 1;
|
|
b->grabs = evas_list_append(b->grabs, g);
|
|
e_button_grab(b->win.main, 0, XEV_BUTTON | XEV_MOUSE_MOVE, EV_KEY_MODIFIER_NONE, 1);
|
|
}
|
|
e_db_close(db);
|
|
}
|
|
b->changed = 1;
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* */
|
|
static void
|
|
e_colormap(Eevent * ev)
|
|
{
|
|
Ev_Colormap *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* handling mouse down events */
|
|
static void
|
|
e_mouse_down(Eevent * ev)
|
|
{
|
|
Ev_Mouse_Down *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
mouse_win_x = e->x;
|
|
mouse_win_y = e->y;
|
|
mouse_x = e->rx;
|
|
mouse_y = e->ry;
|
|
mouse_buttons |= (1 << e->button);
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (e->win == b->win.main) e_cb_border_mouse_down(b, ev);
|
|
else
|
|
{
|
|
Evas evas;
|
|
int x, y;
|
|
|
|
evas = b->evas.l;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_down(evas, x, y, e->button);
|
|
evas = b->evas.r;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_down(evas, x, y, e->button);
|
|
evas = b->evas.t;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_down(evas, x, y, e->button);
|
|
evas = b->evas.b;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_down(evas, x, y, e->button);
|
|
}
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* handling mouse up events */
|
|
static void
|
|
e_mouse_up(Eevent * ev)
|
|
{
|
|
Ev_Mouse_Up *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
mouse_win_x = e->x;
|
|
mouse_win_y = e->y;
|
|
mouse_x = e->rx;
|
|
mouse_y = e->ry;
|
|
mouse_buttons &= ~(1 << e->button);
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (e->win == b->win.main) e_cb_border_mouse_up(b, ev);
|
|
else
|
|
{
|
|
Evas evas;
|
|
int x, y;
|
|
|
|
evas = b->evas.l;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_up(evas, x, y, e->button);
|
|
evas = b->evas.r;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_up(evas, x, y, e->button);
|
|
evas = b->evas.t;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_up(evas, x, y, e->button);
|
|
evas = b->evas.b;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_button_up(evas, x, y, e->button);
|
|
}
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* handling mouse move events */
|
|
static void
|
|
e_mouse_move(Eevent * ev)
|
|
{
|
|
Ev_Mouse_Move *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
mouse_win_x = e->x;
|
|
mouse_win_y = e->y;
|
|
mouse_x = e->rx;
|
|
mouse_y = e->ry;
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (e->win == b->win.main) e_cb_border_mouse_move(b, ev);
|
|
else
|
|
{
|
|
Evas evas;
|
|
int x, y;
|
|
|
|
evas = b->evas.l;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
evas = b->evas.r;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
evas = b->evas.t;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
evas = b->evas.b;
|
|
e_window_get_root_relative_location(evas_get_window(evas),
|
|
&x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
}
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* handling mouse enter events */
|
|
static void
|
|
e_mouse_in(Eevent * ev)
|
|
{
|
|
Ev_Window_Enter *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (e->win == b->win.main) e_cb_border_mouse_in(b, ev);
|
|
if (e->win == b->win.input)
|
|
{
|
|
int x, y;
|
|
Evas evas;
|
|
|
|
evas = b->evas.l;
|
|
e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
evas_event_enter(evas);
|
|
|
|
evas = b->evas.r;
|
|
e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
evas_event_enter(evas);
|
|
|
|
evas = b->evas.t;
|
|
e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
evas_event_enter(evas);
|
|
|
|
evas = b->evas.b;
|
|
e_window_get_root_relative_location(evas_get_window(evas), &x, &y);
|
|
x = e->rx - x;
|
|
y = e->ry - y;
|
|
evas_event_move(evas, x, y);
|
|
evas_event_enter(evas);
|
|
}
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* handling mouse leave events */
|
|
static void
|
|
e_mouse_out(Eevent * ev)
|
|
{
|
|
Ev_Window_Leave *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_find_by_window(e->win);
|
|
if (b)
|
|
{
|
|
if (e->win == b->win.main) e_cb_border_mouse_out(b, ev);
|
|
if (e->win == b->win.input)
|
|
{
|
|
evas_event_leave(b->evas.l);
|
|
evas_event_leave(b->evas.r);
|
|
evas_event_leave(b->evas.t);
|
|
evas_event_leave(b->evas.b);
|
|
}
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* handling expose events */
|
|
static void
|
|
e_window_expose(Eevent * ev)
|
|
{
|
|
Ev_Window_Expose *e;
|
|
|
|
current_ev = ev;
|
|
e = ev->event;
|
|
{
|
|
Evas_List l;
|
|
|
|
for (l = evases; l; l = l->next)
|
|
{
|
|
Evas evas;
|
|
|
|
evas = l->data;
|
|
if (evas_get_window(evas) == e->win)
|
|
evas_update_rect(evas, e->x, e->y, e->w, e->h);
|
|
}
|
|
}
|
|
current_ev = NULL;
|
|
}
|
|
|
|
/* what to do with border events */
|
|
|
|
static void
|
|
e_cb_mouse_in(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
|
|
{
|
|
E_Border *b;
|
|
|
|
b = data;
|
|
if (border_mouse_buttons) return;
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
if (!current_ev) return;
|
|
e_action_stop(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
return;
|
|
UN(o);
|
|
UN(bt);
|
|
UN(ox);
|
|
UN(oy);
|
|
UN(ow);
|
|
UN(oh);
|
|
}
|
|
|
|
static void
|
|
e_cb_mouse_out(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
|
|
{
|
|
E_Border *b;
|
|
|
|
b = data;
|
|
if (border_mouse_buttons) return;
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
if (!current_ev) return;
|
|
e_action_stop(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
return;
|
|
UN(o);
|
|
UN(bt);
|
|
UN(ox);
|
|
UN(oy);
|
|
UN(ow);
|
|
UN(oh);
|
|
}
|
|
|
|
static void
|
|
e_cb_mouse_down(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
|
|
{
|
|
E_Border *b;
|
|
|
|
b = data;
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
border_mouse_buttons = mouse_buttons;
|
|
if (!current_ev) return;
|
|
{
|
|
int act;
|
|
Ev_Key_Modifiers mods;
|
|
|
|
mods = ((Ev_Mouse_Down *)(current_ev->event))->mods;
|
|
act = ACT_MOUSE_CLICK;
|
|
if (((Ev_Mouse_Down *)(current_ev->event))->double_click) act = ACT_MOUSE_DOUBLE;
|
|
else if (((Ev_Mouse_Down *)(current_ev->event))->triple_click) act = ACT_MOUSE_TRIPLE;
|
|
e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
}
|
|
return;
|
|
UN(o);
|
|
UN(ox);
|
|
UN(oy);
|
|
UN(ow);
|
|
UN(oh);
|
|
}
|
|
|
|
static void
|
|
e_cb_mouse_up(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
|
|
{
|
|
E_Border *b;
|
|
|
|
b = data;
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
border_mouse_buttons = mouse_buttons;
|
|
if (!current_ev) return;
|
|
{
|
|
int act;
|
|
Ev_Key_Modifiers mods;
|
|
|
|
mods = ((Ev_Mouse_Up *)(current_ev->event))->mods;
|
|
act = ACT_MOUSE_UP;
|
|
if ((x >= ox) && (x < (ox + ow)) && (y >= oy) && (y < (oy + oh)))
|
|
act = ACT_MOUSE_CLICKED;
|
|
e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
}
|
|
return;
|
|
UN(o);
|
|
}
|
|
|
|
static void
|
|
e_cb_mouse_move(void *data, Ebits_Object o, char *class, int bt, int x, int y, int ox, int oy, int ow, int oh)
|
|
{
|
|
E_Border *b;
|
|
int dx, dy;
|
|
|
|
b = data;
|
|
dx = mouse_x - border_mouse_x;
|
|
dy = mouse_y - border_mouse_y;
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
if (!current_ev) return;
|
|
e_action_go(class, ACT_MOUSE_MOVE, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y, dx, dy);
|
|
return;
|
|
UN(o);
|
|
UN(bt);
|
|
UN(ox);
|
|
UN(oy);
|
|
UN(ow);
|
|
UN(oh);
|
|
}
|
|
|
|
/* callbacks for certain things */
|
|
static void
|
|
e_cb_border_mouse_in(E_Border *b, Eevent *e)
|
|
{
|
|
int x, y;
|
|
char *class = "Window_Grab";
|
|
|
|
if (border_mouse_buttons) return;
|
|
/* pointer focus stuff */
|
|
if (b->client.takes_focus) e_focus_to_window(b->win.client);
|
|
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
border_mouse_buttons = mouse_buttons;
|
|
if (!current_ev) return;
|
|
x = ((Ev_Window_Enter *)(e->event))->x;
|
|
y = ((Ev_Window_Enter *)(e->event))->y;
|
|
e_action_stop(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, ACT_MOUSE_IN, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
}
|
|
|
|
static void
|
|
e_cb_border_mouse_out(E_Border *b, Eevent *e)
|
|
{
|
|
int x, y;
|
|
char *class = "Window_Grab";
|
|
|
|
if (border_mouse_buttons) return;
|
|
/* pointer focus stuff */
|
|
e_focus_to_window(0);
|
|
|
|
x = mouse_x;
|
|
y = mouse_y;
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
border_mouse_buttons = mouse_buttons;
|
|
if (!current_ev) return;
|
|
e_action_stop(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, ACT_MOUSE_OUT, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
return;
|
|
UN(e);
|
|
}
|
|
|
|
static void
|
|
e_cb_border_mouse_down(E_Border *b, Eevent *e)
|
|
{
|
|
int x, y, bt;
|
|
char *class = "Window_Grab";
|
|
|
|
e_pointer_grab(b->win.main, CurrentTime);
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
if (border_mouse_buttons) return;
|
|
border_mouse_buttons = mouse_buttons;
|
|
if (!current_ev) return;
|
|
x = ((Ev_Mouse_Down *)(e->event))->x;
|
|
y = ((Ev_Mouse_Down *)(e->event))->y;
|
|
bt = ((Ev_Mouse_Down *)(e->event))->button;
|
|
{
|
|
Evas_List l;
|
|
|
|
again:
|
|
for (l = b->grabs; l; l = l->next)
|
|
{
|
|
E_Grab *g;
|
|
|
|
g = l->data;
|
|
/* find a grab that triggered this */
|
|
if ((((Ev_Mouse_Down *)(e->event))->button == g->button) &&
|
|
((g->any_mod) ||
|
|
(((Ev_Mouse_Down *)(e->event))->mods == g->mods)))
|
|
{
|
|
if (g->allow)
|
|
e_pointer_replay(((Ev_Mouse_Down *)(e->event))->time);
|
|
if (g->remove_after)
|
|
{
|
|
e_button_ungrab(b->win.main, g->button, g->mods, g->any_mod);
|
|
free(g);
|
|
b->grabs = evas_list_remove(b->grabs, g);
|
|
goto again;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
{
|
|
int act;
|
|
Ev_Key_Modifiers mods;
|
|
|
|
mods = ((Ev_Mouse_Down *)(current_ev->event))->mods;
|
|
act = ACT_MOUSE_CLICK;
|
|
if (((Ev_Mouse_Down *)(current_ev->event))->double_click) act = ACT_MOUSE_DOUBLE;
|
|
else if (((Ev_Mouse_Down *)(current_ev->event))->triple_click) act = ACT_MOUSE_TRIPLE;
|
|
e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
}
|
|
/*
|
|
* e_pointer_ungrab(((Ev_Mouse_Up *)(e->event))->time);
|
|
* e_pointer_replay(((Ev_Mouse_Up *)(e->event))->time);
|
|
*/
|
|
}
|
|
|
|
static void
|
|
e_cb_border_mouse_up(E_Border *b, Eevent *e)
|
|
{
|
|
int x, y, bt;
|
|
char *class = "Window_Grab";
|
|
|
|
e_pointer_ungrab(CurrentTime);
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
border_mouse_buttons = mouse_buttons;
|
|
if (!current_ev) return;
|
|
x = ((Ev_Mouse_Up *)(e->event))->x;
|
|
y = ((Ev_Mouse_Up *)(e->event))->y;
|
|
bt = ((Ev_Mouse_Up *)(e->event))->button;
|
|
{
|
|
int act;
|
|
Ev_Key_Modifiers mods;
|
|
|
|
mods = ((Ev_Mouse_Up *)(current_ev->event))->mods;
|
|
act = ACT_MOUSE_UP;
|
|
e_action_stop(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
e_action_start(class, act, bt, NULL, mods, b, NULL, x, y, border_mouse_x, border_mouse_y);
|
|
}
|
|
}
|
|
|
|
static void
|
|
e_cb_border_mouse_move(E_Border *b, Eevent *e)
|
|
{
|
|
int dx, dy;
|
|
int x, y;
|
|
char *class = "Window_Grab";
|
|
|
|
dx = mouse_x - border_mouse_x;
|
|
dy = mouse_y - border_mouse_y;
|
|
border_mouse_x = mouse_x;
|
|
border_mouse_y = mouse_y;
|
|
if (!current_ev) return;
|
|
x = ((Ev_Mouse_Move *)(e->event))->x;
|
|
y = ((Ev_Mouse_Move *)(e->event))->y;
|
|
e_action_go(class, ACT_MOUSE_MOVE, 0, NULL, EV_KEY_MODIFIER_NONE, b, NULL, x, y, border_mouse_x, border_mouse_y, dx, dy);
|
|
}
|
|
|
|
static void
|
|
e_cb_border_move_resize(E_Border *b)
|
|
{
|
|
return;
|
|
UN(b);
|
|
}
|
|
|
|
static void
|
|
e_cb_border_visibility(E_Border *b)
|
|
{
|
|
return;
|
|
UN(b);
|
|
}
|
|
|
|
static void e_border_poll(int val, void *data)
|
|
{
|
|
e_add_event_timer("e_border_poll()", 1.00, e_border_poll, val + 1, NULL);
|
|
return;
|
|
UN(data);
|
|
}
|
|
|
|
/* border creation, deletion, modification and general queries */
|
|
|
|
void
|
|
e_border_apply_border(E_Border *b)
|
|
{
|
|
int pl, pr, pt, pb;
|
|
|
|
if ((!b->client.titlebar) &&
|
|
(!b->client.border)) e_border_set_bits(b, PACKAGE_DATA_DIR"/data/config/appearance/default/borders/borderless.bits.db");
|
|
else if (b->current.selected) e_border_set_bits(b, PACKAGE_DATA_DIR"/data/config/appearance/default/borders/border.bits.db");
|
|
else e_border_set_bits(b, PACKAGE_DATA_DIR"/data/config/appearance/default/borders/border2.bits.db");
|
|
|
|
pl = pr = pt = pb = 0;
|
|
if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
|
|
e_icccm_set_frame_size(b->win.client, pl, pr, pt, pb);
|
|
}
|
|
|
|
E_Border *
|
|
e_border_adopt(Window win, int use_client_pos)
|
|
{
|
|
E_Border *b;
|
|
|
|
/* create the struct */
|
|
b = e_border_new();
|
|
/* set the right event on the client */
|
|
e_window_set_events(win,
|
|
XEV_VISIBILITY |
|
|
ResizeRedirectMask |
|
|
XEV_CONFIGURE |
|
|
XEV_FOCUS |
|
|
XEV_PROPERTY |
|
|
XEV_COLORMAP);
|
|
/* parent of the client window listens for these */
|
|
e_window_set_events(b->win.container, XEV_CHILD_CHANGE | XEV_CHILD_REDIRECT);
|
|
/* add to save set & border of 0 */
|
|
e_icccm_adopt(win);
|
|
e_window_set_border_width(win, 0);
|
|
b->win.client = win;
|
|
b->current.requested.visible = 1;
|
|
/* get size & location hints */
|
|
e_icccm_get_size_info(win, b);
|
|
e_icccm_get_mwm_hints(win, b);
|
|
e_icccm_get_layer(win, b);
|
|
/* we have now placed the bugger */
|
|
b->placed = 1;
|
|
/* desk area */
|
|
e_icccm_set_desk_area(win, 0, 0);
|
|
e_icccm_set_desk(win, e_desktops_get_current());
|
|
if (use_client_pos)
|
|
{
|
|
int x, y;
|
|
|
|
e_window_get_geometry(win, &x, &y, NULL, NULL);
|
|
b->current.requested.x = x;
|
|
b->current.requested.y = y;
|
|
}
|
|
/* reparent the window finally */
|
|
e_window_reparent(win, b->win.container, 0, 0);
|
|
/* figure what border to use */
|
|
e_border_apply_border(b);
|
|
{
|
|
int pl, pr, pt, pb;
|
|
|
|
pl = pr = pt = pb = 0;
|
|
if (b->bits.l) ebits_get_insets(b->bits.l, &pl, &pr, &pt, &pb);
|
|
b->current.requested.x += pl;
|
|
b->current.requested.y += pt;
|
|
b->changed = 1;
|
|
}
|
|
/* show the client */
|
|
e_icccm_state_mapped(win);
|
|
/* fix size so it matches the hints a client asks for */
|
|
b->changed = 1;
|
|
e_border_adjust_limits(b);
|
|
e_border_raise(b);
|
|
e_window_show(win);
|
|
return b;
|
|
}
|
|
|
|
E_Border *
|
|
e_border_new(void)
|
|
{
|
|
E_Border *b;
|
|
int max_colors = 216;
|
|
int font_cache = 1024 * 1024;
|
|
int image_cache = 8192 * 1024;
|
|
char *font_dir = PACKAGE_DATA_DIR"/data/fonts";
|
|
E_Desktop *desk;
|
|
|
|
b = NEW(E_Border, 1);
|
|
ZERO(b, E_Border, 1);
|
|
|
|
OBJ_INIT(b, e_border_free);
|
|
|
|
b->current.requested.w = 1;
|
|
b->current.requested.h = 1;
|
|
b->client.min.w = 1;
|
|
b->client.min.h = 1;
|
|
b->client.max.w = 1000000;
|
|
b->client.max.h = 1000000;
|
|
b->client.min.aspect = -1000000;
|
|
b->client.max.aspect = 1000000;
|
|
b->client.step.w = 1;
|
|
b->client.step.h = 1;
|
|
b->client.layer = 4;
|
|
b->client.border = 1;
|
|
b->client.handles = 1;
|
|
b->client.titlebar = 1;
|
|
b->client.takes_focus = 1;
|
|
|
|
desk = e_desktops_get(e_desktops_get_current());
|
|
e_desktops_add_border(desk, b);
|
|
b->win.main = e_window_override_new(desk->win.container, 0, 0, 1, 1);
|
|
b->win.input = e_window_input_new(b->win.main, 0, 0, 1, 1);
|
|
b->win.container = e_window_override_new(b->win.main, 0, 0, 1, 1);
|
|
e_window_set_events(b->win.input, XEV_MOUSE_MOVE | XEV_BUTTON | XEV_IN_OUT);
|
|
e_window_show(b->win.input);
|
|
e_window_show(b->win.container);
|
|
|
|
b->evas.l = evas_new_all(e_display_get(),
|
|
b->win.main,
|
|
0, 0, 1, 1,
|
|
RENDER_METHOD_ALPHA_SOFTWARE,
|
|
max_colors,
|
|
font_cache,
|
|
image_cache,
|
|
font_dir);
|
|
b->win.l = evas_get_window(b->evas.l);
|
|
e_add_child(b->win.main, b->win.l);
|
|
b->evas.r = evas_new_all(e_display_get(),
|
|
b->win.main,
|
|
0, 0, 1, 1,
|
|
RENDER_METHOD_ALPHA_SOFTWARE,
|
|
max_colors,
|
|
font_cache,
|
|
image_cache,
|
|
font_dir);
|
|
b->win.r = evas_get_window(b->evas.r);
|
|
e_add_child(b->win.main, b->win.r);
|
|
b->evas.t = evas_new_all(e_display_get(),
|
|
b->win.main,
|
|
0, 0, 1, 1,
|
|
RENDER_METHOD_ALPHA_SOFTWARE,
|
|
max_colors,
|
|
font_cache,
|
|
image_cache,
|
|
font_dir);
|
|
b->win.t = evas_get_window(b->evas.t);
|
|
e_add_child(b->win.main, b->win.t);
|
|
b->evas.b = evas_new_all(e_display_get(),
|
|
b->win.main,
|
|
0, 0, 1, 1,
|
|
RENDER_METHOD_ALPHA_SOFTWARE,
|
|
max_colors,
|
|
font_cache,
|
|
image_cache,
|
|
font_dir);
|
|
b->win.b = evas_get_window(b->evas.b);
|
|
e_add_child(b->win.main, b->win.b);
|
|
|
|
e_window_raise(b->win.input);
|
|
e_window_raise(b->win.container);
|
|
|
|
evases = evas_list_append(evases, b->evas.l);
|
|
evases = evas_list_append(evases, b->evas.r);
|
|
evases = evas_list_append(evases, b->evas.t);
|
|
evases = evas_list_append(evases, b->evas.b);
|
|
|
|
e_window_set_events(b->win.l, XEV_EXPOSE);
|
|
e_window_set_events(b->win.r, XEV_EXPOSE);
|
|
e_window_set_events(b->win.t, XEV_EXPOSE);
|
|
e_window_set_events(b->win.b, XEV_EXPOSE);
|
|
|
|
e_window_show(b->win.l);
|
|
e_window_show(b->win.r);
|
|
e_window_show(b->win.t);
|
|
e_window_show(b->win.b);
|
|
|
|
e_border_attach_mouse_grabs(b);
|
|
|
|
borders = evas_list_prepend(borders, b);
|
|
|
|
return b;
|
|
}
|
|
|
|
void
|
|
e_border_free(E_Border *b)
|
|
{
|
|
Evas_List l;
|
|
|
|
e_desktops_del_border(b->desk, b);
|
|
if (b->bits.l) ebits_free(b->bits.l);
|
|
if (b->bits.r) ebits_free(b->bits.r);
|
|
if (b->bits.t) ebits_free(b->bits.t);
|
|
if (b->bits.b) ebits_free(b->bits.b);
|
|
evases = evas_list_remove(evases, b->evas.l);
|
|
evases = evas_list_remove(evases, b->evas.r);
|
|
evases = evas_list_remove(evases, b->evas.t);
|
|
evases = evas_list_remove(evases, b->evas.b);
|
|
evas_free(b->evas.l);
|
|
evas_free(b->evas.r);
|
|
evas_free(b->evas.t);
|
|
evas_free(b->evas.b);
|
|
e_window_destroy(b->win.container);
|
|
e_window_destroy(b->win.input);
|
|
e_window_destroy(b->win.main);
|
|
borders = evas_list_remove(borders, b);
|
|
|
|
if (b->grabs)
|
|
{
|
|
for (l = b->grabs; l; l = l->next)
|
|
{
|
|
FREE(l->data);
|
|
}
|
|
evas_list_free(b->grabs);
|
|
}
|
|
|
|
free(b);
|
|
}
|
|
|
|
void
|
|
e_border_remove_mouse_grabs(E_Border *b)
|
|
{
|
|
Evas_List l;
|
|
|
|
if (b->grabs)
|
|
{
|
|
for (l = b->grabs; l; l = l->next)
|
|
{
|
|
E_Grab *g;
|
|
|
|
g = l->data;
|
|
e_button_ungrab(b->win.main, g->button, g->mods, g->any_mod);
|
|
FREE(g);
|
|
}
|
|
evas_list_free(b->grabs);
|
|
b->grabs = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
e_border_attach_mouse_grabs(E_Border *b)
|
|
{
|
|
char *grabs_db = PACKAGE_DATA_DIR"/data/config/behavior/default/grabs.db";
|
|
char *settings_db = PACKAGE_DATA_DIR"/data/config/behavior/default/settings.db";
|
|
E_DB_File *db;
|
|
int focus_mode;
|
|
char buf[4096];
|
|
|
|
/* settings - click to focus would affect grabs */
|
|
db = e_db_open_read(settings_db);
|
|
sprintf(buf, "/focus/mode");
|
|
if ((db) && (e_db_int_get(db, buf, &focus_mode)) && (!b->current.selected))
|
|
{
|
|
if (focus_mode == 2) /* click to focus */
|
|
{
|
|
E_Grab *g;
|
|
|
|
g = NEW(E_Grab, 1);
|
|
ZERO(g, E_Grab, 1);
|
|
g->button = 0;
|
|
g->mods = 0;
|
|
g->any_mod = 1;
|
|
g->remove_after = 1;
|
|
b->grabs = evas_list_append(b->grabs, g);
|
|
e_button_grab(b->win.main, 0, XEV_BUTTON | XEV_MOUSE_MOVE, EV_KEY_MODIFIER_NONE, 1);
|
|
e_db_close(db);
|
|
}
|
|
}
|
|
|
|
/* other grabs - liek alt+left to move */
|
|
db = e_db_open_read(grabs_db);
|
|
if (db)
|
|
{
|
|
int i, num;
|
|
|
|
sprintf(buf, "/grabs/count");
|
|
if (!e_db_int_get(db, buf, &num))
|
|
{
|
|
e_db_close(db);
|
|
return;
|
|
}
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
int button, any_mod, mod;
|
|
Ev_Key_Modifiers mods;
|
|
|
|
button = -1;
|
|
mods = EV_KEY_MODIFIER_NONE;
|
|
any_mod = 0;
|
|
sprintf(buf, "/grabs/%i/button", i);
|
|
if (!e_db_int_get(db, buf, &button)) continue;
|
|
sprintf(buf, "/grabs/%i/modifiers", i);
|
|
if (!e_db_int_get(db, buf, &mod)) continue;
|
|
if (mod == -1) any_mod = 1;
|
|
mods = (Ev_Key_Modifiers)mod;
|
|
|
|
if (button >= 0)
|
|
{
|
|
E_Grab *g;
|
|
|
|
g = NEW(E_Grab, 1);
|
|
ZERO(g, E_Grab, 1);
|
|
g->button = button;
|
|
g->mods = mods;
|
|
g->any_mod = any_mod;
|
|
g->remove_after = 0;
|
|
b->grabs = evas_list_append(b->grabs, g);
|
|
e_button_grab(b->win.main, button, XEV_BUTTON | XEV_MOUSE_MOVE, mods, 0);
|
|
}
|
|
}
|
|
e_db_close(db);
|
|
}
|
|
}
|
|
|
|
void
|
|
e_border_remove_all_mouse_grabs(void)
|
|
{
|
|
Evas_List l;
|
|
|
|
for (l = borders; l; l = l->next)
|
|
e_border_remove_mouse_grabs((E_Border *)l->data);
|
|
}
|
|
|
|
void
|
|
e_border_attach_all_mouse_grabs(void)
|
|
{
|
|
Evas_List l;
|
|
|
|
for (l = borders; l; l = l->next)
|
|
e_border_attach_mouse_grabs((E_Border *)l->data);
|
|
}
|
|
|
|
void
|
|
e_border_redo_grabs(void)
|
|
{
|
|
char *grabs_db = PACKAGE_DATA_DIR"/data/config/behavior/default/grabs.db";
|
|
char *settings_db = PACKAGE_DATA_DIR"/data/config/behavior/default/settings.db";
|
|
static time_t mod_date_grabs = 0;
|
|
static time_t mod_date_settings = 0;
|
|
time_t mod;
|
|
int changed = 0;
|
|
Evas_List l;
|
|
|
|
mod = e_file_modified_time(grabs_db);
|
|
if (mod != mod_date_grabs) changed = 1;
|
|
mod_date_grabs = mod;
|
|
if (!changed)
|
|
{
|
|
mod = e_file_modified_time(settings_db);
|
|
if (mod != mod_date_settings) changed = 1;
|
|
mod_date_settings = mod;
|
|
}
|
|
if (!changed) return;
|
|
for (l = borders; l; l = l->next)
|
|
{
|
|
E_Border *b;
|
|
|
|
b = l->data;
|
|
e_border_remove_mouse_grabs(b);
|
|
e_border_attach_mouse_grabs(b);
|
|
}
|
|
}
|
|
|
|
E_Border *
|
|
e_border_find_by_window(Window win)
|
|
{
|
|
Evas_List l;
|
|
|
|
for (l = borders; l; l = l->next)
|
|
{
|
|
E_Border *b;
|
|
|
|
b = l->data;
|
|
|
|
if ((win == b->win.main) ||
|
|
(win == b->win.client) ||
|
|
(win == b->win.container) ||
|
|
(win == b->win.input) ||
|
|
(win == b->win.l) ||
|
|
(win == b->win.r) ||
|
|
(win == b->win.t) ||
|
|
(win == b->win.b))
|
|
return b;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
e_border_set_bits(E_Border *b, char *file)
|
|
{
|
|
int pl, pr, pt, pb, ppl, ppr, ppt, ppb;
|
|
|
|
pl = pr = pt = pb = 0;
|
|
ppl = ppr = ppt = ppb = 0;
|
|
|
|
if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
|
|
|
|
if (b->bits.l) ebits_free(b->bits.l);
|
|
if (b->bits.r) ebits_free(b->bits.r);
|
|
if (b->bits.t) ebits_free(b->bits.t);
|
|
if (b->bits.b) ebits_free(b->bits.b);
|
|
|
|
b->bits.l = ebits_load(file);
|
|
b->bits.r = ebits_load(file);
|
|
b->bits.t = ebits_load(file);
|
|
b->bits.b = ebits_load(file);
|
|
|
|
b->bits.new = 1;
|
|
b->changed = 1;
|
|
|
|
if (b->bits.t) ebits_get_insets(b->bits.l, &ppl, &ppr, &ppt, &ppb);
|
|
b->current.requested.w -= (pl + pr) - (ppl + ppr);
|
|
b->current.requested.h -= (pt + pb) - (ppt + ppb);
|
|
b->current.requested.x += (pl - ppl);
|
|
b->current.requested.y += (pt - ppt);
|
|
|
|
if (b->bits.t)
|
|
{
|
|
ebits_add_to_evas(b->bits.l, b->evas.l);
|
|
ebits_move(b->bits.l, 0, 0);
|
|
ebits_show(b->bits.l);
|
|
|
|
ebits_add_to_evas(b->bits.r, b->evas.r);
|
|
ebits_move(b->bits.r, 0, 0);
|
|
ebits_show(b->bits.r);
|
|
|
|
ebits_add_to_evas(b->bits.t, b->evas.t);
|
|
ebits_move(b->bits.t, 0, 0);
|
|
ebits_show(b->bits.t);
|
|
|
|
ebits_add_to_evas(b->bits.b, b->evas.b);
|
|
ebits_move(b->bits.b, 0, 0);
|
|
ebits_show(b->bits.b);
|
|
|
|
e_border_set_color_class(b, "Title BG", 100, 200, 255, 255);
|
|
|
|
#define HOOK_CB(_class) \
|
|
ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_IN, e_cb_mouse_in, b); \
|
|
ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_OUT, e_cb_mouse_out, b); \
|
|
ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_DOWN, e_cb_mouse_down, b); \
|
|
ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_UP, e_cb_mouse_up, b); \
|
|
ebits_set_bit_callback(b->bits.t, _class, CALLBACK_MOUSE_MOVE, e_cb_mouse_move, b);
|
|
HOOK_CB("Title_Bar");
|
|
HOOK_CB("Resize");
|
|
HOOK_CB("Resize_Horizontal");
|
|
HOOK_CB("Resize_Vertical");
|
|
HOOK_CB("Close");
|
|
HOOK_CB("Iconify");
|
|
HOOK_CB("Max_Size");
|
|
HOOK_CB("Menu");
|
|
|
|
e_border_adjust_limits(b);
|
|
}
|
|
}
|
|
|
|
void
|
|
e_border_set_color_class(E_Border *b, char *class, int rr, int gg, int bb, int aa)
|
|
{
|
|
ebits_set_color_class(b->bits.l, class, rr, gg, bb, aa);
|
|
ebits_set_color_class(b->bits.r, class, rr, gg, bb, aa);
|
|
ebits_set_color_class(b->bits.t, class, rr, gg, bb, aa);
|
|
ebits_set_color_class(b->bits.b, class, rr, gg, bb, aa);
|
|
}
|
|
|
|
void
|
|
e_border_adjust_limits(E_Border *b)
|
|
{
|
|
int w, h, pl, pr, pt, pb, mx, my;
|
|
|
|
if (b->mode.move) e_resist_border(b);
|
|
else
|
|
{
|
|
b->current.x = b->current.requested.x;
|
|
b->current.y = b->current.requested.y;
|
|
}
|
|
|
|
b->current.w = b->current.requested.w;
|
|
b->current.h = b->current.requested.h - b->current.shaded;
|
|
|
|
if (!b->current.shaded)
|
|
{
|
|
if (b->current.w < 1) b->current.w = 1;
|
|
if (b->current.h < 1) b->current.h = 1;
|
|
|
|
pl = pr = pt = pb = 0;
|
|
if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
|
|
|
|
if (b->current.w < (pl + pr + 1)) b->current.w = pl + pr + 1;
|
|
if (b->current.h < (pt + pb + 1)) b->current.h = pt + pb + 1;
|
|
|
|
w = b->current.w - pl - pr;
|
|
h = b->current.h - pt - pb + b->current.shaded;
|
|
|
|
mx = my = 1;
|
|
if (b->bits.t) ebits_get_min_size(b->bits.t, &mx, &my);
|
|
if (b->current.w < mx) b->current.w = mx;
|
|
if (b->current.h < my) b->current.h = my;
|
|
mx = my = 999999;
|
|
if (b->bits.t) ebits_get_max_size(b->bits.t, &mx, &my);
|
|
if (b->current.w > mx) b->current.w = mx;
|
|
if (b->current.h > my) b->current.h = my;
|
|
|
|
if (w < b->client.min.w) w = b->client.min.w;
|
|
if (h < b->client.min.h) h = b->client.min.h;
|
|
if (w > b->client.max.w) w = b->client.max.w;
|
|
if (h > b->client.max.h) h = b->client.max.h;
|
|
if ((w > 0) && (h > 0))
|
|
{
|
|
w -= b->client.base.w;
|
|
h -= b->client.base.h;
|
|
if ((w > 0) && (h > 0))
|
|
{
|
|
int i, j;
|
|
double aspect;
|
|
|
|
aspect = ((double)w) / ((double)h);
|
|
if ((b->mode.resize == 4) || (b->mode.resize == 5))
|
|
{
|
|
if (aspect < b->client.min.aspect)
|
|
h = (int)((double)w / b->client.min.aspect);
|
|
if (aspect > b->client.max.aspect)
|
|
h = (int)((double)w / b->client.max.aspect);
|
|
}
|
|
else if ((b->mode.resize == 6) || (b->mode.resize == 7))
|
|
{
|
|
if (aspect < b->client.min.aspect)
|
|
w = (int)((double)h * b->client.min.aspect);
|
|
if (aspect > b->client.max.aspect)
|
|
w = (int)((double)h * b->client.max.aspect);
|
|
}
|
|
else
|
|
{
|
|
if (aspect < b->client.min.aspect)
|
|
w = (int)((double)h * b->client.min.aspect);
|
|
if (aspect > b->client.max.aspect)
|
|
h = (int)((double)w / b->client.max.aspect);
|
|
}
|
|
i = w / b->client.step.w;
|
|
j = h / b->client.step.h;
|
|
w = i * b->client.step.w;
|
|
h = j * b->client.step.h;
|
|
}
|
|
w += b->client.base.w;
|
|
h += b->client.base.h;
|
|
}
|
|
b->client.w = w;
|
|
b->client.h = h;
|
|
b->current.w = w + pl + pr;
|
|
b->current.h = h + pt + pb;
|
|
}
|
|
|
|
if (b->current.shaded == 0)
|
|
{
|
|
if ((b->mode.resize == 3) || (b->mode.resize == 5) || (b->mode.resize == 7))
|
|
{
|
|
}
|
|
else if ((b->mode.resize == 0) || (b->mode.resize == 4))
|
|
{
|
|
b->current.x += (b->current.requested.w - b->current.w);
|
|
b->current.y += (b->current.requested.h - b->current.h);
|
|
}
|
|
else if ((b->mode.resize == 1) || (b->mode.resize == 6))
|
|
{
|
|
b->current.y += (b->current.requested.h - b->current.h);
|
|
}
|
|
else if ((b->mode.resize == 2))
|
|
{
|
|
b->current.x += (b->current.requested.w - b->current.w);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
e_border_update(E_Border *b)
|
|
{
|
|
int location_changed = 0;
|
|
int size_changed = 0;
|
|
int shape_changed = 0;
|
|
int border_changed = 0;
|
|
int visibility_changed = 0;
|
|
int state_changed = 0;
|
|
|
|
if (!b->changed) return;
|
|
|
|
b->current.visible = b->current.requested.visible;
|
|
|
|
if ((b->current.x != b->previous.x) || (b->current.y != b->previous.y))
|
|
location_changed = 1;
|
|
if ((b->current.w != b->previous.w) || (b->current.h != b->previous.h))
|
|
size_changed = 1;
|
|
if ((size_changed) && (b->has_shape))
|
|
shape_changed = 1;
|
|
if (b->bits.new)
|
|
{
|
|
e_window_gravity_set(b->win.container, StaticGravity);
|
|
border_changed = 1;
|
|
}
|
|
if ((border_changed) && (b->has_shape))
|
|
shape_changed = 1;
|
|
if (b->current.visible != b->previous.visible)
|
|
visibility_changed = 1;
|
|
if (b->current.selected != b->previous.selected)
|
|
state_changed = 1;
|
|
|
|
if (state_changed)
|
|
{
|
|
e_border_apply_border(b);
|
|
if (!border_changed)
|
|
{
|
|
e_window_gravity_set(b->win.container, StaticGravity);
|
|
border_changed = 1;
|
|
size_changed = 1;
|
|
}
|
|
}
|
|
if ((location_changed) && (!size_changed))
|
|
{
|
|
int pl, pr, pt, pb;
|
|
|
|
e_window_move(b->win.main, b->current.x, b->current.y);
|
|
pl = pr = pt = pb = 0;
|
|
if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
|
|
e_icccm_move_resize(b->win.client,
|
|
b->current.x + pl,
|
|
b->current.y + pt,
|
|
b->client.w,
|
|
b->client.h);
|
|
e_cb_border_move_resize(b);
|
|
}
|
|
else if (size_changed)
|
|
{
|
|
int pl, pr, pt, pb, x, y, w, h;
|
|
int smaller;
|
|
|
|
smaller = 0;
|
|
if ((b->current.w < b->previous.w) || (b->current.h < b->previous.h))
|
|
smaller = 1;
|
|
pl = pr = pt = pb = 0;
|
|
if (b->bits.t) ebits_get_insets(b->bits.t, &pl, &pr, &pt, &pb);
|
|
e_window_move_resize(b->win.input,
|
|
0, 0, b->current.w, b->current.h);
|
|
e_window_move_resize(b->win.main,
|
|
b->current.x, b->current.y,
|
|
b->current.w, b->current.h);
|
|
if (b->current.shaded == b->client.h)
|
|
{
|
|
e_window_move_resize(b->win.client,
|
|
0, - b->current.shaded,
|
|
b->client.w,
|
|
b->client.h);
|
|
e_window_move_resize(b->win.container,
|
|
b->current.w + 1,
|
|
b->current.h + 1,
|
|
1,
|
|
1);
|
|
}
|
|
else
|
|
{
|
|
e_window_move_resize(b->win.client,
|
|
0, - b->current.shaded,
|
|
b->client.w,
|
|
b->client.h);
|
|
e_window_move_resize(b->win.container,
|
|
pl,
|
|
pt,
|
|
b->current.w - pl - pr,
|
|
b->current.h - pt - pb);
|
|
}
|
|
x = 0, y = pt, w = pl, h = (b->current.h - pt - pb);
|
|
if ((w <1) || (h < 1)) e_window_hide(b->win.l);
|
|
else
|
|
{
|
|
e_window_show(b->win.l);
|
|
e_window_move_resize(b->win.l, x, y, w, h);
|
|
evas_set_output_size(b->evas.l, w, h);
|
|
evas_set_output_viewport(b->evas.l, x, y, w, h);
|
|
}
|
|
|
|
x = 0, y = 0, w = b->current.w, h = pt;
|
|
if ((w <1) || (h < 1)) e_window_hide(b->win.t);
|
|
else
|
|
{
|
|
e_window_show(b->win.t);
|
|
e_window_move_resize(b->win.t, x, y, w, h);
|
|
evas_set_output_size(b->evas.t, w, h);
|
|
evas_set_output_viewport(b->evas.t, x, y, w, h);
|
|
}
|
|
|
|
x = b->current.w - pr, y = pt, w = pr, h = (b->current.h - pt - pb);
|
|
if ((w <1) || (h < 1)) e_window_hide(b->win.r);
|
|
else
|
|
{
|
|
e_window_show(b->win.r);
|
|
e_window_move_resize(b->win.r, x, y, w, h);
|
|
evas_set_output_size(b->evas.r, w, h);
|
|
evas_set_output_viewport(b->evas.r, x, y, w, h);
|
|
}
|
|
|
|
x = 0, y = b->current.h - pb, w = b->current.w, h = pb;
|
|
if ((w <1) || (h < 1)) e_window_hide(b->win.b);
|
|
else
|
|
{
|
|
e_window_show(b->win.b);
|
|
e_window_move_resize(b->win.b, x, y, w, h);
|
|
evas_set_output_size(b->evas.b, w, h);
|
|
evas_set_output_viewport(b->evas.b, x, y, w, h);
|
|
}
|
|
|
|
if (b->bits.l) ebits_resize(b->bits.l, b->current.w, b->current.h);
|
|
if (b->bits.r) ebits_resize(b->bits.r, b->current.w, b->current.h);
|
|
if (b->bits.t) ebits_resize(b->bits.t, b->current.w, b->current.h);
|
|
if (b->bits.b) ebits_resize(b->bits.b, b->current.w, b->current.h);
|
|
|
|
e_icccm_move_resize(b->win.client,
|
|
b->current.x + pl, b->current.y + pt - b->current.shaded,
|
|
b->client.w, b->client.h);
|
|
e_cb_border_move_resize(b);
|
|
}
|
|
if (visibility_changed)
|
|
{
|
|
if (b->current.visible)
|
|
e_window_show(b->win.main);
|
|
else
|
|
e_window_hide(b->win.main);
|
|
e_cb_border_visibility(b);
|
|
}
|
|
|
|
if (border_changed)
|
|
e_window_gravity_set(b->win.container, NorthWestGravity);
|
|
b->bits.new = 0;
|
|
b->previous = b->current;
|
|
b->changed = 0;
|
|
}
|
|
|
|
void
|
|
e_border_set_layer(E_Border *b, int layer)
|
|
{
|
|
int dl;
|
|
|
|
if (b->client.layer == layer) return;
|
|
dl = layer - b->client.layer;
|
|
b->client.layer = layer;
|
|
if (dl > 0) e_border_lower(b);
|
|
else e_border_raise(b);
|
|
}
|
|
|
|
void
|
|
e_border_raise(E_Border *b)
|
|
{
|
|
Evas_List l;
|
|
E_Border *rel;
|
|
|
|
if (!b->desk->windows)
|
|
{
|
|
b->desk->windows = evas_list_append(b->desk->windows, b);
|
|
b->desk->changed = 1;
|
|
e_window_raise(b->win.main);
|
|
return;
|
|
}
|
|
for (l = b->desk->windows; l; l = l->next)
|
|
{
|
|
rel = l->data;
|
|
if (rel->client.layer > b->client.layer)
|
|
{
|
|
b->desk->windows = evas_list_remove(b->desk->windows, b);
|
|
b->desk->windows = evas_list_prepend_relative(b->desk->windows, b, rel);
|
|
b->desk->changed = 1;
|
|
e_window_stack_below(b->win.main, rel->win.main);
|
|
return;
|
|
}
|
|
if ((!l->next) && (l->data != b))
|
|
{
|
|
b->desk->windows = evas_list_remove(b->desk->windows, b);
|
|
b->desk->windows = evas_list_append(b->desk->windows, b);
|
|
b->desk->changed = 1;
|
|
e_window_raise(b->win.main);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
e_border_lower(E_Border *b)
|
|
{
|
|
Evas_List l;
|
|
E_Border *rel;
|
|
|
|
if (!b->desk->windows)
|
|
{
|
|
b->desk->windows = evas_list_append(b->desk->windows, b);
|
|
b->desk->changed = 1;
|
|
e_window_raise(b->win.main);
|
|
return;
|
|
}
|
|
for (l = b->desk->windows; l; l = l->next)
|
|
{
|
|
rel = l->data;
|
|
if (rel->client.layer == b->client.layer)
|
|
{
|
|
if (b == rel) return;
|
|
b->desk->windows = evas_list_remove(b->desk->windows, b);
|
|
b->desk->windows = evas_list_prepend_relative(b->desk->windows, b, rel);
|
|
b->desk->changed = 1;
|
|
e_window_stack_below(b->win.main, rel->win.main);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
e_border_raise_above(E_Border *b, E_Border *above)
|
|
{
|
|
if (!b->desk->windows)
|
|
{
|
|
b->desk->windows = evas_list_append(b->desk->windows, b);
|
|
b->desk->changed = 1;
|
|
e_window_raise(b->win.main);
|
|
return;
|
|
}
|
|
if (!evas_list_find(b->desk->windows, above)) return;
|
|
if (b->client.layer < above->client.layer) b->client.layer = above->client.layer;
|
|
b->desk->windows = evas_list_remove(b->desk->windows, b);
|
|
b->desk->windows = evas_list_append_relative(b->desk->windows, b, above);
|
|
b->desk->changed = 1;
|
|
e_window_stack_above(b->win.main, above->win.main);
|
|
}
|
|
|
|
void
|
|
e_border_lower_below(E_Border *b, E_Border *below)
|
|
{
|
|
if (!b->desk->windows)
|
|
{
|
|
b->desk->windows = evas_list_append(b->desk->windows, b);
|
|
b->desk->changed = 1;
|
|
return;
|
|
}
|
|
if (!evas_list_find(b->desk->windows, below)) return;
|
|
if (b->client.layer > below->client.layer) b->client.layer = below->client.layer;
|
|
b->desk->windows = evas_list_remove(b->desk->windows, b);
|
|
b->desk->windows = evas_list_prepend_relative(b->desk->windows, b, below);
|
|
b->desk->changed = 1;
|
|
e_window_stack_below(b->win.main, below->win.main);
|
|
}
|
|
|
|
void
|
|
e_border_init(void)
|
|
{
|
|
e_event_filter_handler_add(EV_MOUSE_DOWN, e_mouse_down);
|
|
e_event_filter_handler_add(EV_MOUSE_UP, e_mouse_up);
|
|
e_event_filter_handler_add(EV_MOUSE_MOVE, e_mouse_move);
|
|
e_event_filter_handler_add(EV_MOUSE_IN, e_mouse_in);
|
|
e_event_filter_handler_add(EV_MOUSE_OUT, e_mouse_out);
|
|
e_event_filter_handler_add(EV_WINDOW_EXPOSE, e_window_expose);
|
|
e_event_filter_handler_add(EV_WINDOW_MAP_REQUEST, e_map_request);
|
|
e_event_filter_handler_add(EV_WINDOW_CONFIGURE_REQUEST, e_configure_request);
|
|
e_event_filter_handler_add(EV_WINDOW_PROPERTY, e_property);
|
|
e_event_filter_handler_add(EV_WINDOW_UNMAP, e_unmap);
|
|
e_event_filter_handler_add(EV_WINDOW_DESTROY, e_destroy);
|
|
e_event_filter_handler_add(EV_WINDOW_CIRCULATE_REQUEST, e_circulate_request);
|
|
e_event_filter_handler_add(EV_WINDOW_REPARENT, e_reparent);
|
|
e_event_filter_handler_add(EV_WINDOW_SHAPE, e_shape);
|
|
e_event_filter_handler_add(EV_WINDOW_FOCUS_IN, e_focus_in);
|
|
e_event_filter_handler_add(EV_WINDOW_FOCUS_OUT, e_focus_out);
|
|
e_event_filter_handler_add(EV_COLORMAP, e_colormap);
|
|
e_event_filter_idle_handler_add(e_idle, NULL);
|
|
|
|
e_add_event_timer("e_border_poll()", 1.00, e_border_poll, 0, NULL);
|
|
}
|
|
|
|
void
|
|
e_border_adopt_children(Window win)
|
|
{
|
|
Window *wins;
|
|
int i, num;
|
|
|
|
wins = e_window_get_children(win, &num);
|
|
if (wins)
|
|
{
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
if (e_window_is_manageable(wins[i]))
|
|
{
|
|
E_Border *b;
|
|
|
|
b = e_border_adopt(wins[i], 1);
|
|
{
|
|
int pl, pr, pt, pb;
|
|
|
|
pl = pr = pt = pb = 0;
|
|
if (b->bits.l) ebits_get_insets(b->bits.l, &pl, &pr, &pt, &pb);
|
|
b->current.requested.x -= pl;
|
|
b->current.requested.y -= pt;
|
|
b->changed = 1;
|
|
e_border_adjust_limits(b);
|
|
}
|
|
b->ignore_unmap = 2;
|
|
}
|
|
}
|
|
free(wins);
|
|
}
|
|
}
|