summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--ChangeLog39
-rw-r--r--src/actions.c95
-rw-r--r--src/actions.h3
-rw-r--r--src/conf.h24
-rw-r--r--src/data.h1
-rw-r--r--src/main.c1
-rw-r--r--src/split.c254
-rw-r--r--src/split.h4
9 files changed, 406 insertions, 16 deletions
diff --git a/AUTHORS b/AUTHORS
index b0c3dbb..301874e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -23,3 +23,4 @@ Ben Leslie <benno@sesgroup.net>
Dan Aloni <da-x@gmx.net>
Tim Goodwin <tjg@star.le.ac.uk>
Nicklas Lindgren <nili@lysator.liu.se>
+Henrik Enberg <henrik@enberg.org>
diff --git a/ChangeLog b/ChangeLog
index b182fb8..11325a9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+2003-02-10 Shawn Betts <sabetts@sfu.ca>
+
+ * src/split.h (num_frames): new prototype
+ (resize_shrink_to_window): likewise
+ (resize_frame_vertically): likewise
+ (resize_frame_horizontally): likewise
+
+ * src/split.c (num_frames): no longer a static function
+ (resize_shrink_to_window): new function
+ (resize_frame_vertically): likewise
+ (resize_frame_horizontally): likewise
+
+ * src/main.c (init_defaults): init frame_resize_unit.
+
+ * src/data.h (struct rp_defaults): new member frame_resize_unit.
+
+ * src/conf.h (RESIZE_VGROW_KEY): new define
+ (RESIZE_VGROW_MODIFIER): likewise
+ (RESIZE_VSHRINK_KEY): likewise
+ (RESIZE_VSHRINK_MODIFIER): likewise
+ (RESIZE_HGROW_KEY): likewise
+ (RESIZE_HGROW_MODIFIER): likewise
+ (RESIZE_HSHRINK_KEY): likewise
+ (RESIZE_HSHRINK_MODIFIER): likewise
+ (RESIZE_SHRINK_TO_WINDOW_KEY): likewise
+ (RESIZE_SHRINK_TO_WINDOW_MODIFIER): likewise
+ (RESIZE_END_KEY): likewise
+ (RESIZE_END_MODIFIER): likewise
+
+ * src/actions.h (cmd_shrink): new prototype
+ (cmd_resize): likewise
+ (cmd_defresizeunit): likewise
+
+ * src/actions.c (user_commands): add commands cmd_resize and
+ cmd_shrink, and cmd_defresizeunit.
+ (cmd_shrink): new function
+ (cmd_resize): likewise
+ (cmd_defresizeunit): likewise
+
2003-01-30 Shawn Betts <sabetts@sfu.ca>
* src/actions.c (cmd_bind): more informative error messages
diff --git a/src/actions.c b/src/actions.c
index 623ca40..17a1db2 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -88,6 +88,8 @@ static user_command user_commands[] =
{"prevscreen", cmd_prevscreen, arg_VOID},
{"nextscreen", cmd_nextscreen, arg_VOID},
{"warp", cmd_warp, arg_STRING},
+ {"resize", cmd_resize, arg_STRING},
+ {"shrink", cmd_shrink, arg_VOID},
/*@end (tag required for genrpbindings) */
/* Commands to set default behavior. */
@@ -107,6 +109,7 @@ static user_command user_commands[] =
{"deffgcolor", cmd_deffgcolor, arg_STRING},
{"defbgcolor", cmd_defbgcolor, arg_STRING},
{"defbarpadding", cmd_defbarpadding, arg_STRING},
+ {"defresizeunit", cmd_defresizeunit, arg_STRING},
/* Commands to help debug ratpoison. */
#ifdef DEBUG
@@ -1356,6 +1359,98 @@ cmd_remove (int interactive, void *data)
return NULL;
}
+char *
+cmd_shrink (int interactive, void *data)
+{
+ screen_info *s = current_screen ();
+
+ resize_shrink_to_window (s->rp_current_frame);
+ return NULL;
+}
+
+char *
+cmd_resize (int interactive, void *data)
+{
+ screen_info *s = current_screen ();
+
+ /* If the user calls resize with arguments, treat it like the
+ non-interactive version. */
+ if (interactive && data == NULL)
+ {
+ int nbytes, revert;
+ char buffer[513];
+ unsigned int mod;
+ KeySym c;
+ Window fwin;
+
+ /* If we haven't got at least 2 frames, there isn't anything to
+ scale. */
+ if (num_frames (s) < 2) return NULL;
+
+ XGetInputFocus (dpy, &fwin, &revert);
+ XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime);
+
+ nbytes = read_key (&c, &mod, buffer, sizeof (buffer));
+ while (1)
+ {
+ if (c == RESIZE_VGROW_KEY && mod == RESIZE_VGROW_MODIFIER)
+ resize_frame_vertically (s->rp_current_frame, defaults.frame_resize_unit);
+ else if (c == RESIZE_VSHRINK_KEY && mod == RESIZE_VSHRINK_MODIFIER)
+ resize_frame_vertically (s->rp_current_frame, -defaults.frame_resize_unit);
+ else if (c == RESIZE_HGROW_KEY && mod == RESIZE_HGROW_MODIFIER)
+ resize_frame_horizontally (s->rp_current_frame, defaults.frame_resize_unit);
+ else if (c == RESIZE_HSHRINK_KEY && mod == RESIZE_HSHRINK_MODIFIER)
+ resize_frame_horizontally (s->rp_current_frame, -defaults.frame_resize_unit);
+ else if (c == RESIZE_SHRINK_TO_WINDOW_KEY
+ && mod == RESIZE_SHRINK_TO_WINDOW_MODIFIER)
+ resize_shrink_to_window (s->rp_current_frame);
+ else if (c == RESIZE_END_KEY && mod == RESIZE_END_MODIFIER)
+ break;
+
+ nbytes = read_key (&c, &mod, buffer, sizeof (buffer));
+ }
+
+ XSetInputFocus (dpy, fwin, RevertToPointerRoot, CurrentTime);
+ }
+ else
+ {
+ int xdelta, ydelta;
+
+ if (sscanf (data, "%d %d", &xdelta, &ydelta) < 2)
+ {
+ message (" resize: Two numeric arguments required ");
+ return NULL;
+ }
+
+ resize_frame_horizontally (s->rp_current_frame, xdelta);
+ resize_frame_vertically (s->rp_current_frame, ydelta);
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defresizeunit (int interactive, void *data)
+{
+ int tmp;
+
+ if (data == NULL && !interactive)
+ return xsprintf ("%d", defaults.frame_resize_unit);
+
+ if (data == NULL || sscanf (data, "%d", &tmp) < 1)
+ {
+ message (" defresizeunit: One argument required ");
+ return NULL;
+ }
+
+ if (tmp >= 0)
+ defaults.frame_resize_unit = tmp;
+ else
+ message (" defresizeunit: Bad argument ");
+
+ return NULL;
+}
+
/* banish the rat pointer */
char *
cmd_banish (int interactive, void *data)
diff --git a/src/actions.h b/src/actions.h
index 397e0f4..3446f12 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -68,6 +68,8 @@ char * cmd_h_split (int interactive, void *data);
char * cmd_v_split (int interactive, void *data);
char * cmd_only (int interactive, void *data);
char * cmd_remove (int interactive, void *data);
+char * cmd_shrink (int interactive, void *data);
+char * cmd_resize (int interactive, void *data);
char * cmd_banish (int interactive, void *data);
char * cmd_curframe (int interactive, void *data);
char * cmd_help (int interactive, void *data);
@@ -90,6 +92,7 @@ char * cmd_defwinfmt (int interactive, void *data);
char * cmd_defwinname (int interactive, void *data);
char * cmd_deffgcolor (int interactive, void *data);
char * cmd_defbgcolor (int interactive, void *data);
+char * cmd_defresizeunit (int interactive, void *data);
char * cmd_setenv (int interactive, void *data);
char * cmd_getenv (int interactive, void *data);
char * cmd_chdir (int interactive, void *data);
diff --git a/src/conf.h b/src/conf.h
index 2002a3e..d1b30fd 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -40,6 +40,30 @@
#define INPUT_NEXT_HISTORY_KEY XK_n
#define INPUT_NEXT_HISTORY_MODIFIER ControlMask
+/* Key used to enlarge frame vertically when in resize mode. */
+#define RESIZE_VGROW_KEY XK_n
+#define RESIZE_VGROW_MODIFIER ControlMask
+
+/* Key used to shrink frame vertically when in resize mode. */
+#define RESIZE_VSHRINK_KEY XK_p
+#define RESIZE_VSHRINK_MODIFIER ControlMask
+
+/* Key used to enlarge frame horizontally when in resize mode. */
+#define RESIZE_HGROW_KEY XK_f
+#define RESIZE_HGROW_MODIFIER ControlMask
+
+/* Key used to shrink frame horizontally when in resize mode. */
+#define RESIZE_HSHRINK_KEY XK_b
+#define RESIZE_HSHRINK_MODIFIER ControlMask
+
+/* Key used to shrink frame to fit it's current window. */
+#define RESIZE_SHRINK_TO_WINDOW_KEY XK_s
+#define RESIZE_SHRINK_TO_WINDOW_MODIFIER 0
+
+/* Key used to exit resize mode. */
+#define RESIZE_END_KEY XK_Return
+#define RESIZE_END_MODIFIER 0
+
/* Number of history items to store. */
#define INPUT_MAX_HISTORY 50
diff --git a/src/data.h b/src/data.h
index d81918d..c4b236b 100644
--- a/src/data.h
+++ b/src/data.h
@@ -144,6 +144,7 @@ struct rp_defaults
int bar_border_width;
int frame_indicator_timeout;
+ int frame_resize_unit;
int padding_left;
int padding_right;
diff --git a/src/main.c b/src/main.c
index 4f4e9af..3cf7039 100644
--- a/src/main.c
+++ b/src/main.c
@@ -460,6 +460,7 @@ init_defaults ()
defaults.bar_border_width = 1;
defaults.frame_indicator_timeout = 1;
+ defaults.frame_resize_unit = 10;
defaults.padding_left = 0;
defaults.padding_right = 0;
diff --git a/src/split.c b/src/split.c
index b364868..53b596b 100644
--- a/src/split.c
+++ b/src/split.c
@@ -38,6 +38,22 @@ update_last_access (rp_window_frame *frame)
counter++;
}
+int
+num_frames (screen_info *s)
+{
+ int count = 0;
+ rp_window_frame *cur;
+
+ for (cur = s->rp_window_frame_sentinel->next;
+ cur != s->rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ count++;
+ }
+
+ return count;
+}
+
rp_window *
set_frames_window (rp_window_frame *frame, rp_window *win)
{
@@ -405,6 +421,228 @@ remove_all_splits ()
set_frames_window (s->rp_current_frame, cur_window);
}
+/* Shrink the size of the frame to fit it's current window. */
+void
+resize_shrink_to_window (rp_window_frame *frame)
+{
+ if (frame->win == NULL) return;
+
+ resize_frame_horizontally (frame, frame->win->width + frame->win->border*2 - frame->width);
+ 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)
+{
+ 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. */
+ for (cur = s->rp_window_frame_sentinel->next;
+ cur != s->rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ 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)
+ {
+ for (cur = s->rp_window_frame_sentinel->next;
+ cur != s->rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ if (cur->y == (frame->y - cur->height)
+ && (cur->x + cur->width) > frame->x
+ && cur->x < (frame->x + frame->width))
+ {
+ 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;
+ }
+ }
+
+ /* 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;
+
+ /* If we left any gaps, take care of them too. */
+ for (cur = s->rp_window_frame_sentinel->next;
+ cur != s->rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ 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;
+
+ 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 horizontally by diff pixels. if diff is negative
+ then shrink the frame, otherwise enlarge it. */
+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. */
+ for (cur = s->rp_window_frame_sentinel->next;
+ cur != s->rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ 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;
+ }
+ }
+
+ /* Found no frames to the right, look for some to the left. */
+ if (!found_adjacent_frames)
+ {
+ for (cur = s->rp_window_frame_sentinel->next;
+ cur != s->rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ 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;
+
+ if (cur->win)
+ maximize_all_windows_in_frame (cur);
+
+ found_adjacent_frames = 1;
+ }
+ }
+
+ /* If we found any frames, move the current frame. */
+ if (found_adjacent_frames)
+ {
+ frame->x -= diff;
+ }
+ }
+
+ /* Resize current frame. */
+ if (found_adjacent_frames)
+ {
+ frame->width += diff;
+
+ /* If we left any gaps, take care of them too. */
+ for (cur = s->rp_window_frame_sentinel->next;
+ cur != s->rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ 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);
+ }
+ }
+}
+
static int
frame_is_below (rp_window_frame *src, rp_window_frame *frame)
{
@@ -449,22 +687,6 @@ total_frame_area (screen_info *s)
return area;
}
-static int
-num_frames (screen_info *s)
-{
- int count = 0;
- rp_window_frame *cur;
-
- for (cur = s->rp_window_frame_sentinel->next;
- cur != s->rp_window_frame_sentinel;
- cur = cur->next)
- {
- count++;
- }
-
- return count;
-}
-
/* Return 1 if frames f1 and f2 overlap */
static int
frames_overlap (rp_window_frame *f1, rp_window_frame *f2)
diff --git a/src/split.h b/src/split.h
index 7879329..fe2d853 100644
--- a/src/split.h
+++ b/src/split.h
@@ -22,11 +22,15 @@
#ifndef SPLIT_H
#define SPLIT_H
+int num_frames (screen_info *s);
rp_window *set_frames_window (rp_window_frame *frame, rp_window *win);
void maximize_all_windows_in_frame (rp_window_frame *frame);
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 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);