This commit is contained in:
Kris Maglione 2007-04-16 22:47:32 -04:00
parent 6cc9c57dfd
commit a516c373ef
2 changed files with 115 additions and 161 deletions

View File

@ -182,3 +182,4 @@ uint textwidth_l(Font *font, char *text, uint len);
uint textwidth(Font *font, char *text); uint textwidth(Font *font, char *text);
uint labelh(Font *font); uint labelh(Font *font);
Atom xatom(char *name); Atom xatom(char *name);
int grabpointer(Window *w, Window *confine, Cursor cur, int mask);

View File

@ -276,6 +276,13 @@ warppointer(int x, int y) {
/* target */ x, y); /* target */ x, y);
} }
void
translate(Window *src, Window *dst, int sx, int sy, int *dx, int *dy) {
XWindow w;
XTranslateCoordinates(display, src->w, dst->w, sx, sy, dx, dy, &w);
}
static void static void
do_managed_move(Client *c) { do_managed_move(Client *c) {
Rectangle frect, ofrect; Rectangle frect, ofrect;
@ -287,10 +294,7 @@ do_managed_move(Client *c) {
f = c->sel; f = c->sel;
XSync(display, False); XSync(display, False);
if(XGrabPointer(display, c->framewin->w, False, if(!grabpointer(c->framewin, nil, cursor[CurMove], MouseMask))
MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime
) != GrabSuccess)
return; return;
XGrabServer(display); XGrabServer(display);
@ -301,15 +305,11 @@ do_managed_move(Client *c) {
for(;;) { for(;;) {
XMaskEvent(display, MouseMask | ExposureMask, &ev); XMaskEvent(display, MouseMask | ExposureMask, &ev);
switch (ev.type) { switch (ev.type) {
case ButtonRelease: default:
xorrect(frect); break;
case Expose:
find_droppoint(f, x, y, &frect, True); dispatch_event(&ev);
break;
XUngrabServer(display);
XUngrabPointer(display, CurrentTime);
XSync(display, False);
return;
case MotionNotify: case MotionNotify:
ofrect = frect; ofrect = frect;
x = ev.xmotion.x_root; x = ev.xmotion.x_root;
@ -322,10 +322,15 @@ do_managed_move(Client *c) {
xorrect(frect); xorrect(frect);
} }
break; break;
case Expose: case ButtonRelease:
dispatch_event(&ev); xorrect(frect);
break;
default: break; find_droppoint(f, x, y, &frect, True);
XUngrabServer(display);
XUngrabPointer(display, CurrentTime);
XSync(display, False);
return;
} }
} }
} }
@ -355,12 +360,11 @@ mouse_resizecolframe(Frame *f, Align align) {
} }
for(fp = a->frame; fp; fp = fp->anext) for(fp = a->frame; fp; fp = fp->anext)
if(fp->anext == f) break; if(fp->anext == f) break;
if(align&EAST) if(align&EAST)
d = d->next; d = d->next;
minw = Dx(screen->rect)/NCOL; if(!grabpointer(&scr.root, cwin, cursor[CurSizing], MouseMask))
minh = frame_delta_h() + labelh(def.font); return;
if(align&NORTH) { if(align&NORTH) {
r.min.y = (fp ? fp->rect.min.y : screen->rect.min.y); r.min.y = (fp ? fp->rect.min.y : screen->rect.min.y);
@ -369,9 +373,6 @@ mouse_resizecolframe(Frame *f, Align align) {
r.min.y = f->rect.min.y; r.min.y = f->rect.min.y;
r.max.y = (f->anext ? f->anext->rect.max.y : a->rect.max.y); r.max.y = (f->anext ? f->anext->rect.max.y : a->rect.max.y);
} }
r.min.y += minh;
r.max.y -= minh;
if(align&WEST) { if(align&WEST) {
r.min.x = (ap ? ap->rect.min.x : screen->rect.min.x); r.min.x = (ap ? ap->rect.min.x : screen->rect.min.x);
r.max.x = a->rect.max.x; r.max.x = a->rect.max.x;
@ -379,8 +380,12 @@ mouse_resizecolframe(Frame *f, Align align) {
r.min.x = a->rect.min.x; r.min.x = a->rect.min.x;
r.max.x = (a->next ? a->next->rect.max.x : screen->rect.max.x); r.max.x = (a->next ? a->next->rect.max.x : screen->rect.max.x);
} }
minw = Dx(screen->rect)/NCOL;
minh = frame_delta_h() + labelh(def.font);
r.min.x += minw; r.min.x += minw;
r.max.x -= minw; r.max.x -= minw;
r.min.y += minh;
r.max.y -= minh;
cwin = createwindow(&scr.root, r, 0, InputOnly, &wa, 0); cwin = createwindow(&scr.root, r, 0, InputOnly, &wa, 0);
mapwin(cwin); mapwin(cwin);
@ -391,18 +396,8 @@ mouse_resizecolframe(Frame *f, Align align) {
else else
r.min.y = r.max.y - 1; r.min.y = r.max.y - 1;
r.max.y = r.min.y + 2; r.max.y = r.min.y + 2;
hwin = gethsep(r);
if(XGrabPointer( hwin = gethsep(r);
display, scr.root.w,
/* owner_events*/ False,
/* event_mask */ MouseMask,
/* kbd, mouse */ GrabModeAsync, GrabModeAsync,
/* confine_to */ cwin->w,
/* cursor */ cursor[CurSizing],
/* time */ CurrentTime
) != GrabSuccess)
goto done;
x = ((align&WEST) ? f->rect.min.x : f->rect.max.x); x = ((align&WEST) ? f->rect.min.x : f->rect.max.x);
y = ((align&NORTH) ? f->rect.min.y : f->rect.max.y); y = ((align&NORTH) ? f->rect.min.y : f->rect.max.y);
@ -411,6 +406,25 @@ mouse_resizecolframe(Frame *f, Align align) {
for(;;) { for(;;) {
XMaskEvent(display, MouseMask | ExposureMask, &ev); XMaskEvent(display, MouseMask | ExposureMask, &ev);
switch (ev.type) { switch (ev.type) {
default:
break;
case Expose:
dispatch_event(&ev);
break;
case MotionNotify:
x = ev.xmotion.x_root;
y = ev.xmotion.y_root;
if(align&WEST)
r.min.x = x;
else
r.max.x = x;
r.min.y = ((align&SOUTH) ? y : y-1);
r.max.y = r.min.y+2;
setdiv(d, x);
reshapewin(hwin, r);
break;
case ButtonRelease: case ButtonRelease:
if(align&WEST) if(align&WEST)
r.min.x = x; r.min.x = x;
@ -434,31 +448,11 @@ mouse_resizecolframe(Frame *f, Align align) {
else else
y = f->rect.max.y - 2; y = f->rect.max.y - 2;
warppointer(x, y); warppointer(x, y);
XUngrabPointer(display, CurrentTime);
XSync(display, False);
goto done; goto done;
case MotionNotify:
x = ev.xmotion.x_root;
y = ev.xmotion.y_root;
if(align&WEST)
r.min.x = x;
else
r.max.x = x;
r.min.y = ((align&SOUTH) ? y : y-1);
r.max.y = r.min.y+2;
setdiv(d, x);
reshapewin(hwin, r);
break;
case Expose:
dispatch_event(&ev);
break;
default: break;
} }
} }
done: done:
XUngrabPointer(display, CurrentTime);
destroywindow(cwin); destroywindow(cwin);
destroywindow(hwin); destroywindow(hwin);
} }
@ -471,8 +465,9 @@ mouse_resizecol(Divide *d) {
Divide *dp; Divide *dp;
View *v; View *v;
Area *a; Area *a;
Rectangle r;
uint minw; uint minw;
int x, y, x2; int x, y;
v = screen->sel; v = screen->sel;
@ -483,101 +478,76 @@ mouse_resizecol(Divide *d) {
if(a == nil || a->next == nil) if(a == nil || a->next == nil)
return; return;
minw = Dx(screen->rect)/NCOL; if(!grabpointer(&scr.root, cwin, cursor[CurInvisible], MouseMask))
return;
querypointer(&scr.root, &x, &y); querypointer(&scr.root, &x, &y);
x = a->rect.min.x + minw;
x2 = a->next->rect.max.x - minw;
cwin = createwindow(&scr.root, Rect(x, y, x2, y+1), 0, InputOnly, &wa, 0); minw = Dx(screen->rect)/NCOL;
r.min.x = a->rect.min.x + minw;
r.max.x = a->next->rect.max.x - minw;
r.min.y = y;
r.max.y = y+1;
cwin = createwindow(&scr.root, r, 0, InputOnly, &wa, 0);
mapwin(cwin); mapwin(cwin);
if(XGrabPointer(
display, scr.root.w,
/* owner_events*/ False,
/* event_mask */ MouseMask,
/* kbd, mouse */ GrabModeAsync, GrabModeAsync,
/* confine_to */ cwin->w,
/* cursor */ cursor[CurInvisible],
/* time */ CurrentTime
) != GrabSuccess)
goto done;
querypointer(&scr.root, &x, &y);
for(;;) { for(;;) {
XMaskEvent(display, MouseMask | ExposureMask, &ev); XMaskEvent(display, MouseMask | ExposureMask, &ev);
switch (ev.type) { switch (ev.type) {
case ButtonRelease: default:
resize_column(a, x - a->rect.min.x);
XUngrabPointer(display, CurrentTime);
XSync(display, False);
goto done;
case MotionNotify:
x = ev.xmotion.x_root;
setdiv(d, x);
break; break;
case Expose: case Expose:
dispatch_event(&ev); dispatch_event(&ev);
break; break;
default: break; case MotionNotify:
x = ev.xmotion.x_root;
setdiv(d, x);
break;
case ButtonRelease:
resize_column(a, x - a->rect.min.x);
goto done;
} }
} }
done: done:
XUngrabPointer(display, CurrentTime);
destroywindow(cwin); destroywindow(cwin);
} }
void void
do_mouse_resize(Client *c, Bool opaque, Align align) { do_mouse_resize(Client *c, Bool opaque, Align align) {
Align grav;
XWindow dummy;
Cursor cur;
XEvent ev; XEvent ev;
Rectangle *rects, ofrect, frect, origin; Rectangle *rects;
int snap, dx, dy, pt_x, pt_y, hr_x, hr_y; Rectangle ofrect, frect, origin;
Align grav;
Cursor cur;
int dx, dy, pt_x, pt_y, hr_x, hr_y;
float rx, ry, hrx, hry;
uint num; uint num;
Bool floating; Bool floating;
float rx, ry, hrx, hry;
Frame *f; Frame *f;
f = c->sel; f = c->sel;
floating = f->area->floating;
origin = frect = f->rect; if(!f->area->floating) {
cur = cursor_of_quad(align); if(align==CENTER)
if(floating) { do_managed_move(c);
rects = rects_of_view(f->area->view, &num, (opaque ? c->frame : nil)); else
snap = def.snap; mouse_resizecolframe(f, align);
}else{
mouse_resizecolframe(f, align);
return; return;
rects = nil;
snap = 0;
} }
if(align == CENTER) { origin = frect = f->rect;
if(!opaque) rects = rects_of_view(f->area->view, &num, (opaque ? c->frame : nil));
cur = cursor[CurInvisible];
if(!floating) { cur = cursor_of_quad(align);
do_managed_move(c); if((align==CENTER) && !opaque)
return; cur = cursor[CurInvisible];
}
}
querypointer(c->framewin, &pt_x, &pt_y); querypointer(c->framewin, &pt_x, &pt_y);
rx = (float)pt_x / Dx(frect); rx = (float)pt_x / Dx(frect);
ry = (float)pt_y /Dy(frect); ry = (float)pt_y /Dy(frect);
if(XGrabPointer( if(!grabpointer(c->framewin, nil, cur, MouseMask))
/* display */ display,
/* window */ c->framewin->w,
/* owner_events */ False,
/* event_mask */ MouseMask,
/* pointer_mode */ GrabModeAsync,
/* keyboard_mode */ GrabModeAsync,
/* confine_to */ None,
/* cursor */ cur,
/* time */ CurrentTime
) != GrabSuccess)
return; return;
querypointer(&scr.root, &pt_x, &pt_y); querypointer(&scr.root, &pt_x, &pt_y);
@ -590,12 +560,7 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
if(align&EAST) dx += hr_x; if(align&EAST) dx += hr_x;
if(align&WEST) dx -= hr_x; if(align&WEST) dx -= hr_x;
XTranslateCoordinates(display, translate(c->framewin, &scr.root, dx, dy, &pt_x, &pt_y);
/* src, dst */ c->framewin->w, scr.root.w,
/* src x,y */ dx, dy,
/* dest x,y */ &pt_x, &pt_y,
/* child */ &dummy
);
warppointer(pt_x, pt_y); warppointer(pt_x, pt_y);
} }
else if(f->client->fullscreen) { else if(f->client->fullscreen) {
@ -623,35 +588,11 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
for(;;) { for(;;) {
XMaskEvent(display, MouseMask | ExposureMask, &ev); XMaskEvent(display, MouseMask | ExposureMask, &ev);
switch (ev.type) { switch (ev.type) {
case ButtonRelease: default:
if(!opaque) break;
xorborder(frect); case Expose:
dispatch_event(&ev);
if(!floating) break;
resize_colframe(f, &frect);
else
resize_client(c, &frect);
if(!opaque) {
XTranslateCoordinates(display,
/* src, dst */ c->framewin->w, scr.root.w,
/* src_x */ (Dx(frect) * rx),
/* src_y */ (Dy(frect) * ry),
/* dest x,y */ &pt_x, &pt_y,
/* child */ &dummy
);
if(pt_y > screen->brect.min.y)
pt_y = screen->brect.min.y - 1;
warppointer(pt_x, pt_y);
XUngrabServer(display);
}else
map_client(c);
free(rects);
XUngrabPointer(display, CurrentTime);
XSync(display, False);
return;
case MotionNotify: case MotionNotify:
ofrect = frect; ofrect = frect;
dx = ev.xmotion.x_root; dx = ev.xmotion.x_root;
@ -671,10 +612,7 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
origin = constrain(origin); origin = constrain(origin);
frect = origin; frect = origin;
if(floating) grav = snap_rect(rects, num, &frect, &align, def.snap);
grav = snap_rect(rects, num, &frect, &align, snap);
else
grav = align^CENTER;
apply_sizehints(c, &frect, floating, True, grav); apply_sizehints(c, &frect, floating, True, grav);
frect = constrain(frect); frect = constrain(frect);
@ -687,11 +625,26 @@ do_mouse_resize(Client *c, Bool opaque, Align align) {
xorborder(frect); xorborder(frect);
} }
break; break;
case Expose: case ButtonRelease:
dispatch_event(&ev); if(!opaque)
break; xorborder(frect);
default:
break; resize_client(c, &frect);
if(!opaque) {
translate(c->framewin, &scr.root,
(Dx(frect)*rx), (Dy(frect)*ry),
&pt_x, &pt_y);
if(pt_y > screen->brect.min.y)
pt_y = screen->brect.min.y - 1;
warppointer(pt_x, pt_y);
XUngrabServer(display);
}else
map_client(c);
free(rects);
XUngrabPointer(display, CurrentTime);
return;
} }
} }
} }