enlightenment/src/bin/e_gadcon_popup.c

258 lines
6.6 KiB
C
Raw Normal View History

#include "e.h"
/* local subsystem functions */
static void _e_gadcon_popup_free(E_Gadcon_Popup *pop);
static void _e_gadcon_popup_locked_set(E_Gadcon_Popup *pop, Eina_Bool locked);
static void _e_gadcon_popup_size_recalc(E_Gadcon_Popup *pop, Evas_Object *obj);
static void _e_gadcon_popup_position(E_Gadcon_Popup *pop);
static void _e_gadcon_popup_changed_size_hints_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
/* externally accessible functions */
EAPI E_Gadcon_Popup *
e_gadcon_popup_new(E_Gadcon_Client *gcc)
{
E_Gadcon_Popup *pop;
Evas_Object *o;
2007-11-16 14:27:35 -08:00
E_Zone *zone;
pop = E_OBJECT_ALLOC(E_Gadcon_Popup, E_GADCON_POPUP_TYPE, _e_gadcon_popup_free);
if (!pop) return NULL;
zone = e_gadcon_client_zone_get(gcc);
2007-11-16 14:27:35 -08:00
pop->win = e_popup_new(zone, 0, 0, 0, 0);
e_popup_layer_set(pop->win, E_LAYER_POPUP);
o = edje_object_add(pop->win->evas);
e_theme_edje_object_set(o, "base/theme/gadman", "e/gadman/popup");
evas_object_show(o);
evas_object_move(o, 0, 0);
e_popup_edje_bg_object_set(pop->win, o);
pop->o_bg = o;
pop->gcc = gcc;
pop->gadcon_lock = 1;
pop->gadcon_was_locked = 0;
return pop;
}
EAPI void
e_gadcon_popup_content_set(E_Gadcon_Popup *pop, Evas_Object *o)
{
Evas_Object *old_o;
if (!pop) return;
E_OBJECT_CHECK(pop);
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
old_o = edje_object_part_swallow_get(pop->o_bg, "e.swallow.content");
if (old_o != o)
{
2012-06-26 04:35:45 -07:00
if (old_o)
{
edje_object_part_unswallow(pop->o_bg, old_o);
evas_object_del(old_o);
}
edje_object_part_swallow(pop->o_bg, "e.swallow.content", o);
evas_object_event_callback_add(o, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
_e_gadcon_popup_changed_size_hints_cb, pop);
}
_e_gadcon_popup_size_recalc(pop, o);
}
EAPI void
e_gadcon_popup_show(E_Gadcon_Popup *pop)
{
if (!pop) return;
E_OBJECT_CHECK(pop);
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
if (pop->win->visible) return;
e_popup_show(pop->win);
_e_gadcon_popup_position(pop);
}
EAPI void
e_gadcon_popup_hide(E_Gadcon_Popup *pop)
{
if (!pop) return;
E_OBJECT_CHECK(pop);
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
if (pop->pinned) return;
e_popup_hide(pop->win);
if (pop->gadcon_was_locked)
_e_gadcon_popup_locked_set(pop, 0);
}
EAPI void
e_gadcon_popup_toggle_pinned(E_Gadcon_Popup *pop)
{
if (!pop) return;
E_OBJECT_CHECK(pop);
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
if (pop->pinned)
{
2012-06-26 04:35:45 -07:00
pop->pinned = 0;
edje_object_signal_emit(pop->o_bg, "e,state,unpinned", "e");
}
else
{
2012-06-26 04:35:45 -07:00
pop->pinned = 1;
edje_object_signal_emit(pop->o_bg, "e,state,pinned", "e");
}
}
EAPI void
e_gadcon_popup_lock_set(E_Gadcon_Popup *pop, Eina_Bool setting)
{
if (!pop) return;
E_OBJECT_CHECK(pop);
E_OBJECT_TYPE_CHECK(pop, E_GADCON_POPUP_TYPE);
setting = !!setting;
if (pop->gadcon_lock == setting) return;
pop->gadcon_lock = setting;
if (setting != pop->gadcon_was_locked)
_e_gadcon_popup_locked_set(pop, setting);
}
/* local subsystem functions */
static void
_e_gadcon_popup_free(E_Gadcon_Popup *pop)
{
if (pop->gadcon_was_locked)
_e_gadcon_popup_locked_set(pop, 0);
pop->gcc = NULL;
e_object_del(E_OBJECT(pop->win));
free(pop);
}
static void
_e_gadcon_popup_locked_set(E_Gadcon_Popup *pop, Eina_Bool locked)
{
if (!pop->gcc)
return;
e_gadcon_locked_set(pop->gcc->gadcon, locked);
pop->gadcon_was_locked = locked;
}
static void
_e_gadcon_popup_size_recalc(E_Gadcon_Popup *pop, Evas_Object *obj)
{
Evas_Coord w = 0, h = 0;
e_widget_size_min_get(obj, &w, &h);
if ((!w) || (!h)) evas_object_size_hint_min_get(obj, &w, &h);
if ((!w) || (!h))
{
2012-06-26 04:35:45 -07:00
edje_object_size_min_get(obj, &w, &h);
edje_object_size_min_restricted_calc(obj, &w, &h, w, h);
}
edje_extern_object_min_size_set(obj, w, h);
edje_object_size_min_calc(pop->o_bg, &pop->w, &pop->h);
evas_object_resize(pop->o_bg, pop->w, pop->h);
if (pop->win->visible)
_e_gadcon_popup_position(pop);
}
static void
_e_gadcon_popup_position(E_Gadcon_Popup *pop)
{
Dear all, I'm attaching a patch for some minor bugs in the e17. Please take a look at attached patch. 01. missing E_FREE(inst) File: src/bin/e_exec.c: 347 Function: _e_exec_cb_exec 02. missing null check File: src/bin/e_fm.c: 10173 Function: _e_fm_error_dialog I'm not sure, but all other codes always check the return value of e_fm2_op_registry_entry_get except here. 03. missing free(slave) File: src/bin/e_fm_ipc.c: 804 Function: _e_fm_ipc_slave_run 04. eina_list_remove after free File: src/bin/e_fm/e_fm_ipc.c :1325 Function: _e_fm_ipc_cb_fop_trash_idler 05. invalid check for _udisks_del, it might be _udisks_chg. File: src/bin/e_fm/e_fm_main_udisks.c : 162 Function: _e_fm_main_udisks_test 06. uninitialized gx and gy values File: src/bin/e_gadcon_popup.c: 172 Function: _e_gadcon_popup_position These could be changed in e_gadcon_client_geometry_get if gcc->o_base is null. 07. unnecessary code 'evas = e_win_evas_get(dia->win)' File: src/bin/e_import_config_dialog.c: 456 Function: e_import_config_dialog_show 08. missing free(sizes) src/bin/e_randr_11_serialization.c: 136 Function: _11_try_restore_configuration() 09. unnecessary variable output_info File: src/bin/e_randr_12.c: 560 Function: _output_property_change_event_cb 10. eina_list_remove after free File: src/bin/e_randr_12_serialization.c : 357 Function: _12_serialized_setup_update 11. no check of the return value of symlink. File: src/bin/e_widget_fsel.c: 84 Function: _e_wid_fsel_favorites_add 12. no evr->var check before comparing string values File: src/modules/conf_applications/e_int_config_defapps.c: 432 Function: _basic_apply 13. missing error message or check return value of edje_file_group_exists File: src/modules/conf_theme/e_int_config_theme.c: 333 Function: _open_test_cb Anyway, I've added e_util_dialog_show if failed. Is it okay? 14. missing index range check File: src/modules/gadman/e_mod_config.c: 153 Function: _cb_config It could read negative array index, because return value of e_widget_ilist_selected_get might be negative. BR, Gwanglim SVN revision: 80020
2012-12-02 23:54:07 -08:00
Evas_Coord gx = 0, gy = 0, gw, gh, zw, zh, zx, zy, px, py;
/* Popup positioning */
e_gadcon_client_geometry_get(pop->gcc, &gx, &gy, &gw, &gh);
fix bugs of gadgets using incorrect zones. I found strange behavior in my configuration (xinerama - two screens with two zones). When i select a Enlightenment->Restart from menu the popups for gadgets on desktop doesn't appear or appear wrongly. After some time i've found that this depends on on from what screen i am choosing this enlightenment->restart :) After some debugging i figured it out: When restarting enlightenment some gadgets (i.e. calendar) are calling e_gadgon_popup_new(). Inside that function, zone for popup window (this zone was used later in ecore_evas_move_resize) is calculated like that: {{{ zone = e_util_zone_current_get(e_manager_current_get()); and in e_manager_current_get is: ecore_x_pointer_xy_get() }}} ... so - i have my answer why restaring from one screen (cursor was on that screen) and from second screen i have different results... In other words: during initializing module like calendar - created zone for popup is assigned depending on current cursor position. In my patch i've chage this to obtain zone using the gadget position instead. But it solves the problem partialy. Next thing - in function: e_gadget_popup_show() (which is called later) when calculating popup position coordinates was calculated using zone: {{{ pop->gcc->gadcon->zone }}} which in my case was always the first (initial) zone - (of course it was wrong, because i put a gadgets on different screens for testing). so i changed it to zone of popup window (which was calculated before, in e_gadgon_popup_new()) and after that everythings works ok :) Zones for popups are correctly assigned and popups calculation are also ok - even after restaring enlightenment (tested with cursor on both screens). By: manio SVN revision: 40927
2009-06-06 16:40:58 -07:00
zx = pop->win->zone->x;
zy = pop->win->zone->y;
zw = pop->win->zone->w;
zh = pop->win->zone->h;
switch (pop->gcc->gadcon->orient)
{
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_RB:
case E_GADCON_ORIENT_RIGHT:
2012-06-26 04:35:45 -07:00
px = gx - pop->w;
py = gy;
if (py + pop->h >= (zy + zh))
py = gy + gh - pop->h;
px = MIN(zx + zw - gw - pop->w - 3, px);
2012-06-26 04:35:45 -07:00
break;
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_LB:
2012-06-26 04:35:45 -07:00
px = gx + gw;
py = gy;
if (py + pop->h >= (zy + zh))
py = gy + gh - pop->h;
px = MIN(zx + zw - gw - pop->w + 3, px);
2012-06-26 04:35:45 -07:00
break;
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
2012-06-26 04:35:45 -07:00
py = gy + gh;
px = (gx + (gw / 2)) - (pop->w / 2);
if ((px + pop->w) >= (zx + zw))
px = gx + gw - pop->w;
else if (px < zx)
px = zx;
py = MIN(zy + zh - gh - pop->h + 3, py);
2012-06-26 04:35:45 -07:00
break;
case E_GADCON_ORIENT_BOTTOM:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
2012-06-26 04:35:45 -07:00
py = gy - pop->h;
px = (gx + (gw / 2)) - (pop->w / 2);
if ((px + pop->w) >= (zx + zw))
px = gx + gw - pop->w;
else if (px < zx)
px = zx;
py = MIN(zy + zh - gh - pop->h - 3, py);
2012-06-26 04:35:45 -07:00
break;
case E_GADCON_ORIENT_FLOAT:
2012-06-26 04:35:45 -07:00
px = (gx + (gw / 2)) - (pop->w / 2);
if (gy >= (zy + (zh / 2)))
py = gy - pop->h;
else
py = gy + gh;
if ((px + pop->w) >= (zx + zw))
px = gx + gw - pop->w;
else if (px < zx)
px = zx;
2012-06-26 04:35:45 -07:00
break;
default:
2012-06-26 04:35:45 -07:00
e_popup_move_resize(pop->win, 50, 50, pop->w, pop->h);
return;
}
if (px - zx < 0)
px = zx;
if (py - zy < 0)
py = zy;
e_popup_move_resize(pop->win, px - zx, py - zy, pop->w, pop->h);
if (pop->gadcon_lock && (!pop->gadcon_was_locked))
_e_gadcon_popup_locked_set(pop, 1);
}
static void
2010-08-18 12:31:31 -07:00
_e_gadcon_popup_changed_size_hints_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
2010-08-18 12:31:31 -07:00
E_Gadcon_Popup *pop;
2010-08-18 12:31:31 -07:00
pop = data;
_e_gadcon_popup_size_recalc(pop, obj);
}
2012-06-26 04:35:45 -07:00