enlightenment/src/bin/e_winlist.c

440 lines
12 KiB
C
Raw Normal View History

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
/* local subsystem functions */
typedef struct _E_Winlist_Win E_Winlist_Win;
struct _E_Winlist_Win
{
Evas_Object *bg_object;
Evas_Object *icon_object;
E_Border *border;
};
static void _e_winlist_size_adjust(void);
static void _e_winlist_border_add(E_Border *bd, E_Zone *zone, E_Desk *desk);
static void _e_winlist_border_del(E_Border *bd);
static void _e_winlist_activate_nth(int n);
static void _e_winlist_activate(void);
static void _e_winlist_deactivate(void);
static void _e_winlist_show_active(void);
static int _e_winlist_cb_event_border_add(void *data, int type, void *event);
static int _e_winlist_cb_event_border_remove(void *data, int type, void *event);
static int _e_winlist_cb_key_down(void *data, int type, void *event);
static int _e_winlist_cb_key_up(void *data, int type, void *event);
/* local subsystem globals */
2005-06-07 06:53:27 -07:00
static E_Popup *winlist = NULL;
static Evas_Object *bg_object = NULL;
static Evas_Object *list_object = NULL;
static Evas_List *wins = NULL;
static Evas_List *win_selected = NULL;
static int hold_count = 0;
static int hold_mod = 0;
static Evas_List *handlers = NULL;
static Ecore_X_Window input_window = 0;
/* FIXME: gfx are UGLY. theyare test gfx and nothng more atm */
/* FIXME: support optional warp pointer to window */
/* FIXME: add mouse downa nd up handlers and pass events to bindings from them incase mouse binding starst winlist */
/* externally accessible functions */
int
e_winlist_init(void)
{
return 1;
}
int
e_winlist_shutdown(void)
{
2005-06-07 06:53:27 -07:00
e_winlist_hide();
return 1;
}
int
2005-06-07 06:53:27 -07:00
e_winlist_show(E_Zone *zone)
{
int x, y, w, h;
Evas_Object *o;
Evas_List *l;
E_Desk *desk;
E_Border *bd;
2005-06-07 06:53:27 -07:00
if (winlist) return 0;
2005-06-07 06:53:27 -07:00
/* FIXME: sizes/pos should be config */
2005-06-07 06:53:27 -07:00
w = zone->w / 2;
if (w > 320) w = 320;
2005-06-07 06:53:27 -07:00
h = zone->h / 2;
if (h > 800) h = 800;
else if (h < 400) h = 400;
x = (zone->w - w) / 2;
y = (zone->h - h) / 2;
2005-06-07 06:53:27 -07:00
winlist = e_popup_new(zone, x, y, w, h);
if (!winlist) return;
e_popup_layer_set(winlist, 255);
evas_event_freeze(winlist->evas);
2005-06-07 06:53:27 -07:00
o = edje_object_add(winlist->evas);
bg_object = o;
2005-06-07 06:53:27 -07:00
e_theme_edje_object_set(o, "base/theme/winlist",
"widgets/winlist/main");
evas_object_move(o, 0, 0);
evas_object_resize(o, w, h);
evas_object_show(o);
e_popup_edje_bg_object_set(winlist, o);
o = e_box_add(winlist->evas);
list_object = o;
e_box_align_set(o, 0.5, 0.0);
e_box_orientation_set(o, 0);
e_box_homogenous_set(o, 1);
edje_object_part_swallow(bg_object, "list_swallow", o);
evas_object_show(o);
desk = e_desk_current_get(winlist->zone);
e_box_freeze(list_object);
for (l = e_border_focus_stack_get(); l; l = l->next)
{
E_Border *bd;
bd = l->data;
_e_winlist_border_add(bd, winlist->zone, desk);
}
e_box_thaw(list_object);
bd = e_border_focused_get();
if (bd) e_border_focus_set(bd, 0, 0);
_e_winlist_activate_nth(0);
evas_event_thaw(winlist->evas);
_e_winlist_size_adjust();
input_window = ecore_x_window_input_new(zone->container->win, 0, 0, 1, 1);
ecore_x_window_show(input_window);
ecore_x_pointer_grab(input_window);
ecore_x_keyboard_grab(input_window);
handlers = evas_list_append
(handlers, ecore_event_handler_add
(E_EVENT_BORDER_ADD, _e_winlist_cb_event_border_add, NULL));
handlers = evas_list_append
(handlers, ecore_event_handler_add
(E_EVENT_BORDER_REMOVE, _e_winlist_cb_event_border_remove, NULL));
handlers = evas_list_append
(handlers, ecore_event_handler_add
(ECORE_X_EVENT_KEY_DOWN, _e_winlist_cb_key_down, NULL));
handlers = evas_list_append
(handlers, ecore_event_handler_add
(ECORE_X_EVENT_KEY_UP, _e_winlist_cb_key_up, NULL));
2005-06-07 06:53:27 -07:00
e_popup_show(winlist);
return 1;
2005-06-07 06:53:27 -07:00
}
void
e_winlist_hide(void)
{
if (!winlist) return;
/* FIXME: ensure whatever window is selected is focused after we finish cleanup */
evas_event_freeze(winlist->evas);
2005-06-07 06:53:27 -07:00
e_popup_hide(winlist);
e_box_freeze(list_object);
while (wins)
{
E_Winlist_Win *ww;
ww = wins->data;
evas_object_del(ww->bg_object);
evas_object_del(ww->icon_object);
free(ww);
wins = evas_list_remove_list(wins, wins);
}
e_box_thaw(list_object);
win_selected = NULL;
evas_object_del(list_object);
list_object = NULL;
evas_object_del(bg_object);
bg_object = NULL;
evas_event_thaw(winlist->evas);
2005-06-07 06:53:27 -07:00
e_object_del(E_OBJECT(winlist));
winlist = NULL;
hold_count = 0;
hold_mod = 0;
while (handlers)
{
ecore_event_handler_del(handlers->data);
handlers = evas_list_remove_list(handlers, handlers);
}
ecore_x_window_del(input_window);
input_window = 0;
2005-06-07 06:53:27 -07:00
}
void
e_winlist_next(void)
{
_e_winlist_deactivate();
win_selected = win_selected->next;
if (!win_selected) win_selected = wins;
_e_winlist_show_active();
_e_winlist_activate();
2005-06-07 06:53:27 -07:00
}
void
e_winlist_prev(void)
{
_e_winlist_deactivate();
win_selected = win_selected->prev;
if (!win_selected) win_selected = evas_list_last(wins);
_e_winlist_show_active();
_e_winlist_activate();
2005-06-07 06:53:27 -07:00
}
void
e_winlist_modifiers_set(int mod)
{
hold_mod = mod;
hold_count = 0;
if (hold_mod & ECORE_X_MODIFIER_SHIFT) hold_count++;
if (hold_mod & ECORE_X_MODIFIER_CTRL) hold_count++;
if (hold_mod & ECORE_X_MODIFIER_ALT) hold_count++;
if (hold_mod & ECORE_X_MODIFIER_WIN) hold_count++;
}
/* local subsystem functions */
static void
_e_winlist_size_adjust(void)
{
Evas_Coord mw, mh;
int x, y, w, h;
e_box_freeze(list_object);
e_box_min_size_get(list_object, &mw, &mh);
edje_extern_object_min_size_set(list_object, mw, mh);
edje_object_part_swallow(bg_object, "list_swallow", list_object);
edje_object_size_min_calc(bg_object, &mw, &mh);
edje_extern_object_min_size_set(list_object, -1, -1);
e_box_thaw(list_object);
/* FIXME: sizes/pos should be config */
w = winlist->zone->w / 2;
if (w > 320) w = 320;
h = mh;
if (h > 800) h = 800;
x = (winlist->zone->w - w) / 2;
y = (winlist->zone->h - h) / 2;
evas_object_resize(bg_object, w, h);
e_popup_move_resize(winlist, x, y, w, h);
}
static void
_e_winlist_border_add(E_Border *bd, E_Zone *zone, E_Desk *desk)
{
if ((bd->zone) &&
(bd->zone == zone) &&
((bd->desk == desk) || (bd->sticky)))
{
E_Winlist_Win *ww;
Evas_Coord mw, mh;
Evas_Object *o;
ww = calloc(1, sizeof(E_Winlist_Win));
if (!ww) return;
ww->border = bd;
wins = evas_list_append(wins, ww);
o = edje_object_add(winlist->evas);
ww->bg_object = o;
e_theme_edje_object_set(o, "base/theme/winlist",
"widgets/winlist/item");
if (bd->client.netwm.name)
edje_object_part_text_set(o, "title_text", bd->client.netwm.name);
else if (bd->client.icccm.title)
edje_object_part_text_set(o, "title_text", bd->client.icccm.title);
evas_object_show(o);
o = e_border_icon_add(bd, winlist->evas);
ww->icon_object = o;
edje_object_part_swallow(ww->bg_object, "icon_swallow", o);
evas_object_show(o);
edje_object_size_min_calc(ww->bg_object, &mw, &mh);
e_box_pack_end(list_object, ww->bg_object);
e_box_pack_options_set(ww->bg_object,
1, 1, /* fill */
1, 0, /* expand */
0.5, 0.5, /* align */
mw, mh, /* min */
9999, mh /* max */
);
}
}
static void
_e_winlist_border_del(E_Border *bd)
{
Evas_List *l;
for (l = wins; l; l = l->next)
{
E_Winlist_Win *ww;
ww = l->data;
if (ww->border == bd)
{
evas_object_del(ww->bg_object);
evas_object_del(ww->icon_object);
free(ww);
wins = evas_list_remove_list(wins, l);
return;
}
}
}
static void
_e_winlist_activate_nth(int n)
{
Evas_List *l;
_e_winlist_deactivate();
l = evas_list_nth_list(wins, n);
if (l)
{
win_selected = l;
_e_winlist_show_active();
_e_winlist_activate();
}
}
static void
_e_winlist_activate(void)
{
E_Winlist_Win *ww;
if (!win_selected) return;
ww = win_selected->data;
edje_object_signal_emit(ww->bg_object, "active", "");
e_border_raise(ww->border);
e_border_focus_set(ww->border, 1, 1);
edje_object_signal_emit(bg_object, "active", "");
}
static void
_e_winlist_deactivate(void)
{
E_Winlist_Win *ww;
if (!win_selected) return;
ww = win_selected->data;
edje_object_signal_emit(ww->bg_object, "passive", "");
e_border_focus_set(ww->border, 0, 0);
}
static void
_e_winlist_show_active(void)
{
/* FIXME: scroll so the selected win is visible */
}
static int
_e_winlist_cb_event_border_add(void *data, int type, void *event)
{
E_Event_Border_Add *ev;
ev = event;
_e_winlist_border_add(ev->border, winlist->zone,
e_desk_current_get(winlist->zone));
_e_winlist_size_adjust();
}
static int
_e_winlist_cb_event_border_remove(void *data, int type, void *event)
{
E_Event_Border_Remove *ev;
ev = event;
_e_winlist_border_del(ev->border);
_e_winlist_size_adjust();
}
static int
_e_winlist_cb_key_down(void *data, int type, void *event)
{
Ecore_X_Event_Key_Down *ev;
ev = event;
if (ev->win != input_window) return 1;
if (!strcmp(ev->keysymbol, "Up"))
e_winlist_prev();
else if (!strcmp(ev->keysymbol, "Down"))
e_winlist_next();
else if (!strcmp(ev->keysymbol, "Left"))
e_winlist_prev();
else if (!strcmp(ev->keysymbol, "Right"))
e_winlist_next();
else if (!strcmp(ev->keysymbol, "Return"))
e_winlist_hide();
else if (!strcmp(ev->keysymbol, "space"))
e_winlist_hide();
else if (!strcmp(ev->keysymbol, "Escape"))
e_winlist_hide();
else if (!strcmp(ev->keysymbol, "1"))
_e_winlist_activate_nth(0);
else if (!strcmp(ev->keysymbol, "2"))
_e_winlist_activate_nth(1);
else if (!strcmp(ev->keysymbol, "3"))
_e_winlist_activate_nth(2);
else if (!strcmp(ev->keysymbol, "4"))
_e_winlist_activate_nth(3);
else if (!strcmp(ev->keysymbol, "5"))
_e_winlist_activate_nth(4);
else if (!strcmp(ev->keysymbol, "6"))
_e_winlist_activate_nth(5);
else if (!strcmp(ev->keysymbol, "7"))
_e_winlist_activate_nth(6);
else if (!strcmp(ev->keysymbol, "8"))
_e_winlist_activate_nth(7);
else if (!strcmp(ev->keysymbol, "9"))
_e_winlist_activate_nth(8);
else if (!strcmp(ev->keysymbol, "0"))
_e_winlist_activate_nth(9);
else
e_bindings_key_down_event_handle(E_BINDING_CONTEXT_WINLIST,
E_OBJECT(winlist->zone), ev);
return 1;
}
static int
_e_winlist_cb_key_up(void *data, int type, void *event)
{
Ecore_X_Event_Key_Up *ev;
ev = event;
if (ev->win != input_window) return 1;
if (hold_mod)
{
if ((hold_mod & ECORE_X_MODIFIER_SHIFT) && (!strcmp(ev->keysymbol, "Shift_L"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_SHIFT) && (!strcmp(ev->keysymbol, "Shift_R"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_CTRL) && (!strcmp(ev->keysymbol, "Control_L"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_CTRL) && (!strcmp(ev->keysymbol, "Control_R"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_ALT) && (!strcmp(ev->keysymbol, "Alt_L"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_ALT) && (!strcmp(ev->keysymbol, "Alt_R"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_ALT) && (!strcmp(ev->keysymbol, "Meta_L"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_ALT) && (!strcmp(ev->keysymbol, "Meta_R"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_ALT) && (!strcmp(ev->keysymbol, "Super_L"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_ALT) && (!strcmp(ev->keysymbol, "Super_R"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_WIN) && (!strcmp(ev->keysymbol, "Super_L"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_WIN) && (!strcmp(ev->keysymbol, "Super_R"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_WIN) && (!strcmp(ev->keysymbol, "Mode_switch"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_WIN) && (!strcmp(ev->keysymbol, "Meta_L"))) hold_count--;
else if ((hold_mod & ECORE_X_MODIFIER_WIN) && (!strcmp(ev->keysymbol, "Meta_R"))) hold_count--;
if (hold_count <= 0)
{
e_winlist_hide();
return 1;
}
}
e_bindings_key_up_event_handle(E_BINDING_CONTEXT_WINLIST,
E_OBJECT(winlist->zone), ev);
return 1;
2005-06-07 06:53:27 -07:00
}