focus sanitizing/work in progress

This commit is contained in:
garbeam 2006-01-11 18:07:33 +02:00
parent 87588d1a5e
commit 543aaf3cd9
7 changed files with 38 additions and 121 deletions

View File

@ -29,7 +29,18 @@ void
focus_client(Client * c) focus_client(Client * c)
{ {
Frame *f = 0; Frame *f = 0;
Client *old = sel_client();
if(old && (old != c)) {
fprintf(stderr, "%s", "grabbing everything for window\n");
ungrab_client(old, AnyModifier, AnyButton);
grab_client(old, AnyModifier, AnyButton);
}
/* sel client */ /* sel client */
ungrab_client(c, AnyModifier, AnyButton);
grab_client(c, Mod1Mask, Button1);
grab_client(c, Mod1Mask, Button3);
f = c->frame; f = c->frame;
f->sel = c; f->sel = c;
XRaiseWindow(dpy, c->win); XRaiseWindow(dpy, c->win);
@ -54,8 +65,7 @@ show_client(Client * c)
{ {
XMapRaised(dpy, c->win); XMapRaised(dpy, c->win);
set_client_state(c, NormalState); set_client_state(c, NormalState);
grab_client(c, Mod1Mask, Button1); grab_client(c, AnyModifier, AnyButton);
grab_client(c, Mod1Mask, Button3);
} }
void void
@ -76,14 +86,14 @@ reparent_client(Client * c, Window w, int x, int y)
void void
grab_client(Client * c, unsigned long mod, unsigned int button) grab_client(Client * c, unsigned long mod, unsigned int button)
{ {
XGrabButton(dpy, button, mod, c->win, False, XGrabButton(dpy, button, mod, c->win, True,
ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None); ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);
if((mod != AnyModifier) && num_lock_mask) { if((mod != AnyModifier) && num_lock_mask) {
XGrabButton(dpy, button, mod | num_lock_mask, c->win, False, XGrabButton(dpy, button, mod | num_lock_mask, c->win, True,
ButtonPressMask, GrabModeAsync, GrabModeAsync, None, ButtonPressMask, GrabModeSync, GrabModeAsync, None,
None); None);
XGrabButton(dpy, button, mod | num_lock_mask | LockMask, c->win, XGrabButton(dpy, button, mod | num_lock_mask | LockMask, c->win,
False, ButtonPressMask, GrabModeAsync, GrabModeAsync, True, ButtonPressMask, GrabModeSync, GrabModeAsync,
None, None); None, None);
} }
} }

View File

@ -19,12 +19,8 @@ static void handle_maprequest(XEvent * e);
static void handle_motionnotify(XEvent * e); static void handle_motionnotify(XEvent * e);
static void handle_propertynotify(XEvent * e); static void handle_propertynotify(XEvent * e);
static void handle_unmapnotify(XEvent * e); static void handle_unmapnotify(XEvent * e);
static void handle_enternotify(XEvent * e);
static void handle_ignore_enternotify_crap(XEvent * e);
static void handle_clientmessage(XEvent * e); static void handle_clientmessage(XEvent * e);
static unsigned int ignore_enternotify_crap = 0;
void (*handler[LASTEvent]) (XEvent *); void (*handler[LASTEvent]) (XEvent *);
void void
@ -37,16 +33,11 @@ init_event_hander()
} }
handler[ButtonPress] = handle_buttonpress; handler[ButtonPress] = handle_buttonpress;
handler[ConfigureRequest] = handle_configurerequest; handler[ConfigureRequest] = handle_configurerequest;
handler[ConfigureNotify] = handle_ignore_enternotify_crap;
handler[CirculateNotify] = handle_ignore_enternotify_crap;
handler[DestroyNotify] = handle_destroynotify; handler[DestroyNotify] = handle_destroynotify;
handler[EnterNotify] = handle_enternotify;
handler[Expose] = handle_expose; handler[Expose] = handle_expose;
handler[GravityNotify] = handle_ignore_enternotify_crap;
handler[MapRequest] = handle_maprequest; handler[MapRequest] = handle_maprequest;
handler[MotionNotify] = handle_motionnotify; handler[MotionNotify] = handle_motionnotify;
handler[PropertyNotify] = handle_propertynotify; handler[PropertyNotify] = handle_propertynotify;
handler[MapNotify] = handle_ignore_enternotify_crap;
handler[UnmapNotify] = handle_unmapnotify; handler[UnmapNotify] = handle_unmapnotify;
handler[ClientMessage] = handle_clientmessage; handler[ClientMessage] = handle_clientmessage;
} }
@ -69,17 +60,13 @@ handle_buttonpress(XEvent * e)
XButtonPressedEvent *ev = &e->xbutton; XButtonPressedEvent *ev = &e->xbutton;
Frame *f = win_to_frame(ev->window); Frame *f = win_to_frame(ev->window);
if(f) { if(f)
handle_frame_buttonpress(ev, f); handle_frame_buttonpress(ev, f);
return; else if((c = win_to_client(ev->window))) {
}
if(ev->window == root) {
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
return;
}
if((c = win_to_client(ev->window))) {
if(c->frame) { /* client is attached */ if(c->frame) { /* client is attached */
focus_area(c->frame->area);
c->frame->area->layout->focus(c->frame, False);
focus_client(c);
ev->state &= valid_mask; ev->state &= valid_mask;
if(ev->state & Mod1Mask) { if(ev->state & Mod1Mask) {
Align align; Align align;
@ -275,7 +262,6 @@ handle_unmapnotify(XEvent * e)
{ {
XUnmapEvent *ev = &e->xunmap; XUnmapEvent *ev = &e->xunmap;
Client *c; Client *c;
handle_ignore_enternotify_crap(e);
if((c = win_to_client(ev->window))) { if((c = win_to_client(ev->window))) {
if(!c->ignore_unmap) if(!c->ignore_unmap)
detach_client(c, True); detach_client(c, True);
@ -284,30 +270,6 @@ handle_unmapnotify(XEvent * e)
} }
} }
static void
handle_enternotify(XEvent * e)
{
XCrossingEvent *ev = &e->xcrossing;
Client *c;
if((ev->mode != NotifyNormal) || (ev->detail == NotifyInferior)
|| (ev->serial == ignore_enternotify_crap))
return;
c = win_to_client(ev->window);
if(c && c->frame) {
focus_area(c->frame->area);
c->frame->area->layout->focus(c->frame, False);
}
}
static void
handle_ignore_enternotify_crap(XEvent * e)
{
ignore_enternotify_crap = e->xany.serial;
XSync(dpy, False);
}
static void handle_clientmessage(XEvent *e) static void handle_clientmessage(XEvent *e)
{ {
XClientMessageEvent *ev = &e->xclient; XClientMessageEvent *ev = &e->xclient;

View File

@ -10,16 +10,9 @@
#include "wm.h" #include "wm.h"
static void select_client(void *obj, char *arg);
static void handle_after_write_frame(IXPServer * s, File * file); static void handle_after_write_frame(IXPServer * s, File * file);
static void handle_before_read_frame(IXPServer * s, File * file); static void handle_before_read_frame(IXPServer * s, File * file);
/* action table for /frame/?/ namespace */
Action frame_acttbl[] = {
{"select", select_client},
{0, 0}
};
Frame * Frame *
alloc_frame(XRectangle * r) alloc_frame(XRectangle * r)
{ {
@ -37,9 +30,6 @@ alloc_frame(XRectangle * r)
snprintf(buf, MAX_BUF, "/detached/%d/name", id); snprintf(buf, MAX_BUF, "/detached/%d/name", id);
f->file[F_NAME] = ixp_create(ixps, buf); f->file[F_NAME] = ixp_create(ixps, buf);
f->file[F_NAME]->before_read = handle_before_read_frame; f->file[F_NAME]->before_read = handle_before_read_frame;
snprintf(buf, MAX_BUF, "/detached/%d/ctl", id);
f->file[F_CTL] = ixp_create(ixps, buf);
f->file[F_CTL]->after_write = handle_after_write_frame;
snprintf(buf, MAX_BUF, "/detached/%d/geometry", id); snprintf(buf, MAX_BUF, "/detached/%d/geometry", id);
f->file[F_GEOMETRY] = ixp_create(ixps, buf); f->file[F_GEOMETRY] = ixp_create(ixps, buf);
f->file[F_GEOMETRY]->before_read = handle_before_read_frame; f->file[F_GEOMETRY]->before_read = handle_before_read_frame;
@ -269,17 +259,17 @@ handle_frame_buttonpress(XButtonEvent * e, Frame * f)
{ {
Align align; Align align;
int bindex, cindex = e->x / (f->rect.width / f->nclients); int bindex, cindex = e->x / (f->rect.width / f->nclients);
f->sel = clientat(f->clients, cindex); Client *new = clientat(f->clients, cindex);
f->area->layout->focus(f, False);
sel_client(new);
if(e->button == Button1) { if(e->button == Button1) {
align = cursor_to_align(f->cursor); align = cursor_to_align(f->cursor);
if(align == CENTER) if(align == CENTER)
mouse_move(f); mouse_move(f);
else else
mouse_resize(f, align); mouse_resize(f, align);
f->area->layout->focus(f, False);
return; return;
} }
f->area->layout->focus(f, False);
bindex = WM_EVENT_B2PRESS - 2 + e->button; bindex = WM_EVENT_B2PRESS - 2 + e->button;
/* frame mouse handling */ /* frame mouse handling */
if(def[bindex]->content) if(def[bindex]->content)
@ -300,7 +290,6 @@ attach_client_to_frame(Frame * f, Client * client)
c->next = client; c->next = client;
} }
f->nclients++; f->nclients++;
f->sel = client;
client->frame = f; client->frame = f;
resize_frame(f, &f->rect, 0); resize_frame(f, &f->rect, 0);
reparent_client(client, f->win, client->rect.x, client->rect.y); reparent_client(client, f->win, client->rect.x, client->rect.y);
@ -311,15 +300,10 @@ void
detach_client_from_frame(Client * c, Bool unmap) detach_client_from_frame(Client * c, Bool unmap)
{ {
Frame *f = c->frame; Frame *f = c->frame;
Client *cl;
c->frame = nil; c->frame = nil;
if(f->sel == c) { if(f->sel == c)
if(c->prev) f->sel = nil;
f->sel = c->prev;
else
f->sel = nil;
}
if(f->clients == c) { if(f->clients == c) {
if(c->next) if(c->next)
@ -332,8 +316,6 @@ detach_client_from_frame(Client * c, Bool unmap)
} }
f->nclients--; f->nclients--;
if(!f->sel)
f->sel = f->clients;
if(!c->destroyed) { if(!c->destroyed) {
if(!unmap) { if(!unmap) {
@ -344,27 +326,6 @@ detach_client_from_frame(Client * c, Bool unmap)
c->rect.y = f->rect.y; c->rect.y = f->rect.y;
reparent_client(c, root, c->rect.x, c->rect.y); reparent_client(c, root, c->rect.x, c->rect.y);
} }
if((cl = sel_client())) {
sel_area()->layout->focus(sel_frame(), False);
focus_client(cl);
}
}
static void
select_client(void *obj, char *arg)
{
Client *c;
Frame *f = obj;
if(!f || !arg || !f->clients->next)
return;
if(!strncmp(arg, "prev", 5))
c = f->sel->prev;
else if(!strncmp(arg, "next", 5))
c = f->sel->next;
else
c = clientat(f->clients, blitz_strtonum(arg, 0, f->nclients - 1));
focus_client(c);
f->area->layout->focus(f, False);
} }
static Frame * static Frame *
@ -415,10 +376,6 @@ handle_after_write_frames(IXPServer * s, File * file, Area * a)
{ {
Frame *f; Frame *f;
for(f = a->layout->frames(a); f; f = f->next) { for(f = a->layout->frames(a); f; f = f->next) {
if(file == f->file[F_CTL]) {
run_action(file, f, frame_acttbl);
return f;
}
if(file == f->file[F_TAB] || file == f->file[F_BORDER] if(file == f->file[F_TAB] || file == f->file[F_BORDER]
|| file == f->file[F_HANDLE_INC]) { || file == f->file[F_HANDLE_INC]) {
f->area->layout->arrange(f->area); f->area->layout->arrange(f->area);

View File

@ -431,13 +431,15 @@ focus_col(Frame * f, Bool raise)
Acme *acme = a->aux; Acme *acme = a->aux;
Frame *old = sel_col(a); Frame *old = sel_col(a);
Cell *cell = f->aux; Cell *cell = f->aux;
Client *c = f->sel ? f->sel : f->clients;
acme->sel = cell->col; acme->sel = cell->col;
cell->col->sel = cell; cell->col->sel = cell;
a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content; a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content;
if(raise) if(raise && c)
center_pointer(f); XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
focus_client(f->sel); c->rect.width / 2, c->rect.height / 2);
focus_client(c);
if(old && old != f) if(old && old != f)
draw_frame(old); draw_frame(old);
draw_frame(f); draw_frame(f);

View File

@ -188,15 +188,17 @@ focus_float(Frame * f, Bool raise)
Area *a = f->area; Area *a = f->area;
Float *fl = a->aux; Float *fl = a->aux;
Frame *old = fl->sel; Frame *old = fl->sel;
Client *c = f->sel ? f->sel : f->clients;
sel_client(f->sel);
fl->sel = f; fl->sel = f;
a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content; a->file[A_SEL_FRAME]->content = f->file[F_PREFIX]->content;
if(raise) { if(raise) {
XRaiseWindow(dpy, f->win); XRaiseWindow(dpy, f->win);
center_pointer(f); if(c)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
c->rect.width / 2, c->rect.height / 2);
} }
focus_client(f->sel); focus_client(c);
if(old && old != f) if(old && old != f)
draw_frame(old); draw_frame(old);
draw_frame(f); draw_frame(f);

View File

@ -609,17 +609,3 @@ mouse_resize(Frame * f, Align align)
} }
} }
} }
void
center_pointer(Frame * f)
{
Window dummy;
int wex, wey, ex, ey, i;
unsigned int dmask;
if(!f)
return;
XQueryPointer(dpy, f->win, &dummy, &dummy, &i, &i, &wex, &wey, &dmask);
XTranslateCoordinates(dpy, f->win, root, wex, wey, &ex, &ey, &dummy);
/* suppress EnterNotify's while mouse warping */
XWarpPointer(dpy, None, f->win, 0, 0, 0, 0, f->rect.width / 2, f->rect.height / 2);
}

View File

@ -32,7 +32,6 @@ enum {
enum { enum {
F_PREFIX, F_PREFIX,
F_NAME, F_NAME,
F_CTL,
F_GEOMETRY, F_GEOMETRY,
F_BORDER, F_BORDER,
F_TAB, F_TAB,
@ -86,7 +85,7 @@ enum {
#define GAP 5 #define GAP 5
#define ROOT_MASK SubstructureRedirectMask #define ROOT_MASK SubstructureRedirectMask
#define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | EnterWindowMask) #define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | ButtonPressMask)
typedef struct Page Page; typedef struct Page Page;
typedef struct RunInPage RunInPage; typedef struct RunInPage RunInPage;
@ -266,7 +265,6 @@ Cursor cursor_for_motion(Frame * f, int x, int y);
Align cursor_to_align(Cursor cursor); Align cursor_to_align(Cursor cursor);
Align xy_to_align(XRectangle * rect, int x, int y); Align xy_to_align(XRectangle * rect, int x, int y);
void drop_move(Frame * f, XRectangle * new, XPoint * pt); void drop_move(Frame * f, XRectangle * new, XPoint * pt);
void center_pointer(Frame * f);
/* page.c */ /* page.c */
Page *pageat(unsigned int idx); Page *pageat(unsigned int idx);