Example #1
0
void Kernel::runResizeMode(Thing *thing, XButtonEvent *buttonEvent,
                           Direction dir, bool resize)
{
    Window window = thing->window();
    if (!window) {
        return;
    }

    Monitor *monitor = thing->monitor();
    Window rootWindow = monitor->rootWindow();
    Thing::Type type = thing->type();
    Workspace *workspace = (type == Thing::CLIENT) ?
        ((Client *)thing)->attached() : ((Frame *)thing)->attached();

    if (!workspace) {
        return;
    }

    int origX, origY, lastX, lastY, newX, newY, dx, dy;
    Rectangle rect(*thing);

    XCORE->translateCoordinates(window, rootWindow,
                                 buttonEvent->x, buttonEvent->y,
                                 &lastX, &lastY);
    newX = newY = 0;
    origX = lastX;
    origY = lastY;

    XCORE->grabPointer(window,
                       ButtonMotionMask | ButtonReleaseMask,
                       buttonEvent->time);

    XEvent event;
    bool done = false, found = false, firstMotion = true;

    XCORE->grabServer();
    while (!done) {
        found = false;

        while (XCORE->checkMaskEvent(
                    ButtonReleaseMask | ButtonMotionMask, &event))
        {
            found = true;

            if (event.type != MotionNotify) {
                break;
            }
        }

        if (!found) {
            usleep(20000);
            continue;
        }

        switch (event.type) {
        case ButtonRelease:
            if (!firstMotion) {
                monitor->illuminateTransRect(&rect, thing->titleBarHeight());

                dx = newX - origX;
                dy = newY - origY;

                if ((dir == LEFT) || (dir == UP)) {
                    // normalization
                    dx *= -1;
                    dy *= -1;
                }

                if (type == Thing::FRAME) {
                    Split::resize(workspace->root(),
                                  ((Frame *)thing)->tree(),
                                  dir, dx, dy);
                }
                else {
                    thing->copy(&rect);
                    thing->resize();
                    thing->illuminate();
                }
                XCORE->sync();
            }
            XCORE->ungrabPointer(event.xbutton.time);
            XCORE->ungrabServer();
            done = true;
            break; // ButtonRelease
        case MotionNotify:
            XCORE->translateCoordinates(event.xmotion.window,
                    rootWindow, event.xmotion.x, event.xmotion.y,
                    &newX, &newY);

            dx = newX - lastX;
            dy = newY - lastY;

            lastX = newX;
            lastY = newY;

            if (firstMotion) {
                firstMotion = false;
            }
            else {
                monitor->illuminateTransRect(&rect, thing->titleBarHeight());
            }

            if (type == Thing::FRAME) {
                switch (dir) {
                case LEFT:
                    rect.setX(rect.x() + dx);
                    rect.setWidth(rect.width() - dx);
                    break;
                case RIGHT:
                    rect.setWidth(rect.width() + dx);
                    break;
                case UP:
                    rect.setY(rect.y() + dy);
                    rect.setHeight(rect.height() - dy);
                    break;
                case DOWN:
                    rect.setHeight(rect.height() + dy);
                    break;
                default:
                    break;
                }
            }
            else {

                if (resize) {
                    Float::resize(&rect, dir, dx, dy);
                }
                else {
                    Float::move(&rect, dx, dy);
                }
            }
            monitor->illuminateTransRect(&rect, thing->titleBarHeight());
            break; // MotionNotify
        }
    }
}