From cb5b285aa112884aeb9f16b4d71a7443735c05c6 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sun, 4 Jun 2006 23:47:09 -0400 Subject: [PATCH] Add increment handling to drag/resize. Moved draw_xor_border to fix flicker. --- cmd/wm/client.c | 51 ++++++++++++++++++++++++------------------------- cmd/wm/mouse.c | 20 +++++++++++++++---- cmd/wm/wm.h | 5 +++-- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/cmd/wm/client.c b/cmd/wm/client.c index 2fd83f06..321b9fd9 100644 --- a/cmd/wm/client.c +++ b/cmd/wm/client.c @@ -476,41 +476,40 @@ sel_client() return view.size ? sel_client_of_view(view.data[sel]) : nil; } -static void -match_sizehints(Client *c, int aidx, BlitzAlign sticky) +void +match_sizehints(Client *c, XRectangle *r, int aidx, BlitzAlign sticky) { XSizeHints *s = &c->size; - Frame *f = c->frame.data[c->sel]; unsigned int dx = 2 * def.border; unsigned int dy = def.border + height_of_bar(); unsigned int hdiff, wdiff; if(!aidx && (s->flags & PMinSize)) { - if(f->rect.width < s->min_width + dx) { - wdiff = (s->min_width + dx) - f->rect.width; - f->rect.width += wdiff; + if(r->width < s->min_width + dx) { + wdiff = (s->min_width + dx) - r->width; + r->width += wdiff; if((sticky & EAST) && !(sticky & WEST)) - f->rect.x -= wdiff; + r->x -= wdiff; } - if(f->rect.height < s->min_height + dy) { - hdiff = (s->min_height + dy) - f->rect.height; - f->rect.height += hdiff; + if(r->height < s->min_height + dy) { + hdiff = (s->min_height + dy) - r->height; + r->height += hdiff; if((sticky & SOUTH) && !(sticky & NORTH)) - f->rect.y -= hdiff; + r->y -= hdiff; } } if(!aidx && (s->flags & PMaxSize)) { - if(f->rect.width > s->max_width + dx) { - wdiff = f->rect.width - (s->max_width + dx); - f->rect.width -= wdiff; + if(r->width > s->max_width + dx) { + wdiff = r->width - (s->max_width + dx); + r->width -= wdiff; if((sticky & EAST) && !(sticky & WEST)) - f->rect.x += wdiff; + r->x += wdiff; } - if(f->rect.height > s->max_height + dy) { - hdiff = f->rect.height - (s->max_height + dy); - f->rect.height -= hdiff; + if(r->height > s->max_height + dy) { + hdiff = r->height - (s->max_height + dy); + r->height -= hdiff; if((sticky & SOUTH) && !(sticky & NORTH)) - f->rect.y += hdiff; + r->y += hdiff; } } @@ -526,20 +525,20 @@ match_sizehints(Client *c, int aidx, BlitzAlign sticky) h = s->min_height; } /* client_width = base_width + i * s->width_inc for an integer i */ - w = f->rect.width - dx - w; + w = r->width - dx - w; if(s->width_inc > 0) { wdiff = w % s->width_inc; - f->rect.width -= wdiff; + r->width -= wdiff; if((sticky & EAST) && !(sticky & WEST)) - f->rect.x += wdiff; + r->x += wdiff; } - h = f->rect.height - dy - h; + h = r->height - dy - h; if(s->height_inc > 0) { hdiff = h % s->height_inc; - f->rect.height -= hdiff; + r->height -= hdiff; if((sticky & SOUTH) && !(sticky & NORTH)) - f->rect.y += hdiff; + r->y += hdiff; } } } @@ -562,7 +561,7 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall) f->rect = *r; if((f->area->mode != Colstack) || (f->area->sel == fidx)) - match_sizehints(c, aidx, stickycorner); + match_sizehints(c, &c->frame.data[c->sel]->rect, aidx, stickycorner); if(!ignore_xcall) { if(!aidx && diff --git a/cmd/wm/mouse.c b/cmd/wm/mouse.c index b51a618b..51cfd84d 100644 --- a/cmd/wm/mouse.c +++ b/cmd/wm/mouse.c @@ -99,10 +99,11 @@ snap_line(XRectangle *rects, int num, int x1, int y1, int x2, int y2, } } -void +BlitzAlign snap_rect(XRectangle *rects, int num, XRectangle *current, BlitzAlign *mask, int snap) { + BlitzAlign ret; int dx = snap + 1, dy = snap + 1; if(*mask & NORTH) @@ -124,6 +125,12 @@ snap_rect(XRectangle *rects, int num, XRectangle *current, rect_morph_xy(current, abs(dx) <= snap ? dx : 0, abs(dy) <= snap ? dy : 0, mask); + ret = *mask; + if(abs(dx) <= snap) + ret ^= EAST|WEST; + if(abs(dy) < snap) + ret ^= NORTH|SOUTH; + return ret ^ CENTER; } static void @@ -148,6 +155,7 @@ draw_xor_border(XRectangle *r) void do_mouse_resize(Client *c, BlitzAlign align) { + BlitzAlign grav; int px, py, ox, oy, i; float rx, ry; Window dummy; @@ -157,7 +165,7 @@ do_mouse_resize(Client *c, BlitzAlign align) int aidx = idx_of_area(f->area); int snap = aidx ? 0 : rect.height / 66; XRectangle *rects = aidx ? nil : rects_of_view(f->area->view, &num); - XRectangle frect = f->rect; + XRectangle frect = f->rect, ofrect; XRectangle origin = frect; XPoint pt; @@ -210,7 +218,7 @@ do_mouse_resize(Client *c, BlitzAlign align) return; break; case MotionNotify: - draw_xor_border(&frect); + ofrect = frect; pt.x = ev.xmotion.x; pt.y = ev.xmotion.y; @@ -222,8 +230,12 @@ do_mouse_resize(Client *c, BlitzAlign align) ox=px; oy=py; if(!aidx) - snap_rect(rects, num, &frect, &align, snap); + grav = snap_rect(rects, num, &frect, &align, snap); + else + grav = align ^ CENTER; + match_sizehints(c, &frect, aidx, grav); + draw_xor_border(&ofrect); draw_xor_border(&frect); break; case Expose: diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h index bde23884..d43abe40 100644 --- a/cmd/wm/wm.h +++ b/cmd/wm/wm.h @@ -247,6 +247,7 @@ void reparent_client(Client *c, Window w, int x, int y); void manage_client(Client *c); void focus_client(Client *c, Bool restack); void focus(Client *c, Bool restack); +void match_sizehints(Client *c, XRectangle *r, int aidx, BlitzAlign sticky); void resize_client(Client *c, XRectangle *r, Bool ignore_xcall); void select_client(Client *c, char *arg); void send_client(Client *c, char *arg); @@ -299,8 +300,8 @@ unsigned long mod_key_of_str(char *val); void do_mouse_resize(Client *c,BlitzAlign align); void grab_mouse(Window w, unsigned long mod, unsigned int button); void ungrab_mouse(Window w, unsigned long mod, unsigned int button); -void snap_rect(XRectangle *rects, int num, XRectangle *current, - BlitzAlign *mask, int snap); +BlitzAlign snap_rect(XRectangle *rects, int num, XRectangle *current, + BlitzAlign *mask, int snap); /* rule.c */ void update_rules(RuleVector *rule, const char *data);