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; }
/* 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; }
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; }
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; }
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); }
/* 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; }