enlightenment/src/modules/winlist/e_mod_main.c

200 lines
7.5 KiB
C
Raw Normal View History

2007-08-04 21:41:55 -07:00
#include "e.h"
#include "e_mod_main.h"
/* actual module specifics */
static void _e_mod_action_winlist_cb(E_Object *obj, const char *params);
static void _e_mod_action_winlist_mouse_cb(E_Object *obj, const char *params, E_Binding_Event_Mouse_Button *ev);
static void _e_mod_action_winlist_key_cb(E_Object *obj, const char *params, Ecore_Event_Key *ev);
static void _e_mod_action_winlist_edge_cb(E_Object *obj, const char *params, E_Event_Zone_Edge *ev);
static void _e_mod_action_winlist_signal_cb(E_Object *obj, const char *params, const char *sig, const char *src);
static void _e_mod_action_winlist_acpi_cb(E_Object *obj, const char *params, E_Event_Acpi *ev);
2007-08-04 21:41:55 -07:00
static E_Module *conf_module = NULL;
const char *_winlist_act = NULL;
E_Action *_act_winlist = NULL;
2007-08-04 21:41:55 -07:00
/* module setup */
E_API E_Module_Api e_modapi =
2007-08-04 21:41:55 -07:00
{
E_MODULE_API_VERSION,
2012-06-20 00:01:53 -07:00
"Winlist"
2007-08-04 21:41:55 -07:00
};
E_API void *
2007-08-04 21:41:55 -07:00
e_modapi_init(E_Module *m)
{
conf_module = m;
e_configure_registry_category_add("windows", 50, _("Windows"), NULL, "preferences-system-windows");
e_configure_registry_item_add("windows/window_list", 70, _("Window Switcher"), NULL, "preferences-winlist", e_int_config_winlist);
2007-08-04 21:41:55 -07:00
e_winlist_init();
_winlist_act = eina_stringshare_add("winlist");
2007-08-04 21:41:55 -07:00
/* add module supplied action */
_act_winlist = e_action_add(_winlist_act);
if (_act_winlist)
2007-08-04 21:41:55 -07:00
{
_act_winlist->func.go = _e_mod_action_winlist_cb;
_act_winlist->func.go_mouse = _e_mod_action_winlist_mouse_cb;
_act_winlist->func.go_key = _e_mod_action_winlist_key_cb;
_act_winlist->func.go_edge = _e_mod_action_winlist_edge_cb;
_act_winlist->func.go_signal = _e_mod_action_winlist_signal_cb;
_act_winlist->func.go_acpi = _e_mod_action_winlist_acpi_cb;
e_action_predef_name_set(N_("Window : List"), N_("Next Window"),
"winlist", "next", NULL, 0);
e_action_predef_name_set(N_("Window : List"), N_("Previous Window"),
2012-06-20 00:01:53 -07:00
"winlist", "prev", NULL, 0);
e_action_predef_name_set(N_("Window : List"),
N_("Next window of same class"), "winlist",
2012-06-20 00:01:53 -07:00
"class-next", NULL, 0);
e_action_predef_name_set(N_("Window : List"),
N_("Previous window of same class"),
2012-06-20 00:01:53 -07:00
"winlist", "class-prev", NULL, 0);
e_action_predef_name_set(N_("Window : List"),
N_("Next window class"), "winlist",
2012-06-20 00:01:53 -07:00
"classes-next", NULL, 0);
e_action_predef_name_set(N_("Window : List"),
N_("Previous window class"),
2012-06-20 00:01:53 -07:00
"winlist", "classes-prev", NULL, 0);
e_action_predef_name_set(N_("Window : List"), N_("Window on the Left"),
2012-06-20 00:01:53 -07:00
"winlist", "left", NULL, 0);
e_action_predef_name_set(N_("Window : List"), N_("Window Down"),
2012-06-20 00:01:53 -07:00
"winlist", "down", NULL, 0);
e_action_predef_name_set(N_("Window : List"), N_("Window Up"),
2012-06-20 00:01:53 -07:00
"winlist", "up", NULL, 0);
e_action_predef_name_set(N_("Window : List"), N_("Window on the Right"),
2012-06-20 00:01:53 -07:00
"winlist", "right", NULL, 0);
2007-08-04 21:41:55 -07:00
}
e_module_delayed_set(m, 1);
return m;
}
E_API int
e_modapi_shutdown(E_Module *m EINA_UNUSED)
2007-08-04 21:41:55 -07:00
{
E_Config_Dialog *cfd;
2012-06-20 00:01:53 -07:00
2007-08-04 21:41:55 -07:00
/* remove module-supplied action */
if (_act_winlist)
2007-08-04 21:41:55 -07:00
{
e_action_predef_name_del("Window : List", "Previous Window");
e_action_predef_name_del("Window : List", "Next Window");
e_action_predef_name_del("Window : List",
"Previous window of same class");
e_action_predef_name_del("Window : List",
"Next window of same class");
e_action_predef_name_del("Window : List", "Window on the Left");
e_action_predef_name_del("Window : List", "Window Down");
e_action_predef_name_del("Window : List", "Window Up");
e_action_predef_name_del("Window : List", "Window on the Right");
2012-06-20 00:01:53 -07:00
e_action_del("winlist");
_act_winlist = NULL;
2007-08-04 21:41:55 -07:00
}
e_winlist_shutdown();
2012-06-20 00:01:53 -07:00
while ((cfd = e_config_dialog_get("E", "windows/window_list")))
e_object_del(E_OBJECT(cfd));
e_configure_registry_item_del("windows/window_list");
e_configure_registry_category_del("windows");
2007-08-04 21:41:55 -07:00
conf_module = NULL;
eina_stringshare_replace(&_winlist_act, NULL);
2007-08-04 21:41:55 -07:00
return 1;
}
E_API int
e_modapi_save(E_Module *m EINA_UNUSED)
2007-08-04 21:41:55 -07:00
{
return 1;
}
/* action callback */
static void
2015-03-13 14:44:24 -07:00
_e_mod_action_winlist_cb_helper(E_Object *obj EINA_UNUSED, const char *params, int modifiers, E_Winlist_Activate_Type type)
2007-08-04 21:41:55 -07:00
{
E_Zone *zone = NULL;
E_Winlist_Filter filter = E_WINLIST_FILTER_NONE;
int direction = 0; // -1 for prev, 1 for next;
int udlr = -1; // 0 for up, 1 for down, 2 for left, 3 for right
Eina_Bool ok = EINA_TRUE;
2015-03-13 14:44:24 -07:00
zone = e_zone_current_get();
if (!zone) return;
if (params)
2007-08-04 21:41:55 -07:00
{
if (!strcmp(params, "next"))
direction = 1;
else if (!strcmp(params, "prev"))
direction = -1;
else if (!strcmp(params, "class-next"))
direction = 1, filter = E_WINLIST_FILTER_CLASS_WINDOWS;
else if (!strcmp(params, "class-prev"))
direction = -1, filter = E_WINLIST_FILTER_CLASS_WINDOWS;
else if (!strcmp(params, "classes-next"))
direction = 1, filter = E_WINLIST_FILTER_CLASSES;
else if (!strcmp(params, "classes-prev"))
direction = -1, filter = E_WINLIST_FILTER_CLASSES;
else if (!strcmp(params, "up"))
udlr = 0;
else if (!strcmp(params, "down"))
udlr = 1;
else if (!strcmp(params, "left"))
udlr = 2;
else if (!strcmp(params, "right"))
udlr = 3;
else return;
}
else
direction = 1;
if (direction)
ok = !e_winlist_show(zone, filter);
if (!ok)
{
if (!type) return;
e_winlist_modifiers_set(modifiers, type);
return;
}
if (direction == 1)
e_winlist_next();
else if (direction == -1)
e_winlist_prev();
if (direction) return;
enhance winlist next window selection Summary: The original next window selection of winlist is weak. It searches the next window with the following conditions: 1. Next non-overlaped window in the direction of user's selection (up,down,right,left). 2. The next window has to be the closest window from the currently selected window (calculated from shortest distance from each window's border, in the direction of selection) 3. the second distant requirement is this: delta2_next = abs(ec_orig->x - ec_orig->w / 2 - ec->x + ec->w/2); * Which I believe is a mistake, should be: delta2_next = abs(ec_orig->x + ec_orig->w / 2 - ec->x + ec->w/2); These two conditions are weak, and they sometimes can result in unexpected selection to the user. The enclosed patch enhances the next window selection: 1) A next window selection can be the window that's overlapping with the in-focused window. 2) calculates the next window from the center of the currently focused window to the next window, and it also takes into account directionality (a window that's farther in the direction of selection has a better chance of being selected then a window that's closer in the direction of selection, but offset-ed in the lateral direction.) Test Plan: 1. Create 4 key binds for "next window to left, right, up, down". 2. Open up 4 different windows and position them in odd/random positions. 3. Try to navigate to each window (with the winlist shortcut keys) before this patch. 4. Try with this patch, and evaluate if the window selection is more **PREDICTABLE**. Reviewers: zmike Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D2661 I fixed the weridness and it behaves much more reliably now with "tall" or "wide" windows. also fixed some formatting etc. etc. - this now works better and now if u alt+tab AND then use arrow keys while holding alt... it'll navigate around geometrically rather nicely. so big fixes and good for pointing out the simpleness of the original code. :) - raster @feat
2015-12-21 21:15:17 -08:00
if (udlr == -1) return;
e_winlist_direction_select(zone, udlr);
2007-08-04 21:41:55 -07:00
}
static void
_e_mod_action_winlist_cb(E_Object *obj, const char *params)
2007-08-04 21:41:55 -07:00
{
_e_mod_action_winlist_cb_helper(obj, params, 0, 0);
}
static void
_e_mod_action_winlist_mouse_cb(E_Object *obj, const char *params, E_Binding_Event_Mouse_Button *ev)
{
_e_mod_action_winlist_cb_helper(obj, params, e_bindings_modifiers_to_ecore_convert(ev->modifiers), E_WINLIST_ACTIVATE_TYPE_MOUSE);
2007-08-04 21:41:55 -07:00
}
static void
_e_mod_action_winlist_key_cb(E_Object *obj, const char *params, Ecore_Event_Key *ev)
2007-08-04 21:41:55 -07:00
{
_e_mod_action_winlist_cb_helper(obj, params, ev->modifiers, E_WINLIST_ACTIVATE_TYPE_KEY);
2007-08-04 21:41:55 -07:00
}
2012-06-20 00:01:53 -07:00
static void
_e_mod_action_winlist_edge_cb(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED, E_Event_Zone_Edge *ev EINA_UNUSED)
{
e_util_dialog_show(_("Winlist Error"), _("Winlist cannot be activated from an edge binding"));
}
static void
_e_mod_action_winlist_signal_cb(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
{
e_util_dialog_show(_("Winlist Error"), _("Winlist cannot be activated from a signal binding"));
}
static void
_e_mod_action_winlist_acpi_cb(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED, E_Event_Acpi *ev EINA_UNUSED)
{
e_util_dialog_show(_("Winlist Error"), _("Winlist cannot be activated from an ACPI binding"));
}