mirror of
https://github.com/0intro/wmii
synced 2024-11-22 13:52:17 +03:00
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:
parent
3957992efe
commit
6e1e231588
1
README
1
README
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,24 +101,29 @@ 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);
|
||||||
restack_view(v);
|
if(restack)
|
||||||
|
restack_view(v);
|
||||||
|
|
||||||
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
|
||||||
draw_client(c);
|
draw_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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
cmd/wm/fs.c
41
cmd/wm/fs.c
@ -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,15 +217,25 @@ 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;
|
||||||
|
case FsFindex:
|
||||||
|
return "index";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FsFmode:
|
case FsFmode:
|
||||||
if((qid->dir_type == FsDarea) && (i1 == -1 || i2 == -1))
|
if((qid->dir_type == FsDarea) && (i1 == -1 || i2 == -1))
|
||||||
@ -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)))
|
||||||
|
@ -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 *
|
||||||
|
@ -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);
|
||||||
|
@ -43,7 +43,7 @@ blitz_loadfont(Display *dpy, BlitzFont *font, char *fontstr)
|
|||||||
font->set = XCreateFontSet(dpy, fontname, &missing, &nmissing, &def);
|
font->set = XCreateFontSet(dpy, fontname, &missing, &nmissing, &def);
|
||||||
|
|
||||||
if(missing) {
|
if(missing) {
|
||||||
while(nmissing--)
|
while(nmissing--)
|
||||||
fprintf(stderr, "liblitz: missing fontset: %s\n", missing[nmissing]);
|
fprintf(stderr, "liblitz: missing fontset: %s\n", missing[nmissing]);
|
||||||
XFreeStringList(missing);
|
XFreeStringList(missing);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user