Index: src/actions.c =================================================================== RCS file: /cvsroot/ratpoison/ratpoison/src/actions.c,v retrieving revision 1.125 diff -u -b -u -r1.125 actions.c --- src/actions.c 6 Jul 2002 21:28:05 -0000 1.125 +++ src/actions.c 13 Aug 2002 00:55:43 -0000 @@ -86,6 +86,7 @@ {"unalias", cmd_unalias, arg_STRING}, {"prevscreen", cmd_prevscreen, arg_VOID}, {"nextscreen", cmd_nextscreen, arg_VOID}, + {"resize", cmd_resize, arg_STRING}, /address@hidden (tag required for genrpbindings) */ /* Commands to set default behavior. */ @@ -105,6 +106,7 @@ {"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 @@ -1302,6 +1304,75 @@ return NULL; } + +char * +cmd_resize (int interactive, void *data) +{ + screen_info *s = current_screen (); + + if (interactive) + { + int nbytes, revert; + char buffer[513]; + unsigned int mod; + KeySym c; + Window fwin; + + 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, 1); + else if (c == RESIZE_VSHRINK_KEY && mod == RESIZE_VSHRINK_MODIFIER) + resize_frame_vertically (s->rp_current_frame, -1); + else if (c == RESIZE_HGROW_KEY && mod == RESIZE_HGROW_MODIFIER) + resize_frame_horizontally (s->rp_current_frame, 1); + else if (c == RESIZE_HSHRINK_KEY && mod == RESIZE_HSHRINK_MODIFIER) + resize_frame_horizontally (s->rp_current_frame, -1); + 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 + { + char *dir, *steps; + int tmp; + + dir = strtok (data, " "); + steps = strtok (NULL, "\0"); + + if (dir == NULL || steps == NULL) + { + message (" resize: Two arguments required "); + return NULL; + } + + if (sscanf (steps, "%d", &tmp) < 1) + { + message (" resize: Bad argument "); + return NULL; + } + + if (tmp != 0) + { + if (strcmp (dir, "horizontal") == 0) + resize_frame_horizontally (s->rp_current_frame, tmp); + else if (strcmp (dir, "vertical") == 0) + resize_frame_vertically (s->rp_current_frame, tmp); + } + } + + return NULL; +} + + /* banish the rat pointer */ char * cmd_banish (int interactive, void *data) @@ -2078,6 +2149,29 @@ return NULL; } +char * +cmd_defresizeunit (int interactive, void *data) +{ + int tmp; + + if (data == NULL && !interactive) + return xsprintf ("%d", defaults.resize_unit); + + if (data == NULL || sscanf (data, "%d", &tmp) < 1) + { + message (" defresizeunit: One argument required "); + return NULL; + } + + if (tmp >= 0) + defaults.resize_unit = tmp; + else + message (" defresizeunit: Bad argument "); + + return NULL; +} + + #if !defined(HAVE_SETENV) || !defined(setenv) /* For systems, such as Solaris, where setenv is not implemented * in libc */ Index: src/actions.h =================================================================== RCS file: /cvsroot/ratpoison/ratpoison/src/actions.h,v retrieving revision 1.49 diff -u -b -u -r1.49 actions.h --- src/actions.h 24 Mar 2002 06:05:03 -0000 1.49 +++ src/actions.h 13 Aug 2002 00:55:43 -0000 @@ -68,6 +68,7 @@ char * cmd_v_split (int interactive, void *data); char * cmd_only (int interactive, void *data); char * cmd_remove (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 +91,7 @@ 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); Index: src/conf.h =================================================================== RCS file: /cvsroot/ratpoison/ratpoison/src/conf.h,v retrieving revision 1.29 diff -u -b -u -r1.29 conf.h --- src/conf.h 28 Jul 2002 23:07:04 -0000 1.29 +++ src/conf.h 13 Aug 2002 00:55:43 -0000 @@ -39,6 +39,26 @@ /* This is the next history entry key when typing input. */ #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_f +#define RESIZE_VGROW_MODIFIER ControlMask + +/* Key used to shrink frame vertically when in resize mode. */ +#define RESIZE_VSHRINK_KEY XK_b +#define RESIZE_VSHRINK_MODIFIER ControlMask + +/* Key used to enlarge frame horizontally when in resize mode. */ +#define RESIZE_HGROW_KEY XK_n +#define RESIZE_HGROW_MODIFIER ControlMask + +/* Key used to shrink frame horizontally when in resize mode. */ +#define RESIZE_HSHRINK_KEY XK_p +#define RESIZE_HSHRINK_MODIFIER ControlMask + +/* Key used to exit resize mode. */ +#define RESIZE_END_KEY XK_g +#define RESIZE_END_MODIFIER ControlMask /* Number of history items to store. */ #define INPUT_MAX_HISTORY 50 Index: src/data.h =================================================================== RCS file: /cvsroot/ratpoison/ratpoison/src/data.h,v retrieving revision 1.37 diff -u -b -u -r1.37 data.h --- src/data.h 13 Mar 2002 08:23:30 -0000 1.37 +++ src/data.h 13 Aug 2002 00:55:43 -0000 @@ -150,6 +150,8 @@ int padding_top; int padding_bottom; + int resize_unit; + XFontStruct *font; int wait_for_key_cursor; Index: src/main.c =================================================================== RCS file: /cvsroot/ratpoison/ratpoison/src/main.c,v retrieving revision 1.59 diff -u -b -u -r1.59 main.c --- src/main.c 28 Jul 2002 23:07:04 -0000 1.59 +++ src/main.c 13 Aug 2002 00:55:43 -0000 @@ -436,6 +436,8 @@ defaults.padding_top = 0; defaults.padding_bottom = 0; + defaults.resize_unit = 10; + defaults.font = XLoadQueryFont (dpy, "9x15bold"); if (defaults.font == NULL) { Index: src/split.c =================================================================== RCS file: /cvsroot/ratpoison/ratpoison/src/split.c,v retrieving revision 1.23 diff -u -b -u -r1.23 split.c --- src/split.c 13 Mar 2002 08:23:30 -0000 1.23 +++ src/split.c 13 Aug 2002 00:55:43 -0000 @@ -26,6 +26,8 @@ #include "ratpoison.h" +static int num_frames (screen_info *s); + static void update_last_access (rp_window_frame *frame) { @@ -400,6 +402,259 @@ set_frames_window (s->rp_current_frame, cur_window); } + +/* Resize FRAME horizontally by STEPS resize units. if STEPS is negative + then shrink the frame, otherwise enlarge it. */ + +void +resize_frame_horizontally (rp_window_frame *frame, int steps) +{ + screen_info *s = frames_screen (frame); + int found_adjacent_frames = 0; + int max_bound, min_bound; + int diff, orig_y; + rp_window_frame *cur; + + if (num_frames (s) < 2 || steps == 0) + return; + + diff = defaults.resize_unit * abs (steps); + 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)) + { + if (steps < 0) + { + cur->height += diff; + cur->y -= diff; + } + else + { + 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)) + { + if (steps < 0) + cur->height += diff; + else + 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) + { + if (steps < 0) + frame->y += diff; + else + frame->y -= diff; + } + } + + /* Resize current frame. */ + if (found_adjacent_frames) + { + if (steps < 0) + frame->height -= diff; + else + 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 vertically by STEPS resize units. if STEPS is negative + then shrink the frame, otherwise enlarge it. */ + +void +resize_frame_vertically (rp_window_frame *frame, int steps) +{ + screen_info *s = frames_screen (frame); + int found_adjacent_frames = 0; + int max_bound, min_bound; + int diff, orig_x; + rp_window_frame *cur; + + if (num_frames (s) < 2 || steps == 0) + return; + + diff = defaults.resize_unit * abs (steps); + 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)) + { + if (steps < 0) + { + cur->width += diff; + cur->x -= diff; + } + else + { + 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)) + { + if (steps < 0) + cur->width += diff; + else + 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) + { + if (steps < 0) + frame->x += diff; + else + frame->x -= diff; + } + } + + /* Resize current frame. */ + if (found_adjacent_frames) + { + if (steps < 0) + frame->width -= diff; + else + 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) { Index: src/split.h =================================================================== RCS file: /cvsroot/ratpoison/ratpoison/src/split.h,v retrieving revision 1.9 diff -u -b -u -r1.9 split.h --- src/split.h 8 Feb 2002 02:46:00 -0000 1.9 +++ src/split.h 13 Aug 2002 00:55:43 -0000 @@ -27,6 +27,8 @@ void h_split_frame (rp_window_frame *frame); void v_split_frame (rp_window_frame *frame); void remove_all_splits (); +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);