pre-compute spot xywh
This commit is contained in:
1
proto.h
1
proto.h
@@ -20,7 +20,6 @@ int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned
|
|||||||
int client_send_wm_protocol(client *c, Atom protocol);
|
int client_send_wm_protocol(client *c, Atom protocol);
|
||||||
void client_close(client *c);
|
void client_close(client *c);
|
||||||
void client_position_xywh(client *c, int x, int y, int w, int h);
|
void client_position_xywh(client *c, int x, int y, int w, int h);
|
||||||
void spot_calc_xywh(int spot, int mon, int *x, int *y, int *w, int *h);
|
|
||||||
void client_place_spot(client *c, int spot, int force);
|
void client_place_spot(client *c, int spot, int force);
|
||||||
void client_spot_cycle(client *c);
|
void client_spot_cycle(client *c);
|
||||||
Window spot_focus_top_window(int spot, int mon, Window except);
|
Window spot_focus_top_window(int spot, int mon, Window except);
|
||||||
|
|||||||
130
xoat.c
130
xoat.c
@@ -138,7 +138,7 @@ void ewmh_client_list()
|
|||||||
|
|
||||||
client* window_build_client(Window win)
|
client* window_build_client(Window win)
|
||||||
{
|
{
|
||||||
int i, x, y, w, h;
|
int i;
|
||||||
if (win == None) return NULL;
|
if (win == None) return NULL;
|
||||||
|
|
||||||
client *c = calloc(1, sizeof(client));
|
client *c = calloc(1, sizeof(client));
|
||||||
@@ -165,14 +165,15 @@ client* window_build_client(Window win)
|
|||||||
{ c->monitor = i; break; }
|
{ c->monitor = i; break; }
|
||||||
|
|
||||||
c->spot = SPOT1;
|
c->spot = SPOT1;
|
||||||
|
monitor *m = &monitors[c->monitor];
|
||||||
|
|
||||||
spot_calc_xywh(SPOT2, c->monitor, &x, &y, &w, &h);
|
if (INTERSECT(m->spots[SPOT2].x, m->spots[SPOT2].y, m->spots[SPOT2].w, m->spots[SPOT2].h,
|
||||||
if (INTERSECT(x, y, w, h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1))
|
c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1))
|
||||||
c->spot = SPOT2;
|
c->spot = SPOT2;
|
||||||
|
|
||||||
spot_calc_xywh(SPOT3, c->monitor, &x, &y, &w, &h);
|
if (INTERSECT(m->spots[SPOT3].x, m->spots[SPOT3].y, m->spots[SPOT3].w, m->spots[SPOT3].h,
|
||||||
if (INTERSECT(x, y, w, h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1))
|
c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1))
|
||||||
c->spot = SPOT3;
|
c->spot = SPOT3;
|
||||||
|
|
||||||
if (c->visible)
|
if (c->visible)
|
||||||
{
|
{
|
||||||
@@ -352,38 +353,15 @@ void client_position_xywh(client *c, int x, int y, int w, int h)
|
|||||||
if (h < sh) y += (sh-h)/2;
|
if (h < sh) y += (sh-h)/2;
|
||||||
|
|
||||||
// bump onto screen
|
// bump onto screen
|
||||||
x = MAX(0, MIN(x, m->x + m->w - w - BORDER*2));
|
x = MAX(m->x, MIN(x, m->x + m->w - w - BORDER*2));
|
||||||
y = MAX(0, MIN(y, m->y + m->h - h - BORDER*2));
|
y = MAX(m->y, MIN(y, m->y + m->h - h - BORDER*2));
|
||||||
|
|
||||||
XMoveResizeWindow(display, c->window, x, y, w, h);
|
XMoveResizeWindow(display, c->window, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spot_calc_xywh(int spot, int mon, int *x, int *y, int *w, int *h)
|
|
||||||
{
|
|
||||||
spot = MAX(SPOT1, MIN(SPOT3, spot));
|
|
||||||
monitor *m = &monitors[MIN(nmonitors-1, MAX(0, mon))];
|
|
||||||
int width_spot1 = (double)m->w / 100 * MIN(90, MAX(10, SPOT1_WIDTH_PCT));
|
|
||||||
int height_spot2 = (double)m->h / 100 * MIN(90, MAX(10, SPOT2_HEIGHT_PCT));
|
|
||||||
int x_spot1 = SPOT1_ALIGN == SPOT1_LEFT ? m->x: m->x + m->w - width_spot1;
|
|
||||||
int x_spot2 = SPOT1_ALIGN == SPOT1_LEFT ? m->x + width_spot1: m->x;
|
|
||||||
|
|
||||||
*x = x_spot1, *y = m->y, *w = width_spot1, *h = m->h;
|
|
||||||
if (spot == SPOT1) return;
|
|
||||||
|
|
||||||
*x = x_spot2;
|
|
||||||
*w = m->w - width_spot1;
|
|
||||||
*h = height_spot2;
|
|
||||||
if (spot == SPOT2) return;
|
|
||||||
|
|
||||||
*y = m->y + height_spot2;
|
|
||||||
*h = m->h - height_spot2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void client_place_spot(client *c, int spot, int force)
|
void client_place_spot(client *c, int spot, int force)
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
int x, y, w, h;
|
|
||||||
spot = MAX(SPOT1, MIN(SPOT3, spot));
|
|
||||||
|
|
||||||
if (c->trans && !force)
|
if (c->trans && !force)
|
||||||
{
|
{
|
||||||
@@ -391,17 +369,19 @@ void client_place_spot(client *c, int spot, int force)
|
|||||||
spot = t->spot;
|
spot = t->spot;
|
||||||
client_free(t);
|
client_free(t);
|
||||||
}
|
}
|
||||||
spot_calc_xywh(spot, c->monitor, &x, &y, &w, &h);
|
|
||||||
|
box b;
|
||||||
|
memmove(&b, &monitors[c->monitor].spots[spot], sizeof(box));
|
||||||
|
|
||||||
if (c->type == atoms[_NET_WM_WINDOW_TYPE_DIALOG])
|
if (c->type == atoms[_NET_WM_WINDOW_TYPE_DIALOG])
|
||||||
{
|
{
|
||||||
x += (w - c->attr.width)/2;
|
b.x += (b.w - c->attr.width)/2;
|
||||||
y += (h - c->attr.height)/2;
|
b.y += (b.h - c->attr.height)/2;
|
||||||
w = c->attr.width + BORDER*2;
|
b.w = c->attr.width + BORDER*2;
|
||||||
h = c->attr.height + BORDER*2;
|
b.h = c->attr.height + BORDER*2;
|
||||||
}
|
}
|
||||||
c->spot = spot;
|
c->spot = spot;
|
||||||
client_position_xywh(c, x, y, w, h);
|
client_position_xywh(c, b.x, b.y, b.w, b.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_spot_cycle(client *c)
|
void client_spot_cycle(client *c)
|
||||||
@@ -420,14 +400,14 @@ void client_spot_cycle(client *c)
|
|||||||
|
|
||||||
Window spot_focus_top_window(int spot, int mon, Window except)
|
Window spot_focus_top_window(int spot, int mon, Window except)
|
||||||
{
|
{
|
||||||
int i, x, y, w, h; client *o;
|
int i; client *o; box b;
|
||||||
spot_calc_xywh(spot, mon, &x, &y, &w, &h);
|
memmove(&b, &monitors[mon].spots[spot], sizeof(box));
|
||||||
stack wins; query_visible_windows(&wins);
|
stack wins; query_visible_windows(&wins);
|
||||||
|
|
||||||
for (i = 0; i < wins.depth; i++)
|
for (i = 0; i < wins.depth; i++)
|
||||||
{
|
{
|
||||||
if ((o = wins.clients[i]) && o->window != except && o->manage && o->spot == spot
|
if ((o = wins.clients[i]) && o->window != except && o->manage && o->spot == spot
|
||||||
&& INTERSECT(x + w/2, y + h/2, 1, 1, o->attr.x, o->attr.y, o->attr.width, o->attr.height))
|
&& INTERSECT(b.x + b.w/2, b.y + b.h/2, 1, 1, o->attr.x, o->attr.y, o->attr.width, o->attr.height))
|
||||||
{
|
{
|
||||||
client_raise_family(o);
|
client_raise_family(o);
|
||||||
client_set_focus(o);
|
client_set_focus(o);
|
||||||
@@ -488,7 +468,7 @@ void client_raise_family(client *c)
|
|||||||
|
|
||||||
void client_set_focus(client *c)
|
void client_set_focus(client *c)
|
||||||
{
|
{
|
||||||
if (!c || !c->visible) return;
|
if (!c || !c->visible || c->window == current) return;
|
||||||
|
|
||||||
Window old = current;
|
Window old = current;
|
||||||
current = c->window;
|
current = c->window;
|
||||||
@@ -725,8 +705,13 @@ void map_request(XMapEvent *e)
|
|||||||
|
|
||||||
if (c->manage)
|
if (c->manage)
|
||||||
{
|
{
|
||||||
int x, y, w, h, spot = SPOT_START,
|
int spot = SPOT_START, mon = MAX(nmonitors-1, MIN(0, MONITOR_START));
|
||||||
monitor = MAX(nmonitors-1, MIN(0, MONITOR_START));
|
|
||||||
|
if (MONITOR_START == MONITOR_CURRENT)
|
||||||
|
mon = current_mon;
|
||||||
|
|
||||||
|
c->monitor = mon;
|
||||||
|
monitor *m = &monitors[mon];
|
||||||
|
|
||||||
if (SPOT_START == SPOT_CURRENT)
|
if (SPOT_START == SPOT_CURRENT)
|
||||||
spot = current_spot;
|
spot = current_spot;
|
||||||
@@ -735,19 +720,13 @@ void map_request(XMapEvent *e)
|
|||||||
{
|
{
|
||||||
spot = SPOT1;
|
spot = SPOT1;
|
||||||
|
|
||||||
spot_calc_xywh(SPOT2, c->monitor, &x, &y, &w, &h);
|
if (c->attr.width <= m->spots[SPOT2].w && c->attr.height <= m->spots[SPOT2].h)
|
||||||
if (c->attr.width <= w && c->attr.height <= h)
|
|
||||||
spot = SPOT2;
|
spot = SPOT2;
|
||||||
|
|
||||||
spot_calc_xywh(SPOT3, c->monitor, &x, &y, &w, &h);
|
if (c->attr.width <= m->spots[SPOT3].w && c->attr.height <= m->spots[SPOT3].h)
|
||||||
if (c->attr.width <= w && c->attr.height <= h)
|
|
||||||
spot = SPOT3;
|
spot = SPOT3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MONITOR_START == MONITOR_CURRENT)
|
|
||||||
monitor = current_mon;
|
|
||||||
|
|
||||||
c->monitor = monitor;
|
|
||||||
client_place_spot(c, spot, 0);
|
client_place_spot(c, spot, 0);
|
||||||
client_update_border(c);
|
client_update_border(c);
|
||||||
client_flush_tags(c);
|
client_flush_tags(c);
|
||||||
@@ -948,6 +927,32 @@ int main(int argc, char *argv[])
|
|||||||
// right struts affect last monitor
|
// right struts affect last monitor
|
||||||
monitors[nmonitors-1].w -= struts.right;
|
monitors[nmonitors-1].w -= struts.right;
|
||||||
|
|
||||||
|
// calculate spot boxes
|
||||||
|
for (i = 0; i < nmonitors; i++)
|
||||||
|
{
|
||||||
|
monitor *m = &monitors[i];
|
||||||
|
int width_spot1 = (double)m->w / 100 * MIN(90, MAX(10, SPOT1_WIDTH_PCT));
|
||||||
|
int height_spot2 = (double)m->h / 100 * MIN(90, MAX(10, SPOT2_HEIGHT_PCT));
|
||||||
|
int x_spot1 = SPOT1_ALIGN == SPOT1_LEFT ? m->x: m->x + m->w - width_spot1;
|
||||||
|
int x_spot2 = SPOT1_ALIGN == SPOT1_LEFT ? m->x + width_spot1: m->x;
|
||||||
|
for (j = SPOT1; j <= SPOT3; j++)
|
||||||
|
{
|
||||||
|
m->spots[j].x = x_spot1;
|
||||||
|
m->spots[j].y = m->y;
|
||||||
|
m->spots[j].w = width_spot1;
|
||||||
|
m->spots[j].h = m->h;
|
||||||
|
if (j == SPOT1) continue;
|
||||||
|
|
||||||
|
m->spots[j].x = x_spot2;
|
||||||
|
m->spots[j].w = m->w - width_spot1;
|
||||||
|
m->spots[j].h = height_spot2;
|
||||||
|
if (j == SPOT2) continue;
|
||||||
|
|
||||||
|
m->spots[j].y = m->y + height_spot2;
|
||||||
|
m->spots[j].h = m->h - height_spot2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// dump atoms for debug
|
// dump atoms for debug
|
||||||
for (i = 0; i < ATOMS; i++) warnx("atom 0x%lx %s", (long)atoms[i], atom_names[i]);
|
for (i = 0; i < ATOMS; i++) warnx("atom 0x%lx %s", (long)atoms[i], atom_names[i]);
|
||||||
|
|
||||||
@@ -1000,20 +1005,17 @@ int main(int argc, char *argv[])
|
|||||||
for (i = 0; i < wins.depth; i++)
|
for (i = 0; i < wins.depth; i++)
|
||||||
{
|
{
|
||||||
if (!(c = wins.clients[i]) || !c->manage) continue;
|
if (!(c = wins.clients[i]) || !c->manage) continue;
|
||||||
|
|
||||||
warnx("window 0x%08lx (%d,%d,%d) %s", (long)c->window, c->tags, c->monitor, c->spot, c->class);
|
warnx("window 0x%08lx (%d,%d,%d) %s", (long)c->window, c->tags, c->monitor, c->spot, c->class);
|
||||||
|
|
||||||
window_listen(c->window);
|
window_listen(c->window);
|
||||||
if (c->visible)
|
client_update_border(c);
|
||||||
{
|
client_flush_tags(c);
|
||||||
client_update_border(c);
|
|
||||||
client_flush_tags(c);
|
// only activate first one
|
||||||
// activate first one
|
if (current) continue;
|
||||||
if (!current)
|
|
||||||
{
|
client_raise_family(c);
|
||||||
client_raise_family(c);
|
client_set_focus(c);
|
||||||
client_set_focus(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// main event loop
|
// main event loop
|
||||||
|
|||||||
41
xoat.h
41
xoat.h
@@ -59,8 +59,31 @@ Time latest;
|
|||||||
char *self;
|
char *self;
|
||||||
Window ewmh;
|
Window ewmh;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MONITOR_CURRENT=-1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SPOT1=1, // large left pane
|
||||||
|
SPOT2, // medium top right pane
|
||||||
|
SPOT3, // small bottom right pane
|
||||||
|
SPOT_CURRENT,
|
||||||
|
SPOT_SMART,
|
||||||
|
SPOT1_LEFT,
|
||||||
|
SPOT1_RIGHT
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TAG1 1<<0
|
||||||
|
#define TAG2 1<<1
|
||||||
|
#define TAG3 1<<2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
short x, y, w, h;
|
short x, y, w, h;
|
||||||
|
} box;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
short x, y, w, h;
|
||||||
|
box spots[SPOT3+1];
|
||||||
} monitor;
|
} monitor;
|
||||||
|
|
||||||
#define MAX_MONITORS 3
|
#define MAX_MONITORS 3
|
||||||
@@ -175,21 +198,3 @@ typedef struct {
|
|||||||
void *data;
|
void *data;
|
||||||
int num;
|
int num;
|
||||||
} binding;
|
} binding;
|
||||||
|
|
||||||
enum {
|
|
||||||
MONITOR_CURRENT=-1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SPOT1=1, // large left pane
|
|
||||||
SPOT2, // medium top right pane
|
|
||||||
SPOT3, // small bottom right pane
|
|
||||||
SPOT_CURRENT,
|
|
||||||
SPOT_SMART,
|
|
||||||
SPOT1_LEFT,
|
|
||||||
SPOT1_RIGHT
|
|
||||||
};
|
|
||||||
|
|
||||||
#define TAG1 1<<0
|
|
||||||
#define TAG2 1<<1
|
|
||||||
#define TAG3 1<<2
|
|
||||||
|
|||||||
Reference in New Issue
Block a user