diff options
Diffstat (limited to 'src/split.c')
-rw-r--r-- | src/split.c | 390 |
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)); |