From d9712b14bec0317663b9464108d8155152e41cad Mon Sep 17 00:00:00 2001 From: sabetts Date: Fri, 7 Mar 2003 11:43:25 +0000 Subject: * 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 --- src/Makefile.am | 4 +- src/frame.c | 108 ++++++++++++++++ src/frame.h | 39 ++++++ src/ratpoison.h | 3 + src/split.c | 390 ++++++++++++++++++++++++++++++-------------------------- src/split.h | 4 +- 6 files changed, 366 insertions(+), 182 deletions(-) create mode 100644 src/frame.c create mode 100644 src/frame.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index d776330..798564b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## -## $Id: Makefile.am,v 1.12 2003/03/07 04:42:15 sabetts Exp $ +## $Id: Makefile.am,v 1.13 2003/03/07 11:43:26 sabetts Exp $ bin_PROGRAMS = ratpoison @@ -31,6 +31,8 @@ ratpoison_SOURCES = actions.c \ data.h \ events.c \ events.h \ + frame.c \ + frame.h \ getopt.c \ getopt.h \ getopt1.c \ diff --git a/src/frame.c b/src/frame.c new file mode 100644 index 0000000..3af78f3 --- /dev/null +++ b/src/frame.c @@ -0,0 +1,108 @@ +/* functions that manipulate the frame structure. + * Copyright (C) 2000-2003 Shawn Betts + * + * This file is part of ratpoison. + * + * ratpoison is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ratpoison is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + */ + +#include "ratpoison.h" + +int +frame_left (rp_window_frame *frame) +{ + return frame->x; +} + +int +frame_top (rp_window_frame *frame) +{ + return frame->y; +} + +int +frame_right (rp_window_frame *frame) +{ + return frame->x + frame->width; +} + +int +frame_bottom (rp_window_frame *frame) +{ + return frame->y + frame->height; +} + +int +frame_width(rp_window_frame *frame) +{ + return frame->width; +} + +int +frame_height(rp_window_frame *frame) +{ + return frame->height; +} + +void +frame_resize_left (rp_window_frame *frame, int amount) +{ + frame->x -= amount; + frame->width += amount; +} + +void +frame_resize_right (rp_window_frame *frame, int amount) +{ + frame->width += amount; +} + +void +frame_resize_up (rp_window_frame *frame, int amount) +{ + frame->y -= amount; + frame->height += amount; +} + +void +frame_resize_down (rp_window_frame *frame, int amount) +{ + frame->height += amount; +} + +void +frame_move_left (rp_window_frame *frame, int amount) +{ + frame->x -= amount; +} + +void +frame_move_right (rp_window_frame *frame, int amount) +{ + frame->x += amount; +} + +void +frame_move_up (rp_window_frame *frame, int amount) +{ + frame->y -= amount; +} + +void +frame_move_down (rp_window_frame *frame, int amount) +{ + frame->y += amount; +} diff --git a/src/frame.h b/src/frame.h new file mode 100644 index 0000000..6194bb0 --- /dev/null +++ b/src/frame.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2000-2003 Shawn Betts + * + * This file is part of ratpoison. + * + * ratpoison is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ratpoison is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA + */ + +#ifndef FRAME_H +#define FRAME_H + +void frame_move_down (rp_window_frame *frame, int amount); +void frame_move_up (rp_window_frame *frame, int amount); +void frame_move_right (rp_window_frame *frame, int amount); +void frame_move_left (rp_window_frame *frame, int amount); +void frame_resize_down (rp_window_frame *frame, int amount); +void frame_resize_up (rp_window_frame *frame, int amount); +void frame_resize_right (rp_window_frame *frame, int amount); +void frame_resize_left (rp_window_frame *frame, int amount); +int frame_height(rp_window_frame *frame); +int frame_width(rp_window_frame *frame); +int frame_bottom (rp_window_frame *frame); +int frame_right (rp_window_frame *frame); +int frame_top (rp_window_frame *frame); +int frame_left (rp_window_frame *frame); + +#endif diff --git a/src/ratpoison.h b/src/ratpoison.h index c0b725c..4a5dde7 100644 --- a/src/ratpoison.h +++ b/src/ratpoison.h @@ -39,6 +39,7 @@ do { \ PRINT_LINE (error); \ printf fmt; \ + fflush (stdout); \ } while (0) #ifdef DEBUG @@ -46,6 +47,7 @@ do { \ do { \ PRINT_LINE (debug); \ printf fmt; \ + fflush (stdout); \ } while (0) #else #define PRINT_DEBUG(fmt) @@ -66,6 +68,7 @@ extern XGCValues gv; #include "communications.h" #include "sbuf.h" #include "split.h" +#include "frame.h" void clean_up (); screen_info *find_screen (Window w); 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)); diff --git a/src/split.h b/src/split.h index 79667cc..a9e952d 100644 --- a/src/split.h +++ b/src/split.h @@ -30,8 +30,8 @@ void h_split_frame (rp_window_frame *frame, int pixels); void v_split_frame (rp_window_frame *frame, int pixels); void remove_all_splits (); void resize_shrink_to_window (rp_window_frame *frame); -void resize_frame_horizontally (rp_window_frame *frame, int steps); -void resize_frame_vertically (rp_window_frame *frame, int steps); +void resize_frame_horizontally (rp_window_frame *frame, int diff); +void resize_frame_vertically (rp_window_frame *frame, int diff); void remove_frame (rp_window_frame *frame); rp_window *find_window_for_frame (rp_window_frame *frame); rp_window_frame *find_windows_frame (rp_window *win); -- cgit v1.2.3