summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/frame.c108
-rw-r--r--src/frame.h39
-rw-r--r--src/ratpoison.h3
-rw-r--r--src/split.c390
-rw-r--r--src/split.h4
6 files changed, 366 insertions, 182 deletions
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);