diff --git a/src/modules/conf_randr/e_smart_monitor.c b/src/modules/conf_randr/e_smart_monitor.c index 40ec58785..4e8533584 100644 --- a/src/modules/conf_randr/e_smart_monitor.c +++ b/src/modules/conf_randr/e_smart_monitor.c @@ -13,6 +13,9 @@ struct _E_Smart_Data /* object geometry */ Evas_Coord x, y, w, h; + /* object geometry before move started */ + Evas_Coord mx, my, mw, mh; + /* visible flag */ Eina_Bool visible : 1; @@ -340,6 +343,31 @@ e_smart_monitor_crtc_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y /* } */ } +void +e_smart_monitor_move_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h) +{ + E_Smart_Data *sd; + + if (!(sd = evas_object_smart_data_get(obj))) + return; + + if (x) *x = sd->mx; + if (y) *y = sd->my; + if (w) *w = sd->mw; + if (h) *h = sd->mh; +} + +Eina_Bool +e_smart_monitor_moving_get(Evas_Object *obj) +{ + E_Smart_Data *sd; + + if (!(sd = evas_object_smart_data_get(obj))) + return EINA_FALSE; + + return sd->moving; +} + /* local functions */ static void _e_smart_add(Evas_Object *obj) @@ -858,6 +886,9 @@ _e_smart_cb_thumb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj man = e_manager_current_get(); e_pointer_type_push(man->pointer, obj, "move"); + /* record this monitors geometry before moving */ + e_layout_child_geometry_get(mon, &sd->mx, &sd->my, &sd->mw, &sd->mh); + /* update moving state */ sd->moving = EINA_TRUE; @@ -1131,9 +1162,10 @@ _e_smart_monitor_move(E_Smart_Data *sd, Evas_Object *mon, void *event) /* actually move the monitor */ if ((gx != nx) || (gy != ny)) - e_layout_child_move(mon, nx, ny); - - /* evas_object_smart_callback_call(mon, "monitor_moved", NULL); */ + { + e_layout_child_move(mon, nx, ny); + evas_object_smart_callback_call(mon, "monitor_moved", NULL); + } /* Hmm, this below code worked also ... and seems lighter. * but the above code seems more "proper". diff --git a/src/modules/conf_randr/e_smart_monitor.h b/src/modules/conf_randr/e_smart_monitor.h index dc379fc64..99602b3bf 100644 --- a/src/modules/conf_randr/e_smart_monitor.h +++ b/src/modules/conf_randr/e_smart_monitor.h @@ -7,6 +7,8 @@ void e_smart_monitor_layout_set(Evas_Object *obj, Evas_Object *layout); void e_smart_monitor_crtc_set(Evas_Object *obj, E_Randr_Crtc_Info *crtc); E_Randr_Crtc_Info *e_smart_monitor_crtc_get(Evas_Object *obj); void e_smart_monitor_crtc_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); +void e_smart_monitor_move_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h); +Eina_Bool e_smart_monitor_moving_get(Evas_Object *obj); # define E_SMART_MONITOR_H # endif diff --git a/src/modules/conf_randr/e_smart_randr.c b/src/modules/conf_randr/e_smart_randr.c index 6f97572ee..295ed3adb 100644 --- a/src/modules/conf_randr/e_smart_randr.c +++ b/src/modules/conf_randr/e_smart_randr.c @@ -29,6 +29,7 @@ static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip); static void _e_smart_clip_unset(Evas_Object *obj); static void _e_smart_reconfigure(E_Smart_Data *sd); static void _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj); +static void _e_smart_randr_layout_reposition(E_Smart_Data *sd, Evas_Object *obj); static void _e_smart_cb_monitor_resized(void *data, Evas_Object *obj, void *event __UNUSED__); static void _e_smart_cb_monitor_rotated(void *data, Evas_Object *obj, void *event __UNUSED__); @@ -76,6 +77,8 @@ e_smart_randr_monitor_add(Evas_Object *obj, Evas_Object *mon) if (!(sd = evas_object_smart_data_get(obj))) return; + printf("Adding Monitor Object: %p\n", mon); + /* tell monitor what layout it is in */ e_smart_monitor_layout_set(mon, sd->o_layout); @@ -252,6 +255,8 @@ _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj) if (!sd) return; +#define RESISTANCE_THRESHOLD 5 + /* get the geometry of this monitor */ e_layout_child_geometry_get(obj, &o.x, &o.y, &o.w, &o.h); @@ -285,7 +290,8 @@ _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj) { /* they intersect, we need to move this one */ /* NB: This can happen when monitors get moved manually */ - if ((m.x < (o.x + o.w))) + + if ((m.x <= (o.x + o.w))) e_layout_child_move(mon, (o.x + o.w), m.y); else if ((m.y <= (o.y + o.h))) e_layout_child_move(mon, m.x, (o.y + o.h)); @@ -296,6 +302,53 @@ _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj) e_layout_thaw(sd->o_layout); } +static void +_e_smart_randr_layout_reposition(E_Smart_Data *sd, Evas_Object *obj) +{ + Eina_List *l = NULL; + Evas_Object *mon; + Eina_Rectangle o; + Evas_Coord mx, my; + + if (!sd) return; + + /* get this monitor geometry Before it was moved + * + * NB: This is returned in Virtual coordinates */ + e_smart_monitor_move_geometry_get(obj, &mx, &my, NULL, NULL); + + /* get the geometry of this monitor */ + evas_object_geometry_get(obj, &o.x, &o.y, &o.w, &o.h); + + /* freeze layout */ + e_layout_freeze(sd->o_layout); + + /* find any monitors that this one intersects with */ + EINA_LIST_FOREACH(sd->items, l, mon) + { + Eina_Rectangle m; + + /* skip if it's the current monitor */ + if ((mon == obj)) continue; + + /* get the geometry of this monitor */ + evas_object_geometry_get(mon, &m.x, &m.y, &m.w, &m.h); + + if (eina_rectangles_intersect(&o, &m)) + { + /* if these 2 monitors intersect, we need to move the second one + * as the user is currently moving the first one + * + * NB: Currently, this will move This monitor to the + * position of the old one. This is probably not ideal */ + e_layout_child_move(mon, mx, my); + } + } + + /* thaw layout to allow redraw */ + e_layout_thaw(sd->o_layout); +} + /* callback received from the monitor object to let us know that it was * resized, and we should adjust position of any adjacent monitors */ static void @@ -321,9 +374,18 @@ _e_smart_cb_monitor_rotated(void *data, Evas_Object *obj, void *event __UNUSED__ /* callback received from the monitor object to let us know that it was * moved, and we should adjust position of any adjacent monitors */ static void -_e_smart_cb_monitor_moved(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) +_e_smart_cb_monitor_moved(void *data, Evas_Object *obj, void *event __UNUSED__) { - printf("Monitor Moved\n"); + E_Smart_Data *sd; + + if (!(sd = data)) return; + +// printf("Monitor Moved: %p\n", obj); + + if (e_smart_monitor_moving_get(obj)) + _e_smart_randr_layout_reposition(sd, obj); + else + _e_smart_randr_layout_adjust(sd, obj); } /* callback received from the monitor object to let us know that it was