diff --git a/configure.ac b/configure.ac index b53d55670..26b151606 100644 --- a/configure.ac +++ b/configure.ac @@ -423,6 +423,7 @@ AC_E_OPTIONAL_MODULE([mixer], true, [CHECK_MODULE_MIXER]) AC_E_OPTIONAL_MODULE([connman], false) AC_E_OPTIONAL_MODULE([illume], true) AC_E_OPTIONAL_MODULE([syscon], true) +AC_E_OPTIONAL_MODULE([everything], true) AC_OUTPUT([ Makefile @@ -555,6 +556,8 @@ src/modules/illume/keyboards/Makefile src/modules/illume/dicts/Makefile src/modules/syscon/Makefile src/modules/syscon/module.desktop +src/modules/everything/Makefile +src/modules/everything/module.desktop src/preload/Makefile data/Makefile data/images/Makefile diff --git a/data/themes/default.edc b/data/themes/default.edc index a56c49f86..fd24e77cb 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -25415,4 +25415,354 @@ MIMEBASE("application/x-font-bdf","icon_mime_font_generic.png", ".BDF", 128); } } } + + +///////////////////////////////////////////////////////////////////////////// + /*** MOD: EVERYTHING ***/ + + group { name: "e/widgets/everything/main"; + images { + image: "base_bg.png" COMP; + image: "inset_sunk.png" COMP; + image: "menu_sel_bg.png" COMP; + image: "menu_sel_fg.png" COMP; + } + parts { + part { name: "base"; + mouse_events: 0; + description { state: "default" 0.0; + image { + normal: "base_bg.png"; + border: 2 2 2 2; + } + + fill.smooth: 0; + color: 245 245 245 255; + } + } + part { name: "list_bg"; + type: RECT; + description { state: "default" 0.0; + rel1 { + to: "e.swallow.list"; + offset: -1 -1; + } + rel2 { + to: "e.swallow.list"; + offset: 0 0; + } + color: 255 255 255 255; + } + } + + part { name: "e.swallow.bar"; + type: SWALLOW; + /* clip_to: "list_clip"; */ + description { state: "default" 0.0; + min: 32 32; + max: 9999 32; + align: 0.5 0.0; + rel1 { + relative: 0.0 1.0; + offset: 8 10; + to_y: "bg"; + } + rel2.offset: -9 -13; + } + } + + part { name: "e.swallow.list"; + type: SWALLOW; + clip_to: "list_clip"; + description { state: "default" 0.0; + min: 32 64; + align: 0.5 1.0; + rel1 { + relative: 0.0 1.0; + offset: 12 10; + to_y: "e.swallow.bar"; + } + rel2.offset: -13 -13; + } + } + part { name: "list_clip"; + type: RECT; + description { state: "default" 0.0; + color: 255 255 255 255; + rel1.to_y: "e.swallow.list"; + rel2.to_y: "e.swallow.list"; + } + } + part { name: "list_over"; + mouse_events: 0; + description { state: "default" 0.0; + rel1 { + offset: -1 -1; + to: "list_bg"; + } + rel2 { + offset: 0 0; + to: "list_bg"; + } + image { + normal: "inset_sunk.png"; + border: 7 7 7 7; + middle: 0; + } + fill.smooth : 0; + } + } + part { name: "bg"; + mouse_events: 0; + description { state: "default" 0.0; + min: 0 42; + max: 99999 42; + + rel1 { + relative: 0.0 0.0; + offset: 4 6; + } + rel2 { + relative: 1.0 0.0; + offset: -6 48; + } + + image { + normal: "menu_sel_bg.png"; + border: 8 8 5 9; + } + } + } + part { name: "e.text.label"; + type: TEXT; + effect: SHADOW; + scale: 1; + description { state: "default" 0.0; + fixed: 0 1; + align: 0.0 0.5; + rel1 { + relative: 1.0 0.0; + offset: 4 6; + to_x: "e.swallow.icons"; + } + rel2 { + relative: 1.0 1.0; + offset: -48 -48; + /* to_x: */ + /* to_x: "e.swallow.icons"; */ + } + color: 255 255 255 255; + color3: 0 0 0 64; + text { + font: "Sans:style=Bold"; + size: 14; + align: 0.0 0.5; + min: 1 1; + text_class: "exebuf_command"; + } + } + } + part { name: "cursor"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + min: 1 18; + max: 1 18; + align: 0.0 0.5; + fixed: 1 1; + rel1 { + relative: 1.0 0.0; + offset: 1 0; + to: "e.text.label"; + } + rel2 { + relative: 1.0 1.0; + offset: 1 -1; + to: "e.text.label"; + } + color: 255 255 255 220; + } + description { state: "faded" 0.0; + inherit: "default" 0.0; + color: 255 255 255 0; + } + } + part { name: "e.swallow.icons"; + type: SWALLOW; + description { state: "default" 0.0; + min: 32 32; + max: 32 32; + align: 0.0 0.0; + rel1 { + offset: 6 4; + to: "bg"; + } + rel2 { + offset: -7 -5; + to: "bg"; + } + } + } + part { name: "fg"; + mouse_events: 0; + description { state: "default" 0.0; + rel1.to: "bg"; + rel2.to: "bg"; + image { + normal: "menu_sel_fg.png"; + border: 8 8 5 9; + } + } + } + } + programs { + program { name: "blink_off"; + signal: "show"; + source: ""; + action: STATE_SET "faded" 0.0; + transition: SINUSOIDAL 0.5; + target: "cursor"; + after: "blink_on"; + } + program { name: "blink_on"; + action: STATE_SET "default" 0.0; + transition: SINUSOIDAL 0.25; + target: "cursor"; + after: "blink_off"; + } + } + } + + group { name: "e/widgets/everything/item"; + parts { + part { name: "bg"; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + color: 255 255 255 0; + rel1.offset: -5 -3; + rel2.offset: 4 5; + image { + normal: "menu_sel_bg.png"; + border: 8 8 5 9; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 255 255 255 255; + rel1.offset: -2 0; + rel2.offset: 1 2; + } + } + part { name: "e.text.title"; + type: TEXT; + effect: SOFT_SHADOW; + mouse_events: 0; + scale: 1; + description { + state: "default" 0.0; + rel1 { + offset: 2 1; + relative: 1.0 0.0; + to_x: "e.swallow.icons"; + } + rel2.offset: -3 -2; + color: 0 0 0 255; + color3: 0 0 0 0; + color_class: "menu_item"; + text { + font: "Sans"; + size: 10; + min: 0 1; + align: 0.0 0.5; + text_class: "menu_item"; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + color: 255 255 255 255; + color3: 0 0 0 64; + color_class: "menu_item"; + } + } + part { + name: "e.swallow.icons"; + type: SWALLOW; + description { + state: "default" 0.0; + max: 18 18; + aspect: 1.0 1.0; + align: 0.0 0.5; + aspect_preference: VERTICAL; + rel1 { + relative: 0.0 0.0; + offset: 3 1; + } + rel2 { + relative: 0.0 1.0; + offset: -3 -2; + } + } + } + part { name: "fg"; + mouse_events: 0; + description { state: "default" 0.0; + visible: 0; + color: 255 255 255 0; + rel1.to: "bg"; + rel2.to: "bg"; + image { + normal: "menu_sel_fg.png"; + border: 8 8 5 9; + } + } + description { state: "selected" 0.0; + inherit: "default" 0.0; + visible: 1; + color: 255 255 255 255; + } + } + part { + name: "e.event.exebuf.item"; + type: RECT; + mouse_events: 1; + description { + state: "default" 0.0; + min: 14 14; + visible: 1; + color: 0 0 0 0; + rel1 { + relative: 1.0 0.0; + offset: 1 -1; + to_x: "e.swallow.icons"; + } + rel2 { + relative: 1.0 1.0; + offset: -1 -1; + } + } + } + } + programs { + program { name: "sel"; + signal: "e,state,selected"; + source: "e"; + action: STATE_SET "selected" 0.0; + transition: LINEAR 0.2; + target: "bg"; + target: "fg"; + target: "e.text.title"; + } + program { name: "unsel"; + signal: "e,state,unselected"; + source: "e"; + action: STATE_SET "default" 0.0; + transition: LINEAR 0.1; + target: "bg"; + target: "fg"; + target: "e.text.title"; + } + } + } } diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index dcb345a65..f97f4dd39 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -246,6 +246,9 @@ if USE_MODULE_SYSCON SUBDIRS += syscon endif +# if USE_MODULE_SYSCON +SUBDIRS += everything +# endif @@ -310,5 +313,5 @@ gadman \ mixer \ connman \ illume \ -syscon - +syscon \ +everything diff --git a/src/modules/everything/Makefile.am b/src/modules/everything/Makefile.am new file mode 100644 index 000000000..c332e6722 --- /dev/null +++ b/src/modules/everything/Makefile.am @@ -0,0 +1,37 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = everything + +# data files for the module +filesdir = $(libdir)/enlightenment/modules/$(MODULE) +files_DATA = \ +e-module-$(MODULE).edj module.desktop + +EXTRA_DIST = $(files_DATA) + +# the module .so file +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_srcdir)/src/modules/$(MODULE) \ + -I$(top_srcdir)/src/bin \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/modules \ + @e_cflags@ +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la +module_la_SOURCES = e_mod_main.c \ + e_mod_main.h \ + evry.c \ + evry.h \ + evry_plug_apps.c \ + evry_plug_apps.h \ + evry_plug_border.c \ + evry_plug_border.h \ + evry_plug_config.c \ + evry_plug_config.h + +module_la_LIBADD = @e_libs@ @dlopen_libs@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +uninstall: + rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/modules/everything/e-module-everything.edj b/src/modules/everything/e-module-everything.edj new file mode 100644 index 000000000..98c5eef7f Binary files /dev/null and b/src/modules/everything/e-module-everything.edj differ diff --git a/src/modules/everything/e_mod_main.c b/src/modules/everything/e_mod_main.c new file mode 100644 index 000000000..9fd65fc8b --- /dev/null +++ b/src/modules/everything/e_mod_main.c @@ -0,0 +1,127 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" +#include "e_mod_main.h" + +/* actual module specifics */ +static void _e_mod_action_exebuf_cb(E_Object *obj, const char *params); +static int _e_mod_run_defer_cb(void *data); +static void _e_mod_run_cb(void *data, E_Menu *m, E_Menu_Item *mi); +static void _e_mod_menu_add(void *data, E_Menu *m); + +static E_Module *conf_module = NULL; +static E_Action *act = NULL; +static E_Int_Menu_Augmentation *maug = NULL; + +/* module setup */ +EAPI E_Module_Api e_modapi = + { + E_MODULE_API_VERSION, + "Everything" + }; + +EAPI void * +e_modapi_init(E_Module *m) +{ + conf_module = m; + evry_init(); + + evry_plug_border_init(); + evry_plug_apps_init(); + evry_plug_config_init(); + + /* add module supplied action */ + act = e_action_add("everything"); + if (act) + { + act->func.go = _e_mod_action_exebuf_cb; + e_action_predef_name_set(_("Launch"), _("Run Everything Dialog"), "everything", + NULL, NULL, 0); + } + /* maug = e_int_menus_menu_augmentation_add("main/1", _e_mod_menu_add, NULL, NULL, NULL); */ + e_module_delayed_set(m, 1); + return m; +} + +EAPI int +e_modapi_shutdown(E_Module *m) +{ + /* remove module-supplied menu additions */ + /* if (maug) + * { + * e_int_menus_menu_augmentation_del("main/1", maug); + * maug = NULL; + * } */ + /* remove module-supplied action */ + if (act) + { + e_action_predef_name_del(_("Launch"), _("Run Everything Dialog")); + e_action_del("everything"); + act = NULL; + } + + evry_plug_border_shutdown(); + evry_plug_apps_shutdown(); + evry_plug_config_shutdown(); + + evry_shutdown(); + conf_module = NULL; + return 1; +} + +EAPI int +e_modapi_save(E_Module *m) +{ + return 1; +} + +/* action callback */ +static void +_e_mod_action_exebuf_cb(E_Object *obj, const char *params) +{ + E_Zone *zone = NULL; + + if (obj) + { + if (obj->type == E_MANAGER_TYPE) + zone = e_util_zone_current_get((E_Manager *)obj); + else if (obj->type == E_CONTAINER_TYPE) + zone = e_util_zone_current_get(((E_Container *)obj)->manager); + else if (obj->type == E_ZONE_TYPE) + zone = e_util_zone_current_get(((E_Zone *)obj)->container->manager); + else + zone = e_util_zone_current_get(e_manager_current_get()); + } + if (!zone) zone = e_util_zone_current_get(e_manager_current_get()); + if (zone) evry_show(zone); +} + +/* menu item callback(s) */ +static int +_e_mod_run_defer_cb(void *data) +{ + E_Zone *zone; + + zone = data; + if (zone) evry_show(zone); + return 0; +} + +static void +_e_mod_run_cb(void *data, E_Menu *m, E_Menu_Item *mi) +{ + ecore_idle_enterer_add(_e_mod_run_defer_cb, m->zone); +} + +/* menu item add hook */ +/* static void + * _e_mod_menu_add(void *data, E_Menu *m) + * { + * E_Menu_Item *mi; + * + * mi = e_menu_item_new(m); + * e_menu_item_label_set(mi, _("Run Command")); + * e_util_menu_item_theme_icon_set(mi, "system-run"); + * e_menu_item_callback_set(mi, _e_mod_run_cb, NULL); + * } */ diff --git a/src/modules/everything/e_mod_main.h b/src/modules/everything/e_mod_main.h new file mode 100644 index 000000000..b30395d87 --- /dev/null +++ b/src/modules/everything/e_mod_main.h @@ -0,0 +1,28 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifndef E_MOD_MAIN_H +#define E_MOD_MAIN_H + +#define E_TYPEDEFS 1 +#include "evry.h" + +#undef E_TYPEDEFS +#include "evry.h" + +EAPI extern E_Module_Api e_modapi; + +EAPI void *e_modapi_init (E_Module *m); +EAPI int e_modapi_shutdown (E_Module *m); +EAPI int e_modapi_save (E_Module *m); + +EAPI int evry_plug_apps_init(void); +EAPI int evry_plug_apps_shutdown(void); + +EAPI int evry_plug_border_init(void); +EAPI int evry_plug_border_shutdown(void); + +EAPI int evry_plug_config_init(void); +EAPI int evry_plug_config_shutdown(void); + +#endif diff --git a/src/modules/everything/evry.c b/src/modules/everything/evry.c new file mode 100644 index 000000000..eab41b7f7 --- /dev/null +++ b/src/modules/everything/evry.c @@ -0,0 +1,879 @@ +#include "e.h" +#include "e_mod_main.h" +#include "evry.h" + +#define WIDTH 400 +#define HEIGHT 350 +#define INPUTLEN 40 +#define MATCH_LAG 0.33 + +static int _evry_cb_key_down(void *data, int type, void *event); +static int _evry_cb_key_down(void *data, int type, void *event); +static int _evry_cb_mouse_down(void *data, int type, void *event); +static int _evry_cb_mouse_up(void *data, int type, void *event); +static int _evry_cb_mouse_move(void *data, int type, void *event); +static int _evry_cb_mouse_wheel(void *data, int type, void *event); +static void _evry_cb_item_mouse_in(void *data, Evas *evas, Evas_Object *obj, void *event_info); +static void _evry_cb_item_mouse_out(void *data, Evas *evas, Evas_Object *obj, void *event_info); +static void _evry_backspace(void); +static void _evry_update(void); +static void _evry_matches_clear(void); +static void _evry_list_clear(void); +static void _evry_show_candidates(Evry_Plugin *plugin); +static int _evry_update_timer(void *data); +static void _evry_matches_update(void); +static void _evry_clear(void); +static void _evry_item_next(void); +static void _evry_item_prev(void); +static void _evry_plugin_next(void); +static void _evry_plugin_prev(void); +static void _evry_scroll_to(int i); +static void _evry_item_desel(Evry_Item *it); +static void _evry_item_sel(Evry_Item *it); +static void _evry_item_remove(Evry_Item *it); +static void _evry_action(int finished); +static void _evry_cb_plugin_sel(void *data1, void *data2); + +/* local subsystem globals */ +static E_Popup *popup = NULL; +static Evas_Object *o_list = NULL; +static Evas_Object *o_main = NULL; +static Evas_Object *icon_object = NULL; +static Evas_Object *o_toolbar = NULL; +static char *cmd_buf = NULL; +static Eina_List *handlers = NULL; +static Ecore_X_Window input_window = 0; +static Eina_List *plugins = NULL; +static Ecore_Timer *update_timer = NULL; +/* static Ecore_Animator *animator = NULL; */ +static Evry_Item *item_selected = NULL; +static Evry_Item *item_mouseover = NULL; +static double scroll_align_to; +static double scroll_align; +static int plugin_count; +static Evry_Plugin *plugin_selected; +static int toolbar_nr; + +static int ev_last_is_mouse; + +/* externally accessible functions */ +EAPI int +evry_init(void) +{ + return 1; +} + +EAPI int +evry_shutdown(void) +{ + evry_hide(); + return 1; +} + +EAPI void +evry_plugin_add(Evry_Plugin *plugin) +{ + plugins = eina_list_append(plugins, plugin); + /* TODO sorting, initialization, etc */ +} + +EAPI void +evry_plugin_remove(Evry_Plugin *plugin) +{ + plugins = eina_list_remove(plugins, plugin); + /* cleanup */ +} + +EAPI int +evry_show(E_Zone *zone) +{ + Evas_Object *o; + int x, y, w, h; + + E_OBJECT_CHECK_RETURN(zone, 0); + E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, 0); + + if (popup) return 0; + + input_window = ecore_x_window_input_new(zone->container->win, zone->x, + zone->y, zone->w, zone->h); + ecore_x_window_show(input_window); + if (!e_grabinput_get(input_window, 1, input_window)) + { + ecore_x_window_free(input_window); + input_window = 0; + return 0; + } + + w = WIDTH; + h = HEIGHT; + x = zone->x + (zone->w / 2) - (w / 2); + y = zone->y + (zone->h / 2) - (h / 2); + + popup = e_popup_new(zone, x, y, w, h); + if (!popup) return 0; + + cmd_buf = malloc(INPUTLEN); + if (!cmd_buf) + { + e_object_del(E_OBJECT(popup)); + return 0; + } + + ecore_x_netwm_window_type_set(popup->evas_win, ECORE_X_WINDOW_TYPE_UTILITY); + + cmd_buf[0] = 0; + + e_popup_layer_set(popup, 255); + evas_event_freeze(popup->evas); + evas_event_feed_mouse_in(popup->evas, ecore_x_current_time_get(), NULL); + evas_event_feed_mouse_move(popup->evas, -1000000, -1000000, ecore_x_current_time_get(), NULL); + o = edje_object_add(popup->evas); + o_main = o; + e_theme_edje_object_set(o, "base/theme/everything", + "e/widgets/everything/main"); + edje_object_part_text_set(o, "e.text.label", cmd_buf); + + o = e_box_add(popup->evas); + o_list = o; + e_box_orientation_set(o, 0); + e_box_homogenous_set(o, 1); + edje_object_part_swallow(o_main, "e.swallow.list", o); + evas_object_show(o); + + o = o_main; + evas_object_move(o, 0, 0); + evas_object_resize(o, w, h); + evas_object_show(o); + e_popup_edje_bg_object_set(popup, o); + + o = e_widget_toolbar_add(popup->evas, 48 * e_scale, 48 * e_scale); + e_widget_toolbar_scrollable_set(o, 0); + edje_object_part_swallow(o_main, "e.swallow.bar", o); + evas_object_show(o); + o_toolbar = o; + + evas_event_thaw(popup->evas); + + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_KEY_DOWN, _evry_cb_key_down, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_MOUSE_BUTTON_DOWN, _evry_cb_mouse_down, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_MOUSE_BUTTON_UP, _evry_cb_mouse_up, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_MOUSE_MOVE, _evry_cb_mouse_move, NULL)); + handlers = eina_list_append + (handlers, ecore_event_handler_add + (ECORE_EVENT_MOUSE_WHEEL, _evry_cb_mouse_wheel, NULL)); + + _evry_matches_update(); + + ev_last_is_mouse = 0; + item_mouseover = NULL; + item_selected = NULL; + + e_popup_show(popup); + return 1; +} + +EAPI void +evry_hide(void) +{ + Ecore_Event *ev; + char *str; + Evry_Plugin *plugin; + Eina_List *l; + + if (!popup) return; + + evas_event_freeze(popup->evas); + _evry_matches_clear(); + e_popup_hide(popup); + + e_box_freeze(o_list); + EINA_LIST_FOREACH(plugins, l, plugin) + { + plugin->cleanup(); + } + e_box_thaw(o_list); + + evas_object_del(o_list); + o_list = NULL; + + evas_object_del(o_toolbar); + o_toolbar = NULL; + + evas_object_del(o_main); + o_main = NULL; + + evas_event_thaw(popup->evas); + e_object_del(E_OBJECT(popup)); + popup = NULL; + + EINA_LIST_FREE(handlers, ev) + ecore_event_handler_del(ev); + + ecore_x_window_free(input_window); + e_grabinput_release(input_window, input_window); + input_window = 0; + free(cmd_buf); + cmd_buf = NULL; + + plugin_selected = NULL; + item_selected = NULL; + item_mouseover = NULL; +} + +/* local subsystem functions */ +static int +_evry_cb_key_down(void *data, int type, void *event) +{ + Ecore_Event_Key *ev; + + ev_last_is_mouse = 0; + + ev = event; + if (ev->event_window != input_window) return 1; + + if (!strcmp(ev->key, "Up")) + _evry_item_prev(); + else if (!strcmp(ev->key, "Down")) + _evry_item_next(); + else if (!strcmp(ev->key, "Right")) + _evry_plugin_next(); + else if (!strcmp(ev->key, "Left")) + _evry_plugin_prev(); + else if (!strcmp(ev->key, "Return")) + _evry_action(1); + else if (!strcmp(ev->key, "Return") && + (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) + _evry_action(0); + /* else if (!strcmp(ev->key, "Tab")) + * _evry_complete(); + * else if (!strcmp(ev->key, "Return")) + * _evry_exec(); + */ + else if (!strcmp(ev->key, "u") && + (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL)) + _evry_clear(); + else if (!strcmp(ev->key, "Escape")) + evry_hide(); + else if (!strcmp(ev->key, "BackSpace")) + _evry_backspace(); + else if (!strcmp(ev->key, "Delete")) + _evry_backspace(); + else + { + if (ev->compose) + { + if ((strlen(cmd_buf) < (INPUTLEN - strlen(ev->compose)))) + { + strcat(cmd_buf, ev->compose); + _evry_update(); + if (!update_timer) + update_timer = + ecore_timer_add(MATCH_LAG, _evry_update_timer, NULL); + } + } + } + return 1; +} + +static int +_evry_cb_mouse_down(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Button *ev; + + ev = event; + if (ev->event_window != input_window) return 1; + + if (item_mouseover) + { + if (item_selected != item_mouseover) + { + if (item_selected) _evry_item_desel(item_selected); + item_selected = item_mouseover; + _evry_item_sel(item_selected); + } + } + else + { + evas_event_feed_mouse_up(popup->evas, ev->buttons, 0, ev->timestamp, NULL); + } + + return 1; +} + +static int +_evry_cb_mouse_up(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Button *ev; + + ev = event; + if (ev->event_window != input_window) return 1; + + if (item_mouseover) + { + if (ev->buttons == 1) + _evry_action(1); + else if (ev->buttons == 3) + _evry_action(0); + } + else + { + evas_event_feed_mouse_up(popup->evas, ev->buttons, 0, ev->timestamp, NULL); + } + + return 1; +} + +static int +_evry_cb_mouse_move(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Move *ev; + + ev = event; + if (ev->event_window != input_window) return 1; + + if (!ev_last_is_mouse) + { + ev_last_is_mouse = 1; + if (item_mouseover) + { + if (item_selected && (item_selected != item_mouseover)) + _evry_item_desel(item_selected); + if (!item_selected || (item_selected != item_mouseover)) + { + item_selected = item_mouseover; + _evry_item_sel(item_selected); + } + } + } + + evas_event_feed_mouse_move(popup->evas, ev->x - popup->x, + ev->y - popup->y, ev->timestamp, NULL); + + return 1; +} + +static int +_evry_cb_mouse_wheel(void *data, int type, void *event) +{ + Ecore_Event_Mouse_Wheel *ev; + + ev = event; + if (ev->event_window != input_window) return 1; + + ev_last_is_mouse = 0; + + if (ev->z < 0) /* up */ + { + int i; + + for (i = ev->z; i < 0; i++) _evry_item_prev(); + } + else if (ev->z > 0) /* down */ + { + int i; + + for (i = ev->z; i > 0; i--) _evry_item_next(); + } + return 1; +} + +static void +_evry_cb_item_mouse_in(void *data, Evas *evas, Evas_Object *obj, + void *event_info) +{ + item_mouseover = data; + if (!ev_last_is_mouse) return; + + if (item_selected) _evry_item_desel(item_selected); + if (!(item_selected = data)) return; + _evry_item_sel(item_selected); +} + +static void +_evry_cb_item_mouse_out(void *data, Evas *evas, Evas_Object *obj, + void *event_info) +{ + item_mouseover = NULL; +} + + +static void +_evry_cb_plugin_sel(void *data1, void *data2) +{ + Evry_Plugin *plugin; + Eina_List *l; + int i = 0; + + if (plugin_selected == data1) return; + + _evry_list_clear(); + plugin_selected = data1; + + for (l = plugins; l; l = l->next) + { + plugin = l->data; + + if (!plugin->candidates) continue; + + if (plugin == plugin_selected) + { + _evry_show_candidates(plugin); + toolbar_nr = i; + e_widget_toolbar_item_select(o_toolbar, toolbar_nr); + } + else i++; + } +} + +static void +_evry_backspace(void) +{ + int len, val, pos; + + len = strlen(cmd_buf); + if (len > 0) + { + pos = evas_string_char_prev_get(cmd_buf, len, &val); + if ((pos < len) && (pos >= 0)) + { + cmd_buf[pos] = 0; + _evry_update(); + if (!update_timer) + update_timer = ecore_timer_add(MATCH_LAG, _evry_update_timer, NULL); + } + } +} + +static void +_evry_update(void) +{ + Efreet_Desktop *desktop; + Evas_Object *o; + + edje_object_part_text_set(o_main, "e.text.label", cmd_buf); + if (icon_object) evas_object_del(icon_object); + icon_object = NULL; + + if (!cmd_buf[0]) return; +} + +static void +_evry_action(int finished) +{ + if (plugin_selected && item_selected) + { + plugin_selected->action(item_selected); + } + else + e_exec(popup->zone, NULL, cmd_buf, NULL, "everything"); + + if (finished) + evry_hide(); +} + +static void +_evry_clear(void) +{ + if (cmd_buf[0] != 0) + { + cmd_buf[0] = 0; + _evry_update(); + if (!update_timer) + update_timer = ecore_timer_add(MATCH_LAG, _evry_update_timer, NULL); + } +} + +static void +_evry_show_candidates(Evry_Plugin *plugin) +{ + Evry_Item *it; + Eina_List *l; + int mw, mh, h; + Evas_Object *o; + + e_box_freeze(o_list); + + EINA_LIST_FOREACH(plugin->candidates, l, it) + { + o = edje_object_add(popup->evas); + it->o_bg = o; + e_theme_edje_object_set(o, "base/theme/everything", + "e/widgets/everything/item"); + + edje_object_part_text_set(o, "e.text.title", it->label); + + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, + _evry_cb_item_mouse_in, it); + evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_OUT, + _evry_cb_item_mouse_out, it); + evas_object_show(o); + + /* XXX eek*/ + plugin->icon_get(it, popup->evas); + if (edje_object_part_exists(o, "e.swallow.icons") && it->o_icon) + { + edje_object_part_swallow(o, "e.swallow.icons", it->o_icon); + evas_object_show(it->o_icon); + } + edje_object_size_min_calc(o, &mw, &mh); + e_box_pack_end(o_list, o); + e_box_pack_options_set(o, + 1, 1, /* fill */ + 1, 0, /* expand */ + 0.5, 0.5, /* align */ + mw, mh, /* min */ + 9999, mh /* max */ + ); + } + e_box_thaw(o_list); + + e_box_min_size_get(o_list, NULL, &mh); + evas_object_geometry_get(o_list, NULL, NULL, NULL, &h); + if (mh <= h) + e_box_align_set(o_list, 0.5, 0.0); + else + e_box_align_set(o_list, 0.5, 1.0); + + evas_event_thaw(popup->evas); +} + +static void +_evry_matches_update() +{ + Evry_Plugin *plugin, *first = NULL; + Eina_List *l; + char buf[64]; + int candidates; + + _evry_matches_clear(); + plugin_count = 0; + toolbar_nr = 0; + + EINA_LIST_FOREACH(plugins, l, plugin) + { + if (strlen(cmd_buf) == 0) + { + candidates = !plugin->need_query ? plugin->fetch(NULL) : 0; + } + else + { + candidates = plugin->fetch(cmd_buf); + } + if (candidates) + { + snprintf(buf, 64, "%s (%d)", plugin->name, + eina_list_count(plugin->candidates)); + + e_widget_toolbar_item_append(o_toolbar, + NULL, buf, + _evry_cb_plugin_sel, + plugin, NULL); + if (!first) + first = plugin; + + /* if (!plugin_selected) + * { + * plugin_selected = plugin; + * } + * else */ + if (plugin == plugin_selected) + toolbar_nr = plugin_count; + + plugin_count++; + } + } + + if ((toolbar_nr == 0) && (plugin_count > 0)) + { + plugin_selected = first; + } + + if (plugin_selected) + { + _evry_show_candidates(plugin_selected); + e_widget_toolbar_item_select(o_toolbar, toolbar_nr); + } +} + +static void +_evry_item_remove(Evry_Item *it) +{ + /* if (ev_last_mouse == it) + * ev_last_mouse = NULL; */ + + evas_object_del(it->o_bg); + if (it->o_icon) evas_object_del(it->o_icon); + it->o_icon = NULL; +} + +static void +_evry_matches_clear(void) +{ + Evry_Plugin *plugin; + Eina_List *l; + + // FIXME add toolbar item remove method or use sth different + evas_object_del(o_toolbar); + Evas_Object *o = e_widget_toolbar_add(popup->evas, + 48 * e_scale, + 48 * e_scale); + e_widget_toolbar_scrollable_set(o, 0); + edje_object_part_swallow(o_main, "e.swallow.bar", o); + evas_object_show(o); + o_toolbar = o; + + _evry_list_clear(); + + EINA_LIST_FOREACH(plugins, l, plugin) + plugin->cleanup(); +} + +static void +_evry_list_clear(void) +{ + Evry_Item *it; + Eina_List *l; + + if (plugin_selected) + { + evas_event_freeze(popup->evas); + e_box_freeze(o_list); + EINA_LIST_FOREACH(plugin_selected->candidates, l, it) + _evry_item_remove(it); + e_box_thaw(o_list); + evas_event_thaw(popup->evas); + } + + item_selected = NULL; +} + +static void +_evry_scroll_to(int i) +{ + int n, h, mh; + + n = eina_list_count(plugin_selected->candidates); + + e_box_min_size_get(o_list, NULL, &mh); + evas_object_geometry_get(o_list, NULL, NULL, NULL, &h); + + if (mh <= h) return; + + if (n > 1) + { + scroll_align_to = (double)i / (double)(n - 1); + /* if (e_config->everything_scroll_animate) + * { + * eap_scroll_to = 1; + * if (!eap_scroll_timer) + * eap_scroll_timer = ecore_timer_add(0.01, _evry_eap_scroll_timer, NULL); + * if (!animator) + * animator = ecore_animator_add(_evry_animator, NULL); + * } + * else */ + { + scroll_align = scroll_align_to; + e_box_align_set(o_list, 0.5, 1.0 - scroll_align); + } + } + else + e_box_align_set(o_list, 0.5, 1.0); +} + +static void +_evry_item_desel(Evry_Item *it) +{ + edje_object_signal_emit(it->o_bg, "e,state,unselected", "e"); + if (it->o_icon) + edje_object_signal_emit(it->o_icon, "e,state,unselected", "e"); +} + +static void +_evry_item_sel(Evry_Item *it) +{ + edje_object_signal_emit(it->o_bg, "e,state,selected", "e"); + if (it->o_icon) + edje_object_signal_emit(it->o_icon, "e,state,selected", "e"); +} + +static int +_evry_update_timer(void *data) +{ + _evry_matches_update(); + update_timer = NULL; + return 0; +} + +static void +_evry_item_next(void) +{ + Eina_List *l; + int i; + + if (item_selected) + { + for (i = 0, l = plugin_selected->candidates; l; l = l->next, i++) + { + if (l->data == item_selected) + { + if (l->next) + { + _evry_item_desel(item_selected); + item_selected = l->next->data; + _evry_item_sel(item_selected); + _evry_scroll_to(i + 1); + } + break; + } + } + } + else if (plugin_selected->candidates) + { + item_selected = plugin_selected->candidates->data; + _evry_item_sel(item_selected); + _evry_scroll_to(0); + } + + /* if (item_selected) + * edje_object_part_text_set(o_main, "e.text.label", item_selected->label); */ +} + +static void +_evry_item_prev(void) +{ + Eina_List *l; + int i; + + if (item_selected) + { + _evry_item_desel(item_selected); + + for (i = 0, l = plugin_selected->candidates; l; l = l->next, i++) + { + if (l->data == item_selected) + { + if (l->prev) + { + item_selected = l->prev->data; + _evry_item_sel(item_selected); + _evry_scroll_to(i - 1); + } + else + item_selected = NULL; + break; + } + } + } + /* if (item_selected) + * edje_object_part_text_set(o_main, "e.text.label", item_selected->label); + * else + * edje_object_part_text_set(o_main, "e.text.label", cmd_buf); */ +} + +static void +_evry_plugin_next(void) +{ + Eina_List *l; + Evry_Plugin *plugin; + Evry_Item *it; + int changed = 0; + int i; + + if (!plugin_selected) return; + + l = eina_list_data_find_list(plugins, plugin_selected); + + if (l && l->next) + { + for (l = l->next; l; l = l->next) + { + plugin = l->data; + if (plugin->candidates) + { + toolbar_nr++; + changed = 1; + break; + } + } + } + if (!changed) + { + for (l = plugins; l; l = l->next) + { + plugin = l->data; + if ((plugin != plugin_selected) && plugin->candidates) + { + changed = 1; + toolbar_nr = 0; + break; + } + } + } + if (changed) + { + _evry_list_clear(); + + plugin_selected = plugin; + _evry_show_candidates(plugin); + e_widget_toolbar_item_select(o_toolbar, toolbar_nr); + } +} + + +static void +_evry_plugin_prev(void) +{ + Eina_List *l; + Evry_Plugin *plugin; + Evry_Item *it; + int changed = 0; + int i; + + if (!plugin_selected) return; + + l = eina_list_data_find_list(plugins, plugin_selected); + + if (l && l->prev) + { + for (l = l->prev; l; l = l->prev) + { + plugin = l->data; + if (plugin->candidates) + { + toolbar_nr--; + changed = 1; + break; + } + } + } + if (!changed) + { + for (l = eina_list_last(plugins); l; l = l->prev) + { + plugin = l->data; + if ((plugin != plugin_selected) && plugin->candidates) + { + changed = 1; + toolbar_nr = plugin_count - 1; + break; + } + } + } + if (changed) + { + _evry_list_clear(); + + plugin_selected = plugin; + _evry_show_candidates(plugin); + e_widget_toolbar_item_select(o_toolbar, toolbar_nr); + } +} diff --git a/src/modules/everything/evry.h b/src/modules/everything/evry.h new file mode 100644 index 000000000..fe0a9574c --- /dev/null +++ b/src/modules/everything/evry.h @@ -0,0 +1,121 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifdef E_TYPEDEFS + +typedef struct _Evry_Plugin Evry_Plugin; +typedef struct _Evry_Item Evry_Item; +typedef struct _Evry_Action Evry_Action; +typedef struct _Evry_Config Evry_Config; +typedef struct _Evry_App Evry_App; + +/* typedef enum _Evry_Plugin_Type + * { + * EVRY_SYNC, + * EVRY_ASYNC, + * } Evry_Plugin_Type; */ + +/* typedef enum _Evry_Plugin_State + * { + * EVRY_STATE_NO_CANDIDATES, + * EVRY_STATE_PENDING, + * EVRY_STATE_FINISHED, + * } Evry_Plugin_State; */ + +#else +#ifndef EVRY_H +#define EVRY_H + +struct _Evry_Item +{ + const char *label; + Evas_Object *o_icon; + unsigned int type; /* TODO */ + + /* used by 'everything' for display */ + Evas_Object *o_bg; + + /* these are only for internally use by plugins */ + /* used e.g. as pointer for item data (Efreet_Desktop) or */ + /* for internal stuff, like priority hints for sorting, etc */ + void *data; + int priority; +}; + +struct _Evry_Plugin +{ + const char *name; + const char *type; + Evas_Object *o_icon; + + /* sync/async ?*/ + unsigned int async_query; + + /* whether candidates can be shown without input: e.g. borders, history */ + /* if 0 fetch MUST provide all candidates when string is NULL */ + // TODO better use 'need_query_length' ? + unsigned int need_query; + + /* run when 'everything' is shown */ + void (*begin) (void); + + /* get candidates matching string, fills 'candidates' list */ + int (*fetch) (char *string); + + /* run action with a given candidate - TODO register actions per + candidate type */ + int (*action) (Evry_Item *item); + + /* run before new query and when hiding 'everything' */ + void (*cleanup) (void); + + void (*icon_get) (Evry_Item *it, Evas *e); + /* provide more information for a candidate */ + /* int (*candidate_info) (Evas *evas, Evry_Item *item); */ + + Evas_Object *(*config_page) (void); + void (*config_apply) (void); + + /* Evry_Plugin_State state; */ + Eina_List *candidates; +}; + +struct _Evry_Action +{ + const char *name; + const char *type; + int (*func) (Evry_Item *item); +}; + + +struct _Evry_Config +{ + Eina_List *plugin_order; + +}; + + +struct _Evry_App +{ + const char *file; + Efreet_Desktop *desktop; +}; + + +EAPI int evry_init(void); +EAPI int evry_shutdown(void); + +EAPI int evry_show(E_Zone *zone); +EAPI void evry_hide(void); + +EAPI void evry_plugin_add(Evry_Plugin *plugin); +EAPI void evry_plugin_remove(Evry_Plugin *plugin); +EAPI void evry_action_add(Evry_Action *action); +EAPI void evry_action_remove(Evry_Action *action); + +/* EAPI void evry_plugin_async_update(Evry_Plugin *plugin, int state); */ + +EAPI Evas* evry_evas_get(void); +#endif +#endif + diff --git a/src/modules/everything/evry_app.c b/src/modules/everything/evry_app.c new file mode 100644 index 000000000..6c2d1d7fc --- /dev/null +++ b/src/modules/everything/evry_app.c @@ -0,0 +1,211 @@ +#include "e.h" +#include "e_mod_main.h" + +static Eina_Hash *added = NULL; +static Evry_Plugin plugin; + +static int _evry_app_fetch(char *string); +static int _evry_app_action(Evry_Item *item); +static void _evry_app_cleanup(void); +static void _evry_app_item_add(Efreet_Desktop *desktop, char *file, int prio); +static int _evry_app_cb_sort(const void *data1, const void *data2); +static void _evry_app_item_icon_get(Evry_Item *it, Evas *e); + + +EAPI int +evry_app_init(void) +{ + plugin.name = "Applications"; + plugin.type = "APPLICATION"; + plugin.need_query = 0; + plugin.fetch = &_evry_app_fetch; + plugin.action = &_evry_app_action; + plugin.cleanup = &_evry_app_cleanup; + plugin.icon_get = &_evry_app_item_icon_get; + plugin.candidates = NULL; + + evry_plugin_add(&plugin); + + return 1; +} + +EAPI int +evry_app_shutdown(void) +{ + evry_plugin_remove(&plugin); + + return 1; +} + +static int +_evry_app_action(Evry_Item *item) +{ + E_Zone *zone; + Evry_App *app; + + app = item->data; + zone = e_util_zone_current_get(e_manager_current_get()); + + if (app->desktop) + e_exec(zone, app->desktop, NULL, NULL, "everything"); + else + e_exec(zone, NULL, app->file, NULL, "everything"); + + return 1; +} + +static void +_evry_app_cleanup(void) +{ + Evry_Item *it; + Evry_App *app; + + EINA_LIST_FREE(plugin.candidates, it) + { + if (it->label) eina_stringshare_del(it->label); + if (it->o_icon) evas_object_del(it->o_icon); + app = it->data; + free(app); + free(it); + } +} + +static int +_evry_app_fetch(char *string) +{ + char buf[4096]; + Eina_List *list; + Efreet_Desktop *desktop; + char *file; + + _evry_app_cleanup(); + + if (string) + { + snprintf(buf, sizeof(buf), "%s*", string); + list = efreet_util_desktop_exec_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_app_item_add(desktop, NULL, 1); + + snprintf(buf, sizeof(buf), "*%s*", string); + list = efreet_util_desktop_name_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_app_item_add(desktop, NULL, 2); + + // TODO make these optional/configurable + snprintf(buf, sizeof(buf), "*%s*", string); + list = efreet_util_desktop_generic_name_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_app_item_add(desktop, NULL, 3); + + snprintf(buf, sizeof(buf), "*%s*", string); + list = efreet_util_desktop_comment_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_app_item_add(desktop, NULL, 3); + } + else + { + // TODO option for popular/recent + list = e_exehist_list_get(); + EINA_LIST_FREE(list, file) + _evry_app_item_add(NULL, file, 1); + } + + if (added) + { + eina_hash_free(added); + added = NULL; + + if (string) + plugin.candidates = + eina_list_sort(plugin.candidates, + eina_list_count(plugin.candidates), + _evry_app_cb_sort); + return 1; + } + + return 0; +} + +static void +_evry_app_item_add(Efreet_Desktop *desktop, char *file, int prio) +{ + Evry_Item *it; + Evry_App *app; + + if (desktop) + file = ecore_file_app_exe_get(desktop->exec); + + if (!file) return; + + if (eina_hash_find(added, file)) + { + if (desktop) free(file); + return; + } + + if (!added) + added = eina_hash_string_superfast_new(NULL); + + eina_hash_add(added, file, file); + + if (desktop) + { + free(file); + file = NULL; + } + else + { + desktop = efreet_util_desktop_exec_find(file); + if (desktop) file = NULL; + } + + it = calloc(1, sizeof(Evry_Item)); + app = calloc(1, sizeof(Evry_App)); + app->desktop = desktop; + app->file = file; + it->data = app; + it->priority = prio; + if (desktop) + it->label = eina_stringshare_add(desktop->name); + else + it->label = eina_stringshare_add(file); + it->o_icon = NULL; + + plugin.candidates = eina_list_append(plugin.candidates, it); +} + +static void +_evry_app_item_icon_get(Evry_Item *it, Evas *e) +{ + Evry_App *app = it->data; + + if (app->desktop) + it->o_icon = e_util_desktop_icon_add(app->desktop, 24, e); +} + +static int +_evry_app_cb_sort(const void *data1, const void *data2) +{ + const Evry_Item *it1, *it2; + Evry_App *app1, *app2; + const char *e1, *e2; + double t1, t2; + + it1 = data1; + it2 = data2; + app1 = it1->data; + app2 = it2->data; + e1 = efreet_util_path_to_file_id(app1->desktop->orig_path); + e2 = efreet_util_path_to_file_id(app2->desktop->orig_path); + t1 = e_exehist_newest_run_get(e1); + t2 = e_exehist_newest_run_get(e2); + + if ((int)(t1 - t2)) + return (int)(t1 - t2); + else if (it1->priority - it2->priority) + return (it1->priority - it2->priority); + // TODO compare exe strings? + else return 0; + +} diff --git a/src/modules/everything/evry_border.c b/src/modules/everything/evry_border.c new file mode 100644 index 000000000..c8d1c6348 --- /dev/null +++ b/src/modules/everything/evry_border.c @@ -0,0 +1,168 @@ +#include "e.h" +#include "e_mod_main.h" + +static Evry_Plugin plugin; +static Evry_Action act_close; + +static int _evry_border_fetch(char *string); +static int _evry_border_action(Evry_Item *item); +static void _evry_border_cleanup(void); +static void _evry_border_item_add(E_Border *bd, int prio); +static int _evry_border_cb_sort(const void *data1, const void *data2); +static void _evry_border_item_icon_get(Evry_Item *it, Evas *e); + +EAPI int +evry_border_init(void) +{ + plugin.name = "Windows"; + plugin.type = "BORDER"; + plugin.need_query = 0; + plugin.fetch = &_evry_border_fetch; + plugin.action = &_evry_border_action; + plugin.cleanup = &_evry_border_cleanup; + plugin.icon_get = &_evry_border_item_icon_get; + plugin.candidates = NULL; + evry_plugin_add(&plugin); + + /* act_close.name = "Close"; + * act_close.type = "BORDER"; + * evry_action_add(&act_close); */ + + return 1; +} + +EAPI int +evry_border_shutdown(void) +{ + evry_plugin_remove(&plugin); + /* evry_action_remove(&act_close); */ + + return 1; +} + +static int +_evry_border_action(Evry_Item *item) +{ + E_Border *bd; + E_Zone *zone; + + bd = (E_Border *)item->data; + zone = e_util_zone_current_get(e_manager_current_get()); + + if (bd->desk != (e_desk_current_get(zone))) + e_desk_show(bd->desk); + + if (bd->shaded) + e_border_unshade(bd, E_DIRECTION_UP); + + if (bd->iconic) + e_border_uniconify(bd); + else + e_border_raise(bd); + + /* e_border_focus_set(bd, 1, 1); */ + e_border_focus_set_with_pointer(bd); + + return 1; +} + +static void +_evry_border_cleanup(void) +{ + Evry_Item *it; + + EINA_LIST_FREE(plugin.candidates, it) + { + if (it->data) e_object_unref(E_OBJECT(it->data)); + if (it->label) eina_stringshare_del(it->label); + if (it->o_icon) evas_object_del(it->o_icon); + free(it); + } +} + +static int +_evry_border_fetch(char *string) +{ + E_Manager *man; + E_Zone *zone; + + char match1[4096]; + char match2[4096]; + Eina_List *list; + E_Border *bd; + E_Border_List *bl; + + _evry_border_cleanup(); + + man = e_manager_current_get(); + zone = e_util_zone_current_get(man); + + if (string) + { + snprintf(match1, sizeof(match1), "%s*", string); + snprintf(match2, sizeof(match2), "*%s*", string); + } + + bl = e_container_border_list_first(e_container_current_get(man)); + while ((bd = e_container_border_list_next(bl))) + { + if (zone == bd->zone) + { + if (!string) + _evry_border_item_add(bd, 1); + else if (bd->client.icccm.name && e_util_glob_case_match(bd->client.icccm.name, match1)) + _evry_border_item_add(bd, 1); + else if (e_util_glob_case_match(e_border_name_get(bd), match1)) + _evry_border_item_add(bd, 1); + else if (bd->client.icccm.name && e_util_glob_case_match(bd->client.icccm.name, match2)) + _evry_border_item_add(bd, 2); + else if (e_util_glob_case_match(e_border_name_get(bd), match2)) + _evry_border_item_add(bd, 2); + } + } + e_container_border_list_free(bl); + + if (eina_list_count(plugin.candidates) > 0) + { + plugin.candidates = eina_list_sort(plugin.candidates, + eina_list_count(plugin.candidates), + _evry_border_cb_sort); + return 1; + } + + return 0; +} + +static void +_evry_border_item_icon_get( Evry_Item *it, Evas *e) +{ + it->o_icon = e_border_icon_add(((E_Border *)it->data), e); +} + +static void +_evry_border_item_add(E_Border *bd, int prio) +{ + Evry_Item *it; + + it = calloc(1, sizeof(Evry_Item)); + e_object_ref(E_OBJECT(bd)); + it->data = bd; + it->priority = prio; + it->label = eina_stringshare_add(e_border_name_get(bd)); + it->o_icon = NULL; //e_border_icon_add(bd, evry_evas_get()); + + plugin.candidates = eina_list_append(plugin.candidates, it); +} + + +// TODO sort by focus history and name? +static int +_evry_border_cb_sort(const void *data1, const void *data2) +{ + const Evry_Item *it1, *it2; + + it1 = data1; + it2 = data2; + + return (it1->priority - it2->priority); +} diff --git a/src/modules/everything/evry_plug_apps.c b/src/modules/everything/evry_plug_apps.c new file mode 100644 index 000000000..474031e3d --- /dev/null +++ b/src/modules/everything/evry_plug_apps.c @@ -0,0 +1,211 @@ +#include "e.h" +#include "e_mod_main.h" + +static Eina_Hash *added = NULL; +static Evry_Plugin plugin; + +static int _evry_plug_apps_fetch(char *string); +static int _evry_plug_apps_action(Evry_Item *item); +static void _evry_plug_apps_cleanup(void); +static void _evry_plug_apps_item_add(Efreet_Desktop *desktop, char *file, int prio); +static int _evry_plug_apps_cb_sort(const void *data1, const void *data2); +static void _evry_plug_apps_item_icon_get(Evry_Item *it, Evas *e); + + +EAPI int +evry_plug_apps_init(void) +{ + plugin.name = "Applications"; + plugin.type = "APPLICATION"; + plugin.need_query = 0; + plugin.fetch = &_evry_plug_apps_fetch; + plugin.action = &_evry_plug_apps_action; + plugin.cleanup = &_evry_plug_apps_cleanup; + plugin.icon_get = &_evry_plug_apps_item_icon_get; + plugin.candidates = NULL; + + evry_plugin_add(&plugin); + + return 1; +} + +EAPI int +evry_plug_apps_shutdown(void) +{ + evry_plugin_remove(&plugin); + + return 1; +} + +static int +_evry_plug_apps_action(Evry_Item *item) +{ + E_Zone *zone; + Evry_App *app; + + app = item->data; + zone = e_util_zone_current_get(e_manager_current_get()); + + if (app->desktop) + e_exec(zone, app->desktop, NULL, NULL, "everything"); + else + e_exec(zone, NULL, app->file, NULL, "everything"); + + return 1; +} + +static void +_evry_plug_apps_cleanup(void) +{ + Evry_Item *it; + Evry_App *app; + + EINA_LIST_FREE(plugin.candidates, it) + { + if (it->label) eina_stringshare_del(it->label); + if (it->o_icon) evas_object_del(it->o_icon); + app = it->data; + free(app); + free(it); + } +} + +static int +_evry_plug_apps_fetch(char *string) +{ + char buf[4096]; + Eina_List *list; + Efreet_Desktop *desktop; + char *file; + + _evry_plug_apps_cleanup(); + + if (string) + { + snprintf(buf, sizeof(buf), "%s*", string); + list = efreet_util_desktop_exec_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_plug_apps_item_add(desktop, NULL, 1); + + snprintf(buf, sizeof(buf), "*%s*", string); + list = efreet_util_desktop_name_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_plug_apps_item_add(desktop, NULL, 2); + + // TODO make these optional/configurable + snprintf(buf, sizeof(buf), "*%s*", string); + list = efreet_util_desktop_generic_name_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_plug_apps_item_add(desktop, NULL, 3); + + snprintf(buf, sizeof(buf), "*%s*", string); + list = efreet_util_desktop_comment_glob_list(buf); + EINA_LIST_FREE(list, desktop) + _evry_plug_apps_item_add(desktop, NULL, 3); + } + else + { + // TODO option for popular/recent + list = e_exehist_list_get(); + EINA_LIST_FREE(list, file) + _evry_plug_apps_item_add(NULL, file, 1); + } + + if (added) + { + eina_hash_free(added); + added = NULL; + + if (string) + plugin.candidates = + eina_list_sort(plugin.candidates, + eina_list_count(plugin.candidates), + _evry_plug_apps_cb_sort); + return 1; + } + + return 0; +} + +static void +_evry_plug_apps_item_add(Efreet_Desktop *desktop, char *file, int prio) +{ + Evry_Item *it; + Evry_App *app; + + if (desktop) + file = ecore_file_app_exe_get(desktop->exec); + + if (!file) return; + + if (eina_hash_find(added, file)) + { + if (desktop) free(file); + return; + } + + if (!added) + added = eina_hash_string_superfast_new(NULL); + + eina_hash_add(added, file, file); + + if (desktop) + { + free(file); + file = NULL; + } + else + { + desktop = efreet_util_desktop_exec_find(file); + if (desktop) file = NULL; + } + + it = calloc(1, sizeof(Evry_Item)); + app = calloc(1, sizeof(Evry_App)); + app->desktop = desktop; + app->file = file; + it->data = app; + it->priority = prio; + if (desktop) + it->label = eina_stringshare_add(desktop->name); + else + it->label = eina_stringshare_add(file); + it->o_icon = NULL; + + plugin.candidates = eina_list_append(plugin.candidates, it); +} + +static void +_evry_plug_apps_item_icon_get(Evry_Item *it, Evas *e) +{ + Evry_App *app = it->data; + + if (app->desktop) + it->o_icon = e_util_desktop_icon_add(app->desktop, 24, e); +} + +static int +_evry_plug_apps_cb_sort(const void *data1, const void *data2) +{ + const Evry_Item *it1, *it2; + Evry_App *app1, *app2; + const char *e1, *e2; + double t1, t2; + + it1 = data1; + it2 = data2; + app1 = it1->data; + app2 = it2->data; + e1 = efreet_util_path_to_file_id(app1->desktop->orig_path); + e2 = efreet_util_path_to_file_id(app2->desktop->orig_path); + t1 = e_exehist_newest_run_get(e1); + t2 = e_exehist_newest_run_get(e2); + + if ((int)(t1 - t2)) + return (int)(t1 - t2); + else if (it1->priority - it2->priority) + return (it1->priority - it2->priority); + // TODO compare exe strings? + else return 0; + +} diff --git a/src/modules/everything/evry_plug_border.c b/src/modules/everything/evry_plug_border.c new file mode 100644 index 000000000..0123fb3d4 --- /dev/null +++ b/src/modules/everything/evry_plug_border.c @@ -0,0 +1,168 @@ +#include "e.h" +#include "e_mod_main.h" + +static Evry_Plugin plugin; +static Evry_Action act_close; + +static int _evry_plug_border_fetch(char *string); +static int _evry_plug_border_action(Evry_Item *item); +static void _evry_plug_border_cleanup(void); +static void _evry_plug_border_item_add(E_Border *bd, int prio); +static int _evry_plug_border_cb_sort(const void *data1, const void *data2); +static void _evry_plug_border_item_icon_get(Evry_Item *it, Evas *e); + +EAPI int +evry_plug_border_init(void) +{ + plugin.name = "Windows"; + plugin.type = "BORDER"; + plugin.need_query = 0; + plugin.fetch = &_evry_plug_border_fetch; + plugin.action = &_evry_plug_border_action; + plugin.cleanup = &_evry_plug_border_cleanup; + plugin.icon_get = &_evry_plug_border_item_icon_get; + plugin.candidates = NULL; + evry_plugin_add(&plugin); + + /* act_close.name = "Close"; + * act_close.type = "BORDER"; + * evry_action_add(&act_close); */ + + return 1; +} + +EAPI int +evry_plug_border_shutdown(void) +{ + evry_plugin_remove(&plugin); + /* evry_action_remove(&act_close); */ + + return 1; +} + +static int +_evry_plug_border_action(Evry_Item *item) +{ + E_Border *bd; + E_Zone *zone; + + bd = (E_Border *)item->data; + zone = e_util_zone_current_get(e_manager_current_get()); + + if (bd->desk != (e_desk_current_get(zone))) + e_desk_show(bd->desk); + + if (bd->shaded) + e_border_unshade(bd, E_DIRECTION_UP); + + if (bd->iconic) + e_border_uniconify(bd); + else + e_border_raise(bd); + + /* e_border_focus_set(bd, 1, 1); */ + e_border_focus_set_with_pointer(bd); + + return 1; +} + +static void +_evry_plug_border_cleanup(void) +{ + Evry_Item *it; + + EINA_LIST_FREE(plugin.candidates, it) + { + if (it->data) e_object_unref(E_OBJECT(it->data)); + if (it->label) eina_stringshare_del(it->label); + if (it->o_icon) evas_object_del(it->o_icon); + free(it); + } +} + +static int +_evry_plug_border_fetch(char *string) +{ + E_Manager *man; + E_Zone *zone; + + char match1[4096]; + char match2[4096]; + Eina_List *list; + E_Border *bd; + E_Border_List *bl; + + _evry_plug_border_cleanup(); + + man = e_manager_current_get(); + zone = e_util_zone_current_get(man); + + if (string) + { + snprintf(match1, sizeof(match1), "%s*", string); + snprintf(match2, sizeof(match2), "*%s*", string); + } + + bl = e_container_border_list_first(e_container_current_get(man)); + while ((bd = e_container_border_list_next(bl))) + { + if (zone == bd->zone) + { + if (!string) + _evry_plug_border_item_add(bd, 1); + else if (bd->client.icccm.name && e_util_glob_case_match(bd->client.icccm.name, match1)) + _evry_plug_border_item_add(bd, 1); + else if (e_util_glob_case_match(e_border_name_get(bd), match1)) + _evry_plug_border_item_add(bd, 1); + else if (bd->client.icccm.name && e_util_glob_case_match(bd->client.icccm.name, match2)) + _evry_plug_border_item_add(bd, 2); + else if (e_util_glob_case_match(e_border_name_get(bd), match2)) + _evry_plug_border_item_add(bd, 2); + } + } + e_container_border_list_free(bl); + + if (eina_list_count(plugin.candidates) > 0) + { + plugin.candidates = eina_list_sort(plugin.candidates, + eina_list_count(plugin.candidates), + _evry_plug_border_cb_sort); + return 1; + } + + return 0; +} + +static void +_evry_plug_border_item_icon_get( Evry_Item *it, Evas *e) +{ + it->o_icon = e_border_icon_add(((E_Border *)it->data), e); +} + +static void +_evry_plug_border_item_add(E_Border *bd, int prio) +{ + Evry_Item *it; + + it = calloc(1, sizeof(Evry_Item)); + e_object_ref(E_OBJECT(bd)); + it->data = bd; + it->priority = prio; + it->label = eina_stringshare_add(e_border_name_get(bd)); + it->o_icon = NULL; //e_border_icon_add(bd, evry_evas_get()); + + plugin.candidates = eina_list_append(plugin.candidates, it); +} + + +// TODO sort by focus history and name? +static int +_evry_plug_border_cb_sort(const void *data1, const void *data2) +{ + const Evry_Item *it1, *it2; + + it1 = data1; + it2 = data2; + + return (it1->priority - it2->priority); +} diff --git a/src/modules/everything/evry_plug_config.c b/src/modules/everything/evry_plug_config.c new file mode 100644 index 000000000..c91c57c28 --- /dev/null +++ b/src/modules/everything/evry_plug_config.c @@ -0,0 +1,183 @@ +#include "e.h" +#include "e_mod_main.h" + +static Evry_Plugin plugin; + +static int _evry_plug_config_fetch(char *string); +static int _evry_plug_config_action(Evry_Item *item); +static void _evry_plug_config_cleanup(void); +static void _evry_plug_config_item_add(E_Configure_It *eci, int prio); +static int _evry_plug_config_cb_sort(const void *data1, const void *data2); +static void _evry_plug_config_item_icon_get(Evry_Item *it, Evas *e); + +EAPI int +evry_plug_config_init(void) +{ + plugin.name = "Settings"; + plugin.fetch = &_evry_plug_config_fetch; + plugin.action = &_evry_plug_config_action; + plugin.cleanup = &_evry_plug_config_cleanup; + plugin.icon_get = &_evry_plug_config_item_icon_get; + plugin.candidates = NULL; + evry_plugin_add(&plugin); + + return 1; +} + +EAPI int +evry_plug_config_shutdown(void) +{ + evry_plugin_remove(&plugin); + + return 1; +} + +static int +_evry_plug_config_action(Evry_Item *item) +{ + E_Configure_It *eci, *eci2; + E_Container *con; + E_Configure_Cat *ecat; + Eina_List *l, *ll; + char buf[1024]; + int found = 0; + + eci = item->data; + con = e_container_current_get(e_manager_current_get()); + + for (l = e_configure_registry; l; l = l->next) + { + ecat = l->data; + for (ll = ecat->items; ll; ll = ll->next) + { + eci2 = ll->data; + if (eci == eci2) + { + found = 1; + snprintf(buf, sizeof(buf), "%s/%s", + ecat->cat, + eci->item); + } + } + } + + printf("path: %s\n", buf); + + + if (found) + e_configure_registry_call(buf, con, NULL); + + return 1; +} + +static void +_evry_plug_config_cleanup(void) +{ + Evry_Item *it; + + EINA_LIST_FREE(plugin.candidates, it) + { + /* if (it->data) */ + if (it->label) eina_stringshare_del(it->label); + if (it->o_icon) evas_object_del(it->o_icon); + free(it); + } +} + +static int +_evry_plug_config_fetch(char *string) +{ + E_Manager *man; + E_Zone *zone; + + char match1[4096]; + char match2[4096]; + Eina_List *l, *ll; + E_Configure_Cat *ecat; + E_Configure_It *eci; + + _evry_plug_config_cleanup(); + + snprintf(match1, sizeof(match1), "%s*", string); + snprintf(match2, sizeof(match2), "*%s*", string); + + for (l = e_configure_registry; l; l = l->next) + { + ecat = l->data; + if ((ecat->pri >= 0) && (ecat->items)) + { + for (ll = ecat->items; ll; ll = ll->next) + { + eci = ll->data; + if (eci->pri >= 0) + { + if (e_util_glob_case_match(eci->label, match1)) + _evry_plug_config_item_add(eci, 1); + else if (e_util_glob_case_match(eci->label, match2)) + _evry_plug_config_item_add(eci, 2); + else if (e_util_glob_case_match(ecat->label, match1)) + _evry_plug_config_item_add(eci, 3); + else if (e_util_glob_case_match(ecat->label, match2)) + _evry_plug_config_item_add(eci, 4); + } + } + } + } + + if (eina_list_count(plugin.candidates) > 0) + { + plugin.candidates = + eina_list_sort(plugin.candidates, + eina_list_count(plugin.candidates), + _evry_plug_config_cb_sort); + return 1; + } + + return 0; +} + +static void +_evry_plug_config_item_icon_get(Evry_Item *it, Evas *e) +{ + E_Configure_It *eci = it->data; + Evas_Object *o; + + if (eci->icon) + { + o = e_icon_add(e); + if (!e_util_icon_theme_set(o, eci->icon)) + { + evas_object_del(o); + o = e_util_icon_add(eci->icon, e); + } + } + + it->o_icon = o; +} + +static void +_evry_plug_config_item_add(E_Configure_It *eci, int prio) +{ + Evry_Item *it; + + it = calloc(1, sizeof(Evry_Item)); + it->data = eci; + it->priority = prio; + it->label = eina_stringshare_add(eci->label); + it->o_icon = NULL; + + plugin.candidates = eina_list_append(plugin.candidates, it); +} + + +// TODO sort name? +static int +_evry_plug_config_cb_sort(const void *data1, const void *data2) +{ + const Evry_Item *it1, *it2; + + it1 = data1; + it2 = data2; + + return (it1->priority - it2->priority); +} diff --git a/src/modules/everything/module.desktop.in b/src/modules/everything/module.desktop.in new file mode 100644 index 000000000..b99882a92 --- /dev/null +++ b/src/modules/everything/module.desktop.in @@ -0,0 +1,30 @@ +[Desktop Entry] +Type=Link +Name=Run Everything +Name[cs]=Dialog Spustit +Name[de]= +Name[eo]=Lanĉi komandojn +Name[es]=Ejecutar comando +Name[fr]=Exécuter une commande +Name[hu]=Parancs futtatása +Name[it]=Lanciacomandi +Name[ja]= +Name[pt]= +Name[pt_BR]= +Name[zh_CN]= +Name[zh_TW]= +Icon=e-module-everything +Comment=Run Command Module
The run command module provides an application launcher dialog. +Comment[cs]=Modul dialogu Spustit
Poskytuje dialog pro spuštění aplikací. +Comment[de]= +Comment[eo]=Modulo por lanĉi komandojn<title><br>La modulo de lanĉo de komandoj provizas dialogon de lanĉilo de aplikaĵoj. +Comment[es]=<title>Módulo para ejecutar comandos
El módulo de ejecutar comandos provee un diálogo para ejecutar aplicaciones. +Comment[fr]=Module Exécuter une commande
Fournit une fenêtre de commande pour lancer des applications. +Comment[hu]=Parancs futtatása modul
A parancs futtató modul egy alkalmazásindítót biztosít a számunkra. +Comment[it]=Modulo lanciacomandi
Questo modulo fornisce una voce di menù per l'esecuzione di comandi. +Comment[ja]= +Comment[pt]= +Comment[pt_BR]= +Comment[zh_CN]= +Comment[zh_TW]= +X-Enlightenment-ModuleType=system