summaryrefslogtreecommitdiff
path: root/src/split.c
diff options
context:
space:
mode:
authorsabetts <sabetts>2003-03-07 11:43:25 +0000
committersabetts <sabetts>2003-03-07 11:43:25 +0000
commitd9712b14bec0317663b9464108d8155152e41cad (patch)
tree79c936320c13fd4d4186e95cef65f45d27e26b3c /src/split.c
parent02151f234d5675ed8d1922e06cb74b75c822e142 (diff)
downloadratpoison-d9712b14bec0317663b9464108d8155152e41cad.zip
* src/Makefile.am (ratpoison_SOURCES): add frame.c and frame.h
* src/frame.h (frame_left): new prototype (frame_top): likewise (frame_right): likewise (frame_bottom): likewise (frame_width): likewise (frame_height): likewise (frame_resize_left): likewise (frame_resize_right): likewise (frame_resize_up): likewise (frame_resize_down): likewise (frame_move_left): likewise (frame_move_right): likewise (frame_move_up): likewise (frame_move_down): likewise * src/frame.c (frame_left): new function (frame_top): likewise (frame_right): likewise (frame_bottom): likewise (frame_width): likewise (frame_height): likewise (frame_resize_left): likewise (frame_resize_right): likewise (frame_resize_up): likewise (frame_resize_down): likewise (frame_move_left): likewise (frame_move_right): likewise (frame_move_up): likewise (frame_move_down): likewise * src/split.c (resize_frame): new function (resize_frame_right): likewise (resize_frame_left): likewise (resize_frame_top): likewise (resize_frame_bottom): likewise (resize_frame_horizontally): use resize_frame_right and resize_frame_left to do the resizing. (resize_frame_vertically): use resize_frame_top and resize_frame_bottom to do the resizing. * src/ratpoison.h (PRINT_ERROR): flush stdout (PRINT_DEBUG): likewise include frame.h
Diffstat (limited to 'src/split.c')
-rw-r--r--src/split.c390
1 files changed, 211 insertions, 179 deletions
diff --git a/src/split.c b/src/split.c
index c110001..c39c1ce 100644
--- a/src/split.c
+++ b/src/split.c
@@ -73,7 +73,7 @@ cleanup_frame (rp_window_frame *frame)
#ifdef MAXSIZE_WINDOWS_ARE_TRANSIENTS
if (!win->transient
- && !(win->hints->flags & PMaxSize
+ && !(win->hints->flags & PMaxSize
&& win->hints->max_width < win->scr->root_attr.width
&& win->hints->max_height < win->scr->root_attr.height))
#else
@@ -127,7 +127,7 @@ maximize_all_windows_in_frame (rp_window_frame *frame)
}
}
-/* Make the frame occupy the entire screen */
+/* Make the frame occupy the entire screen */
static void
maximize_frame (rp_window_frame *frame)
{
@@ -259,7 +259,7 @@ find_window_for_frame (rp_window_frame *frame)
list_for_each_entry (cur, &rp_mapped_window, node)
{
if (cur->scr == s
- && cur != current_window()
+ && cur != current_window()
&& !find_windows_frame (cur)
&& cur->last_access >= last_access
&& window_fits_in_frame (cur, frame)
@@ -269,7 +269,7 @@ find_window_for_frame (rp_window_frame *frame)
last_access = cur->last_access;
}
}
-
+
return most_recent;
}
@@ -405,206 +405,238 @@ resize_shrink_to_window (rp_window_frame *frame)
resize_frame_vertically (frame, frame->win->height + frame->win->border*2 - frame->height);
}
-/* Resize FRAME vertically by diff pixels. if diff is negative
- then shrink the frame, otherwise enlarge it. */
-void
-resize_frame_vertically (rp_window_frame *frame, int diff)
+/* resize_frame is a generic frame resizer that can resize vertically,
+ horizontally, to the right, to the left, etc. It all depends on the
+ functions passed to it. */
+static void
+resize_frame (rp_window_frame *frame, rp_window_frame *pusher, int diff,
+ int (*c1)(rp_window_frame *), int (c2)(rp_window_frame *),
+ int (*c3)(rp_window_frame *), int (c4)(rp_window_frame *),
+ void (*resize1)(rp_window_frame *, int),
+ void (*resize2)(rp_window_frame *, int),
+ void (*resize3)(rp_window_frame *, rp_window_frame *, int))
{
screen_info *s = frames_screen (frame);
- int found_adjacent_frames = 0;
- int max_bound, min_bound;
- int orig_y;
rp_window_frame *cur;
- if (num_frames (s) < 2 || diff == 0)
- return;
-
- max_bound = frame->x + frame->width;
- min_bound = frame->x;
- orig_y = frame->y;
-
- /* Look for frames below that needs to be resized. */
+ /* Loop through the frames and determine which ones are affected by
+ resizing frame. */
list_for_each_entry (cur, &s->rp_window_frames, node)
{
- if (cur->y == (frame->y + frame->height)
- && (cur->x + cur->width) > frame->x
- && cur->x < (frame->x + frame->width))
- {
- cur->height -= diff;
- cur->y += diff;
-
- if ((cur->x + cur->width) > max_bound)
- max_bound = cur->x + cur->width;
-
- if (cur->x < min_bound)
- min_bound = cur->x;
-
- if (cur->win)
- maximize_all_windows_in_frame (cur);
-
- found_adjacent_frames = 1;
- }
- }
-
- /* Found no frames below, look for some above. */
- if (!found_adjacent_frames)
- {
- list_for_each_entry (cur, &s->rp_window_frames, node)
+ if (cur == frame || cur == pusher) continue;
+ /* If cur is touching frame along the axis that is being
+ moved then this frame is affected by the resize. */
+ if ((*c1)(cur) == (*c3)(frame))
{
- if (cur->y == (frame->y - cur->height)
- && (cur->x + cur->width) > frame->x
- && cur->x < (frame->x + frame->width))
+ /* Test for this circumstance:
+ --+
+ | |+-+
+ |f||c|
+ | |+-+
+ --+
+
+ In this case, resizing cur will not affect any other
+ frames, so just do the resize.
+ */
+ if (((*c2)(cur) >= (*c2)(frame))
+ && (*c4)(cur) <= (*c4)(frame))
{
- cur->height -= diff;
-
- if ((cur->x + cur->width) > max_bound)
- max_bound = cur->x + cur->width;
-
- if (cur->x < min_bound)
- min_bound = cur->x;
-
- if (cur->win)
- maximize_all_windows_in_frame (cur);
-
- found_adjacent_frames = 1;
+ (*resize2)(cur, -diff);
+ maximize_all_windows_in_frame (cur);
+ }
+ /* Otherwise, cur's corners are either strictly outside
+ frame's corners, or one of them is inside and the other
+ isn't. In either of these cases, resizing cur will affect
+ other adjacent frames, so find them and resize them first
+ (recursive step) and then resize cur. */
+ else if (((*c2)(cur) < (*c2)(frame)
+ && (*c4)(cur) > (*c4)(frame))
+ || ((*c2)(cur) >= (*c2)(frame)
+ && (*c2)(cur) < (*c4)(frame))
+ || ((*c4)(cur) > (*c2)(frame)
+ && (*c4)(cur) <= (*c4)(frame)))
+ {
+ resize3 (cur, frame, -diff);
}
- }
-
- /* If we found any frames, move the current frame. */
- if (found_adjacent_frames)
- {
- frame->y -= diff;
}
}
- /* Resize current frame. */
- if (found_adjacent_frames)
- {
- frame->height += diff;
+ /* Finally, resize the frame and the windows inside. */
+ (*resize1) (frame, diff);
+ maximize_all_windows_in_frame (frame);
+}
- /* If we left any gaps, take care of them too. */
- list_for_each_entry (cur, &s->rp_window_frames, node)
- {
- if (cur->y == orig_y && cur->x >= min_bound
- && cur->x + cur->width <= max_bound
- && cur != frame)
- {
- cur->height = frame->height;
- cur->y = frame->y;
+static void resize_frame_bottom (rp_window_frame *frame, rp_window_frame *pusher, int diff);
+static void resize_frame_top (rp_window_frame *frame, rp_window_frame *pusher, int diff);
+static void resize_frame_left (rp_window_frame *frame, rp_window_frame *pusher, int diff);
+static void resize_frame_right (rp_window_frame *frame, rp_window_frame *pusher, int diff);
- if (cur->win)
- maximize_all_windows_in_frame (cur);
- }
- }
+/* Resize frame by moving it's right side. */
+static void
+resize_frame_right (rp_window_frame *frame, rp_window_frame *pusher, int diff)
+{
+ resize_frame (frame, pusher, diff,
+ frame_left, frame_top, frame_right, frame_bottom,
+ frame_resize_right, frame_resize_left, resize_frame_left);
+}
- if (frame->win)
- {
- maximize_all_windows_in_frame (frame);
- XRaiseWindow (dpy, frame->win->w);
- }
- }
+/* Resize frame by moving it's left side. */
+static void
+resize_frame_left (rp_window_frame *frame, rp_window_frame *pusher, int diff)
+{
+ resize_frame (frame, pusher, diff,
+ frame_right, frame_top, frame_left, frame_bottom,
+ frame_resize_left, frame_resize_right, resize_frame_right);
}
-/* Resize FRAME horizontally by diff pixels. if diff is negative
- then shrink the frame, otherwise enlarge it. */
+/* Resize frame by moving it's top side. */
+static void
+resize_frame_top (rp_window_frame *frame, rp_window_frame *pusher, int diff)
+{
+ resize_frame (frame, pusher, diff,
+ frame_bottom, frame_left, frame_top, frame_right,
+ frame_resize_up, frame_resize_down, resize_frame_bottom);
+}
+
+/* Resize frame by moving it's bottom side. */
+static void
+resize_frame_bottom (rp_window_frame *frame, rp_window_frame *pusher, int diff)
+{
+ resize_frame (frame, pusher, diff,
+ frame_top, frame_left, frame_bottom, frame_right,
+ frame_resize_down, frame_resize_up, resize_frame_top);
+}
+
+/* Resize frame diff pixels by expanding it to the right. If the frame
+ is against the right side of the screen, expand it to the left. */
void
resize_frame_horizontally (rp_window_frame *frame, int diff)
{
screen_info *s = frames_screen (frame);
- int found_adjacent_frames = 0;
- int max_bound, min_bound;
- int orig_x;
- rp_window_frame *cur;
if (num_frames (s) < 2 || diff == 0)
return;
- max_bound = frame->y + frame->height;
- min_bound = frame->y;
- orig_x = frame->x;
-
- /* Look for frames on the right that needs to be resized. */
- list_for_each_entry (cur, &s->rp_window_frames, node)
+ if (frame_right (frame) < DisplayWidth (dpy, s->screen_num) - defaults.padding_right - defaults.padding_left)
{
- if (cur->x == (frame->x + frame->width)
- && (cur->y + cur->height) > frame->y
- && cur->y < (frame->y + frame->height))
- {
- cur->width -= diff;
- cur->x += diff;
-
- if ((cur->y + cur->height) > max_bound)
- max_bound = cur->y + cur->height;
-
- if (cur->y < min_bound)
- min_bound = cur->y;
-
- if (cur->win)
- maximize_all_windows_in_frame (cur);
-
- found_adjacent_frames = 1;
- }
+ resize_frame_right (frame, NULL, diff);
}
-
- /* Found no frames to the right, look for some to the left. */
- if (!found_adjacent_frames)
+ else
{
- list_for_each_entry (cur, &s->rp_window_frames, node)
- {
- if (cur->x == (frame->x - cur->width)
- && (cur->y + cur->height) > frame->y
- && cur->y < (frame->y + frame->height))
- {
- cur->width -= diff;
-
- if ((cur->y + cur->height) > max_bound)
- max_bound = cur->y + cur->height;
-
- if (cur->y < min_bound)
- min_bound = cur->y;
+ resize_frame_left (frame, NULL, diff);
+ }
+}
- if (cur->win)
- maximize_all_windows_in_frame (cur);
+/* Resize frame diff pixels by expanding it down. If the frame is
+ against the bottom of the screen, expand it up. */
+void
+resize_frame_vertically (rp_window_frame *frame, int diff)
+{
+ screen_info *s = frames_screen (frame);
- found_adjacent_frames = 1;
- }
- }
+ if (num_frames (s) < 2 || diff == 0)
+ return;
- /* If we found any frames, move the current frame. */
- if (found_adjacent_frames)
- {
- frame->x -= diff;
- }
+ if (frame_bottom (frame) < DisplayHeight (dpy, s->screen_num) - defaults.padding_bottom - defaults.padding_top)
+ {
+ resize_frame_bottom (frame, NULL, diff);
}
-
- /* Resize current frame. */
- if (found_adjacent_frames)
+ else
{
- frame->width += diff;
-
- /* If we left any gaps, take care of them too. */
- list_for_each_entry (cur, &s->rp_window_frames, node)
- {
- if (cur->x == orig_x && cur->y >= min_bound
- && cur->y + cur->height <= max_bound
- && cur != frame)
- {
- cur->width = frame->width;
- cur->x = frame->x;
-
- if (cur->win)
- maximize_all_windows_in_frame (cur);
- }
- }
-
- if (frame->win)
- {
- maximize_all_windows_in_frame (frame);
- XRaiseWindow (dpy, frame->win->w);
- }
+ resize_frame_top (frame, NULL, diff);
}
}
+
+/* Resize FRAME horizontally by diff pixels. if diff is negative then
+ shrink the frame, otherwise enlarge it. frame is the frame being
+ resized, and pusher is the frame that is forcing frame to
+ resize. pusher may be NULL if the user is resizing the window. */
+
+/* void */
+/* resize_frame_horizontally (rp_window_frame *frame, rp_window_frame *pusher, int diff) */
+/* { */
+/* screen_info *s = frames_screen (frame); */
+/* rp_window_frame *cur; */
+
+/* if (num_frames (s) < 2 || diff == 0) */
+/* return; */
+
+/* if (frame->x + frame->width < DisplayWidth (dpy, s->screen_num) - defaults.padding_right - defaults.padding_left) */
+/* { */
+/* /\* Look for frames on the right that would be pushed over by the */
+/* frame's resize. *\/ */
+/* list_for_each_entry (cur, &s->rp_window_frames, node) */
+/* { */
+/* if (cur == frame || cur == pusher) continue; */
+/* if (cur->x == (frame->x + frame->width)) */
+/* { */
+/* if (cur->y >= frame->y */
+/* && cur->y + cur->height <= frame->y + frame->height) */
+/* { */
+/* /\* Resize the frame and the windows inside. This */
+/* window's resizing will not affect any other */
+/* windows. *\/ */
+/* cur->width -= diff; */
+/* cur->x += diff; */
+/* maximize_all_windows_in_frame (cur); */
+/* } */
+/* else if ((cur->y < frame->y */
+/* && cur->y + cur->height > frame->y + frame->height) */
+/* || (cur->y > frame->y */
+/* && cur->y < frame->y + frame->height) */
+/* || (cur->y + cur->height > frame->y */
+/* && cur->y + cur->height < frame->y + frame->height)) */
+/* { */
+/* /\* Resize this frame and check for any other frames this */
+/* frame may affect. *\/ */
+/* resize_frame_horizontally (cur, frame, -diff); */
+/* } */
+/* } */
+/* } */
+/* } */
+/* else */
+/* { */
+/* /\* Look for frames on theleft that would be pushed over by the */
+/* frame's resize. *\/ */
+/* list_for_each_entry (cur, &s->rp_window_frames, node) */
+/* { */
+/* if (cur == frame || cur == pusher) continue; */
+/* if (cur->x + cur->width == frame->x) */
+/* { */
+/* if (cur->y >= frame->y */
+/* && cur->y + cur->height <= frame->y + frame->height) */
+/* { */
+/* /\* Resize the frame and the windows inside. This */
+/* window's resizing will not affect any other */
+/* windows. *\/ */
+/* cur->width -= diff; */
+/* maximize_all_windows_in_frame (cur); */
+/* } */
+/* else if ((cur->y < frame->y */
+/* && cur->y + cur->height > frame->y + frame->height) */
+/* || (cur->y > frame->y */
+/* && cur->y < frame->y + frame->height) */
+/* || (cur->y + cur->height > frame->y */
+/* && cur->y + cur->height < frame->y + frame->height)) */
+/* { */
+/* /\* Resize this frame and check for any other frames this */
+/* frame may affect. *\/ */
+/* resize_frame_horizontally (cur, frame, -diff); */
+/* } */
+/* } */
+/* } */
+
+/* /\* Since the frame is at the right edge of the screen, the left */
+/* side of the frame will actually move. *\/ */
+/* frame->x -= diff; */
+/* } */
+
+/* /\* Finally, resize the frame and the windows inside. *\/ */
+/* frame->width += diff; */
+/* maximize_all_windows_in_frame (frame); */
+/* } */
+
static int
frame_is_below (rp_window_frame *src, rp_window_frame *frame)
{
@@ -651,9 +683,9 @@ total_frame_area (screen_info *s)
static int
frames_overlap (rp_window_frame *f1, rp_window_frame *f2)
{
- if (f1->x >= f2->x + f2->width
+ if (f1->x >= f2->x + f2->width
|| f1->y >= f2->y + f2->height
- || f2->x >= f1->x + f1->width
+ || f2->x >= f1->x + f1->width
|| f2->y >= f1->y + f1->height)
{
return 0;
@@ -791,7 +823,7 @@ remove_frame (rp_window_frame *frame)
memcpy (cur, &tmp_frame, sizeof (rp_window_frame));
}
}
-
+
free (frame);
}
@@ -813,7 +845,7 @@ set_active_frame (rp_window_frame *frame)
rp_current_screen = s->screen_num;
/* Possibly show the frame indicator. */
- if ((old != s->rp_current_frame && num_frames(s) > 1)
+ if ((old != s->rp_current_frame && num_frames(s) > 1)
|| s != old_s)
{
show_frame_indicator();
@@ -823,23 +855,23 @@ set_active_frame (rp_window_frame *frame)
focus. */
if( !frame->win )
{
- XSetInputFocus (dpy, s->key_window,
+ XSetInputFocus (dpy, s->key_window,
RevertToPointerRoot, CurrentTime);
- }
+ }
}
void
blank_frame (rp_window_frame *frame)
{
if (frame->win == NULL) return;
-
+
hide_window (frame->win);
hide_others (frame->win);
set_frames_window (frame, NULL);
/* Give the key window focus. */
- XSetInputFocus (dpy, current_screen()->key_window,
+ XSetInputFocus (dpy, current_screen()->key_window,
RevertToPointerRoot, CurrentTime);
}
@@ -860,7 +892,7 @@ show_frame_indicator ()
XMoveResizeWindow (dpy, current_screen()->frame_window,
current_screen()->rp_current_frame->x
- + current_screen()->rp_current_frame->width / 2 - width / 2,
+ + current_screen()->rp_current_frame->width / 2 - width / 2,
current_screen()->rp_current_frame->y
+ current_screen()->rp_current_frame->height / 2 - height / 2,
width, height);
@@ -869,8 +901,8 @@ show_frame_indicator ()
XClearWindow (dpy, s->frame_window);
XSync (dpy, False);
- XDrawString (dpy, s->frame_window, s->normal_gc,
- defaults.bar_x_padding,
+ XDrawString (dpy, s->frame_window, s->normal_gc,
+ defaults.bar_x_padding,
defaults.bar_y_padding + defaults.font->max_bounds.ascent,
MESSAGE_FRAME_STRING, strlen (MESSAGE_FRAME_STRING));