Improve window repositioning on screen size change.

SVN revision: 22134
This commit is contained in:
Kim Woelders 2006-04-15 18:32:54 +00:00
parent 0644106a2b
commit 71fafe5f70
6 changed files with 173 additions and 48 deletions

View File

@ -836,10 +836,10 @@ DesksResize(int w, int h)
BackgroundsInvalidate(0);
ModulesSignal(ESIGNAL_DESK_RESIZE, NULL);
for (i = 0; i < Conf.desks.num; i++)
DeskResize(i, w, h);
ModulesSignal(ESIGNAL_DESK_RESIZE, NULL);
}
static void

View File

@ -510,6 +510,8 @@ doEwinMoveResize(EWin * ewin, Desk * dsk, int x, int y, int w, int h, int flags)
}
EwinDetermineArea(ewin);
if (Mode.op_source == OPSRC_USER)
EwinSetPlacementGravity(ewin, x, y);
if (ewin->MoveResize)
ewin->MoveResize(ewin, resize);

View File

@ -121,6 +121,8 @@ EwinCreate(Window win, int type)
ewin->area_x = -1;
ewin->area_y = -1;
ewin->place.gravity = -1;
ewin->ewmh.opacity = 0; /* If 0, ignore */
ewin->props.opaque_when_focused = 1;
@ -1420,6 +1422,9 @@ ShowEwin(EWin * ewin)
EoMap(ewin, 0);
EwinStateUpdate(ewin);
if (ewin->place.gravity < 0)
EwinSetPlacementGravity(ewin, EoGetX(ewin), EoGetY(ewin));
}
void
@ -1577,6 +1582,144 @@ EwinRememberPositionGet(EWin * ewin, Desk * dsk, int *px, int *py)
*py = y;
}
/*
* Set placement gravity
*/
void
EwinSetPlacementGravity(EWin * ewin, int x, int y)
{
int w, h, ax, ay, wd, hd;
Desk *dsk;
dsk = EoGetDesk(ewin);
wd = EoGetW(dsk);
hd = EoGetH(dsk);
DeskGetArea(dsk, &ax, &ay);
w = EoGetW(ewin);
h = EoGetH(ewin);
/* Get relative area */
ewin->place.ax = ewin->area_x;
ewin->place.ay = ewin->area_y;
ax = ewin->place.ax - ax;
ay = ewin->place.ay - ay;
x -= ax * wd;
y -= ay * hd;
if (x <= (wd - w) / 2)
{
if (y <= (hd - h) / 2)
{
ewin->place.gravity = EWIN_GRAVITY_NW;
ewin->place.gx = x;
ewin->place.gy = y;
}
else
{
ewin->place.gravity = EWIN_GRAVITY_SW;
ewin->place.gx = x;
ewin->place.gy = hd - (y + h);
}
}
else
{
if (y <= (hd - h) / 2)
{
ewin->place.gravity = EWIN_GRAVITY_NE;
ewin->place.gx = wd - (x + w);
ewin->place.gy = y;
}
else
{
ewin->place.gravity = EWIN_GRAVITY_SE;
ewin->place.gx = wd - (x + w);
ewin->place.gy = hd - (y + h);
}
}
#if 0 /* Debug */
Eprintf("Set gravity %d,%d %d,%d %d %d,%d %d,%d: %s\n", ax, ay, x, y,
ewin->place.gravity, ewin->place.ax, ewin->place.ay,
ewin->place.gx, ewin->place.gy, EwinGetName(ewin));
#endif
}
void
EwinReposition(EWin * ewin)
{
int wdo, hdo, wdn, hdn;
int x, y, w, h, ax, ay, xn, yn;
wdo = Mode.screen.w_old;
hdo = Mode.screen.h_old;
wdn = VRoot.w;
hdn = VRoot.h;
x = EoGetX(ewin);
y = EoGetY(ewin);
w = EoGetW(ewin);
h = EoGetH(ewin);
/* Get relative area */
if (EoIsSticky(ewin))
{
ax = ay = 0;
}
else
{
DeskGetArea(EoGetDesk(ewin), &ax, &ay);
ax = ewin->place.ax - ax;
ay = ewin->place.ay - ay;
}
x -= ax * wdo;
y -= ay * hdo;
/* Reposition to same distance from screen edges determined by
* placement gravity.
* Fall back to left/top if this causes left/top to go offscreen */
switch (ewin->place.gravity)
{
default:
case EWIN_GRAVITY_NW:
case EWIN_GRAVITY_SW:
xn = ewin->place.gx;
break;
case EWIN_GRAVITY_NE:
case EWIN_GRAVITY_SE:
xn = wdn - w - ewin->place.gx;
break;
}
if (x > 0 && xn < 0)
xn = x;
switch (ewin->place.gravity)
{
default:
case EWIN_GRAVITY_NW:
case EWIN_GRAVITY_NE:
yn = ewin->place.gy;
break;
case EWIN_GRAVITY_SW:
case EWIN_GRAVITY_SE:
yn = hdn - h - ewin->place.gy;
break;
}
if (y > 0 && yn < 0)
yn = y;
#if 0 /* Debug */
Eprintf("Reposition %d,%d -> %d,%d: %s\n", x, y, xn, yn, EwinGetName(ewin));
#endif
xn += ax * wdn;
yn += ay * hdn;
EwinMove(ewin, xn, yn);
}
typedef union
{
unsigned int all;
@ -1752,56 +1895,12 @@ EwinsTouch(Desk * dsk)
static void
EwinsReposition(void)
{
int wdo, hdo, wdn, hdn;
int i, num;
EWin *const *lst, *ewin;
int x, y, w, h, ax, ay, xn, yn;
EWin *const *lst;
lst = EwinListGetAll(&num);
wdo = Mode.screen.w_old;
hdo = Mode.screen.h_old;
wdn = VRoot.w;
hdn = VRoot.h;
for (i = num - 1; i >= 0; i--)
{
ewin = lst[i];
x = EoGetX(ewin);
y = EoGetY(ewin);
w = EoGetW(ewin);
h = EoGetH(ewin);
/* Get relative area */
ax = (x >= 0) ? (x + w / 2) / wdo : (x + w / 2 + 1) / wdo - 1;
ay = (y >= 0) ? (y + h / 2) / hdo : (y + h / 2 + 1) / hdo - 1;
x -= ax * wdo;
y -= ay * hdo;
/* Reposition to same distance from nearest screen edge */
/* Fall back to left/top if this causes left/top to go offscreen */
if (abs(x) <= abs(x + w - wdo))
xn = x;
else
xn = x + (wdn - wdo);
if (x > 0 && xn < 0)
xn = x;
xn += ax * wdn;
if (abs(y) <= abs(y + h - hdo))
yn = y;
else
yn = y + (hdn - hdo);
if (y > 0 && yn < 0)
yn = y;
yn += ay * hdn;
if (xn == EoGetX(ewin) && yn == EoGetY(ewin))
continue;
EwinMove(ewin, xn, yn);
}
EwinReposition(lst[i]);
}
void

View File

@ -208,6 +208,12 @@ struct _ewin
#endif
} ewmh;
struct
{
signed char gravity;
int ax, ay; /* Current placed area */
int gx, gy; /* Distance to edge given by gravity */
} place;
struct
{
int left, right, top, bottom;
} strut;
@ -254,6 +260,11 @@ struct _ewin
#define EWIN_TYPE_ICONBOX 0x04
#define EWIN_TYPE_PAGER 0x08
#define EWIN_GRAVITY_NW 0
#define EWIN_GRAVITY_NE 1
#define EWIN_GRAVITY_SW 2
#define EWIN_GRAVITY_SE 3
#define EwinGetDesk(ewin) EoGetDesk(ewin)
#define EwinIsMapped(ewin) ((ewin)->state.state >= EWIN_STATE_MAPPED)
@ -311,6 +322,8 @@ int EwinIsOnScreen(const EWin * ewin);
void EwinRememberPositionSet(EWin * ewin);
void EwinRememberPositionGet(EWin * ewin, Desk * dsk,
int *px, int *py);
void EwinSetPlacementGravity(EWin * ewin, int x, int y);
void EwinReposition(EWin * ewin);
unsigned int EwinFlagsEncode(const EWin * ewin);
void EwinFlagsDecode(EWin * ewin, unsigned int flags);
void EwinUpdateOpacity(EWin * ewin);

View File

@ -283,6 +283,7 @@ IPC_MoveResize(const char *params, Client * c __UNUSED__)
static void
IPC_WinList(const char *params, Client * c __UNUSED__)
{
static const char *const TxtPG[] = { "NW", "NE", "SW", "SE" };
char param1[FILEPATH_LEN_MAX];
EWin *const *lst, *e;
int num, i;
@ -315,6 +316,15 @@ IPC_WinList(const char *params, Client * c __UNUSED__)
e->area_x, e->area_y, SS(e->icccm.wm_name));
break;
case 'g':
IpcPrintf
("%#10lx : %5d %5d %4dx%4d :: %2d : %s %4d,%4d %2d,%2d : %s\n",
_EwinGetClientXwin(e), EoGetX(e), EoGetY(e), EoGetW(e),
EoGetH(e), (EoIsSticky(e)) ? -1 : (int)EoGetDeskNum(e),
TxtPG[e->place.gravity & 3], e->place.gx, e->place.gy,
e->place.ax, e->place.ay, SS(e->icccm.wm_name));
break;
case 'p':
IpcPrintf
("%#10lx : %5d %5d %4dx%4d :: %2d : \"%s\" \"%s\" \"%s\"\n",

View File

@ -487,6 +487,7 @@ PagerReconfigure(Pager * p, int apply)
w = (int)(ax * VRoot.w / p->scale + .5);
h = (int)(ay * VRoot.h / p->scale + .5);
EwinResize(p->ewin, w, h);
EwinReposition(p->ewin);
}
}