diff --git a/src/bin/e_int_menus.c b/src/bin/e_int_menus.c index 5bf7fce7c..0a33fb211 100644 --- a/src/bin/e_int_menus.c +++ b/src/bin/e_int_menus.c @@ -31,6 +31,8 @@ static void _e_int_menus_apps_start (void *data, E_Menu *m); static void _e_int_menus_apps_del_hook (void *obj); static void _e_int_menus_apps_free_hook (void *obj); static void _e_int_menus_apps_run (void *data, E_Menu *m, E_Menu_Item *mi); +static void _e_int_menus_config_pre_cb (void *data, E_Menu *m); +static void _e_int_menus_config_free_hook (void *obj); static void _e_int_menus_clients_pre_cb (void *data, E_Menu *m); static void _e_int_menus_clients_free_hook (void *obj); static void _e_int_menus_clients_item_cb (void *data, E_Menu *m, E_Menu_Item *mi); @@ -48,10 +50,14 @@ static void _e_int_menus_themes_edit_mode_cb (void *data, E_Menu *m, E_Menu_Item static void _e_int_menus_lost_clients_pre_cb (void *data, E_Menu *m); static void _e_int_menus_lost_clients_free_hook (void *obj); static void _e_int_menus_lost_clients_item_cb (void *data, E_Menu *m, E_Menu_Item *mi); +static void _e_int_menus_augmentation_add (E_Menu *m, Evas_List *augmentation); +static void _e_int_menus_augmentation_del (E_Menu *m, Evas_List *augmentation); /* local subsystem globals */ static Ecore_Job *_e_int_menus_quit_job = NULL; +static Evas_Hash *_e_int_menus_augmentation = NULL; + /* externally accessible functions */ E_Menu * e_int_menus_main_new(void) @@ -134,7 +140,7 @@ e_int_menus_main_new(void) e_menu_item_callback_set(mi, _e_int_menus_main_run, NULL); } - subm = e_int_menus_config_apps_new(); + subm = e_int_menus_config_new(); dat->config = subm; mi = e_menu_item_new(m); e_menu_item_label_set(mi, _("Configuration")); @@ -200,13 +206,13 @@ e_int_menus_favorite_apps_new(void) } E_Menu * -e_int_menus_config_apps_new(void) +e_int_menus_config_new(void) { E_Menu *m; - char buf[4096]; - snprintf(buf, sizeof(buf), "%s/config-apps", e_prefix_data_get()); - m = e_int_menus_apps_new(buf); + m = e_menu_new(); + e_menu_pre_activate_callback_set(m, _e_int_menus_config_pre_cb, NULL); + return m; } @@ -250,6 +256,53 @@ e_int_menus_lost_clients_new(void) return m; } +E_Int_Menu_Augmentation * +e_int_menus_menu_augmentation_add(const char *menu, + void (*func_add) (void *data, E_Menu *m), + void *data_add, + void (*func_del) (void *data, E_Menu *m), + void *data_del) +{ + E_Int_Menu_Augmentation *maug; + Evas_List *l; + + maug = E_NEW(E_Int_Menu_Augmentation, 1); + if (!maug) return NULL; + + maug->add.func = func_add; + maug->add.data = data_add; + + maug->del.func = func_del; + maug->del.data = data_del; + + l = evas_hash_find(_e_int_menus_augmentation, menu); + l = evas_list_append(l, maug); + _e_int_menus_augmentation = evas_hash_add(_e_int_menus_augmentation, menu, l); + + return maug; +} + +void +e_int_menus_menu_augmentation_del(const char *menu, E_Int_Menu_Augmentation *maug) +{ + Evas_List *l; + + l = evas_hash_find(_e_int_menus_augmentation, menu); + if (l) + { + /* + * We should always add the list to the hash, in case the list + * becomes empty, or the first element is removed. + */ + _e_int_menus_augmentation = evas_hash_del(_e_int_menus_augmentation, menu, l); + + l = evas_list_remove(l, maug); + if (l) + _e_int_menus_augmentation = evas_hash_add(_e_int_menus_augmentation, menu, l); + } + free(maug); +} + /* local subsystem functions */ static void _e_int_menus_quit(void) @@ -510,6 +563,44 @@ _e_int_menus_desktops_item_cb(void *data, E_Menu *m, E_Menu_Item *mi) e_desk_show(desk); } +static void +_e_int_menus_config_pre_cb(void *data, E_Menu *m) +{ + E_Menu *subm; + E_Menu_Item *mi; + char buf[4096]; + + e_menu_pre_activate_callback_set(m, NULL, NULL); + + snprintf(buf, sizeof(buf), "%s/config-apps", e_prefix_data_get()); + subm = e_int_menus_apps_new(buf); + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Applications")); + e_menu_item_submenu_set(mi, subm); + + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + + _e_int_menus_augmentation_add(m, evas_hash_find(_e_int_menus_augmentation, "config")); + + e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_config_free_hook); + e_object_data_set(E_OBJECT(m), subm); +} + +static void +_e_int_menus_config_free_hook(void *obj) +{ + E_Menu *m, *subm; + + m = obj; + subm = e_object_data_get(E_OBJECT(obj)); + if (subm) + e_object_del(E_OBJECT(subm)); + + _e_int_menus_augmentation_del(m, evas_hash_find(_e_int_menus_augmentation, "config")); +} + static void _e_int_menus_clients_pre_cb(void *data, E_Menu *m) { @@ -871,3 +962,45 @@ _e_int_menus_lost_clients_item_cb(void *data, E_Menu *m, E_Menu_Item *mi) e_border_raise(bd); e_border_focus_set(bd, 1, 1); } + +static void +_e_int_menus_augmentation_add(E_Menu *m, Evas_List *augmentation) +{ + Evas_List *l; + E_Menu_Item *mi; + int i = 0; + + for (l = augmentation; l; l = l->next) + { + E_Int_Menu_Augmentation *aug; + + aug = l->data; + + if (i) + { + mi = e_menu_item_new(m); + e_menu_item_separator_set(mi, 1); + } + else + i++; + + if (aug->add.func) + aug->add.func(aug->add.data, m); + } +} + +static void +_e_int_menus_augmentation_del(E_Menu *m, Evas_List *augmentation) +{ + Evas_List *l; + + for (l = augmentation; l; l = l->next) + { + E_Int_Menu_Augmentation *aug; + + aug = l->data; + + if (aug->del.func) + aug->del.func(aug->del.data, m); + } +} diff --git a/src/bin/e_int_menus.h b/src/bin/e_int_menus.h index 78b497f22..2b5f39bf6 100644 --- a/src/bin/e_int_menus.h +++ b/src/bin/e_int_menus.h @@ -2,19 +2,38 @@ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #ifdef E_TYPEDEFS + +typedef struct _E_Int_Menu_Augmentation E_Int_Menu_Augmentation; + #else #ifndef E_INT_MENUS_H #define E_INT_MENUS_H +struct _E_Int_Menu_Augmentation +{ + struct { + void (*func)(void *data, E_Menu *m); + void *data; + } add, del; +}; + EAPI E_Menu *e_int_menus_main_new(void); EAPI E_Menu *e_int_menus_desktops_new(void); EAPI E_Menu *e_int_menus_clients_new(void); EAPI E_Menu *e_int_menus_apps_new(char *dir); EAPI E_Menu *e_int_menus_favorite_apps_new(void); -EAPI E_Menu *e_int_menus_config_apps_new(void); +EAPI E_Menu *e_int_menus_config_new(void); EAPI E_Menu *e_int_menus_gadgets_new(void); EAPI E_Menu *e_int_menus_themes_new(void); EAPI E_Menu *e_int_menus_lost_clients_new(void); + +EAPI E_Int_Menu_Augmentation *e_int_menus_menu_augmentation_add(const char *menu, + void (*func_add) (void *data, E_Menu *m), + void *data_add, + void (*func_del) (void *data, E_Menu *m), + void *data_del); +EAPI void e_int_menus_menu_augmentation_del(const char *menu, + E_Int_Menu_Augmentation *maug); #endif #endif diff --git a/src/modules/randr/e_mod_main.c b/src/modules/randr/e_mod_main.c index 3f141e44e..2582a0c2d 100644 --- a/src/modules/randr/e_mod_main.c +++ b/src/modules/randr/e_mod_main.c @@ -4,25 +4,22 @@ #include "e.h" #include "e_mod_main.h" -static Randr *_randr_new(void); -static Randr_Face *_randr_face_new(E_Container *con); -static void _randr_free(Randr *e); -static void _randr_face_free(Randr_Face *face); -static void _randr_face_enable(Randr_Face *e); -static void _randr_face_disable(Randr_Face *e); -static void _randr_config_menu_new(Randr *e); -static void _randr_face_menu_new(Randr_Face *face); -static void _randr_face_menu_resolution_new(Randr_Face *face); -static void _randr_face_cb_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi); -static void _randr_face_post_cb_menu_resolution_change(void *data, E_Menu *m); -static void _randr_face_cb_menu_resolution_change(void *data, E_Menu *m, E_Menu_Item *mi); -static void _randr_face_cb_gmc_change(void *data, E_Gadman_Client *gmc, E_Gadman_Change change); -static void _randr_face_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info); -static int _randr_face_cb_screen_change(void *data, int type, void *event); +/* + * TODO: + * * Check if randr is available. It might be disabled in + * ecore_x, or not available on screen + * * Restore screen res if the user wants it + */ + +static Randr *_randr_new(void); +static void _randr_free(Randr *e); +static void _randr_config_menu_new(Randr *e); +static void _randr_menu_resolution_add(void *data, E_Menu *m); +static void _randr_menu_resolution_del(void *data, E_Menu *m); +static void _randr_menu_cb_store(void *data, E_Menu *m, E_Menu_Item *mi); +static void _randr_menu_cb_resolution_change(void *data, E_Menu *m, E_Menu_Item *mi); -static int button_count; static E_Config_DD *conf_edd; -static E_Config_DD *conf_face_edd; void * e_modapi_init(E_Module *m) @@ -92,171 +89,89 @@ static Randr * _randr_new(void) { Randr *e; - Evas_List *managers, *l, *l2, *cl; - E_Menu_Item *mi; - button_count = 0; e = E_NEW(Randr, 1); if (!e) return NULL; - conf_face_edd = E_CONFIG_DD_NEW("Randr_Config_Face", Config_Face); -#undef T -#undef D -#define T Config_Face -#define D conf_face_edd - E_CONFIG_VAL(D, T, enabled, UCHAR); - conf_edd = E_CONFIG_DD_NEW("Randr_Config", Config); #undef T #undef D #define T Config #define D conf_edd - E_CONFIG_LIST(D, T, faces, conf_face_edd); + E_CONFIG_VAL(D, T, store, INT); + E_CONFIG_VAL(D, T, width, INT); + E_CONFIG_VAL(D, T, height, INT); e->conf = e_config_domain_load("module.randr", conf_edd); if (!e->conf) e->conf = E_NEW(Config, 1); _randr_config_menu_new(e); - - managers = e_manager_list(); - cl = e->conf->faces; - for (l = managers; l; l = l->next) - { - E_Manager *man; - - man = l->data; - for (l2 = man->containers; l2; l2 = l2->next) - { - E_Container *con; - Randr_Face *face; - - con = l2->data; - face = _randr_face_new(con); - if (face) - { - ecore_x_randr_events_select(con->bg_win, 1); - e->faces = evas_list_append(e->faces, face); - /* Config */ - if (!cl) - { - face->conf = E_NEW(Config_Face, 1); - face->conf->enabled = 1; - e->conf->faces = evas_list_append(e->conf->faces, face->conf); - } - else - { - face->conf = cl->data; - cl = cl->next; - } - - /* Menu */ - /* This menu must be initialized after conf */ - _randr_face_menu_new(face); - - mi = e_menu_item_new(e->config_menu); - e_menu_item_label_set(mi, con->name); - - e_menu_item_submenu_set(mi, face->config_menu); - - /* Setup */ - if (!face->conf->enabled) _randr_face_disable(face); - } - } - } + + e->augmentation = e_int_menus_menu_augmentation_add("config", + _randr_menu_resolution_add, e, + _randr_menu_resolution_del, e); + return e; } -static Randr_Face * -_randr_face_new(E_Container *con) +static void +_randr_free(Randr *e) { - Randr_Face *face; - Evas_Object *o; + E_CONFIG_DD_FREE(conf_edd); - face = E_NEW(Randr_Face, 1); - if (!face) return NULL; + e_object_del(E_OBJECT(e->config_menu)); + if (e->resolution_menu) + e_object_del(E_OBJECT(e->resolution_menu)); - face->con = con; - e_object_ref(E_OBJECT(con)); - - evas_event_freeze(con->bg_evas); - o = edje_object_add(con->bg_evas); - face->button_object = o; - - e_theme_edje_object_set(o, "base/theme/modules/randr", "modules/randr/main"); - edje_object_signal_emit(o, "passive", ""); - evas_object_show(o); - - o = evas_object_rectangle_add(con->bg_evas); - face->event_object = o; - evas_object_layer_set(o, 2); - evas_object_repeat_events_set(o, 1); - evas_object_color_set(o, 0, 0, 0, 0); - evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _randr_face_cb_mouse_down, face); - evas_object_show(o); - - face->gmc = e_gadman_client_new(con->gadman); - e_gadman_client_domain_set(face->gmc, "module.randr", button_count++); - e_gadman_client_policy_set(face->gmc, - E_GADMAN_POLICY_ANYWHERE | - E_GADMAN_POLICY_HMOVE | - E_GADMAN_POLICY_VMOVE | - E_GADMAN_POLICY_HSIZE | - E_GADMAN_POLICY_VSIZE); - e_gadman_client_min_size_set(face->gmc, 4, 4); - e_gadman_client_max_size_set(face->gmc, 512, 512); - e_gadman_client_auto_size_set(face->gmc, 40, 40); - e_gadman_client_align_set(face->gmc, 0.0, 1.0); - e_gadman_client_aspect_set(face->gmc, 1.0, 1.0); - e_gadman_client_resize(face->gmc, 40, 40); - e_gadman_client_change_func_set(face->gmc, _randr_face_cb_gmc_change, face); - e_gadman_client_load(face->gmc); - - evas_event_thaw(con->bg_evas); - - face->randr_handler = ecore_event_handler_add(ECORE_X_EVENT_SCREEN_CHANGE, - _randr_face_cb_screen_change, - face); - return face; + e_int_menus_menu_augmentation_del("config", e->augmentation); + free(e->conf); + free(e); } static void -_randr_face_menu_new(Randr_Face *face) +_randr_config_menu_new(Randr *e) { - E_Menu *mn; + E_Menu *m; E_Menu_Item *mi; - - mn = e_menu_new(); - face->config_menu = mn; - - /* Enabled */ - /* - mi = e_menu_item_new(mn); - e_menu_item_label_set(mi, _("Enabled")); - e_menu_item_check_set(mi, 1); - if (face->conf->enabled) e_menu_item_toggle_set(mi, 1); - e_menu_item_callback_set(mi, _clock_face_cb_menu_enabled, face); - */ - - /* Edit */ - mi = e_menu_item_new(mn); - e_menu_item_label_set(mi, _("Edit Mode")); - e_menu_item_callback_set(mi, _randr_face_cb_menu_edit, face); + + m = e_menu_new(); + e->config_menu = m; + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Store")); + e_menu_item_check_set(mi, 1); + e_menu_item_toggle_set(mi, e->conf->store); + e_menu_item_callback_set(mi, _randr_menu_cb_store, e); } static void -_randr_face_menu_resolution_new(Randr_Face *face) +_randr_menu_resolution_add(void *data, E_Menu *m) { - E_Menu *mn; + E_Manager *man; + Randr *e; + E_Menu *subm, *root; E_Menu_Item *mi; Ecore_X_Screen_Size *sizes; Ecore_X_Screen_Size size; int i, n; - mn = e_menu_new(); - face->resolution_menu = mn; + e = data; - sizes = ecore_x_randr_screen_sizes_get(face->con->manager->root, &n); - size = ecore_x_randr_current_screen_size_get(face->con->manager->root); + subm = e_menu_new(); + e->resolution_menu = subm; + + mi = e_menu_item_new(m); + e_menu_item_label_set(mi, _("Resolution")); + e_menu_item_submenu_set(mi, subm); + + root = e_menu_root_get(m); + if (!root->zone) + man = e_manager_current_get(); + else + man = root->zone->container->manager; + + sizes = ecore_x_randr_screen_sizes_get(man->root, &n); + size = ecore_x_randr_current_screen_size_get(man->root); if (sizes) { char buf[16]; @@ -264,176 +179,51 @@ _randr_face_menu_resolution_new(Randr_Face *face) for (i = 0; i < n; i++) { snprintf(buf, sizeof(buf), "%dx%d", sizes[i].width, sizes[i].height); - mi = e_menu_item_new(mn); + mi = e_menu_item_new(subm); e_menu_item_radio_set(mi, 1); e_menu_item_radio_group_set(mi, 1); if ((sizes[i].width == size.width) && (sizes[i].height == size.height)) e_menu_item_toggle_set(mi, 1); e_menu_item_label_set(mi, buf); - e_menu_item_callback_set(mi, _randr_face_cb_menu_resolution_change, face); + e_menu_item_callback_set(mi, _randr_menu_cb_resolution_change, e); } free(sizes); } } static void -_randr_free(Randr *e) +_randr_menu_resolution_del(void *data, E_Menu *m) { - Evas_List *list; - - E_CONFIG_DD_FREE(conf_edd); - E_CONFIG_DD_FREE(conf_face_edd); - - for (list = e->faces; list; list = list->next) - _randr_face_free(list->data); - evas_list_free(e->faces); - - e_object_del(E_OBJECT(e->config_menu)); - - evas_list_free(e->conf->faces); - free(e->conf); - free(e); -} + Randr *e; -static void -_randr_face_free(Randr_Face *face) -{ - e_object_unref(E_OBJECT(face->con)); - e_object_del(E_OBJECT(face->gmc)); - evas_object_del(face->button_object); - evas_object_del(face->event_object); - e_object_del(E_OBJECT(face->config_menu)); - if (face->resolution_menu) e_object_del(E_OBJECT(face->resolution_menu)); - ecore_event_handler_del(face->randr_handler); - - free(face->conf); - free(face); - button_count--; -} - -static void -_randr_config_menu_new(Randr *e) -{ - e->config_menu = e_menu_new(); -} - -static void -_randr_face_disable(Randr_Face *e) -{ - e->conf->enabled = 0; - evas_object_hide(e->button_object); - evas_object_hide(e->event_object); - e_config_save_queue(); -} - -static void -_randr_face_enable(Randr_Face *e) -{ - e->conf->enabled = 1; - evas_object_show(e->button_object); - evas_object_show(e->event_object); - e_config_save_queue(); -} - -static void -_randr_face_cb_gmc_change(void *data, E_Gadman_Client *gmc, E_Gadman_Change change) -{ - Randr_Face *e; - Evas_Coord x, y, w, h; - e = data; - switch (change) + + if (e->resolution_menu) { - case E_GADMAN_CHANGE_MOVE_RESIZE: - e_gadman_client_geometry_get(e->gmc, &x, &y, &w, &h); - evas_object_move(e->button_object, x, y); - evas_object_move(e->event_object, x, y); - evas_object_resize(e->button_object, w, h); - evas_object_resize(e->event_object, w, h); - break; - case E_GADMAN_CHANGE_RAISE: - evas_object_raise(e->button_object); - evas_object_raise(e->event_object); - break; - case E_GADMAN_CHANGE_EDGE: - case E_GADMAN_CHANGE_ZONE: - /* FIXME: Must we do something here? */ - break; + e_object_del(E_OBJECT(e->resolution_menu)); + e->resolution_menu = NULL; } } static void -_randr_face_cb_menu_edit(void *data, E_Menu *m, E_Menu_Item *mi) +_randr_menu_cb_store(void *data, E_Menu *m, E_Menu_Item *mi) { - Randr_Face *face; - - face = data; - e_gadman_mode_set(face->gmc->gadman, E_GADMAN_MODE_EDIT); + Randr *e; + + e = data; + e->conf->store = e_menu_item_toggle_get(mi); } static void -_randr_face_post_cb_menu_resolution_change(void *data, E_Menu *m) +_randr_menu_cb_resolution_change(void *data, E_Menu *m, E_Menu_Item *mi) { - Randr_Face *face; - - face = data; - e_object_del(E_OBJECT(face->resolution_menu)); - face->resolution_menu = NULL; - edje_object_signal_emit(face->button_object, "passive", ""); -} - -static void -_randr_face_cb_menu_resolution_change(void *data, E_Menu *m, E_Menu_Item *mi) -{ - Randr_Face *face; + Randr *e; Ecore_X_Screen_Size size; - face = data; + e = data; if (sscanf(mi->label, "%dx%d", &size.width, &size.height) != 2) return; - ecore_x_randr_screen_size_set(face->con->manager->root, size); -} - -static void -_randr_face_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) -{ - Randr_Face *face; - Evas_Event_Mouse_Down *ev; - - face = data; - ev = event_info; - if (ev->button == 3) - { - e_menu_activate_mouse(face->config_menu, e_zone_current_get(face->con), - ev->output.x, ev->output.y, 1, 1, - E_MENU_POP_DIRECTION_AUTO, ev->timestamp); - e_util_container_fake_mouse_up_all_later(face->con); - } - else if (ev->button == 1) - { - Evas_Coord x, y, w, h; - - _randr_face_menu_resolution_new(face); - e_menu_post_deactivate_callback_set(face->resolution_menu, - _randr_face_post_cb_menu_resolution_change, - face); - e_gadman_client_geometry_get(face->gmc, &x, &y, &w, &h); - e_menu_activate_mouse(face->resolution_menu, e_zone_current_get(face->con), - x, y, w, h, - E_MENU_POP_DIRECTION_AUTO, ev->timestamp); - e_util_container_fake_mouse_up_all_later(face->con); - edje_object_signal_emit(face->button_object, "active", ""); - } -} - -static int -_randr_face_cb_screen_change(void *data, int type, void *event) -{ - Randr_Face *face; - Ecore_X_Event_Screen_Change *ev; - - face = data; - ev = event; - if (ev->win != face->con->bg_win) return 1; - printf("res: %dx%d\n", ev->width, ev->height); - return 1; + ecore_x_randr_screen_size_set(m->zone->container->manager->root, size); + + e->conf->width = size.width; + e->conf->height = size.height; } diff --git a/src/modules/randr/e_mod_main.h b/src/modules/randr/e_mod_main.h index b03dace3e..4a0dc5752 100644 --- a/src/modules/randr/e_mod_main.h +++ b/src/modules/randr/e_mod_main.h @@ -5,42 +5,23 @@ #define E_MOD_MAIN_H typedef struct _Config Config; -typedef struct _Config_Face Config_Face; typedef struct _Randr Randr; -typedef struct _Randr_Face Randr_Face; struct _Config { - Evas_List *faces; -}; - -struct _Config_Face -{ - unsigned char enabled; + int store; + int width; + int height; }; struct _Randr { - Evas_List *faces; - E_Menu *config_menu; - - Config *conf; -}; - -struct _Randr_Face -{ - E_Container *con; E_Menu *config_menu; E_Menu *resolution_menu; - Config_Face *conf; - - Evas_Object *button_object; - Evas_Object *event_object; + E_Int_Menu_Augmentation *augmentation; - Ecore_Event_Handler *randr_handler; - - E_Gadman_Client *gmc; + Config *conf; }; EAPI void *e_modapi_init (E_Module *m);