refactoring
This commit is contained in:
35
proto.h
35
proto.h
@@ -1,7 +1,7 @@
|
|||||||
void catch_exit(int sig);
|
void catch_exit(int sig);
|
||||||
int execsh(char *cmd);
|
int execsh(char *cmd);
|
||||||
int oops(Display *d, XErrorEvent *ee);
|
int oops(Display *d, XErrorEvent *ee);
|
||||||
unsigned int color_get(const char *name);
|
unsigned int color_name_to_pixel(const char *name);
|
||||||
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);
|
||||||
int window_get_atom_prop(Window w, Atom atom, Atom *list, int count);
|
int window_get_atom_prop(Window w, Atom atom, Atom *list, int count);
|
||||||
void window_set_atom_prop(Window w, Atom prop, Atom *atoms, int count);
|
void window_set_atom_prop(Window w, Atom prop, Atom *atoms, int count);
|
||||||
@@ -9,26 +9,25 @@ int window_get_cardinal_prop(Window w, Atom atom, unsigned long *list, int count
|
|||||||
void window_set_cardinal_prop(Window w, Atom prop, unsigned long *values, int count);
|
void window_set_cardinal_prop(Window w, Atom prop, unsigned long *values, int count);
|
||||||
void window_set_window_prop(Window w, Atom prop, Window *values, int count);
|
void window_set_window_prop(Window w, Atom prop, Window *values, int count);
|
||||||
void ewmh_client_list();
|
void ewmh_client_list();
|
||||||
client* window_client(Window win);
|
client* window_build_client(Window win);
|
||||||
int client_state(client *c, Atom state);
|
|
||||||
int client_add_state(client *c, Atom state);
|
|
||||||
int client_drop_state(client *c, Atom state);
|
|
||||||
void windows_visible(stack *s);
|
|
||||||
int window_message(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask);
|
|
||||||
void client_free(client *c);
|
void client_free(client *c);
|
||||||
int client_protocol(client *c, Atom protocol);
|
int client_has_state(client *c, Atom state);
|
||||||
|
int client_toggle_state(client *c, Atom state);
|
||||||
|
void query_visible_windows(stack *s);
|
||||||
|
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask);
|
||||||
|
int client_send_wm_protocol(client *c, Atom protocol);
|
||||||
void client_close(client *c);
|
void client_close(client *c);
|
||||||
void client_position(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_xywh(int spot, int mon, 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_spot(client *c, int spot, int force);
|
void client_place_spot(client *c, int spot, int force);
|
||||||
void client_cycle(client *c);
|
void client_spot_cycle(client *c);
|
||||||
Window spot_active(int spot, int mon, Window except);
|
Window spot_focus_top_window(int spot, int mon, Window except);
|
||||||
void client_stack(client *c, stack *all, stack *raise);
|
void client_stack_family(client *c, stack *all, stack *raise);
|
||||||
void client_raise(client *c);
|
void client_raise_family(client *c);
|
||||||
void client_active(client *c);
|
void client_set_focus(client *c);
|
||||||
void window_listen(Window win);
|
void window_listen(Window win);
|
||||||
void client_review(client *c);
|
void client_update_border(client *c);
|
||||||
void client_set_tags(client *c);
|
void client_flush_tags(client *c);
|
||||||
void action_move(void *data, int num);
|
void action_move(void *data, int num);
|
||||||
void action_focus(void *data, int num);
|
void action_focus(void *data, int num);
|
||||||
void action_close(void *data, int num);
|
void action_close(void *data, int num);
|
||||||
|
|||||||
459
xoat.c
459
xoat.c
@@ -36,11 +36,9 @@ void catch_exit(int sig)
|
|||||||
|
|
||||||
int execsh(char *cmd)
|
int execsh(char *cmd)
|
||||||
{
|
{
|
||||||
// use sh for args parsing
|
|
||||||
return execlp("/bin/sh", "sh", "-c", cmd, NULL);
|
return execlp("/bin/sh", "sh", "-c", cmd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute sub-process
|
|
||||||
pid_t exec_cmd(char *cmd)
|
pid_t exec_cmd(char *cmd)
|
||||||
{
|
{
|
||||||
if (!cmd || !cmd[0]) return -1;
|
if (!cmd || !cmd[0]) return -1;
|
||||||
@@ -69,14 +67,12 @@ int oops(Display *d, XErrorEvent *ee)
|
|||||||
return xerror(display, ee);
|
return xerror(display, ee);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get pixel value for X named color
|
unsigned int color_name_to_pixel(const char *name)
|
||||||
unsigned int color_get(const char *name)
|
|
||||||
{
|
{
|
||||||
XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display));
|
XColor color; Colormap map = DefaultColormap(display, DefaultScreen(display));
|
||||||
return XAllocNamedColor(display, map, name, &color, &color) ? color.pixel: None;
|
return XAllocNamedColor(display, map, name, &color, &color) ? color.pixel: None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve a property of any type from a window
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
Atom _type; if (!type) type = &_type;
|
Atom _type; if (!type) type = &_type;
|
||||||
@@ -127,7 +123,7 @@ void ewmh_client_list()
|
|||||||
{
|
{
|
||||||
int i; client *c; stack all, wins;
|
int i; client *c; stack all, wins;
|
||||||
memset(&wins, 0, sizeof(stack));
|
memset(&wins, 0, sizeof(stack));
|
||||||
windows_visible(&all);
|
query_visible_windows(&all);
|
||||||
|
|
||||||
for (i = all.depth-1; i > -1; i--)
|
for (i = all.depth-1; i > -1; i--)
|
||||||
{
|
{
|
||||||
@@ -142,8 +138,7 @@ void ewmh_client_list()
|
|||||||
window_set_window_prop(root, atoms[_NET_CLIENT_LIST], wins.windows, wins.depth);
|
window_set_window_prop(root, atoms[_NET_CLIENT_LIST], wins.windows, wins.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
// build a client struct
|
client* window_build_client(Window win)
|
||||||
client* window_client(Window win)
|
|
||||||
{
|
{
|
||||||
int i, x, y, w, h;
|
int i, x, y, w, h;
|
||||||
if (win == None) return NULL;
|
if (win == None) return NULL;
|
||||||
@@ -173,18 +168,18 @@ client* window_client(Window win)
|
|||||||
|
|
||||||
c->spot = SPOT1;
|
c->spot = SPOT1;
|
||||||
|
|
||||||
spot_xywh(SPOT2, c->monitor, &x, &y, &w, &h);
|
spot_calc_xywh(SPOT2, c->monitor, &x, &y, &w, &h);
|
||||||
if (INTERSECT(x, y, w, h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1))
|
if (INTERSECT(x, y, w, h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1))
|
||||||
c->spot = SPOT2;
|
c->spot = SPOT2;
|
||||||
|
|
||||||
spot_xywh(SPOT3, c->monitor, &x, &y, &w, &h);
|
spot_calc_xywh(SPOT3, c->monitor, &x, &y, &w, &h);
|
||||||
if (INTERSECT(x, y, w, h, c->attr.x + c->attr.width/2, c->attr.y+c->attr.height/2, 1, 1))
|
if (INTERSECT(x, y, w, h, 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)
|
||||||
{
|
{
|
||||||
window_get_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, MAX_NET_WM_STATES);
|
window_get_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, MAX_NET_WM_STATES);
|
||||||
c->urgent = client_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]);
|
c->urgent = client_has_state(c, atoms[_NET_WM_STATE_DEMANDS_ATTENTION]);
|
||||||
|
|
||||||
unsigned long tags = 0;
|
unsigned long tags = 0;
|
||||||
if (window_get_cardinal_prop(c->window, atoms[XOAT_TAGS], &tags, 1))
|
if (window_get_cardinal_prop(c->window, atoms[XOAT_TAGS], &tags, 1))
|
||||||
@@ -213,7 +208,14 @@ client* window_client(Window win)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_state(client *c, Atom state)
|
void client_free(client *c)
|
||||||
|
{
|
||||||
|
if (!c) return;
|
||||||
|
free(c->class);
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int client_has_state(client *c, Atom state)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < MAX_NET_WM_STATES && c->states[i]; i++)
|
for (i = 0; i < MAX_NET_WM_STATES && c->states[i]; i++)
|
||||||
@@ -222,41 +224,26 @@ int client_state(client *c, Atom state)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int client_add_state(client *c, Atom state)
|
int client_toggle_state(client *c, Atom state)
|
||||||
{
|
{
|
||||||
int i;
|
int i, j, rc = 0;
|
||||||
for (i = 0; i < MAX_NET_WM_STATES; i++)
|
for (i = 0, j = 0; i < MAX_NET_WM_STATES && c->states[i]; i++, j++)
|
||||||
{
|
{
|
||||||
if (c->states[i]) continue;
|
if (c->states[i] == state) i++;
|
||||||
c->states[i] = state;
|
c->states[j] = c->states[i];
|
||||||
window_set_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, i+1);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
if (i == j && j < MAX_NET_WM_STATES)
|
||||||
}
|
|
||||||
|
|
||||||
int client_drop_state(client *c, Atom state)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
for (i = 0, j = 0; i < MAX_NET_WM_STATES && c->states[i]; i++)
|
|
||||||
{
|
{
|
||||||
if (c->states[i] == state) continue;
|
c->states[j++] = state;
|
||||||
c->states[i] = c->states[j++];
|
rc = 1;
|
||||||
}
|
}
|
||||||
window_set_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, j);
|
window_set_atom_prop(c->window, atoms[_NET_WM_STATE], c->states, j);
|
||||||
int rc = i != j ? 1:0;
|
|
||||||
|
|
||||||
for (; j < MAX_NET_WM_STATES; j++)
|
|
||||||
c->states[j] = None;
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// build a list of visible windows
|
void query_visible_windows(stack *s)
|
||||||
void windows_visible(stack *s)
|
|
||||||
{
|
{
|
||||||
// check if the window list is cached
|
if (inplay.depth) // cached?
|
||||||
if (inplay.depth)
|
|
||||||
{
|
{
|
||||||
memmove(s, &inplay, sizeof(stack));
|
memmove(s, &inplay, sizeof(stack));
|
||||||
return;
|
return;
|
||||||
@@ -267,7 +254,7 @@ void windows_visible(stack *s)
|
|||||||
{
|
{
|
||||||
for (i = nwins-1; i > -1; i--)
|
for (i = nwins-1; i > -1; i--)
|
||||||
{
|
{
|
||||||
if ((c = window_client(wins[i])) && c->visible && s->depth < STACK)
|
if ((c = window_build_client(wins[i])) && 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];
|
||||||
@@ -279,8 +266,7 @@ void windows_visible(stack *s)
|
|||||||
memmove(&inplay, s, sizeof(stack));
|
memmove(&inplay, s, sizeof(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
// send a ClientMessage (for WM_PROTOCOLS)
|
int window_send_clientmessage(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask)
|
||||||
int window_message(Window target, Window subject, Atom atom, unsigned long protocol, unsigned long mask)
|
|
||||||
{
|
{
|
||||||
XEvent e; memset(&e, 0, sizeof(XEvent));
|
XEvent e; memset(&e, 0, sizeof(XEvent));
|
||||||
e.xclient.type = ClientMessage;
|
e.xclient.type = ClientMessage;
|
||||||
@@ -295,15 +281,7 @@ int window_message(Window target, Window subject, Atom atom, unsigned long proto
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_free(client *c)
|
int client_send_wm_protocol(client *c, Atom protocol)
|
||||||
{
|
|
||||||
if (!c) return;
|
|
||||||
free(c->class);
|
|
||||||
free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// WM_PROTOCOLS
|
|
||||||
int client_protocol(client *c, Atom protocol)
|
|
||||||
{
|
{
|
||||||
Atom *protocols = NULL;
|
Atom *protocols = NULL;
|
||||||
int i, found = 0, num_pro = 0;
|
int i, found = 0, num_pro = 0;
|
||||||
@@ -311,23 +289,23 @@ int client_protocol(client *c, Atom protocol)
|
|||||||
for (i = 0; i < num_pro && !found; i++)
|
for (i = 0; i < num_pro && !found; i++)
|
||||||
if (protocols[i] == protocol) found = 1;
|
if (protocols[i] == protocol) found = 1;
|
||||||
if (found)
|
if (found)
|
||||||
window_message(c->window, c->window, atoms[WM_PROTOCOLS], protocol, NoEventMask);
|
window_send_clientmessage(c->window, c->window, atoms[WM_PROTOCOLS], protocol, NoEventMask);
|
||||||
if (protocols) XFree(protocols);
|
if (protocols) XFree(protocols);
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_close(client *c)
|
void client_close(client *c)
|
||||||
{
|
{
|
||||||
if (!client_protocol(c, atoms[WM_DELETE_WINDOW]))
|
if (!client_send_wm_protocol(c, atoms[WM_DELETE_WINDOW]))
|
||||||
XKillClient(display, c->window);
|
XKillClient(display, c->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_position(client *c, int x, int y, int w, int h)
|
void client_position_xywh(client *c, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
monitor *m = &monitors[c->monitor];
|
monitor *m = &monitors[c->monitor];
|
||||||
|
|
||||||
if (client_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
if (client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
||||||
{
|
{
|
||||||
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;
|
||||||
@@ -378,8 +356,7 @@ void client_position(client *c, int x, int y, int w, int h)
|
|||||||
XMoveResizeWindow(display, c->window, x, y, w, h);
|
XMoveResizeWindow(display, c->window, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return co-ords for a screen "spot"
|
void spot_calc_xywh(int spot, int mon, int *x, int *y, int *w, int *h)
|
||||||
void spot_xywh(int spot, int mon, int *x, int *y, int *w, int *h)
|
|
||||||
{
|
{
|
||||||
spot = MAX(SPOT1, MIN(SPOT3, spot));
|
spot = MAX(SPOT1, MIN(SPOT3, spot));
|
||||||
monitor *m = &monitors[MIN(nmonitors-1, MAX(0, mon))];
|
monitor *m = &monitors[MIN(nmonitors-1, MAX(0, mon))];
|
||||||
@@ -388,27 +365,20 @@ 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;
|
||||||
|
if (spot == SPOT1) return;
|
||||||
|
|
||||||
if (spot != SPOT1)
|
// right top 2/9 of screen
|
||||||
{
|
*x = m->x + width_spot1;
|
||||||
*x = m->x + width_spot1;
|
*w = m->w - width_spot1;
|
||||||
*w = m->w - width_spot1;
|
*h = height_spot2;
|
||||||
// right top 2/9 of screen
|
if (spot == SPOT2) return;
|
||||||
if (spot == SPOT2)
|
|
||||||
{
|
// right bottom 1/9 of screen
|
||||||
*h = height_spot2;
|
*y = m->y + height_spot2;
|
||||||
}
|
*h = m->h - height_spot2;
|
||||||
// right bottom 1/9 of screen
|
|
||||||
if (spot == SPOT3)
|
|
||||||
{
|
|
||||||
*y = m->y + height_spot2;
|
|
||||||
*h = m->h - height_spot2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move a window to a screen "spot"
|
void client_place_spot(client *c, int spot, int force)
|
||||||
void client_spot(client *c, int spot, int force)
|
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
@@ -416,11 +386,11 @@ void client_spot(client *c, int spot, int force)
|
|||||||
|
|
||||||
if (c->trans && !force)
|
if (c->trans && !force)
|
||||||
{
|
{
|
||||||
client *t = window_client(c->transient_for);
|
client *t = window_build_client(c->transient_for);
|
||||||
spot = t->spot;
|
spot = t->spot;
|
||||||
client_free(t);
|
client_free(t);
|
||||||
}
|
}
|
||||||
spot_xywh(spot, c->monitor, &x, &y, &w, &h);
|
spot_calc_xywh(spot, c->monitor, &x, &y, &w, &h);
|
||||||
|
|
||||||
if (c->type == atoms[_NET_WM_WINDOW_TYPE_DIALOG])
|
if (c->type == atoms[_NET_WM_WINDOW_TYPE_DIALOG])
|
||||||
{
|
{
|
||||||
@@ -430,53 +400,49 @@ void client_spot(client *c, int spot, int force)
|
|||||||
h = c->attr.height + BORDER*2;
|
h = c->attr.height + BORDER*2;
|
||||||
}
|
}
|
||||||
c->spot = spot;
|
c->spot = spot;
|
||||||
client_position(c, x, y, w, h);
|
client_position_xywh(c, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cycle through windows in a screen "spot"
|
void client_spot_cycle(client *c)
|
||||||
void client_cycle(client *c)
|
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
spot_active(c->spot, c->monitor, c->window);
|
spot_focus_top_window(c->spot, c->monitor, c->window);
|
||||||
|
|
||||||
stack lower, all;
|
stack lower; memset(&lower, 0, sizeof(stack));
|
||||||
memset(&lower, 0, sizeof(stack));
|
stack all; query_visible_windows(&all);
|
||||||
windows_visible(&all);
|
|
||||||
|
|
||||||
client_stack(c, &all, &lower);
|
client_stack_family(c, &all, &lower);
|
||||||
XLowerWindow(display, lower.windows[0]);
|
XLowerWindow(display, lower.windows[0]);
|
||||||
XRestackWindows(display, lower.windows, lower.depth);
|
XRestackWindows(display, lower.windows, lower.depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find a window within a screen "spot" and raise/activate
|
Window spot_focus_top_window(int spot, int mon, Window except)
|
||||||
Window spot_active(int spot, int mon, Window except)
|
|
||||||
{
|
{
|
||||||
int i, x, y, w, h; client *o;
|
int i, x, y, w, h; client *o;
|
||||||
spot_xywh(spot, mon, &x, &y, &w, &h);
|
spot_calc_xywh(spot, mon, &x, &y, &w, &h);
|
||||||
stack wins; windows_visible(&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(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_family(o);
|
||||||
client_active(o);
|
client_set_focus(o);
|
||||||
return o->window;
|
return o->window;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// build a stack of a window's transients and itself
|
void client_stack_family(client *c, stack *all, stack *raise)
|
||||||
void client_stack(client *c, stack *all, stack *raise)
|
|
||||||
{
|
{
|
||||||
int i; client *o, *self = NULL;
|
int i; client *o, *self = NULL;
|
||||||
for (i = 0; i < all->depth; i++)
|
for (i = 0; i < all->depth; i++)
|
||||||
{
|
{
|
||||||
if ((o = all->clients[i]) && o->manage && o->visible && o->transient_for == c->window)
|
if ((o = all->clients[i]) && o->manage && o->visible && o->transient_for == c->window)
|
||||||
client_stack(o, all, raise);
|
client_stack_family(o, all, raise);
|
||||||
else
|
else
|
||||||
if (o && o->visible && o->window == c->window)
|
if (o && o->visible && o->window == c->window)
|
||||||
self = o;
|
self = o;
|
||||||
@@ -488,33 +454,32 @@ void client_stack(client *c, stack *all, stack *raise)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// raise a window and all its transients
|
void client_raise_family(client *c)
|
||||||
void client_raise(client *c)
|
|
||||||
{
|
{
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
int i; client *o; 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);
|
query_visible_windows(&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])
|
if ((o = all.clients[i]) && o->type == atoms[_NET_WM_WINDOW_TYPE_DOCK])
|
||||||
client_stack(o, &all, &raise);
|
client_stack_family(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_has_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]))
|
if ((o = all.clients[i]) && client_has_state(o, atoms[_NET_WM_STATE_ABOVE]))
|
||||||
client_stack(o, &all, &raise);
|
client_stack_family(o, &all, &raise);
|
||||||
|
|
||||||
while (c->trans)
|
while (c->trans)
|
||||||
{
|
{
|
||||||
client *t = window_client(c->transient_for);
|
client *t = window_build_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_family(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);
|
||||||
|
|
||||||
@@ -522,8 +487,7 @@ void client_raise(client *c)
|
|||||||
client_free(family.clients[--family.depth]);
|
client_free(family.clients[--family.depth]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// focus a window
|
void client_set_focus(client *c)
|
||||||
void client_active(client *c)
|
|
||||||
{
|
{
|
||||||
if (!c || !c->visible) return;
|
if (!c || !c->visible) return;
|
||||||
|
|
||||||
@@ -533,34 +497,32 @@ void client_active(client *c)
|
|||||||
current_spot = c->spot;
|
current_spot = c->spot;
|
||||||
current_mon = c->monitor;
|
current_mon = c->monitor;
|
||||||
|
|
||||||
if (old && (o = window_client(old)))
|
if (old && (o = window_build_client(old)))
|
||||||
{
|
{
|
||||||
client_review(o);
|
client_update_border(o);
|
||||||
client_free(o);
|
client_free(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
client_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);
|
window_set_window_prop(root, atoms[_NET_ACTIVE_WINDOW], &c->window, 1);
|
||||||
client_review(c);
|
client_update_border(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// client events we care about
|
|
||||||
void window_listen(Window win)
|
void window_listen(Window win)
|
||||||
{
|
{
|
||||||
XSelectInput(display, win, EnterWindowMask | LeaveWindowMask | FocusChangeMask | PropertyChangeMask);
|
XSelectInput(display, win, EnterWindowMask | LeaveWindowMask | FocusChangeMask | PropertyChangeMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set border color based on focus
|
void client_update_border(client *c)
|
||||||
void client_review(client *c)
|
|
||||||
{
|
{
|
||||||
XSetWindowBorder(display, c->window,
|
XSetWindowBorder(display, c->window,
|
||||||
color_get(c->window == current ? BORDER_FOCUS: (c->urgent ? BORDER_URGENT:
|
color_name_to_pixel(c->window == current ? BORDER_FOCUS: (c->urgent ? BORDER_URGENT:
|
||||||
(client_state(c, atoms[_NET_WM_STATE_ABOVE]) ? BORDER_ABOVE: BORDER_BLUR))));
|
(client_has_state(c, atoms[_NET_WM_STATE_ABOVE]) ? BORDER_ABOVE: BORDER_BLUR))));
|
||||||
XSetWindowBorderWidth(display, c->window, client_state(c, atoms[_NET_WM_STATE_FULLSCREEN]) ? 0: BORDER);
|
XSetWindowBorderWidth(display, c->window, client_has_state(c, atoms[_NET_WM_STATE_FULLSCREEN]) ? 0: BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_set_tags(client *c)
|
void client_flush_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);
|
||||||
@@ -573,33 +535,33 @@ void client_set_tags(client *c)
|
|||||||
|
|
||||||
void action_move(void *data, int num)
|
void action_move(void *data, int num)
|
||||||
{
|
{
|
||||||
client *c = window_client(current);
|
client *c = window_build_client(current);
|
||||||
if (c)
|
if (c)
|
||||||
{
|
{
|
||||||
client_raise(c);
|
client_raise_family(c);
|
||||||
client_spot(c, num, 1);
|
client_place_spot(c, num, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_focus(void *data, int num)
|
void action_focus(void *data, int num)
|
||||||
{
|
{
|
||||||
spot_active(num, current_mon, None);
|
spot_focus_top_window(num, current_mon, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_close(void *data, int num)
|
void action_close(void *data, int num)
|
||||||
{
|
{
|
||||||
client_close(window_client(current));
|
client_close(window_build_client(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_cycle(void *data, int num)
|
void action_cycle(void *data, int num)
|
||||||
{
|
{
|
||||||
client_cycle(window_client(current));
|
client_spot_cycle(window_build_client(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_other(void *data, int num)
|
void action_other(void *data, int num)
|
||||||
{
|
{
|
||||||
client *c = window_client(current);
|
client *c = window_build_client(current);
|
||||||
if (c) spot_active(c->spot, c->monitor, c->window);
|
if (c) spot_focus_top_window(c->spot, c->monitor, c->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_command(void *data, int num)
|
void action_command(void *data, int num)
|
||||||
@@ -611,14 +573,14 @@ void action_command(void *data, int num)
|
|||||||
void action_find_or_start(void *data, int num)
|
void action_find_or_start(void *data, int num)
|
||||||
{
|
{
|
||||||
int i; client *c; char *class = data;
|
int i; client *c; char *class = data;
|
||||||
stack all; windows_visible(&all);
|
stack all; query_visible_windows(&all);
|
||||||
|
|
||||||
for (i = 0; i < all.depth; i++)
|
for (i = 0; i < all.depth; i++)
|
||||||
{
|
{
|
||||||
if ((c = all.clients[i]) && c->manage && !strcasecmp(c->class, class))
|
if ((c = all.clients[i]) && c->manage && !strcasecmp(c->class, class))
|
||||||
{
|
{
|
||||||
client_raise(c);
|
client_raise_family(c);
|
||||||
client_active(c);
|
client_set_focus(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,39 +589,35 @@ void action_find_or_start(void *data, int num)
|
|||||||
|
|
||||||
void action_move_monitor(void *data, int num)
|
void action_move_monitor(void *data, int num)
|
||||||
{
|
{
|
||||||
int mon = MAX(0, MIN(current_mon+num, nmonitors-1));
|
client *c = window_build_client(current);
|
||||||
client *c = window_client(current);
|
if (!c) return;
|
||||||
if (c)
|
|
||||||
{
|
client_raise_family(c);
|
||||||
client_raise(c);
|
c->monitor = MAX(0, MIN(current_mon+num, nmonitors-1));
|
||||||
c->monitor = mon;
|
client_place_spot(c, c->spot, 1);
|
||||||
client_spot(c, c->spot, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_focus_monitor(void *data, int num)
|
void action_focus_monitor(void *data, int num)
|
||||||
{
|
{
|
||||||
int mon = MAX(0, MIN(current_mon+num, nmonitors-1));
|
int i, mon = MAX(0, MIN(current_mon+num, nmonitors-1));
|
||||||
if (spot_active(current_spot, mon, None)) return;
|
if (spot_focus_top_window(current_spot, mon, None)) return;
|
||||||
if (spot_active(SPOT1, mon, None)) return;
|
for (i = SPOT1; i <= SPOT3 && !spot_focus_top_window(i, mon, None); i++);
|
||||||
if (spot_active(SPOT2, mon, None)) return;
|
|
||||||
if (spot_active(SPOT3, mon, None)) return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_raise_tag(void *data, int tag)
|
void action_raise_tag(void *data, int tag)
|
||||||
{
|
{
|
||||||
int i; client *c = NULL, *t = NULL;
|
int i; client *c = NULL, *t = NULL;
|
||||||
stack all; windows_visible(&all);
|
stack all; query_visible_windows(&all);
|
||||||
|
|
||||||
for (i = all.depth-1; i > -1; i--)
|
for (i = all.depth-1; i > -1; i--)
|
||||||
{
|
{
|
||||||
if ((c = all.clients[i]) && c->manage && c->visible && c->tags & tag)
|
if ((c = all.clients[i]) && 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_family(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (t) client_active(t);
|
if (t) client_set_focus(t);
|
||||||
|
|
||||||
unsigned long desktop = tag & TAG2 ? 1: (tag & TAG3 ? 2: 0);
|
unsigned long desktop = tag & TAG2 ? 1: (tag & TAG3 ? 2: 0);
|
||||||
window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1);
|
window_set_cardinal_prop(root, atoms[_NET_CURRENT_DESKTOP], &desktop, 1);
|
||||||
@@ -667,59 +625,51 @@ void action_raise_tag(void *data, int tag)
|
|||||||
|
|
||||||
void action_fullscreen(void *data, int num)
|
void action_fullscreen(void *data, int num)
|
||||||
{
|
{
|
||||||
client *c = window_client(current);
|
client *c = window_build_client(current);
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
unsigned long spot = c->spot;
|
unsigned long spot = c->spot;
|
||||||
client_raise(c);
|
client_raise_family(c);
|
||||||
if (client_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
|
||||||
|
if (client_toggle_state(c, atoms[_NET_WM_STATE_FULLSCREEN]))
|
||||||
{
|
{
|
||||||
client_drop_state(c, atoms[_NET_WM_STATE_FULLSCREEN]);
|
|
||||||
if (window_get_cardinal_prop(c->window, atoms[XOAT_SPOT], &spot, 1))
|
|
||||||
c->spot = spot;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client_add_state(c, atoms[_NET_WM_STATE_FULLSCREEN]);
|
|
||||||
window_set_cardinal_prop(c->window, atoms[XOAT_SPOT], &spot, 1);
|
window_set_cardinal_prop(c->window, atoms[XOAT_SPOT], &spot, 1);
|
||||||
c->spot = SPOT1;
|
c->spot = SPOT1;
|
||||||
}
|
}
|
||||||
client_review(c);
|
else
|
||||||
client_spot(c, c->spot, 1);
|
if (window_get_cardinal_prop(c->window, atoms[XOAT_SPOT], &spot, 1))
|
||||||
|
c->spot = spot;
|
||||||
|
|
||||||
|
client_update_border(c);
|
||||||
|
client_place_spot(c, c->spot, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_above(void *data, int num)
|
void action_above(void *data, int num)
|
||||||
{
|
{
|
||||||
client *c = window_client(current);
|
client *c = window_build_client(current);
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
if (client_state(c, atoms[_NET_WM_STATE_ABOVE]))
|
client_toggle_state(c, atoms[_NET_WM_STATE_ABOVE]);
|
||||||
client_drop_state(c, atoms[_NET_WM_STATE_ABOVE]);
|
client_update_border(c);
|
||||||
else
|
client_raise_family(c);
|
||||||
client_add_state(c, atoms[_NET_WM_STATE_ABOVE]);
|
|
||||||
|
|
||||||
client_review(c);
|
|
||||||
client_raise(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_tag(void *data, int num)
|
void action_tag(void *data, int num)
|
||||||
{
|
{
|
||||||
client *c = window_client(current);
|
client *c = window_build_client(current);
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
c->tags |= (unsigned int)num;
|
c->tags |= (unsigned int)num;
|
||||||
client_set_tags(c);
|
client_flush_tags(c);
|
||||||
warnx("tags %d 0x%08lx %s", c->tags, (long)c->window, c->class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void action_untag(void *data, int num)
|
void action_untag(void *data, int num)
|
||||||
{
|
{
|
||||||
client *c = window_client(current);
|
client *c = window_build_client(current);
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
c->tags &= ~((unsigned int)num);
|
c->tags &= ~((unsigned int)num);
|
||||||
client_set_tags(c);
|
client_flush_tags(c);
|
||||||
warnx("tags %d 0x%08lx %s", c->tags, (long)c->window, c->class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// key actions
|
// key actions
|
||||||
@@ -745,7 +695,7 @@ action actions[ACTIONS] = {
|
|||||||
|
|
||||||
void create_notify(XCreateWindowEvent *e)
|
void create_notify(XCreateWindowEvent *e)
|
||||||
{
|
{
|
||||||
client *c = window_client(e->window);
|
client *c = window_build_client(e->window);
|
||||||
|
|
||||||
if (c && c->manage)
|
if (c && c->manage)
|
||||||
window_listen(c->window);
|
window_listen(c->window);
|
||||||
@@ -755,35 +705,34 @@ void create_notify(XCreateWindowEvent *e)
|
|||||||
|
|
||||||
void configure_request(XConfigureRequestEvent *e)
|
void configure_request(XConfigureRequestEvent *e)
|
||||||
{
|
{
|
||||||
client *c = window_client(e->window);
|
client *c = window_build_client(e->window);
|
||||||
|
if (!c) return;
|
||||||
|
|
||||||
if (c)
|
if (c->manage && c->visible && !c->trans)
|
||||||
{
|
{
|
||||||
if (c->manage && c->visible && !c->trans)
|
client_update_border(c);
|
||||||
{
|
client_place_spot(c, c->spot, 0);
|
||||||
client_review(c);
|
}
|
||||||
client_spot(c, c->spot, 0);
|
else
|
||||||
}
|
{
|
||||||
else
|
XWindowChanges wc;
|
||||||
{
|
if (e->value_mask & CWX) wc.x = e->x;
|
||||||
XWindowChanges wc;
|
if (e->value_mask & CWY) wc.y = e->y;
|
||||||
if (e->value_mask & CWX) wc.x = e->x;
|
if (e->value_mask & CWWidth) wc.width = e->width;
|
||||||
if (e->value_mask & CWY) wc.y = e->y;
|
if (e->value_mask & CWHeight) wc.height = e->height;
|
||||||
if (e->value_mask & CWWidth) wc.width = e->width;
|
if (e->value_mask & CWStackMode) wc.stack_mode = e->detail;
|
||||||
if (e->value_mask & CWHeight) wc.height = e->height;
|
if (e->value_mask & CWBorderWidth) wc.border_width = BORDER;
|
||||||
if (e->value_mask & CWStackMode) wc.stack_mode = e->detail;
|
XConfigureWindow(display, c->window, e->value_mask, &wc);
|
||||||
if (e->value_mask & CWBorderWidth) wc.border_width = BORDER;
|
|
||||||
XConfigureWindow(display, c->window, e->value_mask, &wc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
client_free(c);
|
client_free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void map_request(XMapEvent *e)
|
void map_request(XMapEvent *e)
|
||||||
{
|
{
|
||||||
client *c = window_client(e->window);
|
client *c = window_build_client(e->window);
|
||||||
|
if (!c) return;
|
||||||
|
|
||||||
if (c && c->manage)
|
if (c->manage)
|
||||||
{
|
{
|
||||||
int x, y, w, h, spot = SPOT_START,
|
int x, y, w, h, spot = SPOT_START,
|
||||||
monitor = MAX(nmonitors-1, MIN(0, MONITOR_START));
|
monitor = MAX(nmonitors-1, MIN(0, MONITOR_START));
|
||||||
@@ -795,11 +744,11 @@ void map_request(XMapEvent *e)
|
|||||||
{
|
{
|
||||||
spot = SPOT1;
|
spot = SPOT1;
|
||||||
|
|
||||||
spot_xywh(SPOT2, c->monitor, &x, &y, &w, &h);
|
spot_calc_xywh(SPOT2, c->monitor, &x, &y, &w, &h);
|
||||||
if (c->attr.width <= w && c->attr.height <= h)
|
if (c->attr.width <= w && c->attr.height <= h)
|
||||||
spot = SPOT2;
|
spot = SPOT2;
|
||||||
|
|
||||||
spot_xywh(SPOT3, c->monitor, &x, &y, &w, &h);
|
spot_calc_xywh(SPOT3, c->monitor, &x, &y, &w, &h);
|
||||||
if (c->attr.width <= w && c->attr.height <= h)
|
if (c->attr.width <= w && c->attr.height <= h)
|
||||||
spot = SPOT3;
|
spot = SPOT3;
|
||||||
}
|
}
|
||||||
@@ -808,9 +757,9 @@ void map_request(XMapEvent *e)
|
|||||||
monitor = current_mon;
|
monitor = current_mon;
|
||||||
|
|
||||||
c->monitor = monitor;
|
c->monitor = monitor;
|
||||||
client_spot(c, spot, 0);
|
client_place_spot(c, spot, 0);
|
||||||
client_review(c);
|
client_update_border(c);
|
||||||
client_set_tags(c);
|
client_flush_tags(c);
|
||||||
}
|
}
|
||||||
client_free(c);
|
client_free(c);
|
||||||
XMapWindow(display, e->window);
|
XMapWindow(display, e->window);
|
||||||
@@ -818,16 +767,16 @@ void map_request(XMapEvent *e)
|
|||||||
|
|
||||||
void map_notify(XMapEvent *e)
|
void map_notify(XMapEvent *e)
|
||||||
{
|
{
|
||||||
client *a = NULL, *c = window_client(e->window);
|
client *a = NULL, *c = window_build_client(e->window);
|
||||||
|
if (!c) return;
|
||||||
|
|
||||||
if (c && c->manage)
|
if (c->manage)
|
||||||
{
|
{
|
||||||
client_raise(c);
|
client_raise_family(c);
|
||||||
client_review(c);
|
client_update_border(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, focus it
|
||||||
// current spot, activate it
|
if (!(a = window_build_client(current)) || (a && a->spot == c->spot))
|
||||||
if (!(a = window_client(current)) || (a && a->spot == c->spot))
|
client_set_focus(c);
|
||||||
client_active(c);
|
|
||||||
client_free(a);
|
client_free(a);
|
||||||
}
|
}
|
||||||
client_free(c);
|
client_free(c);
|
||||||
@@ -836,25 +785,21 @@ void map_notify(XMapEvent *e)
|
|||||||
|
|
||||||
void unmap_notify(XUnmapEvent *e)
|
void unmap_notify(XUnmapEvent *e)
|
||||||
{
|
{
|
||||||
if (e->window == current && !spot_active(current_spot, current_mon, current))
|
int i;
|
||||||
{
|
// if this window was focused, find something else
|
||||||
// find something to activate
|
if (e->window == current && !spot_focus_top_window(current_spot, current_mon, current))
|
||||||
if (!spot_active(SPOT1, current_mon, current)
|
for (i = SPOT1; i <= SPOT3 && !spot_focus_top_window(i, current_mon, current); i++);
|
||||||
&& !spot_active(SPOT2, current_mon, current)
|
|
||||||
&& !spot_active(SPOT3, current_mon, current))
|
|
||||||
current = None;
|
|
||||||
}
|
|
||||||
ewmh_client_list();
|
ewmh_client_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
void key_press(XKeyEvent *e)
|
void key_press(XKeyEvent *e)
|
||||||
{
|
{
|
||||||
int i; XEvent ev; latest = e->time;
|
int i; XEvent ev; latest = e->time;
|
||||||
|
|
||||||
short act = ACTION_NONE; void *data = NULL; int num = 0;
|
short act = ACTION_NONE; void *data = NULL; int num = 0;
|
||||||
|
|
||||||
|
while (XCheckTypedEvent(display, KeyPress, &ev));
|
||||||
KeySym key = XkbKeycodeToKeysym(display, e->keycode, 0, 0);
|
KeySym key = XkbKeycodeToKeysym(display, e->keycode, 0, 0);
|
||||||
unsigned int state = e->state & ~(LockMask|NumlockMask);
|
unsigned int state = e->state & ~(LockMask|NumlockMask);
|
||||||
while (XCheckTypedEvent(display, KeyPress, &ev));
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(keys)/sizeof(binding); i++)
|
for (i = 0; i < sizeof(keys)/sizeof(binding); i++)
|
||||||
{
|
{
|
||||||
@@ -873,12 +818,12 @@ void key_press(XKeyEvent *e)
|
|||||||
void button_press(XButtonEvent *e)
|
void button_press(XButtonEvent *e)
|
||||||
{
|
{
|
||||||
latest = e->time;
|
latest = e->time;
|
||||||
client *c = window_client(e->subwindow);
|
client *c = window_build_client(e->subwindow);
|
||||||
|
|
||||||
if (c && c->manage)
|
if (c && c->manage)
|
||||||
{
|
{
|
||||||
client_raise(c);
|
client_raise_family(c);
|
||||||
client_active(c);
|
client_set_focus(c);
|
||||||
}
|
}
|
||||||
client_free(c);
|
client_free(c);
|
||||||
|
|
||||||
@@ -888,15 +833,27 @@ void button_press(XButtonEvent *e)
|
|||||||
|
|
||||||
void client_message(XClientMessageEvent *e)
|
void client_message(XClientMessageEvent *e)
|
||||||
{
|
{
|
||||||
client *c = window_client(e->window);
|
if (e->message_type == atoms[XOAT_EXIT])
|
||||||
|
{
|
||||||
|
warnx("exit!");
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
if (e->message_type == atoms[XOAT_RESTART])
|
||||||
|
{
|
||||||
|
warnx("restart!");
|
||||||
|
execsh(self);
|
||||||
|
}
|
||||||
|
|
||||||
if (c && c->manage)
|
client *c = window_build_client(e->window);
|
||||||
|
if (!c) return;
|
||||||
|
|
||||||
|
if (c->manage)
|
||||||
{
|
{
|
||||||
warnx("client message 0x%lx 0x%08lx %s", e->message_type, (long)c->window, c->class);
|
warnx("client message 0x%lx 0x%08lx %s", e->message_type, (long)c->window, c->class);
|
||||||
if (e->message_type == atoms[_NET_ACTIVE_WINDOW])
|
if (e->message_type == atoms[_NET_ACTIVE_WINDOW])
|
||||||
{
|
{
|
||||||
client_raise(c);
|
client_raise_family(c);
|
||||||
client_active(c);
|
client_set_focus(c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (e->message_type == atoms[_NET_CLOSE_WINDOW])
|
if (e->message_type == atoms[_NET_CLOSE_WINDOW])
|
||||||
@@ -904,39 +861,28 @@ void client_message(XClientMessageEvent *e)
|
|||||||
client_close(c);
|
client_close(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (e->message_type == atoms[XOAT_EXIT])
|
|
||||||
{
|
|
||||||
warnx("exit!");
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (e->message_type == atoms[XOAT_RESTART])
|
|
||||||
{
|
|
||||||
warnx("restart!");
|
|
||||||
execsh(self);
|
|
||||||
}
|
|
||||||
client_free(c);
|
client_free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void any_event(XEvent *e)
|
void any_event(XEvent *e)
|
||||||
{
|
{
|
||||||
client *c = window_client(e->xany.window);
|
client *c = window_build_client(e->xany.window);
|
||||||
|
|
||||||
if (c && c->manage)
|
if (c && c->manage)
|
||||||
client_review(c);
|
client_update_border(c);
|
||||||
|
|
||||||
client_free(c);
|
client_free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, j; self = argv[0]; stack wins;
|
int i, j; Atom msg = None; client *c;
|
||||||
memset(&wins, 0, sizeof(stack));
|
stack wins; 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;
|
||||||
|
|
||||||
|
self = argv[0];
|
||||||
screen = DefaultScreenOfDisplay(display);
|
screen = DefaultScreenOfDisplay(display);
|
||||||
scr_id = DefaultScreen(display);
|
scr_id = DefaultScreen(display);
|
||||||
root = DefaultRootWindow(display);
|
root = DefaultRootWindow(display);
|
||||||
@@ -944,18 +890,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
for (i = 0; i < ATOMS; i++) atoms[i] = XInternAtom(display, atom_names[i], False);
|
for (i = 0; i < ATOMS; i++) atoms[i] = XInternAtom(display, atom_names[i], False);
|
||||||
|
|
||||||
// check for restart
|
// check for restart/exit
|
||||||
if (argc > 1 && !strcmp(argv[1], "restart"))
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
Window cli = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, None, None);
|
Window cli = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, None, None);
|
||||||
window_message(root, cli, atoms[XOAT_RESTART], 0, SubstructureNotifyMask | SubstructureRedirectMask);
|
if (!strcmp(argv[1], "restart")) msg = atoms[XOAT_RESTART];
|
||||||
exit(EXIT_SUCCESS);
|
else if (!strcmp(argv[1], "exit")) msg = atoms[XOAT_EXIT];
|
||||||
}
|
else error(EXIT_FAILURE, 0, "huh? %s", argv[1]);
|
||||||
// check for exit
|
window_send_clientmessage(root, cli, msg, 0, SubstructureNotifyMask | SubstructureRedirectMask);
|
||||||
if (argc > 1 && !strcmp(argv[1], "exit"))
|
|
||||||
{
|
|
||||||
Window cli = XCreateSimpleWindow(display, root, 0, 0, 1, 1, 0, None, None);
|
|
||||||
window_message(root, cli, atoms[XOAT_EXIT], 0, SubstructureNotifyMask | SubstructureRedirectMask);
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,12 +909,11 @@ int main(int argc, char *argv[])
|
|||||||
warnx("screen(%d): %dx%d+%d+%d", scr_id, monitors[0].w, monitors[0].h, monitors[0].x, monitors[0].y);
|
warnx("screen(%d): %dx%d+%d+%d", scr_id, monitors[0].w, monitors[0].h, monitors[0].x, monitors[0].y);
|
||||||
|
|
||||||
// detect panel struts
|
// detect panel struts
|
||||||
windows_visible(&wins);
|
query_visible_windows(&wins);
|
||||||
inplay.depth = 0;
|
inplay.depth = 0;
|
||||||
for (i = 0; i < wins.depth; i++)
|
for (i = 0; i < wins.depth; i++)
|
||||||
{
|
{
|
||||||
client *c = wins.clients[i];
|
if (!(c = wins.clients[i])) continue;
|
||||||
if (!c) continue;
|
|
||||||
|
|
||||||
wm_strut strut; memset(&strut, 0, sizeof(wm_strut));
|
wm_strut strut; memset(&strut, 0, sizeof(wm_strut));
|
||||||
if (window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT_PARTIAL], (unsigned long*)&strut, 12)
|
if (window_get_cardinal_prop(c->window, atoms[_NET_WM_STRUT_PARTIAL], (unsigned long*)&strut, 12)
|
||||||
@@ -1063,25 +1004,23 @@ 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
|
||||||
windows_visible(&wins);
|
query_visible_windows(&wins);
|
||||||
inplay.depth = 0;
|
inplay.depth = 0;
|
||||||
for (i = 0; i < wins.depth; i++)
|
for (i = 0; i < wins.depth; i++)
|
||||||
{
|
{
|
||||||
client *c = wins.clients[i];
|
if (!(c = wins.clients[i]) || !c->manage) continue;
|
||||||
if (c && c->manage)
|
|
||||||
|
warnx("window 0x%08lx (%d,%d,%d) %s", (long)c->window, c->tags, c->monitor, c->spot, c->class);
|
||||||
|
window_listen(c->window);
|
||||||
|
if (c->visible)
|
||||||
{
|
{
|
||||||
warnx("window 0x%08lx (%d,%d,%d) %s", (long)c->window, c->tags, c->monitor, c->spot, c->class);
|
client_update_border(c);
|
||||||
window_listen(c->window);
|
client_flush_tags(c);
|
||||||
// activate first one
|
// activate first one
|
||||||
if (!current && c->visible)
|
if (!current)
|
||||||
{
|
{
|
||||||
client_raise(c);
|
client_raise_family(c);
|
||||||
client_active(c);
|
client_set_focus(c);
|
||||||
}
|
|
||||||
if (c->visible)
|
|
||||||
{
|
|
||||||
client_review(c);
|
|
||||||
client_set_tags(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
client_free(c);
|
client_free(c);
|
||||||
|
|||||||
3
xoat.h
3
xoat.h
@@ -38,6 +38,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <error.h>
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -74,7 +75,7 @@ typedef struct {
|
|||||||
XWMHints hints;
|
XWMHints hints;
|
||||||
XSizeHints size;
|
XSizeHints size;
|
||||||
Window transient_for;
|
Window transient_for;
|
||||||
Atom type, states[MAX_NET_WM_STATES];
|
Atom type, states[MAX_NET_WM_STATES+1];
|
||||||
short monitor, spot, visible, trans, manage, input, urgent;
|
short monitor, spot, visible, trans, manage, input, urgent;
|
||||||
unsigned short tags;
|
unsigned short tags;
|
||||||
char *class;
|
char *class;
|
||||||
|
|||||||
Reference in New Issue
Block a user