diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | doc/ratpoison.texi | 10 | ||||
-rw-r--r-- | src/actions.c | 153 | ||||
-rw-r--r-- | src/actions.h | 2 | ||||
-rw-r--r-- | src/events.c | 13 | ||||
-rw-r--r-- | src/frame.c | 59 | ||||
-rw-r--r-- | src/frame.h | 1 | ||||
-rw-r--r-- | src/manage.c | 4 | ||||
-rw-r--r-- | src/number.c | 6 | ||||
-rw-r--r-- | src/number.h | 1 | ||||
-rw-r--r-- | src/window.c | 3 |
12 files changed, 248 insertions, 33 deletions
@@ -1,3 +1,29 @@ +2003-04-04 Shawn Betts <sabetts@sfu.ca> + + * src/actions.c (cmd_setenv): properly parse the environment name + and value using strtok. + + * src/window.c (add_to_window_list): init the window's frame_number to EMPTY. + + * src/number.h (numset_clear): new prototype + + * src/manage.c (unmanage)[AUTO_CLOSE]: code update for new globals. + + * src/frame.c (frame_new): init f->last_access to 0. + (frame_dump): dump the X11 window ID, not the window number. + (frame_read): new function + + * src/events.c (destroy_window): just unmanage the window. + + * src/actions.h (cmd_fdump): new prototype + (cmd_frestore): likewise + + * src/actions.c (user_commands): new commands "fdump" and "frestore". + (cmd_fdump): new function + (cmd_frestore): likewise + + * src/number.c (numset_clear): new function. + 2003-03-31 Shawn Betts <sabetts@sfu.ca> * src/window.c (set_current_window): use current_frame() @@ -1,6 +1,9 @@ ratpoison NEWS --- history of user-visible changes. -*- outline -*- * Changes since 1.1.1 +** new commands 'fdump' and 'frestore' +These commands are for saving and restoring frame sets. + ** key presses All actions now occur after the user has released the key. diff --git a/doc/ratpoison.texi b/doc/ratpoison.texi index 6713534..9580bf7 100644 --- a/doc/ratpoison.texi +++ b/doc/ratpoison.texi @@ -539,6 +539,11 @@ prefix key to @key{C-b}. @item exec @var{command} Execute a shell command. By default, @kbd{C-t !} does this. +@item fdump +dump the current frame layout as text. When used non-interactively +(from the command-line), ratpoison will print the frame layout. When +used interactively, nothing happens. + @item focus cycle through ratpoison's frames. @@ -557,6 +562,11 @@ Move to the frame right of the current frame. @item focusup Move to the frame above the current frame. +@item frestore @var{frames} +Restore the frame layout based on the list of frames +@var{frames}. @var{frames} should be the text that was printed after +calling @code{fdump}. + @item fselect @var{n} Select a frame by number. If an argument is passed to it then attempt to select the frame whose number is @var{n}. If not, ratpoison will diff --git a/src/actions.c b/src/actions.c index 963d35e..5aa6cd3 100644 --- a/src/actions.c +++ b/src/actions.c @@ -93,6 +93,8 @@ static user_command user_commands[] = {"shrink", cmd_shrink, arg_VOID}, {"tmpwm", cmd_tmpwm, arg_STRING}, {"fselect", cmd_fselect, arg_VOID}, + {"fdump", cmd_fdump, arg_STRING}, + {"frestore", cmd_frestore, arg_STRING}, /*@end (tag required for genrpbindings) */ /* Commands to set default behavior. */ @@ -2330,7 +2332,7 @@ cmd_defbgcolor (int interactive, void *data) char * cmd_setenv (int interactive, void *data) { - char *name, *value; + char *token, *dup; struct sbuf *env; if (data == NULL) @@ -2339,25 +2341,34 @@ cmd_setenv (int interactive, void *data) return NULL; } + /* Setup the environment string. */ + env = sbuf_new(0); + /* Get the 2 arguments. */ - name = xmalloc (strlen (data) + 1); - value = xmalloc (strlen (data) + 1); - if (sscanf (data, "%s %s", name, value) < 2) + dup = xstrdup ((char *)data); + token = strtok (dup, " "); + if (token == NULL) { message (" setenv: two arguments required "); - free (name); - free (value); + free (dup); + sbuf_free (env); return NULL; } - - /* Setup the environment string. */ - env = sbuf_new(0); - sbuf_concat (env, name); + sbuf_concat (env, token); sbuf_concat (env, "="); - sbuf_concat (env, value); - free (name); - free (value); - + + token = strtok (NULL, "\0"); + if (token == NULL) + { + message (" setenv: two arguments required "); + free (dup); + sbuf_free (env); + return NULL; + } + sbuf_concat (env, token); + + free (dup); + /* Stick it in the environment. */ PRINT_DEBUG(("%s\n", sbuf_get(env))); putenv (sbuf_get (env)); @@ -2978,7 +2989,119 @@ cmd_fselect (int interactive, void *data) } char * -cmd_restore (int interactively, void *data) +cmd_fdump (int interactively, void *data) { + struct sbuf *s; + char *tmp; + rp_window_frame *cur; + + s = sbuf_new (0); + + /* FIXME: Oooh, gross! there's a trailing comma, yuk! */ + list_for_each_entry (cur, ¤t_screen()->rp_window_frames, node) + { + sbuf_concat (s, frame_dump (cur)); + sbuf_concat (s, ","); + } + + tmp = sbuf_get (s); + free (s); + return tmp; +} + +char * +cmd_frestore (int interactively, void *data) +{ + screen_info *s = current_screen(); + char *token; + char *dup; + rp_window_frame *new, *cur; + rp_window *win; + struct list_head fset; + int max = -1; + + if (data == NULL) + { + message (" frestore: one argument required "); + return NULL; + } + + INIT_LIST_HEAD (&fset); + + dup = xstrdup ((char *)data); + token = strtok (dup, ","); + if (token == NULL) + { + message (" frestore: bad frame format "); + free (dup); + return NULL; + } + + /* Build the new frame set. */ + while (token != NULL) + { + new = frame_read (token); + if (new == NULL) + { + message (" frestore: bad frame format "); + free (dup); + return NULL; + } + list_add_tail (&new->node, &fset); + token = strtok (NULL, ","); + } + + free (dup); + + /* Clear all the frames. */ + list_for_each_entry (cur, &s->rp_window_frames, node) + { + PRINT_DEBUG (("blank %d\n", cur->number)); + blank_frame (cur); + } + + /* Splice in our new frameset. */ + screen_restore_frameset (s, &fset); + numset_clear (s->frames_numset); + + /* Process the frames a bit to make sure everything lines up. */ + list_for_each_entry (cur, &s->rp_window_frames, node) + { + rp_window *win; + + PRINT_DEBUG (("restore %d %d\n", cur->number, cur->win_number)); + + /* Find the current frame based on last_access. */ + if (cur->last_access > max) + { + s->current_frame = cur->number; + max = cur->last_access; + } + + /* Grab the frame's number. */ + numset_add_num (s->frames_numset, cur->number); + + /* Update the window the frame points to. */ + if (cur->win_number != EMPTY) + { + win = find_window_number (cur->win_number); + set_frames_window (cur, win); + } + } + + /* Show the windows in the frames. */ + list_for_each_entry (win, &rp_mapped_window, node) + { + if (win->frame_number != EMPTY) + { + maximize (win); + unhide_window (win); + } + } + + set_active_frame (current_frame()); + show_frame_indicator(); + + PRINT_DEBUG (("Done.\n")); return NULL; } diff --git a/src/actions.h b/src/actions.h index 70a23f4..84a1d97 100644 --- a/src/actions.h +++ b/src/actions.h @@ -117,6 +117,8 @@ char *cmd_unalias (int interactive, void *data); char *cmd_warp(int interactive, void *data); char *cmd_tmpwm (int interactive, void *data); char *cmd_fselect (int interactive, void *data); +char *cmd_fdump (int interactively, void *data); +char *cmd_frestore (int interactively, void *data); void initialize_default_keybindings (void); void free_keybindings (); diff --git a/src/events.c b/src/events.c index e73661f..5241977 100644 --- a/src/events.c +++ b/src/events.c @@ -168,25 +168,12 @@ map_request (XEvent *ev) static void destroy_window (XDestroyWindowEvent *ev) { - rp_window_frame *frame; rp_window *win; win = find_window (ev->window); if (win == NULL) return; ignore_badwindow++; - - /* A destroyed window should never have a frame, since it should - have been cleaned up with an unmap notify event, but just in - case... */ - frame = find_windows_frame (win); - if (frame) - { - cleanup_frame (frame); - if (frame->number == win->scr->current_frame) - set_active_frame (frame); - } - unmanage (win); ignore_badwindow--; diff --git a/src/frame.c b/src/frame.c index 6ac0277..8572981 100644 --- a/src/frame.c +++ b/src/frame.c @@ -114,6 +114,7 @@ frame_new (screen_info *s) f = xmalloc (sizeof (rp_window_frame)); f->number = numset_request (s->frames_numset); + f->last_access = 0; return f; } @@ -147,17 +148,21 @@ frame_copy (rp_window_frame *frame) char * frame_dump (rp_window_frame *frame) { + rp_window *win; char *tmp; struct sbuf *s; + /* rather than use win_number, use the X11 window ID. */ + win = find_window_number (frame->win_number); + s = sbuf_new (0); - sbuf_printf (s, "%d %d %d %d %d %d %d", + sbuf_printf (s, "%d %d %d %d %d %ld %d", frame->number, frame->x, frame->y, frame->width, frame->height, - frame->win_number, + win ? win->w:0, frame->last_access); /* Extract the string and return it, and don't forget to free s. */ @@ -165,3 +170,53 @@ frame_dump (rp_window_frame *frame) free (s); return tmp; } + +rp_window_frame * +frame_read (char *str) +{ + Window w; + rp_window *win; + rp_window_frame *f; + + f = xmalloc (sizeof (rp_window_frame)); + if (sscanf (str, "%d %d %d %d %d %ld %d", + &f->number, + &f->x, + &f->y, + &f->width, + &f->height, + &w, + &f->last_access) < 7) + { + free (f); + return NULL; + } + + /* Perform some integrity checks on what we got and fix any + problems. */ + if (f->number <= 0) + f->number = 0; + if (f->x <= 0) + f->x = 0; + if (f->y <= 0) + f->y = 0; + if (f->width <= defaults.window_border_width*2) + f->width = defaults.window_border_width*2 + 1; + if (f->height <= defaults.window_border_width*2) + f->height = defaults.window_border_width*2 + 1; + if (f->last_access < 0) + f->last_access = 0; + + /* Find the window with the X11 window ID. */ + win = find_window_in_list (w, &rp_mapped_window); + if (win) + { + f->win_number = win->number; + } + else + { + f->win_number = EMPTY; + } + + return f; +} diff --git a/src/frame.h b/src/frame.h index 256bea3..f531f84 100644 --- a/src/frame.h +++ b/src/frame.h @@ -40,5 +40,6 @@ rp_window_frame *frame_new (screen_info *s); void frame_free (screen_info *s, rp_window_frame *f); rp_window_frame *frame_copy (rp_window_frame *frame); char *frame_dump (rp_window_frame *frame); +rp_window_frame *frame_read (char *str); #endif diff --git a/src/manage.c b/src/manage.c index 93fe869..28e6ab3 100644 --- a/src/manage.c +++ b/src/manage.c @@ -272,8 +272,8 @@ unmanage (rp_window *w) free_window (w); #ifdef AUTO_CLOSE - if (rp_mapped_window_sentinel->next == rp_mapped_window_sentinel - && rp_mapped_window_sentinel->prev == rp_mapped_window_sentinel) + if (rp_mapped_window->next == &rp_mapped_window + && rp_mapped_window->prev == &rp_mapped_window) { /* If the mapped window list is empty then we have run out of managed windows, so kill ratpoison. */ diff --git a/src/number.c b/src/number.c index 33dccab..62b9783 100644 --- a/src/number.c +++ b/src/number.c @@ -128,3 +128,9 @@ numset_free (struct numset *ns) free (ns->numbers_taken); free (ns); } + +void +numset_clear (struct numset *ns) +{ + ns->num_taken = 0; +} diff --git a/src/number.h b/src/number.h index 1fc6a09..363b1df 100644 --- a/src/number.h +++ b/src/number.h @@ -41,5 +41,6 @@ void numset_free (struct numset *ns); void numset_release (struct numset *ns, int n); int numset_request (struct numset *ns); int numset_add_num (struct numset *ns, int n); +void numset_clear (struct numset *ns); #endif /* ! _RATPOISON_NUMBER_H */ diff --git a/src/window.c b/src/window.c index 692e53e..37eec0c 100644 --- a/src/window.c +++ b/src/window.c @@ -119,7 +119,8 @@ add_to_window_list (screen_info *s, Window w) new_window->scr = s; new_window->last_access = 0; new_window->state = WithdrawnState; - new_window->number = -1; + new_window->number = -1; + new_window->frame_number = EMPTY; new_window->named = 0; new_window->hints = XAllocSizeHints (); new_window->colormap = DefaultColormap (dpy, s->screen_num); |