Improve window repositioning on screen size change.
SVN revision: 22134
This commit is contained in:
parent
0644106a2b
commit
71fafe5f70
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
191
src/ewins.c
191
src/ewins.c
|
@ -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
|
||||
|
|
13
src/ewins.h
13
src/ewins.h
|
@ -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);
|
||||
|
|
10
src/ipc.c
10
src/ipc.c
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue