Exemple #1
0
static gboolean do_grow_all_edges(ObActionsData* data,
                                  ObClientDirectionalResizeType resize_type)
{
    gint x, y, w, h;
    gint temp_x, temp_y, temp_w, temp_h;

    client_find_resize_directional(data->client,
                                   OB_DIRECTION_NORTH,
                                   resize_type,
                                   &temp_x, &temp_y, &temp_w, &temp_h);
    y = temp_y;
    h = temp_h;

    client_find_resize_directional(data->client,
                                   OB_DIRECTION_SOUTH,
                                   resize_type,
                                   &temp_x, &temp_y, &temp_w, &temp_h);
    h += temp_h - data->client->area.height;


    client_find_resize_directional(data->client,
                                   OB_DIRECTION_WEST,
                                   resize_type,
                                   &temp_x, &temp_y, &temp_w, &temp_h);
    x = temp_x;
    w = temp_w;

    client_find_resize_directional(data->client,
                                   OB_DIRECTION_EAST,
                                   resize_type,
                                   &temp_x, &temp_y, &temp_w, &temp_h);
    w += temp_w - data->client->area.width;

    /* When filling, we allow the window to move to an arbitrary x/y
       position, since we'll be growing the other edge as well. */
    int lw, lh;
    client_try_configure(data->client, &x, &y, &w, &h, &lw, &lh, TRUE);

    if (x == data->client->area.x &&
        y == data->client->area.y &&
        w == data->client->area.width &&
        h == data->client->area.height)
    {
        return FALSE;
    }

    actions_client_move(data, TRUE);
    client_move_resize(data->client, x, y, w, h);
    actions_client_move(data, FALSE);
    return TRUE;
}
Exemple #2
0
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
    Options *o = options;

    if (data->client) {
        ObClient *c = data->client;
        gint x, y, ow, xoff, nw, oh, yoff, nh, lw, lh, wshrink, hshrink;
        gint left = o->left, right = o->right, top = o->top, bottom = o->bottom;

        if (o->left_denom)
            left = left * c->area.width / o->left_denom;
        if (o->right_denom)
            right = right * c->area.width / o->right_denom;
        if (o->top_denom)
            top = top * c->area.height / o->top_denom;
        if (o->bottom_denom)
            bottom = bottom * c->area.height / o->bottom_denom;

        // When resizing, if the resize has a non-zero value then make sure it
        // is at least as big as the size increment so the window does actually
        // resize.
        x = c->area.x;
        y = c->area.y;
        ow = c->area.width;
        xoff = -MAX(left, (left ? c->size_inc.width : 0));
        wshrink = right + left < 0 ? -1 : 1;
        nw = ow + wshrink * MAX(abs(right + left), (abs(right + left) ? c->size_inc.width : 0));
        oh = c->area.height;
        yoff = -MAX(top, (top ? c->size_inc.height : 0));
        hshrink = bottom + top < 0 ? -1 : 1;
        nh = oh + hshrink * MAX(abs(bottom + top), (bottom + top ? c->size_inc.height : 0));

        client_try_configure(c, &x, &y, &nw, &nh, &lw, &lh, TRUE);
        xoff = xoff == 0 ? 0 :
            (xoff < 0 ? MAX(xoff, ow-nw) : MIN(xoff, ow-nw));
        yoff = yoff == 0 ? 0 :
            (yoff < 0 ? MAX(yoff, oh-nh) : MAX(yoff, oh-nh));

        actions_client_move(data, TRUE);
        client_move_resize(c, x + xoff, y + yoff, nw, nh);
        actions_client_move(data, FALSE);
    }

    return FALSE;
}
Exemple #3
0
static gboolean do_grow(ObActionsData *data, gint x, gint y, gint w, gint h)
{
    gint realw, realh, lw, lh;

    realw = w;
    realh = h;
    client_try_configure(data->client, &x, &y, &realw, &realh,
                         &lw, &lh, TRUE);
    /* if it's going to be resized smaller than it intended, don't
       move the window over */
    if (x != data->client->area.x) x += w - realw;
    if (y != data->client->area.y) y += h - realh;

    if (x != data->client->area.x || y != data->client->area.y ||
        realw != data->client->area.width ||
        realh != data->client->area.height)
    {
        actions_client_move(data, TRUE);
        client_move_resize(data->client, x, y, realw, realh);
        actions_client_move(data, FALSE);
        return TRUE;
    }
    return FALSE;
}
Exemple #4
0
static void calc_resize(gboolean keyboard, gint keydist, gint *dw, gint *dh,
                        ObDirection dir)
{
    gint resist, x = 0, y = 0, lw, lh, ow, oh, nw, nh;
    gint trydw, trydh;

    ow = cur_w;
    oh = cur_h;
    nw = ow + *dw;
    nh = oh + *dh;

    if (!keyboard &&
        (moveresize_client->max_ratio || moveresize_client->min_ratio))
    {
        switch (dir) {
        case OB_DIRECTION_NORTH:
        case OB_DIRECTION_SOUTH:
            /* resize the width based on the height */
            if (moveresize_client->min_ratio) {
                if (nh * moveresize_client->min_ratio > nw)
                    nw = (gint)(nh * moveresize_client->min_ratio);
            }
            if (moveresize_client->max_ratio) {
                if (nh * moveresize_client->max_ratio < nw)
                    nw = (gint)(nh * moveresize_client->max_ratio);
            }
            break;
        default:
            /* resize the height based on the width */
            if (moveresize_client->min_ratio) {
                if (nh * moveresize_client->min_ratio > nw)
                    nh = (gint)(nw / moveresize_client->min_ratio);
            }
            if (moveresize_client->max_ratio) {
                if (nh * moveresize_client->max_ratio < nw)
                    nh = (gint)(nw / moveresize_client->max_ratio);
            }
            break;
        }

        /* see its actual size (apply aspect ratios) */
        client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh,
                             TRUE);
        trydw = nw - ow;
        trydh = nh - oh;
    }

    /* resist_size_* needs the frame size */
    nw += moveresize_client->frame->size.left +
        moveresize_client->frame->size.right;
    nh += moveresize_client->frame->size.top +
        moveresize_client->frame->size.bottom;

    if (keyboard) resist = keydist - 1; /* resist for one key press */
    else resist = config_resist_win;
    resist_size_windows(moveresize_client, resist, &nw, &nh, dir);
    if (!keyboard) resist = config_resist_edge;
    resist_size_monitors(moveresize_client, resist, &nw, &nh, dir);

    nw -= moveresize_client->frame->size.left +
        moveresize_client->frame->size.right;
    nh -= moveresize_client->frame->size.top +
        moveresize_client->frame->size.bottom;

    *dw = nw - ow;
    *dh = nh - oh;

    /* take aspect ratios into account for resistance */
    if (!keyboard &&
        (moveresize_client->max_ratio || moveresize_client->min_ratio))
    {
        if (*dh != trydh) { /* got resisted */
            /* resize the width based on the height */
            if (moveresize_client->min_ratio) {
                if (nh * moveresize_client->min_ratio > nw)
                    nw = (gint)(nh * moveresize_client->min_ratio);
            }
            if (moveresize_client->max_ratio) {
                if (nh * moveresize_client->max_ratio < nw)
                    nw = (gint)(nh * moveresize_client->max_ratio);
            }
        }
        if (*dw != trydw) { /* got resisted */
            /* resize the height based on the width */
            if (moveresize_client->min_ratio) {
                if (nh * moveresize_client->min_ratio > nw)
                    nh = (gint)(nw / moveresize_client->min_ratio);
            }
            if (moveresize_client->max_ratio) {
                if (nh * moveresize_client->max_ratio < nw)
                    nh = (gint)(nw / moveresize_client->max_ratio);
            }
        }
    }

    /* make sure it's all valid */
    client_try_configure(moveresize_client, &x, &y, &nw, &nh, &lw, &lh, TRUE);

    *dw = nw - ow;
    *dh = nh - oh;
}
Exemple #5
0
static void do_resize(void)
{
    gint x, y, w, h, lw, lh;

    /* see if it is actually going to resize
       USE cur_x AND cur_y HERE !  Otherwise the try_configure won't know
       what struts to use !!
     */
    x = cur_x;
    y = cur_y;
    w = cur_w;
    h = cur_h;
    client_try_configure(moveresize_client, &x, &y, &w, &h,
                         &lw, &lh, TRUE);
    if (!(w == moveresize_client->area.width &&
          h == moveresize_client->area.height) &&
        /* if waiting_for_sync == 0, then we aren't waiting.
           if it is > SYNC_TIMEOUTS, then we have timed out
           that many times already, so forget about waiting more */
        (waiting_for_sync == 0 || waiting_for_sync > SYNC_TIMEOUTS))
    {
#ifdef SYNC
        if (config_resize_redraw && obt_display_extension_sync &&
            /* don't send another sync when one is pending */
            waiting_for_sync == 0 &&
            moveresize_client->sync_request &&
            moveresize_client->sync_counter &&
            !moveresize_client->not_responding)
        {
            XEvent ce;
            XSyncValue val;

            /* increment the value we're waiting for */
            ++moveresize_client->sync_counter_value;
            XSyncIntToValue(&val, moveresize_client->sync_counter_value);

            /* tell the client what we're waiting for */
            ce.xclient.type = ClientMessage;
            ce.xclient.message_type = OBT_PROP_ATOM(WM_PROTOCOLS);
            ce.xclient.display = obt_display;
            ce.xclient.window = moveresize_client->window;
            ce.xclient.format = 32;
            ce.xclient.data.l[0] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST);
            ce.xclient.data.l[1] = event_time();
            ce.xclient.data.l[2] = XSyncValueLow32(val);
            ce.xclient.data.l[3] = XSyncValueHigh32(val);
            ce.xclient.data.l[4] = 0l;
            XSendEvent(obt_display, moveresize_client->window, FALSE,
                       NoEventMask, &ce);

            waiting_for_sync = 1;

            if (sync_timer) g_source_remove(sync_timer);
            sync_timer = g_timeout_add(2000, sync_timeout_func, NULL);
        }
#endif

        /* force a ConfigureNotify, it is part of the spec for SYNC resizing
           and MUST follow the sync counter notification */
        client_configure(moveresize_client, cur_x, cur_y, cur_w, cur_h,
                         TRUE, FALSE, TRUE);
    }

    /* this would be better with a fixed width font ... XXX can do it better
       if there are 2 text boxes */
    if (config_resize_popup_show == 2 || /* == "Always" */
            (config_resize_popup_show == 1 && /* == "Nonpixel" */
             moveresize_client->size_inc.width > 1 &&
             moveresize_client->size_inc.height > 1))
        popup_coords(moveresize_client, "%d x %d", lw, lh);
}
Exemple #6
0
/* Always return FALSE because its not interactive */
static gboolean run_func(ObActionsData *data, gpointer options)
{
    Options *o = options;

    if (data->client) {
        Rect *area, *carea;
        ObClient *c;
        guint mon, cmon;
        gint x, y, lw, lh, w, h;

        c = data->client;
        mon = o->monitor;
        cmon = client_monitor(c);
        switch (mon) {
        case CURRENT_MONITOR:
            mon = cmon; break;
        case ALL_MONITORS:
            mon = SCREEN_AREA_ALL_MONITORS; break;
        case NEXT_MONITOR:
            mon = (cmon + 1 > screen_num_monitors - 1) ? 0 : (cmon + 1); break;
        case PREV_MONITOR:
            mon = (cmon == 0) ? (screen_num_monitors - 1) : (cmon - 1); break;
        default:
            g_assert_not_reached();
        }

        area = screen_area(c->desktop, mon, NULL);
        carea = screen_area(c->desktop, cmon, NULL);

        w = o->w;
        if (w == G_MININT) w = c->area.width;
        else if (o->w_denom) w = (w * area->width) / o->w_denom;

        h = o->h;
        if (h == G_MININT) h = c->area.height;
        else if (o->h_denom) h = (h * area->height) / o->h_denom;

        /* it might not be able to resize how they requested, so find out what
           it will actually be resized to */
        x = c->area.x;
        y = c->area.y;
        client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);

        /* get the frame's size */
        w += c->frame->size.left + c->frame->size.right;
        h += c->frame->size.top + c->frame->size.bottom;

        x = o->x.pos;
        if (o->x.denom)
            x = (x * area->width) / o->x.denom;
        if (o->x.center) x = (area->width - w) / 2;
        else if (x == G_MININT) x = c->frame->area.x - carea->x;
        else if (o->x.opposite) x = area->width - w - x;
        x += area->x;

        y = o->y.pos;
        if (o->y.denom)
            y = (y * area->height) / o->y.denom;
        if (o->y.center) y = (area->height - h) / 2;
        else if (y == G_MININT) y = c->frame->area.y - carea->y;
        else if (o->y.opposite) y = area->height - h - y;
        y += area->y;

        /* get the client's size back */
        w -= c->frame->size.left + c->frame->size.right;
        h -= c->frame->size.top + c->frame->size.bottom;

        frame_frame_gravity(c->frame, &x, &y); /* get the client coords */
        client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);
        /* force it on screen if its moving to another monitor */
        client_find_onscreen(c, &x, &y, w, h, mon != cmon);

        actions_client_move(data, TRUE);
        client_configure(c, x, y, w, h, TRUE, TRUE, FALSE);
        actions_client_move(data, FALSE);

        g_slice_free(Rect, area);
        g_slice_free(Rect, carea);
    }

    return FALSE;
}