summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsabetts <sabetts>2003-04-04 17:17:58 +0000
committersabetts <sabetts>2003-04-04 17:17:58 +0000
commitf42294c8d8d0d8899f256ae9f233d80f09179d33 (patch)
tree69749d5e84f71f9afbf77955ecbe6800d677cfe2
parent7eac68127c67d4c007b65548af5901f4e381d512 (diff)
downloadratpoison-f42294c8d8d0d8899f256ae9f233d80f09179d33.zip
* 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.
-rw-r--r--ChangeLog26
-rw-r--r--NEWS3
-rw-r--r--doc/ratpoison.texi10
-rw-r--r--src/actions.c153
-rw-r--r--src/actions.h2
-rw-r--r--src/events.c13
-rw-r--r--src/frame.c59
-rw-r--r--src/frame.h1
-rw-r--r--src/manage.c4
-rw-r--r--src/number.c6
-rw-r--r--src/number.h1
-rw-r--r--src/window.c3
12 files changed, 248 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 48403ee..4bc7da9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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()
diff --git a/NEWS b/NEWS
index bcfe6e0..6671e04 100644
--- a/NEWS
+++ b/NEWS
@@ -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, &current_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);