forked from enlightenment/enlightenment
Patch by: Lucas Joia <lucasjoia@profusion.mobi> SVN revision: 82178devs/asdfuser/comp-sounds
parent
5e0c91af3c
commit
c83d114491
11 changed files with 722 additions and 1 deletions
@ -0,0 +1,77 @@ |
||||
group { name: "e/modules/appmenu/item"; |
||||
images.image: "vgrad_med_dark.png" COMP; |
||||
data.item: "padding_horizontal" "5"; |
||||
data.item: "padding_vertical" "5"; |
||||
parts { |
||||
part { |
||||
name: "event_area"; |
||||
type: RECT; |
||||
mouse_events: 1; |
||||
description { |
||||
state: "default" 0.0; |
||||
color: 0 0 0 0; |
||||
} |
||||
} |
||||
part { |
||||
name: "background"; |
||||
type: IMAGE; |
||||
mouse_events: 0; |
||||
description { |
||||
state: "default" 0.0; |
||||
image.normal: "vgrad_med_dark.png"; |
||||
fill.smooth: 0; |
||||
TILED_HORIZ(120) |
||||
visible: 0; |
||||
} |
||||
description { |
||||
state: "selected" 0.0; |
||||
inherit: "default" 0.0; |
||||
visible: 1; |
||||
} |
||||
} |
||||
part { |
||||
name: "text"; |
||||
type: TEXT; |
||||
mouse_events: 0; |
||||
effect: SHADOW BOTTOM; |
||||
scale: 1; |
||||
description { |
||||
state: "default" 0.0; |
||||
rel1.offset: 2 2; |
||||
rel2.offset: -3 -3; |
||||
color: 255 255 255 255; |
||||
color3: 0 0 0 128; |
||||
text { |
||||
font: "Sans"; |
||||
size: 10; |
||||
min: 1 1; |
||||
align: 0.5 0.5; |
||||
text_class: "label"; |
||||
} |
||||
} |
||||
description { |
||||
state: "selected" 0.0; |
||||
inherit: "default" 0.0; |
||||
color: 51 153 255 255; |
||||
color2: 51 153 255 24; |
||||
color3: 51 153 255 18; |
||||
} |
||||
} |
||||
} |
||||
programs { |
||||
program { |
||||
signal: "mouse,in"; |
||||
source: "event_area"; |
||||
action: STATE_SET "selected" 0.0; |
||||
target: "background"; |
||||
target: "text"; |
||||
} |
||||
program { |
||||
signal: "mouse,out"; |
||||
source: "event_area"; |
||||
action: STATE_SET "default" 0.0; |
||||
target: "background"; |
||||
target: "text"; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,17 @@ |
||||
appmenudir = $(MDIR)/appmenu |
||||
appmenu_DATA = appmenu/module.desktop |
||||
|
||||
EXTRA_DIST += $(appmenu2_DATA) |
||||
|
||||
appmenupkgdir = $(MDIR)/appmenu/$(MODULE_ARCH) |
||||
appmenupkg_LTLIBRARIES = appmenu/module.la |
||||
|
||||
appmenu_module_la_SOURCES = appmenu/e_mod_main.c \ |
||||
appmenu/e_mod_dbus_registrar_server.c \ |
||||
appmenu/e_mod_appmenu_render.c \ |
||||
appmenu/e_mod_appmenu_private.h |
||||
|
||||
|
||||
.PHONY: appmenu install-appmenu |
||||
appmenu: $(appmenupkg_LTLIBRARIES) $(appmenu_DATA) |
||||
install-appmenu: install-appmenuDATA install-appmenupkgLTLIBRARIES |
@ -0,0 +1,44 @@ |
||||
#ifndef APPMENU_PRIVATE_H |
||||
#define APPMENU_PRIVATE_H |
||||
|
||||
#include "e.h" |
||||
|
||||
typedef struct _E_AppMenu_Window E_AppMenu_Window; |
||||
|
||||
typedef struct _E_AppMenu_Context |
||||
{ |
||||
Eina_List *instances; |
||||
EDBus_Connection *conn; |
||||
EDBus_Service_Interface *iface; |
||||
Eina_List *windows; |
||||
unsigned window_with_focus; |
||||
E_AppMenu_Window *window; |
||||
Ecore_Event_Handler *events[2]; |
||||
} E_AppMenu_Context; |
||||
|
||||
typedef struct _E_AppMenu_Instance |
||||
{ |
||||
Evas_Object *box; |
||||
Evas *evas; |
||||
E_Gadcon_Client *gcc; |
||||
E_AppMenu_Context *ctx; |
||||
Eina_Bool orientation_horizontal; |
||||
} E_AppMenu_Instance; |
||||
|
||||
struct _E_AppMenu_Window |
||||
{ |
||||
unsigned window_id; |
||||
const char *bus_id; |
||||
const char *path; |
||||
E_DBusMenu_Ctx *dbus_menu; |
||||
E_AppMenu_Context *ctxt; |
||||
E_DBusMenu_Item *root_item; |
||||
}; |
||||
|
||||
void appmenu_window_free(E_AppMenu_Window *window); |
||||
void appmenu_dbus_registrar_server_init(E_AppMenu_Context *ctx); |
||||
void appmenu_application_monitor(void *data, const char *bus, const char *old, const char *new); |
||||
void appmenu_menu_render(E_AppMenu_Context *ctxt EINA_UNUSED, E_AppMenu_Window *w); |
||||
void appmenu_menu_of_instance_render(E_AppMenu_Instance *inst, E_AppMenu_Window *window); |
||||
|
||||
#endif |
@ -0,0 +1,169 @@ |
||||
#include "e_mod_appmenu_private.h" |
||||
|
||||
static void |
||||
menu_deactive(E_Menu *m) |
||||
{ |
||||
Eina_List *iter; |
||||
E_Menu_Item *mi; |
||||
EINA_LIST_FOREACH(m->items, iter, mi) |
||||
{ |
||||
if (mi->submenu) |
||||
{ |
||||
menu_deactive(mi->submenu); |
||||
e_menu_deactivate(mi->submenu); |
||||
} |
||||
} |
||||
e_object_del(E_OBJECT(m)); |
||||
} |
||||
|
||||
static void |
||||
menu_post_deactivate(void *data, E_Menu *m) |
||||
{ |
||||
E_Gadcon *gadcon = data; |
||||
|
||||
e_gadcon_locked_set(gadcon, 0); |
||||
menu_deactive(m); |
||||
} |
||||
|
||||
static void |
||||
sub_item_clicked_cb(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) |
||||
{ |
||||
E_DBusMenu_Item *item = data; |
||||
e_dbusmenu_event_send(item, E_DBUSMENU_ITEM_EVENT_CLICKED); |
||||
} |
||||
|
||||
static E_Menu * |
||||
item_submenu_new(E_DBusMenu_Item *item, E_Menu_Item *mi) |
||||
{ |
||||
E_Menu *m; |
||||
E_DBusMenu_Item *child; |
||||
|
||||
m = e_menu_new(); |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); |
||||
if (mi) |
||||
e_menu_item_submenu_set(mi, m); |
||||
|
||||
EINA_INLIST_FOREACH(item->sub_items, child) |
||||
{ |
||||
E_Menu_Item *submi; |
||||
if (!child->visible) |
||||
continue; |
||||
submi = e_menu_item_new(m); |
||||
if (child->type == E_DBUSMENU_ITEM_TYPE_SEPARATOR) |
||||
{ |
||||
e_menu_item_separator_set(submi, 1); |
||||
continue; |
||||
} |
||||
e_menu_item_label_set(submi, child->label); |
||||
e_menu_item_callback_set(submi, sub_item_clicked_cb, child); |
||||
if (!child->enabled) |
||||
e_menu_item_disabled_set(submi, 1); |
||||
if (child->toggle_type) |
||||
{ |
||||
if (child->toggle_type == E_DBUSMENU_ITEM_TOGGLE_TYPE_CHECKMARK) |
||||
e_menu_item_check_set(submi, 1); |
||||
else if (child->toggle_type == E_DBUSMENU_ITEM_TOGGLE_TYPE_RADIO) |
||||
e_menu_item_radio_set(submi, 1); |
||||
e_menu_item_toggle_set(submi, child->toggle_state); |
||||
} |
||||
if (eina_inlist_count(child->sub_items)) |
||||
item_submenu_new(child, submi); |
||||
e_util_menu_item_theme_icon_set(submi, child->icon_name); |
||||
} |
||||
return m; |
||||
} |
||||
|
||||
static void |
||||
item_menu_open(E_DBusMenu_Item *item, E_Gadcon *gadcon) |
||||
{ |
||||
E_Menu *m = item_submenu_new(item, NULL); |
||||
E_Zone *zone; |
||||
int x, y; |
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN(m); |
||||
e_gadcon_locked_set(gadcon, 1); |
||||
e_menu_post_deactivate_callback_set(m, menu_post_deactivate, gadcon); |
||||
|
||||
zone = e_util_zone_current_get(e_manager_current_get()); |
||||
ecore_x_pointer_xy_get(zone->container->win, &x, &y); |
||||
e_menu_activate_mouse(m, zone, x, y, 1, 1, E_MENU_POP_DIRECTION_DOWN, |
||||
ecore_x_current_time_get()); |
||||
} |
||||
|
||||
static void |
||||
clicked_toolbar_item(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED) |
||||
{ |
||||
E_DBusMenu_Item *item = data; |
||||
E_Gadcon *gadcon = evas_object_data_get(obj, "gadcon"); |
||||
item_menu_open(item, gadcon); |
||||
} |
||||
|
||||
void |
||||
appmenu_menu_of_instance_render(E_AppMenu_Instance *inst, E_AppMenu_Window *window) |
||||
{ |
||||
E_DBusMenu_Item *child; |
||||
Evas_Coord w, h, sum_w = 0, sum_h = 0, padding = 0; |
||||
Eina_List *l; |
||||
Evas_Object *item; |
||||
|
||||
l = evas_object_box_children_get(inst->box); |
||||
EINA_LIST_FREE(l, item) |
||||
evas_object_del(item); |
||||
e_gadcon_client_min_size_set(inst->gcc, 0, 0); |
||||
|
||||
if (!window || !window->root_item) |
||||
return; |
||||
|
||||
EINA_INLIST_FOREACH(window->root_item->sub_items, child) |
||||
{ |
||||
if (!child->label) |
||||
continue; |
||||
|
||||
item = edje_object_add(inst->evas); |
||||
e_theme_edje_object_set(item, "base/themes", "e/modules/appmenu/item"); |
||||
edje_object_part_text_set(item, "text", child->label); |
||||
evas_object_box_append(inst->box, item); |
||||
edje_object_size_min_calc(item, &w, &h); |
||||
|
||||
if (!padding) |
||||
{ |
||||
const char *padding_txt; |
||||
if (inst->orientation_horizontal) |
||||
padding_txt = edje_object_data_get(item, "padding_horizontal"); |
||||
else |
||||
padding_txt = edje_object_data_get(item, "padding_vertical"); |
||||
padding = atoi(padding_txt); |
||||
} |
||||
|
||||
if (inst->orientation_horizontal) |
||||
{ |
||||
h = inst->gcc->gadcon->shelf->h; |
||||
w = w + padding; |
||||
sum_w = sum_w + w; |
||||
} |
||||
else |
||||
{ |
||||
w = inst->gcc->gadcon->shelf->w; |
||||
h = h + padding; |
||||
sum_h = sum_h + h; |
||||
} |
||||
evas_object_resize(item, w, h); |
||||
evas_object_show(item); |
||||
evas_object_data_set(item, "gadcon", inst->gcc->gadcon); |
||||
evas_object_event_callback_add(item, EVAS_CALLBACK_MOUSE_DOWN, |
||||
clicked_toolbar_item, child); |
||||
} |
||||
e_gadcon_client_min_size_set(inst->gcc, sum_w, sum_h); |
||||
} |
||||
|
||||
void |
||||
appmenu_menu_render(E_AppMenu_Context *ctxt, E_AppMenu_Window *window) |
||||
{ |
||||
Eina_List *list; |
||||
E_AppMenu_Instance *inst; |
||||
|
||||
ctxt->window = window; |
||||
|
||||
EINA_LIST_FOREACH(ctxt->instances, list, inst) |
||||
appmenu_menu_of_instance_render(inst, window); |
||||
} |
@ -0,0 +1,194 @@ |
||||
#include "e_mod_appmenu_private.h" |
||||
|
||||
#define REGISTRAR_BUS "com.canonical.AppMenu.Registrar" |
||||
#define REGISTRAR_PATH "/com/canonical/AppMenu/Registrar" |
||||
#define REGISTRAR_IFACE "com.canonical.AppMenu.Registrar" |
||||
|
||||
#define ERROR_WINDOW_NOT_FOUND "com.canonical.AppMenu.Registrar.WindowNotFound" |
||||
|
||||
void |
||||
appmenu_application_monitor(void *data, const char *bus EINA_UNUSED, const char *old __UNUSED__, const char *new __UNUSED__) |
||||
{ |
||||
E_AppMenu_Window *window = data; |
||||
edbus_service_signal_emit(window->ctxt->iface, 1, window->window_id); |
||||
appmenu_window_free(window); |
||||
} |
||||
|
||||
static void |
||||
menu_update_cb(void *data, E_DBusMenu_Item *item) |
||||
{ |
||||
E_AppMenu_Window *window = data; |
||||
window->root_item = item; |
||||
if (!item) |
||||
return; |
||||
if (window->window_id == window->ctxt->window_with_focus) |
||||
appmenu_menu_render(window->ctxt, window); |
||||
} |
||||
|
||||
static void |
||||
menu_pop_cb(void *data EINA_UNUSED, const E_DBusMenu_Item *new_root_item EINA_UNUSED) |
||||
{ |
||||
//TODO
|
||||
} |
||||
|
||||
static EDBus_Message * |
||||
_on_register_window(const EDBus_Service_Interface *iface, const EDBus_Message *msg) |
||||
{ |
||||
EDBus_Connection *conn = edbus_service_connection_get(iface); |
||||
E_AppMenu_Context *ctxt = edbus_service_object_data_get(iface, "ctxt"); |
||||
unsigned window_id; |
||||
const char *path, *bus_id; |
||||
E_AppMenu_Window *window; |
||||
|
||||
if (!edbus_message_arguments_get(msg, "uo", &window_id, &path)) |
||||
{ |
||||
ERR("Error reading message"); |
||||
return NULL; |
||||
} |
||||
|
||||
window = calloc(1, sizeof(E_AppMenu_Window)); |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL); |
||||
|
||||
|
||||
bus_id = edbus_message_sender_get(msg); |
||||
|
||||
window->window_id = window_id; |
||||
window->dbus_menu = e_dbusmenu_load(conn, bus_id, path, window); |
||||
e_dbusmenu_update_cb_set(window->dbus_menu, menu_update_cb); |
||||
e_dbusmenu_pop_request_cb_set(window->dbus_menu, menu_pop_cb); |
||||
window->bus_id = eina_stringshare_add(bus_id); |
||||
window->path = eina_stringshare_add(path); |
||||
|
||||
edbus_name_owner_changed_callback_add(conn, bus_id, appmenu_application_monitor, |
||||
window, EINA_FALSE); |
||||
ctxt->windows = eina_list_append(ctxt->windows, window); |
||||
window->ctxt = ctxt; |
||||
|
||||
edbus_service_signal_emit(iface, 0, window_id, bus_id, path); |
||||
return edbus_message_method_return_new(msg); |
||||
} |
||||
|
||||
static E_AppMenu_Window * |
||||
window_find(E_AppMenu_Context *ctxt, unsigned window_id) |
||||
{ |
||||
Eina_List *l; |
||||
E_AppMenu_Window *w; |
||||
EINA_LIST_FOREACH(ctxt->windows, l, w) |
||||
{ |
||||
if (w->window_id == window_id) |
||||
return w; |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
static EDBus_Message * |
||||
_on_unregister_window(const EDBus_Service_Interface *iface, const EDBus_Message *msg) |
||||
{ |
||||
E_AppMenu_Context *ctxt = edbus_service_object_data_get(iface, "ctxt"); |
||||
E_AppMenu_Window *w; |
||||
unsigned window_id; |
||||
|
||||
if (!edbus_message_arguments_get(msg, "u", &window_id)) |
||||
{ |
||||
ERR("Error reading message."); |
||||
return NULL; |
||||
} |
||||
|
||||
w = window_find(ctxt, window_id); |
||||
if (w) |
||||
appmenu_window_free(w); |
||||
edbus_service_signal_emit(iface, 1, window_id); |
||||
return edbus_message_method_return_new(msg); |
||||
} |
||||
|
||||
static EDBus_Message * |
||||
_on_getmenu(const EDBus_Service_Interface *iface, const EDBus_Message *msg) |
||||
{ |
||||
unsigned window_id; |
||||
Eina_List *l; |
||||
E_AppMenu_Window *w; |
||||
E_AppMenu_Context *ctxt = edbus_service_object_data_get(iface, "ctxt"); |
||||
|
||||
if (!edbus_message_arguments_get(msg, "u", &window_id)) |
||||
{ |
||||
ERR("Error reading message"); |
||||
return NULL; |
||||
} |
||||
EINA_LIST_FOREACH(ctxt->windows, l, w) |
||||
{ |
||||
if (w->window_id == window_id) |
||||
{ |
||||
EDBus_Message *reply; |
||||
reply = edbus_message_method_return_new(msg); |
||||
edbus_message_arguments_append(reply, "so", w->bus_id, w->path); |
||||
return reply; |
||||
} |
||||
} |
||||
return edbus_message_error_new(msg, ERROR_WINDOW_NOT_FOUND, ""); |
||||
} |
||||
|
||||
static EDBus_Message * |
||||
_on_getmenus(const EDBus_Service_Interface *iface, const EDBus_Message *msg) |
||||
{ |
||||
Eina_List *l; |
||||
E_AppMenu_Window *w; |
||||
E_AppMenu_Context *ctxt = edbus_service_object_data_get(iface, "ctxt"); |
||||
EDBus_Message *reply; |
||||
EDBus_Message_Iter *array, *main_iter; |
||||
|
||||
reply = edbus_message_method_return_new(msg); |
||||
main_iter = edbus_message_iter_get(reply); |
||||
edbus_message_iter_arguments_append(main_iter, "a(uso)", &array); |
||||
|
||||
EINA_LIST_FOREACH(ctxt->windows, l, w) |
||||
{ |
||||
EDBus_Message_Iter *entry; |
||||
edbus_message_iter_arguments_append(array, "(uso)", &entry); |
||||
edbus_message_iter_arguments_append(entry, "uso", w->window_id, |
||||
w->bus_id, w->path); |
||||
edbus_message_iter_container_close(array, entry); |
||||
} |
||||
|
||||
edbus_message_iter_container_close(main_iter, array); |
||||
return reply; |
||||
} |
||||
|
||||
static const EDBus_Method registrar_methods[] = { |
||||
{ |
||||
"RegisterWindow", EDBUS_ARGS({"u", "windowId"},{"o", "menuObjectPath"}), |
||||
NULL, _on_register_window, 0 |
||||
}, |
||||
{ |
||||
"UnregisterWindow", EDBUS_ARGS({"u", "windowId"}), |
||||
NULL, _on_unregister_window, 0 |
||||
}, |
||||
{ |
||||
"GetMenuForWindow", EDBUS_ARGS({"u", "windowId"}), |
||||
EDBUS_ARGS({"s", "bus_id"},{"o", "menu_path"}), _on_getmenu, 0 |
||||
}, |
||||
{ |
||||
"GetMenus", NULL, EDBUS_ARGS({"a(uso)", "array_of_menu"}), _on_getmenus, 0 |
||||
}, |
||||
{ NULL, NULL, NULL, NULL, 0 } |
||||
}; |
||||
|
||||
static const EDBus_Signal registrar_signals[] = { |
||||
{ "WindowRegistered", EDBUS_ARGS({"u", "windowId"}, {"s", "bus_id"}, {"o", "menu_path"}), 0 }, |
||||
{ "WindowUnregistered", EDBUS_ARGS({"u", "windowId"}), 0 }, |
||||
{ NULL, NULL, 0 } |
||||
}; |
||||
|
||||
static const EDBus_Service_Interface_Desc registrar_iface = { |
||||
REGISTRAR_IFACE, registrar_methods, registrar_signals, NULL, NULL, NULL |
||||
}; |
||||
|
||||
void |
||||
appmenu_dbus_registrar_server_init(E_AppMenu_Context *ctx) |
||||
{ |
||||
ctx->iface = edbus_service_interface_register(ctx->conn, |
||||
REGISTRAR_PATH, |
||||
®istrar_iface); |
||||
edbus_service_object_data_set(ctx->iface, "ctxt", ctx); |
||||
edbus_name_request(ctx->conn, REGISTRAR_BUS, |
||||
EDBUS_NAME_REQUEST_FLAG_REPLACE_EXISTING, NULL, NULL); |
||||
} |
@ -0,0 +1,207 @@ |
||||
#include "e_mod_appmenu_private.h" |
||||
|
||||
static E_Module *appmenu_module = NULL; |
||||
|
||||
static void |
||||
_gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient) |
||||
{ |
||||
E_AppMenu_Instance *inst = gcc->data; |
||||
switch (orient) |
||||
{ |
||||
case E_GADCON_ORIENT_HORIZ: |
||||
case E_GADCON_ORIENT_TOP: |
||||
case E_GADCON_ORIENT_BOTTOM: |
||||
case E_GADCON_ORIENT_CORNER_TL: |
||||
case E_GADCON_ORIENT_CORNER_TR: |
||||
case E_GADCON_ORIENT_CORNER_BL: |
||||
case E_GADCON_ORIENT_CORNER_BR: |
||||
inst->orientation_horizontal = EINA_TRUE; |
||||
break; |
||||
case E_GADCON_ORIENT_VERT: |
||||
case E_GADCON_ORIENT_LEFT: |
||||
case E_GADCON_ORIENT_RIGHT: |
||||
case E_GADCON_ORIENT_CORNER_LT: |
||||
case E_GADCON_ORIENT_CORNER_RT: |
||||
case E_GADCON_ORIENT_CORNER_LB: |
||||
case E_GADCON_ORIENT_CORNER_RB: |
||||
default: |
||||
inst->orientation_horizontal = EINA_FALSE; |
||||
break; |
||||
} |
||||
if (inst->orientation_horizontal) |
||||
evas_object_box_layout_set(inst->box, evas_object_box_layout_horizontal, NULL, NULL); |
||||
else |
||||
evas_object_box_layout_set(inst->box, evas_object_box_layout_vertical, NULL, NULL); |
||||
appmenu_menu_of_instance_render(inst, inst->ctx->window); |
||||
} |
||||
|
||||
/* Gadcon Api Functions */ |
||||
static E_Gadcon_Client * |
||||
_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) |
||||
{ |
||||
E_AppMenu_Instance *inst; |
||||
E_AppMenu_Context *ctxt; |
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(appmenu_module, NULL); |
||||
inst = calloc(1, sizeof(E_AppMenu_Instance)); |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(inst, NULL); |
||||
|
||||
ctxt = appmenu_module->data; |
||||
ctxt->instances = eina_list_append(ctxt->instances, inst); |
||||
inst->evas = gc->evas; |
||||
inst->ctx = ctxt; |
||||
|
||||
inst->box = evas_object_box_add(inst->evas); |
||||
evas_object_show(inst->box); |
||||
|
||||
inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->box); |
||||
if (!inst->gcc) |
||||
{ |
||||
evas_object_del(inst->box); |
||||
ctxt->instances = eina_list_remove(ctxt->instances, inst); |
||||
free(inst); |
||||
return NULL; |
||||
} |
||||
inst->gcc->data = inst; |
||||
_gc_orient(inst->gcc, inst->gcc->gadcon->orient); |
||||
return inst->gcc; |
||||
} |
||||
|
||||
static void |
||||
_gc_shutdown(E_Gadcon_Client *gcc) |
||||
{ |
||||
E_AppMenu_Instance *inst = gcc->data; |
||||
evas_object_del(inst->box); |
||||
inst->ctx->instances = eina_list_remove(inst->ctx->instances, inst); |
||||
free(inst); |
||||
} |
||||
|
||||
static const char * |
||||
_gc_label(const E_Gadcon_Client_Class *client_class EINA_UNUSED) |
||||
{ |
||||
return "Application Menu"; |
||||
} |
||||
|
||||
static Evas_Object * |
||||
_gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas EINA_UNUSED) |
||||
{ |
||||
return NULL; |
||||
} |
||||
|
||||
static char tmpbuf[64]; /* general purpose buffer, just use immediately */ |
||||
|
||||
static const char * |
||||
_gc_id_new(const E_Gadcon_Client_Class *client_class EINA_UNUSED) |
||||
{ |
||||
E_AppMenu_Context *ctxt; |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(appmenu_module, NULL); |
||||
ctxt = appmenu_module->data; |
||||
snprintf(tmpbuf, sizeof(tmpbuf), "appmenu.%d", |
||||
eina_list_count(ctxt->instances)); |
||||
return tmpbuf; |
||||
} |
||||
|
||||
EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "AppMenu" }; |
||||
|
||||
static Eina_Bool |
||||
cb_focus_in(void *data, int type __UNUSED__, void *event) |
||||
{ |
||||
E_AppMenu_Context *ctxt = data; |
||||
E_Event_Border_Focus_In *ev = event; |
||||
Eina_List *l; |
||||
E_AppMenu_Window *w, *found = NULL; |
||||
ctxt->window_with_focus = ev->border->client.win; |
||||
|
||||
EINA_LIST_FOREACH(ctxt->windows, l, w) |
||||
{ |
||||
if (w->window_id == ev->border->client.win) |
||||
{ |
||||
found = w; |
||||
break; |
||||
} |
||||
} |
||||
appmenu_menu_render(ctxt, found); |
||||
return EINA_TRUE; |
||||
} |
||||
|
||||
static Eina_Bool |
||||
cb_focus_out(void *data, int type __UNUSED__, void *event EINA_UNUSED) |
||||
{ |
||||
E_AppMenu_Context *ctxt = data; |
||||
appmenu_menu_render(ctxt, NULL); |
||||
return EINA_TRUE; |
||||
} |
||||
|
||||
static const E_Gadcon_Client_Class _gc_class = |
||||
{ |
||||
GADCON_CLIENT_CLASS_VERSION, "appmenu", |
||||
{ |
||||
_gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL, |
||||
e_gadcon_site_is_not_toolbar |
||||
}, |
||||
E_GADCON_CLIENT_STYLE_PLAIN |
||||
}; |
||||
|
||||
EAPI void * |
||||
e_modapi_init(E_Module *m) |
||||
{ |
||||
E_AppMenu_Context *ctxt; |
||||
Ecore_Event_Handler *event; |
||||
|
||||
ctxt = calloc(1, sizeof(E_AppMenu_Context)); |
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctxt, NULL); |
||||
|
||||
appmenu_module = m; |
||||
|
||||
edbus_init(); |
||||
ctxt->conn = edbus_connection_get(EDBUS_CONNECTION_TYPE_SESSION); |
||||
appmenu_dbus_registrar_server_init(ctxt); |
||||
|
||||
event = ecore_event_handler_add(E_EVENT_BORDER_FOCUS_IN, cb_focus_in, ctxt); |
||||
ctxt->events[0] = event; |
||||
event = ecore_event_handler_add(E_EVENT_BORDER_FOCUS_OUT, cb_focus_out, ctxt); |
||||
ctxt->events[1] = event; |
||||
|
||||
e_gadcon_provider_register(&_gc_class); |
||||
|
||||
return ctxt; |
||||
} |
||||
|
||||
EAPI int |
||||
e_modapi_save(E_Module *m EINA_UNUSED) |
||||
{ |
||||
return 1; |
||||
} |
||||
|
||||
EAPI int |
||||
e_modapi_shutdown(E_Module *m) |
||||
{ |
||||
E_AppMenu_Context *ctxt = m->data; |
||||
E_AppMenu_Window *w; |
||||
Eina_List *l, *l2; |
||||
|
||||
ecore_event_handler_del(ctxt->events[0]); |
||||
ecore_event_handler_del(ctxt->events[1]); |
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctxt, 0); |
||||
EINA_LIST_FOREACH_SAFE(ctxt->windows, l, l2, w) |
||||
appmenu_window_free(w); |
||||
|
||||
edbus_service_interface_unregister(ctxt->iface); |
||||
edbus_connection_unref(ctxt->conn); |
||||
edbus_shutdown(); |
||||
free(ctxt); |
||||
return 1; |
||||
} |
||||
|
||||
void |
||||
appmenu_window_free(E_AppMenu_Window *window) |
||||
{ |
||||
window->ctxt->windows = eina_list_remove(window->ctxt->windows, window); |
||||
e_dbusmenu_unload(window->dbus_menu); |
||||
edbus_name_owner_changed_callback_del(window->ctxt->conn, window->bus_id, |
||||
appmenu_application_monitor, window); |
||||
eina_stringshare_del(window->bus_id); |
||||
eina_stringshare_del(window->path); |
||||
free(window); |
||||
} |
@ -0,0 +1,6 @@ |
||||
[Desktop Entry] |
||||
Type=Link |
||||
Name=Application Menu |
||||
Icon=e-module-appmenu |
||||
Comment=Gadget that hold the toolbar of the foreground application. |
||||
X-Enlightenment-ModuleType=utils |
Loading…
Reference in new issue