This commit is contained in:
seanpringle
2012-09-04 01:11:34 +10:00
parent db944a1a25
commit 3ddd1aed2e
2 changed files with 60 additions and 117 deletions

View File

@@ -25,7 +25,6 @@ void client_cycle(client *c);
Window spot_active(int spot, int mon, Window except); Window spot_active(int spot, int mon, Window except);
void client_stack(client *c, stack *all, stack *raise); void client_stack(client *c, stack *all, stack *raise);
void client_raise(client *c); void client_raise(client *c);
void client_lower(client *c);
void client_active(client *c); void client_active(client *c);
void find_or_start(char *class); void find_or_start(char *class);
void window_listen(Window win); void window_listen(Window win);
@@ -40,6 +39,5 @@ void unmap_notify(XUnmapEvent *e);
void key_press(XKeyEvent *e); void key_press(XKeyEvent *e);
void button_press(XButtonEvent *e); void button_press(XButtonEvent *e);
void client_message(XClientMessageEvent *e); void client_message(XClientMessageEvent *e);
void focus_change(XFocusChangeEvent *e); void any_event(XEvent *e);
void property_notify(XPropertyEvent *e);
int main(int argc, char *argv[]); int main(int argc, char *argv[]);

173
xoat.c
View File

@@ -125,14 +125,13 @@ void window_set_window_prop(Window w, Atom prop, Window *values, int count)
void ewmh_client_list() void ewmh_client_list()
{ {
int i; stack all, wins; int i; client *c; stack all, wins;
memset(&wins, 0, sizeof(stack)); memset(&wins, 0, sizeof(stack));
windows_visible(&all); windows_visible(&all);
for (i = all.depth-1; i > -1; i--) for (i = all.depth-1; i > -1; i--)
{ {
client *c = all.clients[i]; if ((c = all.clients[i]) && c->manage)
if (c && c->manage)
{ {
wins.clients[wins.depth] = c; wins.clients[wins.depth] = c;
wins.windows[wins.depth++] = c->window; wins.windows[wins.depth++] = c->window;
@@ -263,19 +262,17 @@ void windows_visible(stack *s)
return; return;
} }
memset(s, 0, sizeof(stack)); memset(s, 0, sizeof(stack));
unsigned int nwins; int i; Window w1, w2, *wins; unsigned int nwins; int i; Window w1, w2, *wins; client *c;
if (XQueryTree(display, root, &w1, &w2, &wins, &nwins) && wins) if (XQueryTree(display, root, &w1, &w2, &wins, &nwins) && wins)
{ {
for (i = nwins-1; i > -1; i--) for (i = nwins-1; i > -1; i--)
{ {
client *c = window_client(wins[i]); if ((c = window_client(wins[i])) && c->visible && s->depth < STACK)
if (c && c->visible && s->depth < STACK)
{ {
s->clients[s->depth] = c; s->clients[s->depth] = c;
s->windows[s->depth++] = wins[i]; s->windows[s->depth++] = wins[i];
} }
else else client_free(c);
client_free(c);
} }
} }
if (wins) XFree(wins); if (wins) XFree(wins);
@@ -337,8 +334,7 @@ void client_position(client *c, int x, int y, int w, int h)
} }
w -= BORDER*2; h -= BORDER*2; w -= BORDER*2; h -= BORDER*2;
int basew = 0, baseh = 0; int basew = 0, baseh = 0, sw = w, sh = h;
int sw = w, sh = h;
if (c->size.flags & PBaseSize) if (c->size.flags & PBaseSize)
{ {
@@ -393,23 +389,21 @@ void spot_xywh(int spot, int mon, int *x, int *y, int *w, int *h)
// default, left 2/3 of screen // default, left 2/3 of screen
*x = m->x, *y = m->y, *w = width_spot1, *h = m->h; *x = m->x, *y = m->y, *w = width_spot1, *h = m->h;
switch (spot) if (spot != SPOT1)
{ {
*x = m->x + width_spot1;
*w = m->w - width_spot1;
// right top 2/9 of screen // right top 2/9 of screen
case SPOT2: if (spot == SPOT2)
*x = m->x + width_spot1; {
*y = m->y;
*w = m->w - width_spot1;
*h = height_spot2; *h = height_spot2;
break; }
// right bottom 1/9 of screen // right bottom 1/9 of screen
case SPOT3: if (spot == SPOT3)
*x = m->x + width_spot1; {
*y = m->y + height_spot2; *y = m->y + height_spot2;
*w = m->w - width_spot1;
*h = m->h - height_spot2; *h = m->h - height_spot2;
break; }
} }
} }
@@ -443,20 +437,26 @@ void client_spot(client *c, int spot, int force)
void client_cycle(client *c) void client_cycle(client *c)
{ {
spot_active(c->spot, c->monitor, c->window); spot_active(c->spot, c->monitor, c->window);
client_lower(c);
stack lower, all;
memset(&lower, 0, sizeof(stack));
windows_visible(&all);
client_stack(c, &all, &lower);
XLowerWindow(display, lower.windows[0]);
XRestackWindows(display, lower.windows, lower.depth);
} }
// find a window within a screen "spot" and raise/activate // find a window within a screen "spot" and raise/activate
Window spot_active(int spot, int mon, Window except) Window spot_active(int spot, int mon, Window except)
{ {
int i, x, y, w, h; int i, x, y, w, h; client *o;
spot_xywh(spot, mon, &x, &y, &w, &h); spot_xywh(spot, mon, &x, &y, &w, &h);
stack wins; windows_visible(&wins); stack wins; windows_visible(&wins);
for (i = 0; i < wins.depth; i++) for (i = 0; i < wins.depth; i++)
{ {
client *o = wins.clients[i]; if ((o = wins.clients[i]) && o->window != except && o->manage && o->spot == spot
if (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(x + w/2, y + h/2, 1, 1, o->attr.x, o->attr.y, o->attr.width, o->attr.height))
{ {
client_raise(o); client_raise(o);
@@ -470,14 +470,13 @@ Window spot_active(int spot, int mon, Window except)
// build a stack of a window's transients and itself // build a stack of a window's transients and itself
void client_stack(client *c, stack *all, stack *raise) void client_stack(client *c, stack *all, stack *raise)
{ {
int i; client *self = NULL; int i; client *o, *self = NULL;
for (i = 0; i < all->depth; i++) for (i = 0; i < all->depth; i++)
{ {
client *o = all->clients[i]; if ((o = all->clients[i]) && o->manage && o->visible && o->transient_for == c->window)
if (o->manage && o->visible && o->transient_for == c->window)
client_stack(o, all, raise); client_stack(o, all, raise);
else else
if (o->visible && o->window == c->window) if (o && o->visible && o->window == c->window)
self = o; self = o;
} }
if (self) if (self)
@@ -492,34 +491,28 @@ void client_raise(client *c)
{ {
if (!c) return; if (!c) return;
int i; stack raise, all, family; int i; client *o; stack raise, all, family;
memset(&raise, 0, sizeof(stack)); memset(&raise, 0, sizeof(stack));
memset(&family, 0, sizeof(stack)); memset(&family, 0, sizeof(stack));
windows_visible(&all); windows_visible(&all);
for (i = 0; i < all.depth; i++) for (i = 0; i < all.depth; i++)
{ if ((o = all.clients[i]) && o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK])
client *o = all.clients[i];
if (o && o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK])
client_stack(o, &all, &raise); client_stack(o, &all, &raise);
}
// above only counts for fullscreen windows // above only counts for fullscreen windows
if (client_state(c, atoms[_NET_WM_STATE_FULLSCREEN])) if (client_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
{
for (i = 0; i < all.depth; i++) for (i = 0; i < all.depth; i++)
{ if ((o = all.clients[i]) && client_state(o, atoms[_NET_WM_STATE_ABOVE]))
client *o = all.clients[i];
if (o && client_state(o, atoms[_NET_WM_STATE_ABOVE]))
client_stack(o, &all, &raise); client_stack(o, &all, &raise);
}
}
while (c->trans) while (c->trans)
{ {
client *t = window_client(c->transient_for); client *t = window_client(c->transient_for);
if (t) c = family.clients[family.depth++] = t; if (t) c = family.clients[family.depth++] = t;
} }
client_stack(c, &all, &raise);
client_stack(c, &all, &raise);
XRaiseWindow(display, raise.windows[0]); XRaiseWindow(display, raise.windows[0]);
XRestackWindows(display, raise.windows, raise.depth); XRestackWindows(display, raise.windows, raise.depth);
@@ -527,28 +520,12 @@ void client_raise(client *c)
client_free(family.clients[--family.depth]); client_free(family.clients[--family.depth]);
} }
// lower a window and all its transients
void client_lower(client *c)
{
if (!c || client_state(c, atoms[_NET_WM_STATE_ABOVE]))
return;
stack lower, all;
memset(&lower, 0, sizeof(stack));
windows_visible(&all);
client_stack(c, &all, &lower);
XLowerWindow(display, lower.windows[0]);
XRestackWindows(display, lower.windows, lower.depth);
}
// focus a window // focus a window
void client_active(client *c) void client_active(client *c)
{ {
client *o;
if (!c || !c->visible) return; if (!c || !c->visible) return;
client *o;
Window old = current; Window old = current;
current = c->window; current = c->window;
current_spot = c->spot; current_spot = c->spot;
@@ -569,14 +546,13 @@ void client_active(client *c)
// real simple switcher/launcher // real simple switcher/launcher
void find_or_start(char *class) void find_or_start(char *class)
{ {
int i; client *found = NULL; int i; client *c, *found = NULL;
stack all; windows_visible(&all); stack all; windows_visible(&all);
for (i = 0; !found && i < all.depth; i++) for (i = 0; !found && i < all.depth; i++)
{ {
XClassHint chint; XClassHint chint;
client *c = all.clients[i]; if ((c = all.clients[i]) && c->manage && XGetClassHint(display, c->window, &chint))
if (c && c->manage && XGetClassHint(display, c->window, &chint))
{ {
if (!strcasecmp(chint.res_class, class) || !strcasecmp(chint.res_name, class)) if (!strcasecmp(chint.res_class, class) || !strcasecmp(chint.res_name, class))
found = c; found = c;
@@ -615,8 +591,7 @@ void raise_tag(unsigned long tag)
for (i = all.depth-1; i > -1; i--) for (i = all.depth-1; i > -1; i--)
{ {
c = all.clients[i]; if ((c = all.clients[i]) && c->manage && c->visible && c->tags & tag)
if (c && c->manage && c->visible && c->tags & tag)
{ {
if (c->monitor == current_mon && c->spot == current_spot) t = c; if (c->monitor == current_mon && c->spot == current_spot) t = c;
client_raise(c); client_raise(c);
@@ -624,9 +599,7 @@ void raise_tag(unsigned long tag)
} }
if (t) client_active(t); if (t) client_active(t);
unsigned long desktop = 0; unsigned long desktop = tag & TAG2 ? 1: (tag & TAG3 ? 2: 0);
if (tag & TAG2) desktop = 1;
if (tag & TAG3) desktop = 2;
window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1); window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1);
} }
@@ -635,10 +608,7 @@ void client_set_tags(client *c)
unsigned long tags = c->tags; unsigned long tags = c->tags;
window_set_cardinal_prop(c->window, atoms[XOAT_TAGS], &tags, 1); window_set_cardinal_prop(c->window, atoms[XOAT_TAGS], &tags, 1);
unsigned long desktop = 0xffffffff; unsigned long desktop = tags & TAG3 ? 2: (tags & TAG2 ? 1: (tags & TAG1 ? 0: 0xffffffff));
if (tags & TAG3) desktop = 2;
if (tags & TAG2) desktop = 1;
if (tags & TAG1) desktop = 0;
window_set_cardinal_prop(c->window, atoms[_NET_WM_DESKTOP], &desktop, 1); window_set_cardinal_prop(c->window, atoms[_NET_WM_DESKTOP], &desktop, 1);
} }
@@ -686,16 +656,14 @@ void map_request(XMapEvent *e)
if (c && c->manage) if (c && c->manage)
{ {
client_review(c); int x, y, w, h, spot = SPOT_START,
monitor = MAX(nmonitors-1, MIN(0, MONITOR_START));
int spot = SPOT_START;
if (SPOT_START == SPOT_CURRENT) if (SPOT_START == SPOT_CURRENT)
spot = current_spot; spot = current_spot;
if (SPOT_START == SPOT_SMART) if (SPOT_START == SPOT_SMART)
{ {
int x, y, w, h;
spot = SPOT1; spot = SPOT1;
spot_xywh(SPOT2, c->monitor, &x, &y, &w, &h); spot_xywh(SPOT2, c->monitor, &x, &y, &w, &h);
@@ -707,13 +675,12 @@ void map_request(XMapEvent *e)
spot = SPOT3; spot = SPOT3;
} }
int monitor = MAX(nmonitors-1, MIN(0, MONITOR_START));
if (MONITOR_START == MONITOR_CURRENT) if (MONITOR_START == MONITOR_CURRENT)
monitor = current_mon; monitor = current_mon;
c->monitor = monitor; c->monitor = monitor;
client_spot(c, spot, 0); client_spot(c, spot, 0);
client_review(c);
} }
client_free(c); client_free(c);
XMapWindow(display, e->window); XMapWindow(display, e->window);
@@ -726,15 +693,11 @@ void map_notify(XMapEvent *e)
if (c && c->manage) if (c && c->manage)
{ {
client_raise(c); client_raise(c);
a = window_client(current); client_review(c);
// if no current window, or new window has opened in the // if no current window, or new window has opened in the
// current spot, activate it // current spot, activate it
if (!a || (a && a->spot == c->spot)) if (!(a = window_client(current)) || (a && a->spot == c->spot))
client_active(c); client_active(c);
else
client_review(c);
client_free(a); client_free(a);
} }
client_free(c); client_free(c);
@@ -804,19 +767,13 @@ void key_press(XKeyEvent *e)
break; break;
case ACTION_MOVE_MONITOR_INC: case ACTION_MOVE_MONITOR_INC:
client_raise(c); client_raise(c);
if (c->monitor < nmonitors-1) c->monitor = MIN(c->monitor+1, nmonitors-1);
{ client_spot(c, c->spot, 1);
c->monitor++;
client_spot(c, c->spot, 1);
}
break; break;
case ACTION_MOVE_MONITOR_DEC: case ACTION_MOVE_MONITOR_DEC:
client_raise(c); client_raise(c);
if (c->monitor > 0) c->monitor = MAX(c->monitor-1, 0);
{ client_spot(c, c->spot, 1);
c->monitor--;
client_spot(c, c->spot, 1);
}
break; break;
case ACTION_FULLSCREEN_TOGGLE: case ACTION_FULLSCREEN_TOGGLE:
spot = c->spot; spot = c->spot;
@@ -950,19 +907,9 @@ void client_message(XClientMessageEvent *e)
client_free(c); client_free(c);
} }
void focus_change(XFocusChangeEvent *e) void any_event(XEvent *e)
{ {
client *c = window_client(e->window); client *c = window_client(e->xany.window);
if (c && c->manage)
client_review(c);
client_free(c);
}
void property_notify(XPropertyEvent *e)
{
client *c = window_client(e->window);
if (c && c->manage) if (c && c->manage)
client_review(c); client_review(c);
@@ -972,8 +919,8 @@ void property_notify(XPropertyEvent *e)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i, j; self = argv[0]; int i, j; self = argv[0]; stack wins;
stack wins; memset(&wins, 0, sizeof(stack)); memset(&wins, 0, sizeof(stack));
signal(SIGCHLD, catch_exit); signal(SIGCHLD, catch_exit);
if (!(display = XOpenDisplay(0))) return 1; if (!(display = XOpenDisplay(0))) return 1;
@@ -1066,12 +1013,12 @@ int main(int argc, char *argv[])
ewmh = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, 0, 0); ewmh = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, 0, 0);
window_set_atom_prop(root, atoms[_NET_SUPPORTED], atoms, ATOMS); window_set_atom_prop(root, atoms[_NET_SUPPORTED], atoms, ATOMS);
window_set_window_prop(root, atoms[_NET_SUPPORTING_WM_CHECK], &ewmh, 1); window_set_window_prop(root, atoms[_NET_SUPPORTING_WM_CHECK], &ewmh, 1);
window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1); window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1);
window_set_cardinal_prop(root, atoms[_NET_NUMBER_OF_DESKTOPS], &desktops, 1); window_set_cardinal_prop(root, atoms[_NET_NUMBER_OF_DESKTOPS], &desktops, 1);
window_set_cardinal_prop(root, atoms[_NET_DESKTOP_GEOMETRY], geometry, 2); window_set_cardinal_prop(root, atoms[_NET_DESKTOP_GEOMETRY], geometry, 2);
window_set_cardinal_prop(root, atoms[_NET_DESKTOP_VIEWPORT], viewport, 2); window_set_cardinal_prop(root, atoms[_NET_DESKTOP_VIEWPORT], viewport, 2);
window_set_cardinal_prop(ewmh, atoms[_NET_WM_PID], &pid, 1); window_set_cardinal_prop(ewmh, atoms[_NET_WM_PID], &pid, 1);
XChangeProperty(display, ewmh, atoms[_NET_WM_NAME], XA_STRING, 8, PropModeReplace, (const unsigned char*)"xoat", 4); XChangeProperty(display, ewmh, atoms[_NET_WM_NAME], XA_STRING, 8, PropModeReplace, (const unsigned char*)"xoat", 4);
@@ -1163,10 +1110,8 @@ int main(int argc, char *argv[])
break; break;
case FocusIn: case FocusIn:
case FocusOut: case FocusOut:
focus_change(&ev.xfocus);
break;
case PropertyNotify: case PropertyNotify:
property_notify(&ev.xproperty); any_event(&ev);
break; break;
} }
} }