implemented sloppy focus changes as described at wmii@wmii.de to Sander, implemented ClientFocus event in /event, implemented client/index file (yesterday I decided to do it before wmii-3)

This commit is contained in:
Anselm R. Garbe 2006-04-26 08:59:55 +02:00
parent 3957992efe
commit 6e1e231588
10 changed files with 76 additions and 33 deletions

1
README
View File

@ -76,6 +76,7 @@ The following people have contributed especially to wmii in various ways:
- Norman Golisz <norman dot golisz at arcor dot de > - Norman Golisz <norman dot golisz at arcor dot de >
- Stefano K. Lee <wizinblack at gmail dot com > - Stefano K. Lee <wizinblack at gmail dot com >
- Stefan Tibus <sjti at gmx dot net> - Stefan Tibus <sjti at gmx dot net>
- Neptun <neptun at gmail dot com>
References References

View File

@ -6,8 +6,9 @@
- tagbars - tagbars
- slot will be similiar to old wmi-10 slot, a separate window at the right side of the screen - slot will be similiar to old wmi-10 slot, a separate window at the right side of the screen
- MWM/EWMH handling to support borderless apps? - MWM/EWMH handling to support borderless apps?
- implement client/id file, change /client/<n> namespace to /client/<id>/
- consider a Focus event whenever a client is focused - consider a Focus event whenever a client is focused
- screen dimension rescaling if screen resolution changes (even with Xrandr) - screen dimension rescaling if screen resolution changes (even with Xrandr)
- Xinerama support - Xinerama support
- partly EWMH support - partly EWMH support
- libixp: idea from PoP: implement a va_args method similiar to printf for
marshalling 9P messages, might reduce LOC drastically

View File

@ -142,7 +142,7 @@ select_area(Area *a, char *arg)
} }
new = v->area.data[i]; new = v->area.data[i];
if(new->frame.size) if(new->frame.size)
focus_client(new->frame.data[new->sel]->client); focus_client(new->frame.data[new->sel]->client, True);
v->sel = i; v->sel = i;
for(i = 0; i < a->frame.size; i++) for(i = 0; i < a->frame.size; i++)
draw_client(a->frame.data[i]->client); draw_client(a->frame.data[i]->client);
@ -154,7 +154,7 @@ send_to_area(Area *to, Area *from, Client *c)
c->revert = from; c->revert = from;
detach_from_area(from, c); detach_from_area(from, c);
attach_to_area(to, c); attach_to_area(to, c);
focus_client(c); focus_client(c, True);
} }
void void

View File

@ -10,7 +10,7 @@
#include "wm.h" #include "wm.h"
#define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask) #define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | EnterWindowMask)
static Vector * static Vector *
vector_of_clients(ClientVector *cv) vector_of_clients(ClientVector *cv)
@ -75,7 +75,7 @@ create_client(Window w, XWindowAttributes *wa)
fwa.override_redirect = 1; fwa.override_redirect = 1;
fwa.background_pixmap = ParentRelative; fwa.background_pixmap = ParentRelative;
fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask fwa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
| EnterWindowMask | ExposureMask | ButtonPressMask | ButtonReleaseMask; | ExposureMask | ButtonPressMask | ButtonReleaseMask;
c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y, c->framewin = XCreateWindow(dpy, root, c->rect.x, c->rect.y,
c->rect.width + 2 * def.border, c->rect.width + 2 * def.border,
@ -101,17 +101,19 @@ set_client_state(Client * c, int state)
} }
void void
focus_client(Client *c) focus_client(Client *c, Bool restack)
{ {
Client *old = sel_client(); Client *old = sel_client();
Frame *f = c->frame.data[c->sel]; Frame *f = c->frame.data[c->sel];
View *v = f->area->view; View *v = f->area->view;
int i = idx_of_area(f->area); int i = idx_of_area(f->area);
static char buf[256];
v->sel = i; v->sel = i;
f->area->sel = idx_of_frame(f); f->area->sel = idx_of_frame(f);
if(old) if(old)
draw_client(old); draw_client(old);
if(restack)
restack_view(v); restack_view(v);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
@ -119,6 +121,9 @@ focus_client(Client *c)
XSync(dpy, False); XSync(dpy, False);
if(i > 0 && f->area->mode == Colstack) if(i > 0 && f->area->mode == Colstack)
arrange_column(f->area, False); arrange_column(f->area, False);
snprintf(buf, sizeof(buf), "ClientFocus %d %s\n",
idx_of_client_id(c->id), c->name);
write_event(buf);
} }
void void
@ -364,7 +369,7 @@ manage_client(Client *c)
reparent_client(c, c->framewin, c->rect.x, c->rect.y); reparent_client(c, c->framewin, c->rect.x, c->rect.y);
update_views(); update_views();
flush_enter_events(); flush_events(EnterWindowMask);
} }
static int static int
@ -401,7 +406,7 @@ destroy_client(Client *c)
XSync(dpy, False); XSync(dpy, False);
XSetErrorHandler(wmii_error_handler); XSetErrorHandler(wmii_error_handler);
XUngrabServer(dpy); XUngrabServer(dpy);
flush_enter_events(); flush_events(EnterWindowMask);
} }
Client * Client *
@ -508,8 +513,8 @@ select_client(Client *c, char *arg)
if(errstr) if(errstr)
return; return;
} }
focus_client(a->frame.data[i]->client); focus_client(a->frame.data[i]->client, True);
flush_enter_events(); flush_events(EnterWindowMask);
} }
void void
@ -565,8 +570,8 @@ Swaparea:
} }
if(idx_of_area(a)) if(idx_of_area(a))
arrange_column(a, False); arrange_column(a, False);
focus_client(c); focus_client(c, True);
flush_enter_events(); flush_events(EnterWindowMask);
} }
void void
@ -616,7 +621,7 @@ send_client_to(Client *c, char *arg)
to = v->area.data[i]; to = v->area.data[i];
} }
send_to_area(to, a, c); send_to_area(to, a, c);
flush_enter_events(); flush_events(EnterWindowMask);
} }
void void
@ -632,12 +637,12 @@ resize_all_clients()
resize_client(c, &c->frame.data[c->sel]->rect, False); resize_client(c, &c->frame.data[c->sel]->rect, False);
} }
} }
flush_enter_events(); flush_events(EnterWindowMask);
} }
/* convenience function */ /* convenience function */
void void
focus(Client *c) focus(Client *c, Bool restack)
{ {
Frame *f = c->frame.size ? c->frame.data[c->sel] : nil; Frame *f = c->frame.size ? c->frame.data[c->sel] : nil;
View *v; View *v;
@ -648,7 +653,7 @@ focus(Client *c)
v = f->area->view; v = f->area->view;
if(view.data[sel] != v) if(view.data[sel] != v)
focus_view(v); focus_view(v);
focus_client(c); focus_client(c, restack);
} }
int int

View File

@ -338,7 +338,7 @@ drop_moving(Frame *f, XRectangle *new, XPoint *pt)
src->frame.data[j] = src->frame.data[i]; src->frame.data[j] = src->frame.data[i];
src->frame.data[i] = tmp; src->frame.data[i] = tmp;
arrange_column(src, False); arrange_column(src, False);
focus_client(f->client); focus_client(f->client, True);
} }
} }
} }

View File

@ -57,10 +57,10 @@ check_x_event(IXPConn *c)
} }
void void
flush_enter_events() flush_events(long even_mask)
{ {
XEvent ev; XEvent ev;
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); while(XCheckMaskEvent(dpy, even_mask, &ev));
} }
static void static void
@ -97,7 +97,7 @@ handle_buttonpress(XEvent *e)
if(ev->state & def.mod) { if(ev->state & def.mod) {
if((ev->button == Button1 || ev->button == Button3) if((ev->button == Button1 || ev->button == Button3)
&& (sel_client() != c)) && (sel_client() != c))
focus(c); focus(c, True);
if(ev->button == Button1) if(ev->button == Button1)
do_mouse_move(c); do_mouse_move(c);
else if (ev->button == Button3) { else if (ev->button == Button3) {
@ -110,7 +110,7 @@ handle_buttonpress(XEvent *e)
} }
else if(ev->button == Button1) { else if(ev->button == Button1) {
if(sel_client() != c) if(sel_client() != c)
focus(c); focus(c, True);
} }
} }
} }
@ -211,9 +211,9 @@ handle_enternotify(XEvent *e)
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior) if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
return; return;
if((c = frame_of_win(ev->window))) { if((c = client_of_win(ev->window))) {
if(c != sel_client_of_view(view.data[sel])) if(c != sel_client_of_view(view.data[sel]))
focus(c); focus(c, False);
} }
} }

View File

@ -62,6 +62,7 @@ enum { WMII_IOUNIT = 2048 };
* /view/1/mode FsFmode column mode * /view/1/mode FsFmode column mode
* /view/1/sel/ FsDclient * /view/1/sel/ FsDclient
* /view/1/1/class FsFclass class:instance of client * /view/1/1/class FsFclass class:instance of client
* /view/1/1/index FsFindex index of client in /client
* /view/1/1/name FsFname name of client * /view/1/1/name FsFname name of client
* /view/1/1/tags FsFtags tag of client * /view/1/1/tags FsFtags tag of client
* /view/1/geom FsFgeom geometry of client * /view/1/geom FsFgeom geometry of client
@ -216,16 +217,26 @@ qid2name(Qid *qid)
return "tags"; return "tags";
break; break;
case FsFclass: case FsFclass:
case FsFindex:
case FsFname: case FsFname:
if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1)) if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1))
return nil; return nil;
else if(i1 == -1) else if(i1 == -1)
return nil; return nil;
if(type == FsFname) switch(type) {
case FsFname:
return "name"; return "name";
else break;
case FsFclass:
return "class"; return "class";
break; break;
case FsFindex:
return "index";
break;
default:
break;
}
break;
case FsFmode: case FsFmode:
if((qid->dir_type == FsDarea) && (i1 == -1 || i2 == -1)) if((qid->dir_type == FsDarea) && (i1 == -1 || i2 == -1))
return nil; return nil;
@ -237,6 +248,7 @@ qid2name(Qid *qid)
case FsFevent: return "event"; break; case FsFevent: return "event"; break;
default: return nil; break; default: return nil; break;
} }
return nil;
} }
static unsigned char static unsigned char
@ -259,8 +271,10 @@ name2type(char *name, unsigned char dir_type)
return FsFctl; return FsFctl;
if(!strncmp(name, "event", 6)) if(!strncmp(name, "event", 6))
return FsFevent; return FsFevent;
if(!strncmp(name, "class", 5)) if(!strncmp(name, "class", 6))
return FsFclass; return FsFclass;
if(!strncmp(name, "index", 6))
return FsFindex;
if(!strncmp(name, "name", 5)) if(!strncmp(name, "name", 5))
return FsFname; return FsFname;
if(!strncmp(name, "border", 7)) if(!strncmp(name, "border", 7))
@ -413,6 +427,7 @@ mkqid(Qid *dir, char *wname, Qid *new)
break; break;
case FsFgeom: case FsFgeom:
case FsFname: case FsFname:
case FsFindex:
case FsFclass: case FsFclass:
if(dir_type == FsDroot) if(dir_type == FsDroot)
return -1; return -1;
@ -522,6 +537,15 @@ type2stat(Stat *stat, char *wname, Qid *dir)
else else
return mkstat(stat, dir, wname, strlen(client.data[dir_i1]->classinst), IXP_DMREAD); return mkstat(stat, dir, wname, strlen(client.data[dir_i1]->classinst), IXP_DMREAD);
break; break;
case FsFindex:
if(dir_type == FsDclient) {
f = view.data[dir_i1]->area.data[dir_i2]->frame.data[dir_i3];
snprintf(buf, sizeof(buf), "%d", idx_of_client_id(f->client->id));
}
else
snprintf(buf, sizeof(buf), "%d", dir_i1);
return mkstat(stat, dir, wname, strlen(buf), IXP_DMREAD);
break;
case FsFname: case FsFname:
if(dir_type == FsDclient) { if(dir_type == FsDclient) {
f = view.data[dir_i1]->area.data[dir_i2]->frame.data[dir_i3]; f = view.data[dir_i1]->area.data[dir_i2]->frame.data[dir_i3];
@ -1046,6 +1070,8 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat); p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "name", &m->qid); fcall->count += type2stat(&stat, "name", &m->qid);
p = ixp_enc_stat(p, &stat); p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "index", &m->qid);
p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "tags", &m->qid); fcall->count += type2stat(&stat, "tags", &m->qid);
p = ixp_enc_stat(p, &stat); p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "geom", &m->qid); fcall->count += type2stat(&stat, "geom", &m->qid);
@ -1090,6 +1116,15 @@ xread(IXPConn *c, Fcall *fcall)
memcpy(p, client.data[i1]->classinst, fcall->count); memcpy(p, client.data[i1]->classinst, fcall->count);
} }
break; break;
case FsFindex:
if(m->qid.dir_type == FsDclient)
snprintf(buf, sizeof(buf), "%d",
idx_of_client_id(view.data[i1]->area.data[i2]->frame.data[i3]->client->id));
else
snprintf(buf, sizeof(buf), "%d", i1);
if((fcall->count = strlen(buf)))
memcpy(p, buf, fcall->count);
break;
case FsFname: case FsFname:
if(m->qid.dir_type == FsDclient) { if(m->qid.dir_type == FsDclient) {
if((fcall->count = strlen(view.data[i1]->area.data[i2]->frame.data[i3]->client->name))) if((fcall->count = strlen(view.data[i1]->area.data[i2]->frame.data[i3]->client->name)))

View File

@ -86,7 +86,7 @@ focus_view(View *v)
/* gives all(!) clients proper geometry (for use of different tags) */ /* gives all(!) clients proper geometry (for use of different tags) */
if((c = sel_client_of_view(v))) if((c = sel_client_of_view(v)))
focus_client(c); focus_client(c, True);
for(i = 0; i < client.size; i++) for(i = 0; i < client.size; i++)
if(client.data[i]->frame.size) { if(client.data[i]->frame.size) {
Frame *f = client.data[i]->frame.data[client.data[i]->sel]; Frame *f = client.data[i]->frame.data[client.data[i]->sel];
@ -103,7 +103,7 @@ focus_view(View *v)
update_view_bars(); update_view_bars();
XSync(dpy, False); XSync(dpy, False);
XUngrabServer(dpy); XUngrabServer(dpy);
flush_enter_events(); flush_events(EnterWindowMask);
} }
XRectangle * XRectangle *

View File

@ -61,6 +61,7 @@ enum {
FsFclass, FsFclass,
FsFmode, FsFmode,
FsFtags, FsFtags,
FsFindex,
FsFcolw FsFcolw
}; };
@ -220,8 +221,8 @@ void unmap_client(Client *c);
void map_client(Client *c); void map_client(Client *c);
void reparent_client(Client *c, Window w, int x, int y); void reparent_client(Client *c, Window w, int x, int y);
void manage_client(Client *c); void manage_client(Client *c);
void focus_client(Client *c); void focus_client(Client *c, Bool restack);
void focus(Client *c); void focus(Client *c, Bool restack);
void resize_client(Client *c, XRectangle *r, Bool ignore_xcall); void resize_client(Client *c, XRectangle *r, Bool ignore_xcall);
void select_client(Client *c, char *arg); void select_client(Client *c, char *arg);
void send_client_to(Client *c, char *arg); void send_client_to(Client *c, char *arg);
@ -244,7 +245,7 @@ Area *new_right_column(View *v);
/* event.c */ /* event.c */
void init_x_event_handler(); void init_x_event_handler();
void check_x_event(IXPConn *c); void check_x_event(IXPConn *c);
void flush_enter_events(); void flush_events(long even_mask);
/* frame.c */ /* frame.c */
Frame *create_frame(Area *a, Client *c); Frame *create_frame(Area *a, Client *c);