merge from master
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,4 +1,4 @@
|
|||||||
CFLAGS?=-Wall -Os
|
CFLAGS?=-Wall -Os -std=c99
|
||||||
LDADD?=`pkg-config --cflags --libs x11 xinerama`
|
LDADD?=`pkg-config --cflags --libs x11 xinerama`
|
||||||
|
|
||||||
normal:
|
normal:
|
||||||
|
|||||||
205
xoat.c
205
xoat.c
@@ -85,7 +85,7 @@ Atom atoms[ATOMS];
|
|||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
#define OVERLAP(a,b,c,d) (((a)==(c) && (b)==(d)) || MIN((a)+(b), (c)+(d)) - MAX((a), (c)) > 0)
|
#define OVERLAP(a,b,c,d) (((a)==(c) && (b)==(d)) || MIN((a)+(b), (c)+(d)) - MAX((a), (c)) > 0)
|
||||||
#define INTERSECT(x,y,w,h,x1,y1,w1,h1) (OVERLAP((x),(w),(x1),(w1)) && OVERLAP((y),(h),(y1),(h1)))
|
#define INTERSECT(x,y,w,h,x1,y1,w1,h1) (OVERLAP((x),(w),(x1),(w1)) && OVERLAP((y),(h),(y1),(h1)))
|
||||||
#define execsh(cmd) execlp("/bin/sh", "sh", "-c", (cmd), NULL)
|
#define EXECSH(cmd) execlp("/bin/sh", "sh", "-c", (cmd), NULL)
|
||||||
|
|
||||||
#define MAX_STRUT 150
|
#define MAX_STRUT 150
|
||||||
#define MAX_MONITORS 3
|
#define MAX_MONITORS 3
|
||||||
@@ -111,10 +111,13 @@ typedef struct {
|
|||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
Window transient, leader;
|
Window transient, leader;
|
||||||
Atom type, states[MAX_ATOMLIST+1];
|
Atom type, states[MAX_ATOMLIST+1];
|
||||||
short monitor, spot, visible, manage, input, urgent;
|
short monitor, visible, manage, input, urgent, full, above;
|
||||||
|
unsigned long spot;
|
||||||
char *class;
|
char *class;
|
||||||
} client;
|
} client;
|
||||||
|
|
||||||
|
void client_free(client*);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
long left, right, top, bottom,
|
long left, right, top, bottom,
|
||||||
ly1, ly2, ry1, ry3,
|
ly1, ly2, ry1, ry3,
|
||||||
@@ -127,6 +130,9 @@ typedef struct {
|
|||||||
Window windows[STACK];
|
Window windows[STACK];
|
||||||
} stack;
|
} stack;
|
||||||
|
|
||||||
|
#define STACK_INIT(n) stack (n); memset(&(n), 0, sizeof(stack))
|
||||||
|
#define STACK_FREE(s) while ((s)->depth) client_free((s)->clients[--(s)->depth])
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int mod;
|
unsigned int mod;
|
||||||
KeySym key;
|
KeySym key;
|
||||||
@@ -190,7 +196,7 @@ void exec_cmd(char *cmd)
|
|||||||
if (fork()) return;
|
if (fork()) return;
|
||||||
|
|
||||||
setsid();
|
setsid();
|
||||||
execsh(cmd);
|
EXECSH(cmd);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,12 +213,6 @@ int oops(Display *d, XErrorEvent *ee)
|
|||||||
return xerror(display, ee);
|
return xerror(display, ee);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int color_name_to_pixel(const char *name)
|
|
||||||
{
|
|
||||||
XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display));
|
|
||||||
return XAllocNamedColor(display, map, name, &color, &color) ? color.pixel: None;
|
|
||||||
}
|
|
||||||
|
|
||||||
int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, int bytes)
|
int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, int bytes)
|
||||||
{
|
{
|
||||||
memset(buffer, 0, bytes);
|
memset(buffer, 0, bytes);
|
||||||
@@ -229,53 +229,29 @@ int window_get_prop(Window w, Atom prop, Atom *type, int *items, void *buffer, i
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int window_get_atom_prop(Window w, Atom atom, Atom *list, int count)
|
Atom wgp_type; int wgp_items;
|
||||||
{
|
|
||||||
Atom type; int items;
|
|
||||||
return window_get_prop(w, atom, &type, &items, list, count*sizeof(Atom)) && type == XA_ATOM ? items:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void window_set_atom_prop(Window w, Atom prop, Atom *atoms, int count)
|
#define GETPROP_ATOM(w, a, l, c) (window_get_prop((w), (a), &wgp_type, &wgp_items, (l), (c)*sizeof(Atom)) && wgp_type == XA_ATOM ? wgp_items:0)
|
||||||
{
|
#define GETPROP_LONG(w, a, l, c) (window_get_prop((w), (a), &wgp_type, &wgp_items, (l), (c)*sizeof(unsigned long)) && wgp_type == XA_CARDINAL ? wgp_items:0)
|
||||||
XChangeProperty(display, w, prop, XA_ATOM, 32, PropModeReplace, (unsigned char*)atoms, count);
|
#define GETPROP_WIND(w, a, l, c) (window_get_prop((w), (a), &wgp_type, &wgp_items, (l), (c)*sizeof(Window)) && wgp_type == XA_WINDOW ? wgp_items:0)
|
||||||
}
|
|
||||||
|
|
||||||
int window_get_cardinal_prop(Window w, Atom atom, unsigned long *list, int count)
|
#define SETPROP_ATOM(w, p, a, c) XChangeProperty(display, (w), (p), XA_ATOM, 32, PropModeReplace, (unsigned char*)(a), (c))
|
||||||
{
|
#define SETPROP_LONG(w, p, a, c) XChangeProperty(display, (w), (p), XA_CARDINAL, 32, PropModeReplace, (unsigned char*)(a), (c))
|
||||||
Atom type; int items;
|
#define SETPROP_WIND(w, p, a, c) XChangeProperty(display, (w), (p), XA_WINDOW, 32, PropModeReplace, (unsigned char*)(a), (c))
|
||||||
return window_get_prop(w, atom, &type, &items, list, count*sizeof(unsigned long)) && type == XA_CARDINAL ? items:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void window_set_cardinal_prop(Window w, Atom prop, unsigned long *values, int count)
|
|
||||||
{
|
|
||||||
XChangeProperty(display, w, prop, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)values, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int window_get_window_prop(Window w, Atom atom, Window *list, int count)
|
|
||||||
{
|
|
||||||
Atom type; int items;
|
|
||||||
return window_get_prop(w, atom, &type, &items, list, count*sizeof(Window)) && type == XA_WINDOW ? items:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void window_set_window_prop(Window w, Atom prop, Window *values, int count)
|
|
||||||
{
|
|
||||||
XChangeProperty(display, w, prop, XA_WINDOW, 32, PropModeReplace, (unsigned char*)values, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int client_has_state(client *c, Atom state)
|
int client_has_state(client *c, Atom state)
|
||||||
{
|
{
|
||||||
int i;
|
for (int i = 0; i < MAX_ATOMLIST && c->states[i]; i++)
|
||||||
for (i = 0; i < MAX_ATOMLIST && c->states[i]; i++)
|
|
||||||
if (c->states[i] == state) return 1;
|
if (c->states[i] == state) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_update_border(client *c)
|
void client_update_border(client *c)
|
||||||
{
|
{
|
||||||
XSetWindowBorder(display, c->window,
|
XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display));
|
||||||
color_name_to_pixel(c->window == current ? BORDER_FOCUS: (c->urgent ? BORDER_URGENT:
|
char *colorname = c->window == current ? BORDER_FOCUS: (c->urgent ? BORDER_URGENT: (c->above ? BORDER_ABOVE: BORDER_BLUR));
|
||||||
(client_has_state(c, atoms[_NET_WM_STATE_ABOVE]) ? BORDER_ABOVE: BORDER_BLUR))));
|
XSetWindowBorder(display, c->window, XAllocNamedColor(display, map, colorname, &color, &color) ? color.pixel: None);
|
||||||
XSetWindowBorderWidth(display, c->window, client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]) ? 0: BORDER);
|
XSetWindowBorderWidth(display, c->window, c->full ? 0: BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_toggle_state(client *c, Atom state)
|
int client_toggle_state(client *c, Atom state)
|
||||||
@@ -291,7 +267,10 @@ int client_toggle_state(client *c, Atom state)
|
|||||||
c->states[j++] = state;
|
c->states[j++] = state;
|
||||||
rc = 1;
|
rc = 1;
|
||||||
}
|
}
|
||||||
window_set_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, j);
|
SETPROP_ATOM(c->window, atoms[_NET_WM_STATE], c->states, j);
|
||||||
|
if (state == atoms[_NET_WM_STATE_FULLSCREEN]) c->full = rc;
|
||||||
|
if (state == atoms[_NET_WM_STATE_ABOVE]) c->above = rc;
|
||||||
|
if (state == atoms[_NET_WM_STATE_DEMANDS_ATTENTION]) c->urgent = rc;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,8 +286,8 @@ client* window_build_client(Window win)
|
|||||||
{
|
{
|
||||||
c->visible = c->attr.map_state == IsViewable ? 1:0;
|
c->visible = c->attr.map_state == IsViewable ? 1:0;
|
||||||
XGetTransientForHint(display, c->window, &c->transient);
|
XGetTransientForHint(display, c->window, &c->transient);
|
||||||
window_get_atom_prop(win, atoms[_NET_WM_WINDOW_TYPE], &c->type, 1);
|
GETPROP_ATOM(win, atoms[_NET_WM_WINDOW_TYPE], &c->type, 1);
|
||||||
window_get_window_prop(win, atoms[WM_CLIENT_LEADER], &c->leader, 1);
|
GETPROP_WIND(win, atoms[WM_CLIENT_LEADER], &c->leader, 1);
|
||||||
|
|
||||||
c->manage = !c->attr.override_redirect
|
c->manage = !c->attr.override_redirect
|
||||||
&& c->type != atoms[_NET_WM_WINDOW_TYPE_DESKTOP]
|
&& c->type != atoms[_NET_WM_WINDOW_TYPE_DESKTOP]
|
||||||
@@ -331,8 +310,10 @@ client* window_build_client(Window win)
|
|||||||
|
|
||||||
if (c->visible)
|
if (c->visible)
|
||||||
{
|
{
|
||||||
window_get_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, MAX_ATOMLIST);
|
GETPROP_ATOM(c->window, atoms[_NET_WM_STATE], c->states, MAX_ATOMLIST);
|
||||||
c->urgent = client_has_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]);
|
c->urgent = client_has_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]);
|
||||||
|
c->full = client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]);
|
||||||
|
c->above = client_has_state(c, atoms[_NET_WM_STATE_ABOVE]);
|
||||||
|
|
||||||
if ((hints = XGetWMHints(display, c->window)))
|
if ((hints = XGetWMHints(display, c->window)))
|
||||||
{
|
{
|
||||||
@@ -359,12 +340,6 @@ void client_free(client *c)
|
|||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stack_free(stack *s)
|
|
||||||
{
|
|
||||||
while (s->depth)
|
|
||||||
client_free(s->clients[--s->depth]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// build windows cache
|
// build windows cache
|
||||||
void query_windows()
|
void query_windows()
|
||||||
{
|
{
|
||||||
@@ -385,20 +360,17 @@ void query_windows()
|
|||||||
|
|
||||||
void ewmh_client_list()
|
void ewmh_client_list()
|
||||||
{
|
{
|
||||||
int i; client *c; stack wins;
|
int i; client *c; STACK_INIT(wins);
|
||||||
memset(&wins, 0, sizeof(stack));
|
|
||||||
|
|
||||||
for_windows_rev(i, c) if (c->manage)
|
for_windows_rev(i, c) if (c->manage)
|
||||||
wins.windows[wins.depth++] = c->window;
|
wins.windows[wins.depth++] = c->window;
|
||||||
|
SETPROP_WIND(root, atoms[_NET_CLIENT_LIST_STACKING], wins.windows, wins.depth);
|
||||||
window_set_window_prop(root, atoms[_NET_CLIENT_LIST_STACKING], wins.windows, wins.depth);
|
|
||||||
// hack for now, since we dont track window mapping history
|
// hack for now, since we dont track window mapping history
|
||||||
window_set_window_prop(root, atoms[_NET_CLIENT_LIST], wins.windows, wins.depth);
|
SETPROP_WIND(root, atoms[_NET_CLIENT_LIST], wins.windows, wins.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask)
|
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask)
|
||||||
{
|
{
|
||||||
XEvent e; memset(&e, 0, sizeof(XEvent));
|
XEvent e;
|
||||||
e.xclient.type = ClientMessage;
|
e.xclient.type = ClientMessage;
|
||||||
e.xclient.message_type = atom;
|
e.xclient.message_type = atom;
|
||||||
e.xclient.window = subject;
|
e.xclient.window = subject;
|
||||||
@@ -414,18 +386,12 @@ 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)
|
||||||
{
|
{
|
||||||
Atom protocols[MAX_ATOMLIST]; int i, n;
|
Atom protocols[MAX_ATOMLIST]; int i, n;
|
||||||
if ((n = window_get_atom_prop(c->window, atoms[WM_PROTOCOLS], protocols, MAX_ATOMLIST)))
|
if ((n = GETPROP_ATOM(c->window, atoms[WM_PROTOCOLS], protocols, MAX_ATOMLIST)))
|
||||||
for (i = 0; i < n; i++) if (protocols[i] == protocol)
|
for (i = 0; i < n; i++) if (protocols[i] == protocol)
|
||||||
return window_send_clientmessage(c->window, c->window, atoms[WM_PROTOCOLS], protocol, NoEventMask);
|
return window_send_clientmessage(c->window, c->window, atoms[WM_PROTOCOLS], protocol, NoEventMask);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_close(client *c)
|
|
||||||
{
|
|
||||||
if (c && !client_send_wm_protocol(c, atoms[WM_DELETE_WINDOW]))
|
|
||||||
XKillClient(display, c->window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void client_place_spot(client *c, int spot, int mon, int force)
|
void client_place_spot(client *c, int spot, int mon, int force)
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
@@ -462,7 +428,7 @@ void client_place_spot(client *c, int spot, int mon, int force)
|
|||||||
h = c->attr.height + BORDER*2;
|
h = c->attr.height + BORDER*2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
if (c->full)
|
||||||
{
|
{
|
||||||
XMoveResizeWindow(display, c->window, m->x, m->y, m->w, m->h);
|
XMoveResizeWindow(display, c->window, m->x, m->y, m->w, m->h);
|
||||||
return;
|
return;
|
||||||
@@ -521,17 +487,14 @@ void client_stack_family(client *c, stack *raise)
|
|||||||
void client_raise_family(client *c)
|
void client_raise_family(client *c)
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
int i; client *o; stack raise, family;
|
int i; client *o; STACK_INIT(raise); STACK_INIT(family);
|
||||||
memset(&raise, 0, sizeof(stack));
|
|
||||||
memset(&family, 0, sizeof(stack));
|
|
||||||
|
|
||||||
for_windows(i, o) if (o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK])
|
for_windows(i, o) if (o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK])
|
||||||
client_stack_family(o, &raise);
|
client_stack_family(o, &raise);
|
||||||
|
|
||||||
// above only counts for fullscreen windows
|
// above only counts for fullscreen windows
|
||||||
if (client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
if (c->full) for_windows(i, o) if (o->above)
|
||||||
for_windows(i, o) if (client_has_state(o, atoms[_NET_WM_STATE_ABOVE]))
|
client_stack_family(o, &raise);
|
||||||
client_stack_family(o, &raise);
|
|
||||||
|
|
||||||
while (c->transient && (o = window_build_client(c->transient)))
|
while (c->transient && (o = window_build_client(c->transient)))
|
||||||
c = family.clients[family.depth++] = o;
|
c = family.clients[family.depth++] = o;
|
||||||
@@ -539,18 +502,18 @@ void client_raise_family(client *c)
|
|||||||
client_stack_family(c, &raise);
|
client_stack_family(c, &raise);
|
||||||
XRaiseWindow(display, raise.windows[0]);
|
XRaiseWindow(display, raise.windows[0]);
|
||||||
XRestackWindows(display, raise.windows, raise.depth);
|
XRestackWindows(display, raise.windows, raise.depth);
|
||||||
stack_free(&family);
|
STACK_FREE(&family);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_set_focus(client *c)
|
void client_set_focus(client *c)
|
||||||
{
|
{
|
||||||
if (!c || !c->visible || c->window == current) return;
|
if (!c || !c->visible || c->window == current) return;
|
||||||
Window old = current;
|
client *o; Window old = current;
|
||||||
|
|
||||||
current = c->window;
|
current = c->window;
|
||||||
current_spot = c->spot;
|
current_spot = c->spot;
|
||||||
current_mon = c->monitor;
|
current_mon = c->monitor;
|
||||||
|
|
||||||
client *o;
|
|
||||||
if (old && (o = window_build_client(old)))
|
if (old && (o = window_build_client(old)))
|
||||||
{
|
{
|
||||||
client_update_border(o);
|
client_update_border(o);
|
||||||
@@ -558,7 +521,7 @@ void client_set_focus(client *c)
|
|||||||
}
|
}
|
||||||
client_send_wm_protocol(c, atoms[WM_TAKE_FOCUS]);
|
client_send_wm_protocol(c, atoms[WM_TAKE_FOCUS]);
|
||||||
XSetInputFocus(display, c->input ? c->window: PointerRoot, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(display, c->input ? c->window: PointerRoot, RevertToPointerRoot, CurrentTime);
|
||||||
window_set_window_prop(root, atoms[_NET_ACTIVE_WINDOW], &c->window, 1);
|
SETPROP_WIND(root, atoms[_NET_ACTIVE_WINDOW], &c->window, 1);
|
||||||
client_update_border(c);
|
client_update_border(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,16 +564,6 @@ int spot_choose_by_direction(int spot, int mon, int dir)
|
|||||||
return spot;
|
return spot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_spot_cycle(client *c)
|
|
||||||
{
|
|
||||||
if (!c) return;
|
|
||||||
spot_focus_top_window(c->spot, c->monitor, c->window);
|
|
||||||
stack lower; memset(&lower, 0, sizeof(stack));
|
|
||||||
client_stack_family(c, &lower);
|
|
||||||
XLowerWindow(display, lower.windows[0]);
|
|
||||||
XRestackWindows(display, lower.windows, lower.depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
void window_listen(Window win)
|
void window_listen(Window win)
|
||||||
{
|
{
|
||||||
XSelectInput(display, win, EnterWindowMask | LeaveWindowMask | FocusChangeMask | PropertyChangeMask);
|
XSelectInput(display, win, EnterWindowMask | LeaveWindowMask | FocusChangeMask | PropertyChangeMask);
|
||||||
@@ -644,12 +597,18 @@ void action_focus_direction(void *data, int num, client *cli)
|
|||||||
|
|
||||||
void action_close(void *data, int num, client *cli)
|
void action_close(void *data, int num, client *cli)
|
||||||
{
|
{
|
||||||
if (cli) client_close(cli);
|
if (cli && !client_send_wm_protocol(cli, atoms[WM_DELETE_WINDOW]))
|
||||||
|
XKillClient(display, cli->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_cycle(void *data, int num, client *cli)
|
void action_cycle(void *data, int num, client *cli)
|
||||||
{
|
{
|
||||||
if (cli) client_spot_cycle(cli);
|
if (!cli) return;
|
||||||
|
STACK_INIT(lower);
|
||||||
|
spot_focus_top_window(cli->spot, cli->monitor, cli->window);
|
||||||
|
client_stack_family(cli, &lower);
|
||||||
|
XLowerWindow(display, lower.windows[0]);
|
||||||
|
XRestackWindows(display, lower.windows, lower.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_other(void *data, int num, client *cli)
|
void action_other(void *data, int num, client *cli)
|
||||||
@@ -665,11 +624,9 @@ void action_command(void *data, int num, client *cli)
|
|||||||
void action_find_or_start(void *data, int num, client *cli)
|
void action_find_or_start(void *data, int num, client *cli)
|
||||||
{
|
{
|
||||||
int i; client *c; char *class = data;
|
int i; client *c; char *class = data;
|
||||||
|
|
||||||
for_windows(i, c)
|
for_windows(i, c)
|
||||||
if (c->visible && c->manage && c->class && !strcasecmp(c->class, class))
|
if (c->visible && c->manage && c->class && !strcasecmp(c->class, class))
|
||||||
{ client_activate(c); return; }
|
{ client_activate(c); return; }
|
||||||
|
|
||||||
exec_cmd(class);
|
exec_cmd(class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,18 +649,12 @@ void action_focus_monitor(void *data, int num, client *cli)
|
|||||||
void action_fullscreen(void *data, int num, client *cli)
|
void action_fullscreen(void *data, int num, client *cli)
|
||||||
{
|
{
|
||||||
if (!cli) return;
|
if (!cli) return;
|
||||||
unsigned long spot = cli->spot;
|
if (cli->full) GETPROP_LONG(cli->window, atoms[XOAT_SPOT], &cli->spot, 1);
|
||||||
client_raise_family(cli);
|
else SETPROP_LONG(cli->window, atoms[XOAT_SPOT], &cli->spot, 1);
|
||||||
cli->spot = SPOT1;
|
client_toggle_state(cli, atoms[_NET_WM_STATE_FULLSCREEN]);
|
||||||
|
client_place_spot(cli, cli->full ? SPOT1: cli->spot, cli->monitor, 1);
|
||||||
if (client_toggle_state(cli, atoms[_NET_WM_STATE_FULLSCREEN]))
|
|
||||||
window_set_cardinal_prop(cli->window, atoms[XOAT_SPOT], &spot, 1);
|
|
||||||
else
|
|
||||||
if (window_get_cardinal_prop(cli->window, atoms[XOAT_SPOT], &spot, 1))
|
|
||||||
cli->spot = spot;
|
|
||||||
|
|
||||||
client_update_border(cli);
|
client_update_border(cli);
|
||||||
client_place_spot(cli, cli->spot, cli->monitor, 1);
|
client_raise_family(cli);
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_above(void *data, int num, client *cli)
|
void action_above(void *data, int num, client *cli)
|
||||||
@@ -717,13 +668,9 @@ void action_above(void *data, int num, client *cli)
|
|||||||
void action_snapshot(void *data, int num, client *cli)
|
void action_snapshot(void *data, int num, client *cli)
|
||||||
{
|
{
|
||||||
int i; client *c;
|
int i; client *c;
|
||||||
stack_free(&snapshot);
|
STACK_FREE(&snapshot);
|
||||||
|
for_windows(i, c) if (c->manage && c->class)
|
||||||
for_windows(i, c) if (c->manage)
|
snapshot.clients[snapshot.depth++] = window_build_client(c->window);
|
||||||
{
|
|
||||||
snapshot.clients[snapshot.depth] = window_build_client(c->window);
|
|
||||||
snapshot.windows[snapshot.depth++] = c->window;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_rollback(void *data, int num, client *cli)
|
void action_rollback(void *data, int num, client *cli)
|
||||||
@@ -835,10 +782,9 @@ void map_notify(XEvent *e)
|
|||||||
|
|
||||||
void unmap_notify(XEvent *e)
|
void unmap_notify(XEvent *e)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
// if this window was focused, find something else
|
// if this window was focused, find something else
|
||||||
if (e->xunmap.window == current && !spot_focus_top_window(current_spot, current_mon, current))
|
if (e->xunmap.window == current && !spot_focus_top_window(current_spot, current_mon, current))
|
||||||
for_spots(i) if (spot_focus_top_window(i, current_mon, current)) break;
|
{ int i; for_spots(i) if (spot_focus_top_window(i, current_mon, current)) break; }
|
||||||
ewmh_client_list();
|
ewmh_client_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,8 +795,8 @@ void key_press(XEvent *ev)
|
|||||||
unsigned int state = e->state & ~(LockMask|NumlockMask);
|
unsigned int state = e->state & ~(LockMask|NumlockMask);
|
||||||
while (XCheckTypedEvent(display, KeyPress, ev));
|
while (XCheckTypedEvent(display, KeyPress, ev));
|
||||||
|
|
||||||
int i; binding *bind = NULL;
|
binding *bind = NULL;
|
||||||
for (i = 0; i < sizeof(keys)/sizeof(binding) && !bind; i++)
|
for (int i = 0; i < sizeof(keys)/sizeof(binding) && !bind; i++)
|
||||||
if (keys[i].key == key && (keys[i].mod == AnyModifier || keys[i].mod == state))
|
if (keys[i].key == key && (keys[i].mod == AnyModifier || keys[i].mod == state))
|
||||||
bind = &keys[i];
|
bind = &keys[i];
|
||||||
|
|
||||||
@@ -883,13 +829,13 @@ void client_message(XEvent *ev)
|
|||||||
if (e->message_type == atoms[XOAT_RESTART])
|
if (e->message_type == atoms[XOAT_RESTART])
|
||||||
{
|
{
|
||||||
warnx("restart!");
|
warnx("restart!");
|
||||||
execsh(self);
|
EXECSH(self);
|
||||||
}
|
}
|
||||||
client *c = window_build_client(e->window);
|
client *c = window_build_client(e->window);
|
||||||
if (c && c->manage)
|
if (c && c->manage)
|
||||||
{
|
{
|
||||||
if (e->message_type == atoms[_NET_ACTIVE_WINDOW]) client_activate(c);
|
if (e->message_type == atoms[_NET_ACTIVE_WINDOW]) client_activate(c);
|
||||||
if (e->message_type == atoms[_NET_CLOSE_WINDOW]) client_close(c);
|
if (e->message_type == atoms[_NET_CLOSE_WINDOW]) action_close(NULL, 0, c);
|
||||||
}
|
}
|
||||||
client_free(c);
|
client_free(c);
|
||||||
}
|
}
|
||||||
@@ -919,7 +865,7 @@ void (*handlers[LASTEvent])(XEvent*) = {
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, j; client *c; XEvent ev;
|
int i, j; client *c; XEvent ev; Atom msg = None;
|
||||||
wm_strut struts; memset(&struts, 0, sizeof(wm_strut));
|
wm_strut struts; memset(&struts, 0, sizeof(wm_strut));
|
||||||
|
|
||||||
if (!(display = XOpenDisplay(0))) return 1;
|
if (!(display = XOpenDisplay(0))) return 1;
|
||||||
@@ -935,7 +881,6 @@ int main(int argc, char *argv[])
|
|||||||
// check for restart/exit
|
// check for restart/exit
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
Atom msg = None;
|
|
||||||
Window cli = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, None, None);
|
Window cli = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, None, None);
|
||||||
if (!strcmp(argv[1], "restart")) msg = atoms[XOAT_RESTART];
|
if (!strcmp(argv[1], "restart")) msg = atoms[XOAT_RESTART];
|
||||||
else if (!strcmp(argv[1], "exit")) msg = atoms[XOAT_EXIT];
|
else if (!strcmp(argv[1], "exit")) msg = atoms[XOAT_EXIT];
|
||||||
@@ -956,9 +901,9 @@ int main(int argc, char *argv[])
|
|||||||
for (i = 0; i < nmonitors; i++)
|
for (i = 0; i < nmonitors; i++)
|
||||||
{
|
{
|
||||||
monitors[i].x = info[i].x_org;
|
monitors[i].x = info[i].x_org;
|
||||||
monitors[i].y = info[i].y_org + struts.top;
|
monitors[i].y = info[i].y_org;
|
||||||
monitors[i].w = info[i].width;
|
monitors[i].w = info[i].width;
|
||||||
monitors[i].h = info[i].height - struts.top - struts.bottom;
|
monitors[i].h = info[i].height;
|
||||||
}
|
}
|
||||||
XFree(info);
|
XFree(info);
|
||||||
}
|
}
|
||||||
@@ -967,8 +912,8 @@ int main(int argc, char *argv[])
|
|||||||
for_windows(i, c)
|
for_windows(i, c)
|
||||||
{
|
{
|
||||||
wm_strut strut; memset(&strut, 0, sizeof(wm_strut));
|
wm_strut strut; memset(&strut, 0, sizeof(wm_strut));
|
||||||
int v2 = window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT_PARTIAL], (unsigned long*)&strut, 12);
|
int v2 = GETPROP_LONG(c->window, atoms[_NET_WM_STRUT_PARTIAL], (unsigned long*)&strut, 12);
|
||||||
int v1 = v2 ? 0: window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT], (unsigned long*)&strut, 4);
|
int v1 = v2 ? 0: GETPROP_LONG(c->window, atoms[_NET_WM_STRUT], (unsigned long*)&strut, 4);
|
||||||
if (!c->visible || (!v1 && !v2)) continue;
|
if (!c->visible || (!v1 && !v2)) continue;
|
||||||
|
|
||||||
for (j = 0; j < nmonitors; j++)
|
for (j = 0; j < nmonitors; j++)
|
||||||
@@ -1061,9 +1006,9 @@ int main(int argc, char *argv[])
|
|||||||
unsigned long pid = getpid();
|
unsigned long pid = getpid();
|
||||||
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);
|
SETPROP_ATOM(root, atoms[_NET_SUPPORTED], atoms, ATOMS);
|
||||||
window_set_window_prop(root, atoms[_NET_SUPPORTING_WM_CHECK], &ewmh, 1);
|
SETPROP_WIND(root, atoms[_NET_SUPPORTING_WM_CHECK], &ewmh, 1);
|
||||||
window_set_cardinal_prop(ewmh, atoms[_NET_WM_PID], &pid, 1);
|
SETPROP_LONG(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);
|
||||||
|
|
||||||
@@ -1091,21 +1036,19 @@ int main(int argc, char *argv[])
|
|||||||
XGrabButton(display, Button3, AnyModifier, root, True, ButtonPressMask, GrabModeSync, GrabModeSync, None, None);
|
XGrabButton(display, Button3, AnyModifier, root, True, ButtonPressMask, GrabModeSync, GrabModeSync, None, None);
|
||||||
|
|
||||||
// setup existing managable windows
|
// setup existing managable windows
|
||||||
stack_free(&windows);
|
STACK_FREE(&windows);
|
||||||
for_windows(i, c) if (c->manage)
|
for_windows(i, c) if (c->manage)
|
||||||
{
|
{
|
||||||
window_listen(c->window);
|
window_listen(c->window);
|
||||||
client_update_border(c);
|
client_update_border(c);
|
||||||
client_place_spot(c, c->spot, c->monitor, 0);
|
client_place_spot(c, c->spot, c->monitor, 0);
|
||||||
|
|
||||||
// only activate first one
|
|
||||||
if (!current) client_activate(c);
|
if (!current) client_activate(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// main event loop
|
// main event loop
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
stack_free(&windows);
|
STACK_FREE(&windows);
|
||||||
XNextEvent(display, &ev);
|
XNextEvent(display, &ev);
|
||||||
if (handlers[ev.type])
|
if (handlers[ev.type])
|
||||||
handlers[ev.type](&ev);
|
handlers[ev.type](&ev);
|
||||||
|
|||||||
Reference in New Issue
Block a user