forked from enlightenment/enlightenment
Big giant Monitor Snapping Fix when we resize or move !! ;)
- Add previous monitor geometry to smart data structure. - When we set the crtc, also set the monitor current geometry. - Add function to return the previous monitor geometry. - On a mouse up, check for monitor location difference versus previous geometry, if nothing changed then we have no 'move' to do. - When we start a resize, record the previous geometry and raise the monitor. - When a monitor is moved/resized we call the position_update function which already loops all monitors, so no need to loop them twice. - Fix position_update function to allow some Snapping Fuzziness so that on a move/resize any adjoining monitors (within tolerance) will more reliably snap to each other. Signed-off-by: Chris Michael <cp.michael@samsung.com>
This commit is contained in:
parent
d2a0e36c85
commit
3f2e850259
|
@ -106,6 +106,11 @@ struct _E_Smart_Data
|
||||||
Eina_Bool enabled : 1;
|
Eina_Bool enabled : 1;
|
||||||
} current;
|
} current;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
Evas_Coord x, y, w, h;
|
||||||
|
} prev;
|
||||||
|
|
||||||
/* visibility flag */
|
/* visibility flag */
|
||||||
Eina_Bool visible : 1;
|
Eina_Bool visible : 1;
|
||||||
|
|
||||||
|
@ -236,6 +241,11 @@ e_smart_monitor_crtc_set(Evas_Object *obj, Ecore_X_Randr_Crtc crtc, Evas_Coord c
|
||||||
sd->crtc.w = cw;
|
sd->crtc.w = cw;
|
||||||
sd->crtc.h = ch;
|
sd->crtc.h = ch;
|
||||||
|
|
||||||
|
sd->current.x = cx;
|
||||||
|
sd->current.y = cy;
|
||||||
|
sd->current.w = cw;
|
||||||
|
sd->current.h = ch;
|
||||||
|
|
||||||
/* get the root window */
|
/* get the root window */
|
||||||
root = ecore_x_window_root_first_get();
|
root = ecore_x_window_root_first_get();
|
||||||
|
|
||||||
|
@ -510,6 +520,22 @@ e_smart_monitor_current_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord
|
||||||
if (h) *h = sd->current.h;
|
if (h) *h = sd->current.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
e_smart_monitor_previous_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
|
||||||
|
{
|
||||||
|
E_Smart_Data *sd;
|
||||||
|
|
||||||
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
||||||
|
|
||||||
|
/* try to get the objects smart data */
|
||||||
|
if (!(sd = evas_object_smart_data_get(obj))) return;
|
||||||
|
|
||||||
|
if (x) *x = sd->prev.x;
|
||||||
|
if (y) *y = sd->prev.y;
|
||||||
|
if (w) *w = sd->prev.w;
|
||||||
|
if (h) *h = sd->prev.h;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
e_smart_monitor_clone_set(Evas_Object *obj, Evas_Object *parent)
|
e_smart_monitor_clone_set(Evas_Object *obj, Evas_Object *parent)
|
||||||
{
|
{
|
||||||
|
@ -1600,6 +1626,10 @@ _e_smart_monitor_thumb_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Obje
|
||||||
/* reset mouse pointer */
|
/* reset mouse pointer */
|
||||||
_e_smart_monitor_pointer_pop(obj, "move");
|
_e_smart_monitor_pointer_pop(obj, "move");
|
||||||
|
|
||||||
|
if ((sd->current.x == sd->prev.x) &&
|
||||||
|
(sd->current.y == sd->prev.y))
|
||||||
|
return;
|
||||||
|
|
||||||
/* any objects below this monitor ? */
|
/* any objects below this monitor ? */
|
||||||
if ((below = evas_object_below_get(mon)))
|
if ((below = evas_object_below_get(mon)))
|
||||||
{
|
{
|
||||||
|
@ -1688,8 +1718,8 @@ _e_smart_monitor_thumb_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Ob
|
||||||
|
|
||||||
/* record current size of monitor */
|
/* record current size of monitor */
|
||||||
evas_object_grid_pack_get(sd->grid.obj, mon,
|
evas_object_grid_pack_get(sd->grid.obj, mon,
|
||||||
&sd->current.x, &sd->current.y,
|
&sd->prev.x, &sd->prev.y,
|
||||||
&sd->current.w, &sd->current.h);
|
&sd->prev.w, &sd->prev.h);
|
||||||
|
|
||||||
/* raise the monitor */
|
/* raise the monitor */
|
||||||
evas_object_raise(mon);
|
evas_object_raise(mon);
|
||||||
|
@ -1797,8 +1827,16 @@ _e_smart_monitor_frame_cb_resize_start(void *data, Evas_Object *obj EINA_UNUSED,
|
||||||
&sd->current.x, &sd->current.y,
|
&sd->current.x, &sd->current.y,
|
||||||
&sd->current.w, &sd->current.h);
|
&sd->current.w, &sd->current.h);
|
||||||
|
|
||||||
|
sd->prev.x = sd->current.x;
|
||||||
|
sd->prev.y = sd->current.y;
|
||||||
|
sd->prev.w = sd->current.w;
|
||||||
|
sd->prev.h = sd->current.h;
|
||||||
|
|
||||||
/* set resizing flag */
|
/* set resizing flag */
|
||||||
sd->resizing = EINA_TRUE;
|
sd->resizing = EINA_TRUE;
|
||||||
|
|
||||||
|
/* raise the monitor */
|
||||||
|
evas_object_raise(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1853,6 +1891,11 @@ _e_smart_monitor_frame_cb_rotate_start(void *data, Evas_Object *obj EINA_UNUSED,
|
||||||
&sd->current.x, &sd->current.y,
|
&sd->current.x, &sd->current.y,
|
||||||
&sd->current.w, &sd->current.h);
|
&sd->current.w, &sd->current.h);
|
||||||
|
|
||||||
|
sd->prev.x = sd->current.x;
|
||||||
|
sd->prev.y = sd->current.y;
|
||||||
|
sd->prev.w = sd->current.w;
|
||||||
|
sd->prev.h = sd->current.h;
|
||||||
|
|
||||||
/* set resizing flag */
|
/* set resizing flag */
|
||||||
sd->rotating = EINA_TRUE;
|
sd->rotating = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2234,6 +2277,9 @@ _e_smart_monitor_move_event(E_Smart_Data *sd, Evas_Object *mon, void *event)
|
||||||
/* take current object position, translate to virtual */
|
/* take current object position, translate to virtual */
|
||||||
_e_smart_monitor_coord_canvas_to_virtual(sd, nx, ny, &px, &py);
|
_e_smart_monitor_coord_canvas_to_virtual(sd, nx, ny, &px, &py);
|
||||||
|
|
||||||
|
sd->current.x = px;
|
||||||
|
sd->current.y = py;
|
||||||
|
|
||||||
/* set monitor position text */
|
/* set monitor position text */
|
||||||
_e_smart_monitor_position_set(sd, px, py);
|
_e_smart_monitor_position_set(sd, px, py);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "e_smart_randr.h"
|
#include "e_smart_randr.h"
|
||||||
#include "e_smart_monitor.h"
|
#include "e_smart_monitor.h"
|
||||||
|
|
||||||
|
#define SNAP_FUZZ 100
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
*
|
*
|
||||||
|
@ -653,11 +655,10 @@ _e_smart_randr_monitor_cb_changed(void *data, Evas_Object *obj EINA_UNUSED, void
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_e_smart_randr_monitor_cb_moved(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
_e_smart_randr_monitor_cb_moved(void *data, Evas_Object *obj, void *event EINA_UNUSED)
|
||||||
{
|
{
|
||||||
E_Smart_Data *sd;
|
E_Smart_Data *sd;
|
||||||
Evas_Object *randr, *mon;
|
Evas_Object *randr;
|
||||||
Eina_List *l = NULL;
|
|
||||||
|
|
||||||
if (!(randr = data)) return;
|
if (!(randr = data)) return;
|
||||||
|
|
||||||
|
@ -671,18 +672,7 @@ _e_smart_randr_monitor_cb_moved(void *data, Evas_Object *obj EINA_UNUSED, void *
|
||||||
/* move any monitors which are adjacent to this one to their new
|
/* move any monitors which are adjacent to this one to their new
|
||||||
* positions due to the resize, specifying this resized monitor as
|
* positions due to the resize, specifying this resized monitor as
|
||||||
* the one to skip */
|
* the one to skip */
|
||||||
_e_smart_randr_monitor_position_update(sd, randr, randr);
|
_e_smart_randr_monitor_position_update(sd, obj, obj);
|
||||||
|
|
||||||
EINA_LIST_FOREACH(sd->monitors, l, mon)
|
|
||||||
{
|
|
||||||
/* skip the monitor which was currently resized */
|
|
||||||
if ((mon == randr)) continue;
|
|
||||||
|
|
||||||
/* move any monitors which are adjacent to this one to their new
|
|
||||||
* positions due to the resize, specifying this resized monitor as
|
|
||||||
* the one to skip */
|
|
||||||
_e_smart_randr_monitor_position_update(sd, mon, randr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tell main dialog that something changed and to enable apply button */
|
/* tell main dialog that something changed and to enable apply button */
|
||||||
evas_object_smart_callback_call(randr, "randr_changed", NULL);
|
evas_object_smart_callback_call(randr, "randr_changed", NULL);
|
||||||
|
@ -692,8 +682,7 @@ static void
|
||||||
_e_smart_randr_monitor_cb_resized(void *data, Evas_Object *obj, void *event EINA_UNUSED)
|
_e_smart_randr_monitor_cb_resized(void *data, Evas_Object *obj, void *event EINA_UNUSED)
|
||||||
{
|
{
|
||||||
E_Smart_Data *sd;
|
E_Smart_Data *sd;
|
||||||
Evas_Object *randr, *mon;
|
Evas_Object *randr;
|
||||||
Eina_List *l = NULL;
|
|
||||||
|
|
||||||
if (!(randr = data)) return;
|
if (!(randr = data)) return;
|
||||||
|
|
||||||
|
@ -705,17 +694,6 @@ _e_smart_randr_monitor_cb_resized(void *data, Evas_Object *obj, void *event EINA
|
||||||
* the one to skip */
|
* the one to skip */
|
||||||
_e_smart_randr_monitor_position_update(sd, obj, obj);
|
_e_smart_randr_monitor_position_update(sd, obj, obj);
|
||||||
|
|
||||||
EINA_LIST_FOREACH(sd->monitors, l, mon)
|
|
||||||
{
|
|
||||||
/* skip the monitor which was currently resized */
|
|
||||||
if ((mon == obj)) continue;
|
|
||||||
|
|
||||||
/* move any monitors which are adjacent to this one to their new
|
|
||||||
* positions due to the resize, specifying this resized monitor as
|
|
||||||
* the one to skip */
|
|
||||||
_e_smart_randr_monitor_position_update(sd, mon, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tell main dialog that something changed and to enable apply button */
|
/* tell main dialog that something changed and to enable apply button */
|
||||||
evas_object_smart_callback_call(randr, "randr_changed", NULL);
|
evas_object_smart_callback_call(randr, "randr_changed", NULL);
|
||||||
}
|
}
|
||||||
|
@ -725,11 +703,13 @@ _e_smart_randr_monitor_position_update(E_Smart_Data *sd, Evas_Object *obj, Evas_
|
||||||
{
|
{
|
||||||
Eina_List *l = NULL;
|
Eina_List *l = NULL;
|
||||||
Evas_Object *mon;
|
Evas_Object *mon;
|
||||||
Eina_Rectangle o;
|
Eina_Rectangle o, op;
|
||||||
|
|
||||||
/* get the current geometry of the monitor we were passed in */
|
/* get the current geometry of the monitor we were passed in */
|
||||||
e_smart_monitor_current_geometry_get(obj, &o.x, &o.y, &o.w, &o.h);
|
e_smart_monitor_current_geometry_get(obj, &o.x, &o.y, &o.w, &o.h);
|
||||||
|
|
||||||
|
e_smart_monitor_previous_geometry_get(obj, &op.x, &op.y, &op.w, &op.h);
|
||||||
|
|
||||||
/* loop the list of monitors */
|
/* loop the list of monitors */
|
||||||
EINA_LIST_FOREACH(sd->monitors, l, mon)
|
EINA_LIST_FOREACH(sd->monitors, l, mon)
|
||||||
{
|
{
|
||||||
|
@ -744,27 +724,28 @@ _e_smart_randr_monitor_position_update(E_Smart_Data *sd, Evas_Object *obj, Evas_
|
||||||
|
|
||||||
/* check if this monitor is adjacent to the original one,
|
/* check if this monitor is adjacent to the original one,
|
||||||
* if it is, then we need to move it */
|
* if it is, then we need to move it */
|
||||||
if ((m.x == o.x) || (m.y == o.y))
|
|
||||||
|
/* check for any monitors that are on this X axis
|
||||||
|
* (within a certain threshold of distance) */
|
||||||
|
if ((m.x >= (op.x + (op.w / 3))) &&
|
||||||
|
(((m.x <= ((op.x + op.w) + SNAP_FUZZ)) ||
|
||||||
|
(m.x <= ((op.x + op.w) - SNAP_FUZZ)))))
|
||||||
{
|
{
|
||||||
if ((m.x == o.x))
|
/* don't move the monitor IF this movement would place it
|
||||||
{
|
* outside the virual grid */
|
||||||
if ((m.y >= o.y))
|
if (((o.x + o.w) + m.w) <= sd->vw)
|
||||||
{
|
e_smart_monitor_current_geometry_set(mon, (o.x + o.w),
|
||||||
/* vertical positioning */
|
m.y, m.w, m.h);
|
||||||
e_smart_monitor_current_geometry_set(mon, m.x,
|
}
|
||||||
(o.y + o.h),
|
else if ((m.y >= (op.y + (op.h / 3))) &&
|
||||||
m.w, m.h);
|
(((m.y <= ((op.y + op.h) + SNAP_FUZZ)) ||
|
||||||
}
|
(m.y <= ((op.y + op.h) - SNAP_FUZZ)))))
|
||||||
}
|
{
|
||||||
else if ((m.y == o.y))
|
/* don't move the monitor IF this movement would place it
|
||||||
{
|
* outside the virual grid */
|
||||||
if ((m.x >= o.x))
|
if (((o.y + o.h) + m.h) <= sd->vh)
|
||||||
{
|
e_smart_monitor_current_geometry_set(mon, m.x, (o.y + o.h),
|
||||||
/* horizontal positioning */
|
m.w, m.h);
|
||||||
e_smart_monitor_current_geometry_set(mon, (o.x + o.w),
|
|
||||||
m.y, m.w, m.h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue