summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis Pohlmann <jannis@xfce.org>2009-09-06 18:39:14 +0200
committerJannis Pohlmann <jannis@xfce.org>2009-09-06 18:39:14 +0200
commita2c6d7f29c29f3eb8b7cee1dcb228fb0d565efdd (patch)
tree3f8b84215fc8cef55043481a894534b1f322123b
parent9bba86a823462899a4be48d942837b8cab0ef8db (diff)
downloadxfwm4-snap-spacing-experiments.tar.gz
Snap with respect to the window spacing when resizing windows.snap-spacing-experiments
When resizing, snap to windows and struts by taking the new window spacing option into account. When snapping to a window, snap with a distance of window spacing to the other window's edge if we're approaching this edge from outside (e.g. window A is placed left of window B, window A is enlarged and the right edge of window A snaps to the left edge of window B minus the spacing). If we're approaching a window edge from inside, snap to this edge without spacing (e.g. window A is placed inside window B, window A is enlarged an the right edge of window A snaps to the right edge of window B). When snapping to struts, allow both snapping directly to the edges and snapping with spacing.
-rw-r--r--src/moveresize.c178
1 files changed, 158 insertions, 20 deletions
diff --git a/src/moveresize.c b/src/moveresize.c
index f96087e09..a4c0a1f05 100644
--- a/src/moveresize.c
+++ b/src/moveresize.c
@@ -387,36 +387,105 @@ clientFindClosestEdgeX (Client *c, int edge_pos)
Client *c2;
ScreenInfo *screen_info;
- int i, closest;
- int snap_width;
+ int i, closest, snap_width, left_margin, right_margin;
+ gboolean is_visible, is_snap_window, is_snap_strut;
screen_info = c->screen_info;
snap_width = screen_info->params->snap_width;
closest = edge_pos + snap_width + 2; /* This only needs to be out of the snap range to work. -Cliff */
+ /* iterate over all client windows */
for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
{
- if (FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c) &&
- (((screen_info->params->snap_to_windows) && (c2->win_layer == c->win_layer))
- || ((screen_info->params->snap_to_border)
- && FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
- && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE))))
+ /* skip the parameter client itself */
+ if (c2 == c)
+ {
+ continue;
+ }
+
+ /* check if the client is visible */
+ is_visible = FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE);
+
+ /* check if this is a window we can snap to (if window snapping is enabled) */
+ is_snap_window = is_visible && screen_info->params->snap_to_windows && (c2->win_layer == c->win_layer);
+
+ /* check if this a strut we can snap to (if snapping to the screen edges is enabled) */
+ is_snap_strut = is_visible && screen_info->params->snap_to_border && FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT);
+
+ /* calculate margins */
+ if (is_snap_window)
{
-
+ left_margin = right_margin = screen_info->params->window_spacing;
+ }
+ else if (is_snap_strut)
+ {
+ left_margin = screen_info->params->xfwm_margins[STRUTS_RIGHT];
+ right_margin = screen_info->params->xfwm_margins[STRUTS_LEFT];
+ }
+
+ /* check if this client is something we can snap to */
+ if (is_snap_window || is_snap_strut)
+ {
+ /* check if the two clients overlap vertically */
if (clientCheckOverlap (c->y - frameTop (c) - 1, c->y + c->height + frameBottom (c) + 1, c2->y - frameTop (c) - 1, c2->y + c2->height + frameBottom (c) + 1))
{
+ /* check if we are closer to the left edge of c2 than to any previous edge */
if (abs (c2->x - frameLeft (c2) - edge_pos) < abs (closest - edge_pos))
{
+ /* snap directly to the edge */
closest = c2->x - frameLeft (c2);
}
- if (abs ((c2->x + c2->width) + frameRight (c2) - edge_pos) < abs (closest - edge_pos))
+
+ if (abs (c2->x - frameLeft (c2) - left_margin - edge_pos) < (closest - edge_pos))
{
- closest = (c2->x + c2->width) + frameRight (c2);
+ /* we're approaching the edge from the left. snap to the edge from the left, with a certain space between the two clients */
+ closest = c2->x - frameLeft (c2) - left_margin;
+ }
+
+ if (abs (c2->x - frameLeft (c2) + left_margin - edge_pos) < (closest - edge_pos))
+ {
+ if (is_snap_window)
+ {
+ /* we're approaching the edge from the right. snap to the edge directly */
+ closest = c2->x - frameLeft (c2);
+ }
+ else
+ {
+ /* we're approaching the edge from the right. snap to the edge from the right, with a certain space between the two clients */
+ closest = c2->x - frameLeft (c2) + left_margin;
+ }
+ }
+
+ /* check if we are closer to the right edge of c2 than to any previous edge */
+ if (abs (c2->x + c2->width + frameRight (c2) - edge_pos) < abs (closest - edge_pos))
+ {
+ /* snap directly to the edge */
+ closest = c2->x + c2->width + frameRight (c2);
+ }
+
+ if (abs (c2->x + c2->width + frameRight (c2) - right_margin - edge_pos) < (closest - edge_pos))
+ {
+ if (is_snap_window)
+ {
+ /* we're approaching the edge from the left. snap to directly to the edge */
+ closest = c2->x + c2->width + frameRight (c2);
+ }
+ else
+ {
+ /* we're approaching the edge from the left. snap to the edge from the left, with a certain space between the two clients */
+ closest = c2->x + c2->width + frameRight (c2) - right_margin;
+ }
+ }
+
+ if (abs (c2->x + c2->width + frameRight (c2) + right_margin - edge_pos) < (closest - edge_pos))
+ {
+ /* we're approaching the edge from the right. snap to the edge from the right, with a certain space between the two clients */
+ closest = c2->x + c2->width + frameRight (c2) + right_margin;
}
}
}
}
-
+
if (abs (closest - edge_pos) > snap_width)
{
closest = edge_pos;
@@ -434,31 +503,100 @@ clientFindClosestEdgeY (Client *c, int edge_pos)
Client *c2;
ScreenInfo *screen_info;
- int i, closest;
- int snap_width;
+ int i, closest, snap_width, top_margin, bottom_margin;
+ gboolean is_visible, is_snap_window, is_snap_strut;
screen_info = c->screen_info;
snap_width = screen_info->params->snap_width;
closest = edge_pos + snap_width + 1; /* This only needs to be out of the snap range to work. -Cliff */
+ /* iterate over all client windows */
for (c2 = screen_info->clients, i = 0; i < screen_info->client_count; c2 = c2->next, i++)
{
- if (FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2 != c) &&
- (((screen_info->params->snap_to_windows) && (c2->win_layer == c->win_layer))
- || ((screen_info->params->snap_to_border)
- && FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT)
- && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE))))
+ /* skip the parameter client itself */
+ if (c2 == c)
{
+ continue;
+ }
+
+ /* check if the client is visible */
+ is_visible = FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE);
+
+ /* check if this is a window we can snap to (if window snapping is enabled) */
+ is_snap_window = is_visible && screen_info->params->snap_to_windows && (c2->win_layer == c->win_layer);
+ /* check if this a strut we can snap to (if snapping to the screen edges is enabled) */
+ is_snap_strut = is_visible && screen_info->params->snap_to_border && FLAG_TEST (c2->flags, CLIENT_FLAG_HAS_STRUT);
+
+ /* calculate margins */
+ if (is_snap_window)
+ {
+ top_margin = bottom_margin = screen_info->params->window_spacing;
+ }
+ else if (is_snap_strut)
+ {
+ top_margin = screen_info->params->xfwm_margins[STRUTS_BOTTOM];
+ bottom_margin = screen_info->params->xfwm_margins[STRUTS_TOP];
+ }
+
+ /* check if this client is something we can snap to */
+ if (is_snap_window || is_snap_strut)
+ {
+ /* check if the two clients overlap horizontally */
if (clientCheckOverlap (c->x - frameLeft (c) - 1, c->x + c->width + frameRight (c) + 1, c2->x - frameLeft (c) - 1, c2->x + c2->width + frameRight (c) + 1))
{
+ /* check if we are closer to the top edge of c2 than to any previous edge */
if (abs (c2->y - frameTop(c2) - edge_pos) < abs (closest - edge_pos))
{
+ /* snap directly to the edge */
closest = c2->y - frameTop (c2);
}
- if (abs ((c2->y + c2->height) + frameBottom (c2) - edge_pos) < abs (closest - edge_pos))
+
+ if (abs (c2->y - frameTop (c2) - top_margin - edge_pos) < abs (closest - edge_pos))
+ {
+ /* we're approaching the edge from the top. snap to the edge from the top, with a certain space between the two clients */
+ closest = c2->y - frameTop (c2) - top_margin;
+ }
+
+ if (abs (c2->y - frameTop (c2) + top_margin - edge_pos) < abs (closest - edge_pos))
+ {
+ if (is_snap_window)
+ {
+ /* we're approaching the edge from the bottom. snap directly to the edge */
+ closest = c2->y - frameTop (c2);
+ }
+ else
+ {
+ /* we're approaching the edge from the bottom. snap to the edge from the bottom, with a certain space between the two clients */
+ closest = c2->y - frameTop (c2) + top_margin;
+ }
+ }
+
+ /* check if we are closer to the bottom edge of c2 than to any previous edge */
+ if (abs (c2->y + c2->height + frameBottom (c2) - edge_pos) < abs (closest - edge_pos))
+ {
+ /* snap directly to the edge */
+ closest = c2->y + c2->height + frameBottom (c2);
+ }
+
+ if (abs (c2->y + c2->height + frameBottom (c2) - bottom_margin - edge_pos) < (closest - edge_pos))
+ {
+ if (is_snap_window)
+ {
+ /* we're approaching the edge from the top. snap directly to the edge */
+ closest = c2->y + c2->height + frameBottom (c2);
+ }
+ else
+ {
+ /* we're approaching the edge from the top. snap to the edge from the top, with a certain space between the two clients */
+ closest = c2->y + c2->height + frameBottom (c2) - bottom_margin;
+ }
+ }
+
+ if (abs (c2->y + c2->height + frameBottom (c2) + bottom_margin - edge_pos) < (closest - edge_pos))
{
- closest = (c2->y + c2->height) + frameBottom (c2);
+ /* snap to the edge from the bottom, with a certain space between the two clients */
+ closest = c2->y + c2->height + frameBottom (c2) + bottom_margin;
}
}
}