Improve maximzation.
This makes H/V maximization independent, and improves simultaneous H/V maximization. Based on patch by Daniel Manjarres. SVN revision: 57922
This commit is contained in:
parent
a2968d89f2
commit
318288c1c6
172
src/size.c
172
src/size.c
|
@ -26,6 +26,13 @@
|
||||||
#include "hints.h"
|
#include "hints.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
|
#define DEBUG_SIZE 0
|
||||||
|
#if DEBUG_SIZE
|
||||||
|
#define Dprintf Eprintf
|
||||||
|
#else
|
||||||
|
#define Dprintf(fmt...)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_ABSOLUTE 0 /* Fill screen */
|
#define MAX_ABSOLUTE 0 /* Fill screen */
|
||||||
#define MAX_AVAILABLE 1 /* Expand until don't cover */
|
#define MAX_AVAILABLE 1 /* Expand until don't cover */
|
||||||
#define MAX_CONSERVATIVE 2 /* Expand until something */
|
#define MAX_CONSERVATIVE 2 /* Expand until something */
|
||||||
|
@ -37,6 +44,8 @@ MaxSizeHV(EWin * ewin, const char *resize_type, int hor, int ver)
|
||||||
int x, y, w, h, x1, x2, y1, y2, type, bl, br, bt, bb;
|
int x, y, w, h, x1, x2, y1, y2, type, bl, br, bt, bb;
|
||||||
EWin *const *lst, *pe;
|
EWin *const *lst, *pe;
|
||||||
int i, num;
|
int i, num;
|
||||||
|
int old_hor = ewin->state.maximized_horz != 0;
|
||||||
|
int old_ver = ewin->state.maximized_vert != 0;
|
||||||
|
|
||||||
if (!ewin)
|
if (!ewin)
|
||||||
return;
|
return;
|
||||||
|
@ -46,16 +55,49 @@ MaxSizeHV(EWin * ewin, const char *resize_type, int hor, int ver)
|
||||||
if (ewin->state.inhibit_max_ver && ver)
|
if (ewin->state.inhibit_max_ver && ver)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ewin->state.maximized_horz || ewin->state.maximized_vert)
|
if (!old_hor && !old_ver)
|
||||||
{
|
{
|
||||||
EwinMoveResize(ewin, ewin->save_max.x, ewin->save_max.y,
|
|
||||||
ewin->save_max.w, ewin->save_max.h);
|
|
||||||
ewin->save_max.x = EoGetX(ewin);
|
ewin->save_max.x = EoGetX(ewin);
|
||||||
ewin->save_max.y = EoGetY(ewin);
|
ewin->save_max.y = EoGetY(ewin);
|
||||||
ewin->save_max.w = ewin->client.w;
|
ewin->save_max.w = ewin->client.w;
|
||||||
ewin->save_max.h = ewin->client.h;
|
ewin->save_max.h = ewin->client.h;
|
||||||
ewin->state.maximized_horz = 0;
|
}
|
||||||
ewin->state.maximized_vert = 0;
|
|
||||||
|
/* Figure out target state */
|
||||||
|
if (hor && ver)
|
||||||
|
{
|
||||||
|
hor = ver = (old_hor && old_ver) ? 0 : 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hor = (hor) ? !old_hor : old_hor;
|
||||||
|
ver = (ver) ? !old_ver : old_ver;
|
||||||
|
}
|
||||||
|
|
||||||
|
ewin->state.maximizing = 1;
|
||||||
|
ewin->state.maximized_horz = hor;
|
||||||
|
ewin->state.maximized_vert = ver;
|
||||||
|
|
||||||
|
Dprintf("h/v old = %d/%d new=%d/%d\n", old_hor, old_ver, hor, ver);
|
||||||
|
if (!hor && !ver)
|
||||||
|
{
|
||||||
|
/* Restore regular state */
|
||||||
|
EwinMoveResize(ewin, ewin->save_max.x, ewin->save_max.y,
|
||||||
|
ewin->save_max.w, ewin->save_max.h);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (old_ver == ver && old_hor && !hor)
|
||||||
|
{
|
||||||
|
/* Turn off horizontal maxsize */
|
||||||
|
EwinMoveResize(ewin, ewin->save_max.x, EoGetY(ewin),
|
||||||
|
ewin->save_max.w, ewin->client.h);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (old_hor == hor && old_ver && !ver)
|
||||||
|
{
|
||||||
|
/* Turn off vertical maxsize */
|
||||||
|
EwinMoveResize(ewin, EoGetX(ewin), ewin->save_max.y,
|
||||||
|
ewin->client.w, ewin->save_max.h);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,13 +126,11 @@ MaxSizeHV(EWin * ewin, const char *resize_type, int hor, int ver)
|
||||||
{
|
{
|
||||||
x = 0;
|
x = 0;
|
||||||
w = WinGetW(VROOT);
|
w = WinGetW(VROOT);
|
||||||
ewin->state.maximized_horz = 1;
|
|
||||||
}
|
}
|
||||||
if (ver)
|
if (ver)
|
||||||
{
|
{
|
||||||
y = 0;
|
y = 0;
|
||||||
h = WinGetH(VROOT);
|
h = WinGetH(VROOT);
|
||||||
ewin->state.maximized_vert = 1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -144,6 +184,112 @@ MaxSizeHV(EWin * ewin, const char *resize_type, int hor, int ver)
|
||||||
lst = EwinListGetAll(&num);
|
lst = EwinListGetAll(&num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ver && hor && !old_ver && !old_hor)
|
||||||
|
{
|
||||||
|
for (i = 0; i < num;)
|
||||||
|
{
|
||||||
|
int x1n, x2n, y1n, y2n;
|
||||||
|
int need_chop_y, need_chop_x;
|
||||||
|
int top, bottom, left, right;
|
||||||
|
|
||||||
|
pe = lst[i];
|
||||||
|
x1n = x1;
|
||||||
|
x2n = x2;
|
||||||
|
y1n = y1;
|
||||||
|
y2n = y2;
|
||||||
|
|
||||||
|
left = EoGetX(pe);
|
||||||
|
right = left + EoGetW(pe);
|
||||||
|
top = EoGetY(pe);
|
||||||
|
bottom = top + EoGetH(pe);
|
||||||
|
|
||||||
|
need_chop_x = need_chop_y = 0;
|
||||||
|
|
||||||
|
Dprintf
|
||||||
|
("trying window #%d %s x:%d-%d y:%d-%d vs x:%d-%d y:%d-%d\n",
|
||||||
|
i, EoGetName(pe), left, right, top, bottom,
|
||||||
|
x1, x2, y1, y2);
|
||||||
|
|
||||||
|
if (pe == ewin || pe->state.iconified || EoIsFloating(pe) ||
|
||||||
|
pe->props.ignorearrange ||
|
||||||
|
(EoGetDesk(ewin) != EoGetDesk(pe) && !EoIsSticky(pe)) ||
|
||||||
|
(pe->type & (EWIN_TYPE_DIALOG | EWIN_TYPE_MENU)) ||
|
||||||
|
(type == MAX_AVAILABLE && !pe->props.never_use_area) ||
|
||||||
|
/* ignore windws that do not overlap with current search area */
|
||||||
|
!(SPANS_COMMON(x1, x2 - x1, EoGetX(pe), EoGetW(pe)) &&
|
||||||
|
SPANS_COMMON(y1, y2 - y1, EoGetY(pe), EoGetH(pe))) ||
|
||||||
|
/* ignore windows that already overlap with the orig window */
|
||||||
|
(SPANS_COMMON(x + 1, w - 2, EoGetX(pe), EoGetW(pe)) &&
|
||||||
|
SPANS_COMMON(y + 1, h - 2, EoGetY(pe), EoGetH(pe))))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right <= x + w / 2)
|
||||||
|
{
|
||||||
|
need_chop_x = 1;
|
||||||
|
x1n = right;
|
||||||
|
}
|
||||||
|
if (left >= x + w / 2)
|
||||||
|
{
|
||||||
|
need_chop_x = 1;
|
||||||
|
x2n = left;
|
||||||
|
}
|
||||||
|
if (bottom <= y + h / 2)
|
||||||
|
{
|
||||||
|
need_chop_y = 1;
|
||||||
|
y1n = bottom;
|
||||||
|
}
|
||||||
|
if (top >= y + h / 2)
|
||||||
|
{
|
||||||
|
need_chop_y = 1;
|
||||||
|
y2n = top;
|
||||||
|
}
|
||||||
|
Dprintf("chop v: %d chop_x:%d\n",
|
||||||
|
(y2n - y1n) * (x2 - x1), (y2 - y1) * (x2n - x1n));
|
||||||
|
|
||||||
|
if (!(need_chop_y || need_chop_x))
|
||||||
|
{
|
||||||
|
Dprintf("no chop\n");
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!need_chop_x)
|
||||||
|
{
|
||||||
|
Dprintf("chop_v\n");
|
||||||
|
y2 = y2n;
|
||||||
|
y1 = y1n;
|
||||||
|
}
|
||||||
|
else if (!need_chop_y)
|
||||||
|
{
|
||||||
|
Dprintf("chop_h\n");
|
||||||
|
x2 = x2n;
|
||||||
|
x1 = x1n;
|
||||||
|
}
|
||||||
|
/* greedily chop the minimum area either from the sides or top/bottom
|
||||||
|
* We may need to do a final cleanup pass below to escape from a
|
||||||
|
* local local minima of the area decision function */
|
||||||
|
else if ((y2 - y1) * (x2n - x1n) > (y2n - y1n) * (x2 - x1))
|
||||||
|
{
|
||||||
|
Dprintf("___chop_h\n");
|
||||||
|
x2 = x2n;
|
||||||
|
x1 = x1n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dprintf("___chop_v\n");
|
||||||
|
y2 = y2n;
|
||||||
|
y1 = y1n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x = x1;
|
||||||
|
w = x2 - x1;
|
||||||
|
y = y1;
|
||||||
|
h = y2 - y1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (ver)
|
if (ver)
|
||||||
{
|
{
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
|
@ -166,8 +312,6 @@ MaxSizeHV(EWin * ewin, const char *resize_type, int hor, int ver)
|
||||||
}
|
}
|
||||||
y = y1;
|
y = y1;
|
||||||
h = y2 - y1;
|
h = y2 - y1;
|
||||||
|
|
||||||
ewin->state.maximized_vert = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hor)
|
if (hor)
|
||||||
|
@ -192,8 +336,6 @@ MaxSizeHV(EWin * ewin, const char *resize_type, int hor, int ver)
|
||||||
}
|
}
|
||||||
x = x1;
|
x = x1;
|
||||||
w = x2 - x1;
|
w = x2 - x1;
|
||||||
|
|
||||||
ewin->state.maximized_horz = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -207,14 +349,8 @@ MaxSizeHV(EWin * ewin, const char *resize_type, int hor, int ver)
|
||||||
if (h < 10)
|
if (h < 10)
|
||||||
h = 10;
|
h = 10;
|
||||||
|
|
||||||
ewin->save_max.x = EoGetX(ewin);
|
|
||||||
ewin->save_max.y = EoGetY(ewin);
|
|
||||||
ewin->save_max.w = ewin->client.w;
|
|
||||||
ewin->save_max.h = ewin->client.h;
|
|
||||||
|
|
||||||
ewin->state.maximizing = 1;
|
|
||||||
EwinMoveResize(ewin, x, y, w, h);
|
EwinMoveResize(ewin, x, y, w, h);
|
||||||
ewin->state.maximizing = 0;
|
|
||||||
done:
|
done:
|
||||||
|
ewin->state.maximizing = 0;
|
||||||
HintsSetWindowState(ewin);
|
HintsSetWindowState(ewin);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue