/* Copyright (c) 1999 Decklin Foster Copyright (c) 2000 Linus Nilsson */ #include "yawm.h" #include #include #include #define DYN_HEIGHT (!c->shaded ? c->height + 3*opt_bw : 2*opt_bw) void draw_outline(Client *c) { char buf[40]; XDrawRectangle(dpy, root, invert_gc, c->x + opt_bw/2, c->y - theight(c) + opt_bw/2, c->width + opt_bw, c->height + theight(c) + opt_bw); XDrawLine(dpy, root, invert_gc, c->x + opt_bw, c->y + opt_bw/2, c->x + c->width + opt_bw, c->y + opt_bw/2); sprintf(buf, "%dx%d+%d+%d", c->width, c->height, c->x, c->y); XDrawString(dpy, root, invert_gc, c->x + c->width - XTextWidth(font, buf, strlen(buf)) - SPACE, c->y + c->height - SPACE, buf, strlen(buf)); } void get_mouse_position(int *x, int *y) { Window dw1, dw2; int t1, t2; unsigned int t3; XQueryPointer(dpy, root, &dw1, &dw2, x, y, &t1, &t2, &t3); } void fix_size(Client *c) { int basex; int basey; if (c->size->flags & PResizeInc) { basex = (c->size->flags & PBaseSize) ? c->size->base_width : (c->size->flags & PMinSize) ? c->size->min_width : 0; basey = (c->size->flags & PBaseSize) ? c->size->base_height : (c->size->flags & PMinSize) ? c->size->min_height : 0; c->width -= (c->width - basex) % c->size->width_inc; c->height -= (c->height - basey) % c->size->height_inc; } if (c->size->flags & PMinSize) { if (c->width < c->size->min_width) { c->width = c->size->min_width; } if (c->height < c->size->min_height) { c->height = c->size->min_height; } } if (c->size->flags & PMaxSize) { if (c->width > c->size->max_width) { c->width = c->size->max_width; } if (c->height > c->size->max_height) { c->height = c->size->max_height; } } } void recalculate_sweep(Client *c, int x1, int y1, int x2, int y2) { int basex, basey; c->width = abs(x1 - x2) - opt_bw; c->height = abs(y1 - y2) - opt_bw; if (c->size->flags & PResizeInc) { basex = (c->size->flags & PBaseSize) ? c->size->base_width : (c->size->flags & PMinSize) ? c->size->min_width : 0; basey = (c->size->flags & PBaseSize) ? c->size->base_height : (c->size->flags & PMinSize) ? c->size->min_height : 0; c->width -= (c->width - basex) % c->size->width_inc; c->height -= (c->height - basey) % c->size->height_inc; } if (c->size->flags & PMinSize) { if (c->width < c->size->min_width) { c->width = c->size->min_width; } if (c->height < c->size->min_height) { c->height = c->size->min_height; } } if (c->size->flags & PMaxSize) { if (c->width > c->size->max_width) { c->width = c->size->max_width; } if (c->height > c->size->max_height) { c->height = c->size->max_height; } } c->x = (x1 <= x2) ? x1 : x1 - c->width; c->y = (y1 <= y2) ? y1 : y1 - c->height; } void sweep(Client *c) { XEvent ev; int old_cx = c->x; int old_cy = c->y; if (!grab(root, MouseMask, resize_curs)) { return; } XGrabServer(dpy); draw_outline(c); setmouse(c->window, c->width, c->height); for (;;) { XMaskEvent(dpy, MouseMask, &ev); switch (ev.type) { case MotionNotify: draw_outline(c); /* clear */ recalculate_sweep(c, old_cx, old_cy, ev.xmotion.x, ev.xmotion.y); draw_outline(c); break; case ButtonRelease: draw_outline(c); /* clear */ XUngrabServer(dpy); ungrab(); return; } } } void move(Client *c) { XEvent ev; int x1, y1; int old_cx = c->x; int old_cy = c->y; int first_motion = 1; int stepx; int stepy; int moved = 0; long old_time; long new_time; struct timeval mytp; if (!grab(root, MouseMask, move_curs)) { return; } get_mouse_position(&x1, &y1); gettimeofday(&mytp, NULL); old_time = mytp.tv_usec; for (;;) { XMaskEvent(dpy, MouseMask | ExposureMask | PropertyChangeMask | SubstructureRedirectMask, &ev); switch (ev.type) { case MotionNotify: moved = 1; stepx = old_cx + (ev.xmotion.x - x1); stepy = old_cy + (ev.xmotion.y - y1); if (stepx < 0 && stepx > -EDGE_RESISTANCE) { c->x = 0; } else if (stepx + c->width + 2*opt_bw > DisplayWidth(dpy, 0) && stepx + c->width < DisplayWidth(dpy, 0) + EDGE_RESISTANCE) { c->x = DisplayWidth(dpy, 0) - c->width - 2*opt_bw; } else { c->x = stepx; } if (stepy < theight(c) && stepy > -EDGE_RESISTANCE) { c->y = theight(c); } else if (stepy + DYN_HEIGHT + TASKBAR_HEIGHT + opt_bw > DisplayHeight(dpy, 0) && stepy + DYN_HEIGHT + TASKBAR_HEIGHT < DisplayHeight(dpy, 0) + EDGE_RESISTANCE) { c->y = DisplayHeight(dpy, 0) - TASKBAR_HEIGHT - DYN_HEIGHT - opt_bw; } else { c->y = stepy; } if (first_motion) { first_motion = 0; } else { XMoveWindow(dpy, c->parent, c->x, c->y - theight(c)); send_config(c); } break; case ButtonRelease: gettimeofday(&mytp, NULL); new_time = mytp.tv_usec; if (!moved && (new_time - old_time) < 1000*175) { XRaiseWindow(dpy, c->parent); } ungrab(); return; case Expose: handle_expose_event(&ev.xexpose); break; case PropertyNotify: handle_property_change(&ev.xproperty); case ConfigureRequest: handle_configure_request(&ev.xconfigurerequest); default: #ifdef DEBUG show_event(ev); #endif break; } } } void resize(Client *c) { if (c) { sweep(c); XMoveResizeWindow(dpy, c->parent, c->x, c->y - theight(c), c->width, c->height + theight(c)); XMoveResizeWindow(dpy, c->window, 0, theight(c), c->width, c->height); c->stored_x = c->x; c->stored_y = c->y; c->stored_width = c->width; c->stored_height = c->height; c->maximized = 0; send_config(c); } } void shade(Client *c) { if (c) { if (!c->shaded) { XResizeWindow(dpy, c->parent, c->width, theight(c) - opt_bw); c->shaded = 1; } else { XResizeWindow(dpy, c->parent, c->width, c->height + theight(c)); c->shaded = 0; } send_config(c); } } void maximize(Client *c) { if (c) { if (!c->maximized) { c->stored_x = c->x; c->stored_y = c->y; c->stored_width = c->width; c->stored_height = c->height; c->x = 0; c->y = theight(c); c->width = DisplayWidth(dpy, 0) - 2*opt_bw; c->height = DisplayHeight(dpy, 0) - TASKBAR_HEIGHT - theight(c) - 4*opt_bw; fix_size(c); XMoveResizeWindow(dpy, c->parent, c->x, c->y - theight(c), c->width, c->height + theight(c)); XMoveResizeWindow(dpy, c->window, 0, theight(c), c->width, c->height); c->maximized = 1; c->shaded = 0; } else { c->x = c->stored_x; c->y = c->stored_y; c->width = c->stored_width; c->height = c->stored_height; c->maximized = 0; XMoveResizeWindow(dpy, c->parent, c->x, c->y - theight(c), c->width, c->height + theight(c)); XMoveResizeWindow(dpy, c->window, 0, theight(c), c->width, c->height); } send_config(c); } } void maximize_vertically(Client *c) { if (c) { if (!c->maximized) { c->stored_x = c->x; c->stored_y = c->y; c->stored_width = c->width; c->stored_height = c->height; c->y = theight(c); c->height = DisplayHeight(dpy, 0) - TASKBAR_HEIGHT - theight(c) - 3*opt_bw; fix_size(c); XMoveResizeWindow(dpy, c->parent, c->x, c->y - theight(c), c->width, c->height + theight(c)); XMoveResizeWindow(dpy, c->window, 0, theight(c), c->width, c->height); c->maximized = 1; } else { c->x = c->stored_x; c->y = c->stored_y; c->width = c->stored_width; c->height = c->stored_height; c->maximized = 0; XMoveResizeWindow(dpy, c->parent, c->x, c->y - theight(c), c->width, c->height + theight(c)); XMoveResizeWindow(dpy, c->window, 0, theight(c), c->width, c->height); } send_config(c); } } void hide(Client *c) { if (c) { c->ignore_unmap++; XUnmapWindow(dpy, c->parent); XUnmapWindow(dpy, c->window); set_wm_state(c, IconicState); c->minimized = 1; } } void unhide(Client *c) { if (c) { XMapWindow(dpy, c->window); XMapRaised(dpy, c->parent); set_wm_state(c, NormalState); c->minimized = 0; } }