mirror of https://github.com/0intro/wmii
Account for window groups. Better focus semantics. Check size against iounit on dir reads. Misc. changes.
This commit is contained in:
parent
aef6e4c22e
commit
ba8e24be1e
|
@ -174,6 +174,17 @@ area_moveto(Area *to, Frame *f) {
|
|||
area_attach(to, f);
|
||||
}
|
||||
|
||||
void
|
||||
area_setsel(Area *a, Frame *f) {
|
||||
View *v;
|
||||
|
||||
v = a->view;
|
||||
if(a == v->sel && f)
|
||||
frame_focus(f);
|
||||
else
|
||||
a->sel = f;
|
||||
}
|
||||
|
||||
void
|
||||
area_attach(Area *a, Frame *f) {
|
||||
uint n_frame;
|
||||
|
@ -202,12 +213,8 @@ area_attach(Area *a, Frame *f) {
|
|||
client_resize(f->client, f->r);
|
||||
}
|
||||
|
||||
if(!a->sel) {
|
||||
if(a == a->view->sel)
|
||||
frame_focus(f);
|
||||
else
|
||||
a->sel = f;
|
||||
}
|
||||
if(!a->sel)
|
||||
area_setsel(a, f);
|
||||
view_restack(a->view);
|
||||
|
||||
if(!a->floating)
|
||||
|
@ -220,7 +227,7 @@ area_attach(Area *a, Frame *f) {
|
|||
void
|
||||
area_detach(Frame *f) {
|
||||
Frame *pr;
|
||||
Client *c, *cp;
|
||||
Client *c;
|
||||
Area *a;
|
||||
View *v;
|
||||
|
||||
|
@ -234,10 +241,8 @@ area_detach(Frame *f) {
|
|||
if(a->sel == f) {
|
||||
if(!pr)
|
||||
pr = a->frame;
|
||||
if(pr && (v->sel == a))
|
||||
frame_focus(pr);
|
||||
else
|
||||
a->sel = pr;
|
||||
if(pr)
|
||||
area_setsel(a, pr);
|
||||
}
|
||||
|
||||
if(!a->floating) {
|
||||
|
@ -248,20 +253,14 @@ area_detach(Frame *f) {
|
|||
area_destroy(a);
|
||||
else if((a->frame == nil) && (v->area->frame))
|
||||
area_focus(v->area);
|
||||
|
||||
view_arrange(v);
|
||||
}
|
||||
}else if(!a->frame) {
|
||||
if(c->trans) {
|
||||
cp = win2client(c->trans);
|
||||
if(cp && cp->frame) {
|
||||
a = cp->sel->area;
|
||||
if(a->view == v) {
|
||||
area_focus(a);
|
||||
return;
|
||||
}
|
||||
if(c->trans || (c->w.ewmh.type & (TypeDialog|TypeSplash)))
|
||||
if(v->oldsel) {
|
||||
area_focus(v->oldsel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(v->area->next->frame)
|
||||
area_focus(v->area->next);
|
||||
}else
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "fns.h"
|
||||
|
@ -22,10 +23,74 @@ enum {
|
|||
| ButtonReleaseMask
|
||||
};
|
||||
|
||||
static Group* group;
|
||||
|
||||
static void
|
||||
group_init(Client *c) {
|
||||
Group *g;
|
||||
long *ret;
|
||||
XWindow w;
|
||||
long n;
|
||||
|
||||
n = getprop_long(&c->w, "WM_CLIENT_LEADER", "WINDOW", 0L, &ret, 1L);
|
||||
if(n == 0)
|
||||
return;
|
||||
w = *ret;
|
||||
|
||||
for(g=group; g; g=g->next)
|
||||
if(g->leader == w)
|
||||
break;
|
||||
if(g == nil) {
|
||||
g = emallocz(sizeof *g);
|
||||
g->leader = w;
|
||||
g->next = group;
|
||||
group = g;
|
||||
}
|
||||
c->group = g;
|
||||
g->ref++;
|
||||
}
|
||||
|
||||
static void
|
||||
group_remove(Client *c) {
|
||||
Group **gp;
|
||||
Group *g;
|
||||
|
||||
g = c->group;
|
||||
if(g == nil)
|
||||
return;
|
||||
if(g->client == c)
|
||||
g->client = nil;
|
||||
g->ref--;
|
||||
if(g->ref == 0) {
|
||||
for(gp=&group; *gp; gp=&gp[0]->next)
|
||||
if(*gp == g)
|
||||
break;
|
||||
assert(*gp == g);
|
||||
gp[0] = gp[0]->next;
|
||||
}
|
||||
}
|
||||
|
||||
static Client*
|
||||
group_leader(Group *g) {
|
||||
Client *c;
|
||||
|
||||
c = win2client(g->leader);
|
||||
if(c)
|
||||
return c;
|
||||
if(g->client)
|
||||
return g->client;
|
||||
/* Could do better. */
|
||||
for(c=client; c; c=c->next)
|
||||
if(c->frame && c->group == g)
|
||||
break;
|
||||
return c;
|
||||
}
|
||||
|
||||
Client*
|
||||
client_create(XWindow w, XWindowAttributes *wa) {
|
||||
Client **t, *c;
|
||||
WinAttr fwa;
|
||||
Point p;
|
||||
|
||||
c = emallocz(sizeof(Client));
|
||||
c->border = wa->border_width;
|
||||
|
@ -68,7 +133,12 @@ client_create(XWindow w, XWindowAttributes *wa) {
|
|||
sethandler(c->framewin, &framehandler);
|
||||
sethandler(&c->w, &handlers);
|
||||
|
||||
p.x = def.border;
|
||||
p.y = labelh(def.font);
|
||||
reparentwindow(&c->w, c->framewin, p);
|
||||
|
||||
ewmh_initclient(c);
|
||||
group_init(c);
|
||||
|
||||
grab_button(c->framewin->w, AnyButton, AnyModifier);
|
||||
|
||||
|
@ -86,7 +156,6 @@ client_create(XWindow w, XWindowAttributes *wa) {
|
|||
|
||||
void
|
||||
client_manage(Client *c) {
|
||||
Point p;
|
||||
Client *trans;
|
||||
char *tags;
|
||||
|
||||
|
@ -94,18 +163,16 @@ client_manage(Client *c) {
|
|||
if(tags == nil)
|
||||
tags = gettextproperty(&c->w, "_WIN_TAGS");
|
||||
|
||||
if((trans = win2client(c->trans)))
|
||||
utflcpy(c->tags, trans->tags, sizeof(c->tags));
|
||||
else if(tags)
|
||||
trans = win2client(c->trans);
|
||||
if(trans == nil && c->group)
|
||||
trans = group_leader(c->group);
|
||||
|
||||
if(tags)
|
||||
utflcpy(c->tags, tags, sizeof(c->tags));
|
||||
|
||||
else if(trans)
|
||||
utflcpy(c->tags, trans->tags, sizeof(c->tags));
|
||||
free(tags);
|
||||
|
||||
p.x = def.border;
|
||||
p.y = labelh(def.font);
|
||||
|
||||
reparentwindow(&c->w, c->framewin, p);
|
||||
|
||||
if(c->tags[0])
|
||||
apply_tags(c, c->tags);
|
||||
else
|
||||
|
@ -116,8 +183,14 @@ client_manage(Client *c) {
|
|||
|
||||
if(c->sel->view == screen->sel)
|
||||
if(!(c->w.ewmh.type & TypeSplash))
|
||||
if(!c->group || c->group->ref == 1
|
||||
|| selclient() && selclient()->group == c->group)
|
||||
focus(c, false);
|
||||
flushevents(EnterWindowMask, False);
|
||||
else {
|
||||
frame_restack(c->sel, c->sel->area->sel);
|
||||
view_restack(c->sel->view);
|
||||
}
|
||||
flushenterevents();
|
||||
}
|
||||
|
||||
static int /* Temporary Xlib error handler */
|
||||
|
@ -156,7 +229,7 @@ client_destroy(Client *c) {
|
|||
handler = XSetErrorHandler(ignoreerrors);
|
||||
|
||||
dummy = nil;
|
||||
view_setclient(c, &dummy);
|
||||
client_setviews(c, &dummy);
|
||||
client_unmap(c, IconicState);
|
||||
sethandler(&c->w, nil);
|
||||
|
||||
|
@ -171,9 +244,10 @@ client_destroy(Client *c) {
|
|||
XUngrabServer(display);
|
||||
|
||||
ewmh_destroyclient(c);
|
||||
group_remove(c);
|
||||
event("DestroyClient %C\n", c);
|
||||
|
||||
flushevents(EnterWindowMask, False);
|
||||
flushenterevents();
|
||||
free(c->w.hints);
|
||||
free(c);
|
||||
}
|
||||
|
@ -339,17 +413,19 @@ client_focus(Client *c) {
|
|||
|
||||
Dprint(DFocus, "client_focus(%p[%C]) => %s\n", c, c, clientname(c));
|
||||
|
||||
if(c && c->noinput)
|
||||
return;
|
||||
if(c) {
|
||||
if(c->noinput)
|
||||
return;
|
||||
if(c->group)
|
||||
c->group->client = c;
|
||||
}
|
||||
|
||||
if(screen->focus != c) {
|
||||
Dprint(DFocus, "\t%s => %s\n", clientname(screen->focus), clientname(c));
|
||||
|
||||
if(c)
|
||||
setfocus(&c->w, RevertToParent);
|
||||
else
|
||||
setfocus(screen->barwin, RevertToParent);
|
||||
|
||||
event("ClientFocus %C\n", c);
|
||||
|
||||
sync();
|
||||
|
@ -565,11 +641,10 @@ updatemwm(Client *c) {
|
|||
};
|
||||
Rectangle r;
|
||||
ulong *ret;
|
||||
Atom real;
|
||||
int n;
|
||||
|
||||
n = getproperty(&c->w, "_MOTIF_WM_HINTS", "_MOTIF_WM_HINTS", &real,
|
||||
0L, (void*)&ret, 3L);
|
||||
n = getprop_long(&c->w, "_MOTIF_WM_HINTS", "_MOTIF_WM_HINTS",
|
||||
0L, (long**)&ret, 3L);
|
||||
|
||||
if(c->sel)
|
||||
r = frame_rect2client(c->sel, c->sel->r);
|
||||
|
@ -671,8 +746,11 @@ configreq_event(Window *w, XConfigureRequestEvent *e) {
|
|||
if((Dx(cr) == Dx(screen->r)) && (Dy(cr) == Dy(screen->r)))
|
||||
fullscreen(c, True);
|
||||
|
||||
if(c->sel->area->floating)
|
||||
if(c->sel->area->floating) {
|
||||
client_resize(c, r);
|
||||
sync();
|
||||
flushenterevents();
|
||||
}
|
||||
else {
|
||||
c->sel->revert = r;
|
||||
client_configure(c);
|
||||
|
@ -807,12 +885,12 @@ newcol_client(Client *c, char *arg) {
|
|||
}
|
||||
else
|
||||
return;
|
||||
flushevents(EnterWindowMask, False);
|
||||
flushenterevents();
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
view_setclient(Client *c, char **tags) {
|
||||
client_setviews(Client *c, char **tags) {
|
||||
Frame **fp, *f;
|
||||
int cmp;
|
||||
|
||||
|
@ -953,7 +1031,7 @@ apply_tags(Client *c, const char *tags) {
|
|||
}
|
||||
toks[n] = nil;
|
||||
|
||||
view_setclient(c, toks);
|
||||
client_setviews(c, toks);
|
||||
|
||||
changeprop_string(&c->w, "_WMII_TAGS", c->tags);
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ scale_column(Area *a) {
|
|||
j--;
|
||||
}
|
||||
/* Doesn't change if we 'continue' */
|
||||
fp=&f->anext;
|
||||
fp = &f->anext;
|
||||
}
|
||||
|
||||
surplus = 0;
|
||||
|
|
115
cmd/wmii/dat.h
115
cmd/wmii/dat.h
|
@ -72,35 +72,16 @@ typedef struct Bar Bar;
|
|||
typedef struct Client Client;
|
||||
typedef struct Divide Divide;
|
||||
typedef struct Frame Frame;
|
||||
typedef struct Group Group;
|
||||
typedef struct Key Key;
|
||||
typedef struct Map Map;
|
||||
typedef struct MapEnt MapEnt;
|
||||
typedef struct Rule Rule;
|
||||
typedef struct Ruleset Ruleset;
|
||||
typedef struct Strut Strut;
|
||||
typedef struct View View;
|
||||
typedef struct WMScreen WMScreen;
|
||||
|
||||
struct Map {
|
||||
MapEnt**bucket;
|
||||
uint nhash;
|
||||
};
|
||||
|
||||
struct MapEnt {
|
||||
ulong hash;
|
||||
const char* key;
|
||||
void* val;
|
||||
MapEnt* next;
|
||||
};
|
||||
|
||||
struct View {
|
||||
View* next;
|
||||
char name[256];
|
||||
ushort id;
|
||||
Area* area;
|
||||
Area* sel;
|
||||
Area* revert;
|
||||
};
|
||||
|
||||
struct Area {
|
||||
Area* next;
|
||||
Area* prev;
|
||||
|
@ -114,23 +95,15 @@ struct Area {
|
|||
Rectangle r;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
Frame* cnext;
|
||||
Frame* anext;
|
||||
Frame* aprev;
|
||||
Frame* snext;
|
||||
Frame* sprev;
|
||||
View* view;
|
||||
Area* area;
|
||||
Client* client;
|
||||
struct Bar {
|
||||
Bar* next;
|
||||
Bar* smaller;
|
||||
char buf[280];
|
||||
char text[256];
|
||||
char name[256];
|
||||
ushort id;
|
||||
bool collapsed;
|
||||
float ratio;
|
||||
Rectangle r;
|
||||
Rectangle crect;
|
||||
Rectangle revert;
|
||||
Rectangle grabbox;
|
||||
Rectangle titlebar;
|
||||
Rectangle r;
|
||||
CTuple col;
|
||||
};
|
||||
|
||||
struct Client {
|
||||
|
@ -141,6 +114,8 @@ struct Client {
|
|||
Window w;
|
||||
Window* framewin;
|
||||
XWindow trans;
|
||||
Group* group;
|
||||
Strut* strut;
|
||||
Cursor cursor;
|
||||
Rectangle r;
|
||||
char name[256];
|
||||
|
@ -165,6 +140,32 @@ struct Divide {
|
|||
int x;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
Frame* cnext;
|
||||
Frame* anext;
|
||||
Frame* aprev;
|
||||
Frame* snext;
|
||||
Frame* sprev;
|
||||
View* view;
|
||||
Area* area;
|
||||
Client* client;
|
||||
ushort id;
|
||||
bool collapsed;
|
||||
float ratio;
|
||||
Rectangle r;
|
||||
Rectangle crect;
|
||||
Rectangle revert;
|
||||
Rectangle grabbox;
|
||||
Rectangle titlebar;
|
||||
};
|
||||
|
||||
struct Group {
|
||||
Group* next;
|
||||
XWindow leader;
|
||||
Client *client;
|
||||
int ref;
|
||||
};
|
||||
|
||||
struct Key {
|
||||
Key* next;
|
||||
Key* lnext;
|
||||
|
@ -175,15 +176,16 @@ struct Key {
|
|||
KeyCode key;
|
||||
};
|
||||
|
||||
struct Bar {
|
||||
Bar* next;
|
||||
Bar* smaller;
|
||||
char buf[280];
|
||||
char text[256];
|
||||
char name[256];
|
||||
ushort id;
|
||||
Rectangle r;
|
||||
CTuple col;
|
||||
struct Map {
|
||||
MapEnt**bucket;
|
||||
uint nhash;
|
||||
};
|
||||
|
||||
struct MapEnt {
|
||||
ulong hash;
|
||||
const char* key;
|
||||
void* val;
|
||||
MapEnt* next;
|
||||
};
|
||||
|
||||
struct Rule {
|
||||
|
@ -193,11 +195,28 @@ struct Rule {
|
|||
};
|
||||
|
||||
struct Ruleset {
|
||||
Rule *rule;
|
||||
char *string;
|
||||
Rule* rule;
|
||||
char* string;
|
||||
uint size;
|
||||
};
|
||||
|
||||
struct Strut {
|
||||
Rectangle left;
|
||||
Rectangle right;
|
||||
Rectangle top;
|
||||
Rectangle bottom;
|
||||
};
|
||||
|
||||
struct View {
|
||||
View* next;
|
||||
char name[256];
|
||||
ushort id;
|
||||
Area* area;
|
||||
Area* sel;
|
||||
Area* oldsel;
|
||||
Area* revert;
|
||||
};
|
||||
|
||||
#ifndef EXTERN
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,8 @@ dispatch_event(XEvent *e) {
|
|||
handler[e->type](e);
|
||||
}
|
||||
|
||||
#define handle(w, fn, ev) if(!(w)->handler->fn) {}else (w)->handler->fn((w), ev)
|
||||
#define handle(w, fn, ev) \
|
||||
BLOCK(if((w)->handler->fn) (w)->handler->fn((w), ev))
|
||||
|
||||
uint
|
||||
flushevents(long event_mask, bool dispatch) {
|
||||
|
@ -29,6 +30,37 @@ flushevents(long event_mask, bool dispatch) {
|
|||
return n;
|
||||
}
|
||||
|
||||
static Bool
|
||||
findenter(Display *d, XEvent *e, XPointer v) {
|
||||
long *l;
|
||||
|
||||
l = (long*)v;
|
||||
if(*l)
|
||||
return False;
|
||||
if(e->type == EnterNotify)
|
||||
return True;
|
||||
if(e->type == MotionNotify)
|
||||
(*l)++;
|
||||
return False;
|
||||
}
|
||||
|
||||
/* This isn't perfect. If there were motion events in the queue
|
||||
* before this was called, then it flushes nothing. If we don't
|
||||
* check for them, we might lose a legitamate enter event.
|
||||
*/
|
||||
uint
|
||||
flushenterevents(void) {
|
||||
XEvent e;
|
||||
long l;
|
||||
int n;
|
||||
|
||||
l = 0;
|
||||
n = 0;
|
||||
while(XCheckIfEvent(display, &e, findenter, (void*)&l))
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
static void
|
||||
buttonrelease(XEvent *e) {
|
||||
XButtonPressedEvent *ev;
|
||||
|
@ -236,11 +268,10 @@ maprequest(XEvent *e) {
|
|||
XWindowAttributes wa;
|
||||
|
||||
ev = &e->xmaprequest;
|
||||
|
||||
if(!XGetWindowAttributes(display, ev->window, &wa))
|
||||
return;
|
||||
|
||||
if(wa.override_redirect) {
|
||||
/* Do I really want these? */
|
||||
XSelectInput(display, ev->window,
|
||||
(StructureNotifyMask | PropertyChangeMask));
|
||||
return;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com>
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include "dat.h"
|
||||
#include <assert.h>
|
||||
#include <sys/limits.h>
|
||||
#include "fns.h"
|
||||
|
||||
Window *ewmhwin;
|
||||
|
@ -190,20 +191,40 @@ ewmh_getstrut(Client *c) {
|
|||
enum {
|
||||
Left, Right, Top, Bottom,
|
||||
LeftMin, LeftMax,
|
||||
RithtMin, RightMax,
|
||||
RightMin, RightMax,
|
||||
TopMin, TopMax,
|
||||
BottomMin, BottomMax
|
||||
BottomMin, BottomMax,
|
||||
Last = BottomMax
|
||||
};
|
||||
Atom actual;
|
||||
long strut[12];
|
||||
long *strut;
|
||||
ulong n;
|
||||
|
||||
n = getproperty(&c->w, Net("WM_STRUT_PARTIAL"), "CARDINAL", &actual,
|
||||
0L, (void*)&strut, nelem(strut));
|
||||
if(n != nelem(strut))
|
||||
return;
|
||||
if(actual != xatom("ATOM"))
|
||||
return;
|
||||
if(c->strut)
|
||||
free(c->strut);
|
||||
c->strut = nil;
|
||||
|
||||
n = getprop_long(&c->w, Net("WM_STRUT_PARTIAL"), "CARDINAL",
|
||||
0L, &strut, Last);
|
||||
if(n != nelem(strut)) {
|
||||
free(strut);
|
||||
n = getprop_long(&c->w, Net("WM_STRUT"), "CARDINAL",
|
||||
0L, &strut, 4L);
|
||||
if(n != 4) {
|
||||
free(strut);
|
||||
return;
|
||||
}
|
||||
strut = erealloc(strut, Last * sizeof *strut);
|
||||
strut[LeftMin] = strut[RightMin] = 0;
|
||||
strut[LeftMax] = strut[RightMax] = INT_MAX;
|
||||
strut[TopMin] = strut[BottomMin] = 0;
|
||||
strut[TopMax] = strut[BottomMax] = INT_MAX;
|
||||
}
|
||||
c->strut = emalloc(sizeof *c->strut);
|
||||
c->strut->left = Rect(0, strut[LeftMin], strut[Left], strut[LeftMax]);
|
||||
c->strut->right = Rect(-strut[Right], strut[RightMin], 0, strut[RightMax]);
|
||||
c->strut->top = Rect(strut[TopMin], 0, strut[TopMax], strut[Top]);
|
||||
c->strut->bottom = Rect(strut[BottomMin], -strut[Bottom], strut[BottomMax], 0);
|
||||
free(strut);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -251,23 +272,24 @@ ewmh_clientmessage(XClientMessageEvent *e) {
|
|||
if(msg == NET("ACTIVE_WINDOW")) {
|
||||
if(e->format != 32)
|
||||
return -1;
|
||||
if(l[0] != 2)
|
||||
return 1;
|
||||
c == win2client(e->window);
|
||||
Dprint(DEwmh, "\tsource: %ld\n", l[0]);
|
||||
Dprint(DEwmh, "\twindow: 0x%lx\n", e->window);
|
||||
c = win2client(e->window);
|
||||
if(c == nil)
|
||||
return 1;
|
||||
Dprint(DEwmh, "\tclient: %s\n", clientname(c));
|
||||
if(l[0] != 2)
|
||||
return 1;
|
||||
focus(c, true);
|
||||
return 1;
|
||||
}else
|
||||
if(msg == NET("CURRENT_DESKTOP")) {
|
||||
print("\t%ld\n", l[0]);
|
||||
if(e->format != 32)
|
||||
return -1;
|
||||
print("\t%ld\n", l[0]);
|
||||
for(v=view, i=l[0]; v; v=v->next, i--)
|
||||
if(i == 0)
|
||||
break;
|
||||
print("\t%d\n", i);
|
||||
Dprint(DEwmh, "\t%s\n", v->name);
|
||||
if(i == 0)
|
||||
view_select(v->name);
|
||||
return 1;
|
||||
|
|
|
@ -57,6 +57,7 @@ uint area_idx(Area*);
|
|||
void area_moveto(Area*, Frame*);
|
||||
char* area_name(Area*);
|
||||
Client* area_selclient(Area*);
|
||||
void area_setsel(Area*, Frame*);
|
||||
|
||||
/* bar.c */
|
||||
Bar* bar_create(Bar**, const char*);
|
||||
|
@ -108,6 +109,7 @@ void div_update_all(void);
|
|||
/* event.c */
|
||||
void check_x_event(IxpConn*);
|
||||
void dispatch_event(XEvent*);
|
||||
uint flushenterevents(void);
|
||||
uint flushevents(long, bool dispatch);
|
||||
void print_focus(Client*, const char*);
|
||||
|
||||
|
@ -138,9 +140,9 @@ uint frame_idx(Frame*);
|
|||
void frame_insert(Frame *pos, Frame*);
|
||||
void frame_remove(Frame*);
|
||||
void frame_resize(Frame*, Rectangle);
|
||||
bool frame_restack(Frame*, Frame*);
|
||||
void frame_setcursor(Frame*, Point);
|
||||
void frame_swap(Frame*, Frame*);
|
||||
bool frame_to_top(Frame*);
|
||||
int ingrabbox_p(Frame*, int x, int y);
|
||||
void move_focus(Frame*, Frame*);
|
||||
Rectangle constrain(Rectangle);
|
||||
|
@ -217,7 +219,7 @@ void view_restack(View*);
|
|||
void view_scale(View*, int w);
|
||||
Client* view_selclient(View*);
|
||||
void view_select(const char*);
|
||||
void view_setclient(Client*, char**);
|
||||
void client_setviews(Client*, char**);
|
||||
void view_update_all(void);
|
||||
Rectangle* view_rects(View*, uint *num, Frame *ignore);
|
||||
|
||||
|
|
|
@ -90,25 +90,34 @@ frame_insert(Frame *pos, Frame *f) {
|
|||
}
|
||||
|
||||
bool
|
||||
frame_to_top(Frame *f) {
|
||||
frame_restack(Frame *f, Frame *above) {
|
||||
Area *a;
|
||||
|
||||
a = f->area;
|
||||
if(!a->floating || f == a->stack)
|
||||
return False;
|
||||
if(!a->floating)
|
||||
return false;
|
||||
if(above && above->area != a)
|
||||
return false;
|
||||
|
||||
if(f->sprev)
|
||||
f->sprev->snext = f->snext;
|
||||
else
|
||||
a->stack = f->snext;
|
||||
if(f->snext)
|
||||
f->snext->sprev = f->sprev;
|
||||
|
||||
f->snext = a->stack;
|
||||
a->stack = f;
|
||||
f->sprev = nil;
|
||||
f->sprev = above;
|
||||
if(above == nil)
|
||||
a->stack = f;
|
||||
else
|
||||
f->snext = above->snext;
|
||||
if(f->snext)
|
||||
f->snext->sprev = f;
|
||||
if(f->sprev)
|
||||
f->sprev->snext = f;
|
||||
|
||||
return True;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Handlers */
|
||||
|
@ -130,12 +139,12 @@ bdown_event(Window *w, XButtonEvent *e) {
|
|||
case Button1:
|
||||
mouse_resize(c, False, CENTER);
|
||||
focus(c, false);
|
||||
frame_to_top(f);
|
||||
frame_restack(f, nil);
|
||||
focus(c, false); /* Blech */
|
||||
break;
|
||||
case Button3:
|
||||
mouse_resize(c, False, quadrant(f->r, Pt(e->x_root, e->y_root)));
|
||||
frame_to_top(f);
|
||||
frame_restack(f, nil);
|
||||
focus(c, false);
|
||||
break;
|
||||
default:
|
||||
|
@ -146,7 +155,7 @@ bdown_event(Window *w, XButtonEvent *e) {
|
|||
XUngrabPointer(display, e->time);
|
||||
}else{
|
||||
if(e->button == Button1) {
|
||||
if(frame_to_top(f))
|
||||
if(frame_restack(f, nil))
|
||||
view_restack(f->view);
|
||||
else if(rect_haspoint_p(Pt(e->x, e->y), f->grabbox))
|
||||
mouse_resize(c, True, CENTER);
|
||||
|
@ -381,25 +390,29 @@ move_focus(Frame *old_f, Frame *f) {
|
|||
|
||||
void
|
||||
frame_focus(Frame *f) {
|
||||
Client *c;
|
||||
Frame *old_f;
|
||||
View *v;
|
||||
Area *a, *old_a;
|
||||
Frame *old_f;
|
||||
|
||||
a = f->area;
|
||||
c = f->client;
|
||||
v = f->view;
|
||||
a = f->area;
|
||||
old_a = v->sel;
|
||||
|
||||
old_f = old_a->sel;
|
||||
a->sel = f;
|
||||
|
||||
if(a != old_a)
|
||||
if(a != old_a) {
|
||||
if(c->trans || (c->w.ewmh.type & (TypeDialog|TypeSplash)))
|
||||
v->oldsel = v->sel;
|
||||
area_focus(f->area);
|
||||
}
|
||||
|
||||
if(v != screen->sel || a != v->sel)
|
||||
return;
|
||||
|
||||
move_focus(old_f, f);
|
||||
|
||||
client_focus(f->client);
|
||||
|
||||
if(!a->floating && ((a->mode == Colstack) || (a->mode == Colmax)))
|
||||
|
|
|
@ -247,7 +247,7 @@ message(Ixp9Req *r, MsgFunc fn) {
|
|||
c = *p;
|
||||
*p = '\0';
|
||||
|
||||
m = ixp_message((uchar*)s, p-s, 0);
|
||||
m = ixp_message(s, p-s, 0);
|
||||
s = fn(f->p.ref, &m);
|
||||
if(s)
|
||||
err = s;
|
||||
|
@ -563,7 +563,7 @@ fs_stat(Ixp9Req *r) {
|
|||
IxpMsg m;
|
||||
Stat s;
|
||||
int size;
|
||||
uchar *buf;
|
||||
char *buf;
|
||||
FileId *f;
|
||||
|
||||
f = r->fid->aux;
|
||||
|
@ -589,7 +589,7 @@ fs_read(Ixp9Req *r) {
|
|||
char *buf;
|
||||
FileId *f, *tf;
|
||||
int n, offset;
|
||||
int size;
|
||||
ulong size;
|
||||
|
||||
f = r->fid->aux;
|
||||
|
||||
|
@ -604,8 +604,10 @@ fs_read(Ixp9Req *r) {
|
|||
|
||||
offset = 0;
|
||||
size = r->ifcall.count;
|
||||
if(size > IXP_MAX_MSG)
|
||||
size = r->fid->iounit;
|
||||
buf = emallocz(size);
|
||||
m = ixp_message((uchar*)buf, size, MsgPack);
|
||||
m = ixp_message(buf, size, MsgPack);
|
||||
|
||||
tf = f = lookup_file(f, nil);
|
||||
/* Note: f->tab.name == "." so we skip it */
|
||||
|
@ -892,7 +894,7 @@ fs_clunk(Ixp9Req *r) {
|
|||
case FsFBar:
|
||||
p = toutf8(f->p.bar->buf);
|
||||
|
||||
m = ixp_message((uchar*)p, strlen(p), 0);
|
||||
m = ixp_message(p, strlen(p), 0);
|
||||
msg_parsecolors(&m, &f->p.bar->col);
|
||||
|
||||
q = (char*)m.end-1;
|
||||
|
|
|
@ -374,15 +374,18 @@ main(int argc, char *argv[]) {
|
|||
wmiirc = "wmiistartrc";
|
||||
|
||||
ARGBEGIN{
|
||||
case 'v':
|
||||
print("%s", version);
|
||||
exit(0);
|
||||
case 'a':
|
||||
address = EARGF(usage());
|
||||
break;
|
||||
case 'G':
|
||||
debug |= DGeneric;
|
||||
break;
|
||||
case 'r':
|
||||
wmiirc = EARGF(usage());
|
||||
break;
|
||||
case 'v':
|
||||
print("%s", version);
|
||||
exit(0);
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
|
|
@ -598,7 +598,7 @@ msg_selectframe(Frame *f, IxpMsg *m, int sym) {
|
|||
return "invalid selection";
|
||||
|
||||
frame_focus(fp);
|
||||
frame_to_top(fp);
|
||||
frame_restack(fp, nil);
|
||||
if(f->view == screen->sel)
|
||||
view_restack(f->view);
|
||||
return nil;
|
||||
|
@ -677,7 +677,7 @@ msg_sendclient(View *v, IxpMsg *m, bool swap) {
|
|||
else
|
||||
return Ebadvalue;
|
||||
|
||||
flushevents(EnterWindowMask, False);
|
||||
flushenterevents();
|
||||
frame_focus(f);
|
||||
view_arrange(v);
|
||||
view_update_all();
|
||||
|
@ -716,7 +716,7 @@ msg_sendframe(Frame *f, int sym, bool swap) {
|
|||
|
||||
view_arrange(f->view);
|
||||
|
||||
flushevents(EnterWindowMask, False);
|
||||
flushenterevents();
|
||||
frame_focus(f);
|
||||
view_update_all();
|
||||
return nil;
|
||||
|
|
|
@ -139,7 +139,7 @@ view_focus(WMScreen *s, View *v) {
|
|||
|
||||
sync();
|
||||
XUngrabServer(display);
|
||||
flushevents(EnterWindowMask, False);
|
||||
flushenterevents();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -161,6 +161,7 @@ view_select(const char *arg) {
|
|||
void
|
||||
view_attach(View *v, Frame *f) {
|
||||
Client *c;
|
||||
Frame *ff;
|
||||
Area *a;
|
||||
|
||||
c = f->client;
|
||||
|
@ -169,12 +170,14 @@ view_attach(View *v, Frame *f) {
|
|||
a = v->sel;
|
||||
if(c->trans || c->floating || c->fixedsize
|
||||
|| c->titleless || c->borderless || c->fullscreen
|
||||
|| (c->w.ewmh.type & TypeDialog))
|
||||
|| (c->w.ewmh.type & (TypeDialog|TypeSplash|TypeDock)))
|
||||
a = v->area;
|
||||
else if(c->group && c->group->client
|
||||
&& (ff = client_viewframe(c->group->client, v)))
|
||||
a = ff->area;
|
||||
else if(starting && v->sel->floating)
|
||||
a = v->area->next;
|
||||
if(!(c->w.ewmh.type & TypeSplash))
|
||||
area_focus(a);
|
||||
|
||||
area_attach(a, f);
|
||||
}
|
||||
|
||||
|
@ -213,10 +216,8 @@ view_restack(View *v) {
|
|||
}
|
||||
|
||||
ewmh_updatestacking();
|
||||
if(wins.n) {
|
||||
XRaiseWindow(display, wins.ary[0]);
|
||||
if(wins.n)
|
||||
XRestackWindows(display, (ulong*)wins.ary, wins.n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -337,10 +337,10 @@ findwin(XWindow w) {
|
|||
uint
|
||||
winprotocols(Window *w) {
|
||||
Atom *protocols;
|
||||
Atom actual, delete;
|
||||
Atom delete;
|
||||
int i, n, protos;
|
||||
|
||||
n = getproperty(w, "WM_PROTOCOLS", "ATOM", &actual, 0L, (void*)&protocols, 20L);
|
||||
n = getprop_long(w, "WM_PROTOCOLS", "ATOM", 0L, (long**)&protocols, 20L);
|
||||
if(n == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -683,17 +683,17 @@ freestringlist(char *list[]) {
|
|||
XFreeStringList(list);
|
||||
}
|
||||
|
||||
ulong
|
||||
getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length) {
|
||||
static ulong
|
||||
getprop(Window *w, char *prop, char *type, Atom *actual, int *format, ulong offset, uchar **ret, ulong length) {
|
||||
Atom typea;
|
||||
ulong n, extra;
|
||||
int status, format;
|
||||
int status;
|
||||
|
||||
typea = (type ? xatom(type) : 0L);
|
||||
|
||||
status = XGetWindowProperty(display, w->w,
|
||||
xatom(prop), offset, length, False /* delete */,
|
||||
typea, actual, &format, &n, &extra, ret);
|
||||
typea, actual, format, &n, &extra, ret);
|
||||
|
||||
if(status != Success) {
|
||||
*ret = nil;
|
||||
|
@ -706,6 +706,29 @@ getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar
|
|||
return n;
|
||||
}
|
||||
|
||||
ulong
|
||||
getproperty(Window *w, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length) {
|
||||
int format;
|
||||
|
||||
return getprop(w, prop, type, actual, &format, offset, ret, length);
|
||||
}
|
||||
|
||||
ulong
|
||||
getprop_long(Window *w, char *prop, char *type, ulong offset, long **ret, ulong length) {
|
||||
Atom actual;
|
||||
ulong n;
|
||||
int format;
|
||||
|
||||
n = getprop(w, prop, type, &actual, &format, offset, (uchar**)ret, length);
|
||||
if(n == 0 || format == 32 && xatom(type) == actual)
|
||||
return n;
|
||||
Dprint(DGeneric, "getprop_long(%W, %s, %s) format=%d, actual=\"%A\"\n",
|
||||
w, prop, type, format, actual);
|
||||
free(*ret);
|
||||
*ret = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char**
|
||||
strlistdup(char *list[], int n) {
|
||||
char **p, *q;
|
||||
|
|
|
@ -14,7 +14,7 @@ LIBS = -L/usr/lib -lc -L${ROOT}/lib
|
|||
|
||||
# Flags
|
||||
include ${ROOT}/mk/gcc.mk
|
||||
CFLAGS += -g -O0 -DIXPlint
|
||||
CFLAGS += ${DEBUGCFLAGS} -DIXPlint
|
||||
LDFLAGS += -g ${LIBS}
|
||||
STATIC = -static
|
||||
MKDEP = cpp -M
|
||||
|
@ -35,10 +35,14 @@ LIBICONV = # Leave blank if your libc includes iconv (glibc does)
|
|||
LIBIXP = ${ROOT}/libixp/libixp.a
|
||||
LIBIXP = ${LIBDIR}/libixp.a
|
||||
|
||||
# *BSD
|
||||
#LIBICONV = -liconv
|
||||
# +Darwin
|
||||
#STATIC = # Darwon doesn't like static linking
|
||||
|
||||
# Solaris
|
||||
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
|
||||
#LDFLAGS = ${LIBS} -R${PREFIX}/lib
|
||||
#LDFLAGS += -lsocket -lnsl
|
||||
#CFLAGS += -xtarget=ultra
|
||||
|
||||
|
||||
|
|
|
@ -183,6 +183,7 @@ Window* findwin(XWindow);
|
|||
void freefont(Font*);
|
||||
void freeimage(Image *);
|
||||
void freestringlist(char**);
|
||||
ulong getprop_long(Window*, char*, char*, ulong, long**, ulong);
|
||||
ulong getproperty(Window*, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length);
|
||||
int gettextlistproperty(Window *w, char *name, char **ret[]);
|
||||
int grabpointer(Window*, Window *confine, Cursor, int mask);
|
||||
|
|
12
mk/gcc.mk
12
mk/gcc.mk
|
@ -1,7 +1,15 @@
|
|||
DEBUGCFLAGS = \
|
||||
-g \
|
||||
-O1 \
|
||||
-fno-builtin \
|
||||
-fno-inline \
|
||||
-fno-omit-frame-pointer \
|
||||
-fno-optimize-sibling-calls \
|
||||
-fno-unroll-loops
|
||||
CFLAGS += \
|
||||
-std=c99 \
|
||||
-pipe \
|
||||
-pedantic \
|
||||
-pipe \
|
||||
-Wall \
|
||||
-Wimplicit \
|
||||
-Wmissing-prototypes \
|
||||
|
@ -13,4 +21,4 @@ CFLAGS += \
|
|||
-Wpointer-arith \
|
||||
-Wreturn-type \
|
||||
-Wstrict-prototypes \
|
||||
-Wtrigraphs \
|
||||
-Wtrigraphs
|
||||
|
|
Loading…
Reference in New Issue