diff --git a/src/actions.c b/src/actions.c index 2369067..2db049c 100644 --- a/src/actions.c +++ b/src/actions.c @@ -249,6 +249,8 @@ init_user_commands(void) "Frames: ", arg_REST); add_command ("fselect", cmd_fselect, 1, 1, 1, "", arg_FRAME); + add_command ("gclean", cmd_gclean, 1, 0, 0, + "Group: ", arg_GROUP); add_command ("gdelete", cmd_gdelete, 1, 0, 0, "Group:", arg_GROUP); add_command ("getenv", cmd_getenv, 1, 1, 1, @@ -266,6 +268,8 @@ init_user_commands(void) "Number: ", arg_NUMBER); add_command ("grename", cmd_grename, 1, 1, 1, "Change group name to: ", arg_REST); + add_command ("grestore", cmd_grestore, 1, 0, 0, + "Group: ", arg_GROUP); add_command ("gnext", cmd_gnext, 0, 0, 0); add_command ("gprev", cmd_gprev, 0, 0, 0); add_command ("gother", cmd_gother, 0, 0, 0); @@ -5043,6 +5047,7 @@ set_winliststyle (struct cmdarg **args) cmdret * cmd_gnext (int interactive UNUSED, struct cmdarg **args UNUSED) { + store_current_group_frames (sfdump()); set_current_group (group_next_group ()); return cmdret_new (RET_SUCCESS, NULL); } @@ -5050,6 +5055,7 @@ cmd_gnext (int interactive UNUSED, struct cmdarg **args UNUSED) cmdret * cmd_gprev (int interactive UNUSED, struct cmdarg **args UNUSED) { + store_current_group_frames (sfdump()); set_current_group (group_prev_group ()); return cmdret_new (RET_SUCCESS, NULL); } @@ -5057,6 +5063,7 @@ cmd_gprev (int interactive UNUSED, struct cmdarg **args UNUSED) cmdret * cmd_gother (int interactive UNUSED, struct cmdarg **args UNUSED) { + store_current_group_frames (sfdump()); set_current_group (group_last_group ()); return cmdret_new (RET_SUCCESS, NULL); } @@ -5066,6 +5073,7 @@ cmd_gnew (int interactive UNUSED, struct cmdarg **args) { if (groups_find_group_by_name (ARG_STRING (0), 1)) return cmdret_new (RET_FAILURE, "gnew: group already exists"); + store_current_group_frames (sfdump()); set_current_group (group_add_new_group (ARG_STRING(0))); return cmdret_new (RET_SUCCESS, NULL); } @@ -5146,7 +5154,97 @@ cmd_gselect (int interactive, struct cmdarg **args) g = find_group (ARG_STRING(0)); if (g) - set_current_group (g); + { + store_current_group_frames (sfdump()); + set_current_group (g); + } + else + return cmd_groups (interactive, NULL); + + return cmdret_new (RET_SUCCESS, NULL); +} + +/* Restore group's sfdump, i.e. the screens' state when the group was last + used. */ +cmdret * +cmd_grestore (int interactive, struct cmdarg **args) +{ + rp_group *g; + cmdret *ret = NULL; + struct sbuf *s; + char *tmp; + int i; + + if (args[0]) + g = find_group (ARG_STRING(0)); + else + g = rp_current_group; + + if (g) + { + if (g->sframes) + { + ret = sfrestore (g->sframes); + } + else + { + /* No saved sfdump: blanks screens by creating an sfdump with a single + empty frame per screen, then restoring it. */ + s = sbuf_new (0); + for (i=0; iwin_number); + /* blank frame if window doesn't belong to group */ + if (win && !group_find_window(&g->mapped_windows, win)) + blank_frame(cur); + } + } + } else return cmd_groups (interactive, NULL); @@ -5471,12 +5569,10 @@ cmd_set (int interactive UNUSED, struct cmdarg **args) return result; } } - -cmdret * -cmd_sfdump (int interactively UNUSED, struct cmdarg **args UNUSED) +char * +sfdump (void) { char screen_suffix[16]; - cmdret *ret; struct sbuf *dump; rp_frame *cur; int i; @@ -5501,13 +5597,21 @@ cmd_sfdump (int interactively UNUSED, struct cmdarg **args UNUSED) free (frameset); } } - ret = cmdret_new (RET_SUCCESS, "%s", sbuf_get (dump)); - sbuf_free (dump); + + return sbuf_free_struct (dump); +} + +cmdret * +cmd_sfdump (int interactively UNUSED, struct cmdarg **args UNUSED) +{ + char *s = sfdump(); + cmdret *ret = cmdret_new (RET_SUCCESS, "%s", s); + free (s); return ret; } cmdret * -cmd_sfrestore (int interactively UNUSED, struct cmdarg **args) +sfrestore (char *sframes) { struct sbuf *buffer[num_screens]; char *copy, *ptr, *token; @@ -5519,7 +5623,7 @@ cmd_sfrestore (int interactively UNUSED, struct cmdarg **args) for (i = 0; i < num_screens; i++) buffer[i] = sbuf_new (0); - copy = xstrdup (ARG_STRING (0)); + copy = xstrdup (sframes); token = strtok (copy, ","); if (token == NULL) @@ -5578,6 +5682,12 @@ cmd_sfrestore (int interactively UNUSED, struct cmdarg **args) } cmdret * +cmd_sfrestore (int interactively UNUSED, struct cmdarg **args) +{ + return sfrestore (ARG_STRING(0)); +} + +cmdret * cmd_sdump (int interactive UNUSED, struct cmdarg **args UNUSED) { cmdret *ret; diff --git a/src/actions.h b/src/actions.h index 519c1a7..4e9dffa 100644 --- a/src/actions.h +++ b/src/actions.h @@ -131,6 +131,7 @@ RP_CMD (exchangeright); RP_CMD (swap); RP_CMD (frestore); RP_CMD (fselect); +RP_CMD (gclean); RP_CMD (gdelete); RP_CMD (getenv); RP_CMD (gmerge); @@ -143,6 +144,7 @@ RP_CMD (gprev); RP_CMD (gother); RP_CMD (gravity); RP_CMD (grename); +RP_CMD (grestore); RP_CMD (groups); RP_CMD (gselect); RP_CMD (h_split); @@ -234,6 +236,8 @@ void free_keymaps (void); char *wingravity_to_string (int g); rp_action* find_keybinding (KeySym keysym, unsigned int state, rp_keymap *map); rp_action* find_keybinding_by_action (char *action, rp_keymap *map); +char *sfdump (void); +cmdret *sfrestore (char *sframes); #endif /* ! _RATPOISON_ACTIONS_H */ diff --git a/src/data.h b/src/data.h index 2be9a98..172883f 100644 --- a/src/data.h +++ b/src/data.h @@ -147,6 +147,9 @@ struct rp_group /* This structure can exist in a list. */ struct list_head node; + + /* screens' frame dump from the last time this group was used */ + char *sframes; }; struct rp_screen diff --git a/src/globals.c b/src/globals.c index 05ebe28..6ad16bb 100644 --- a/src/globals.c +++ b/src/globals.c @@ -235,6 +235,7 @@ LIST_HEAD (rp_switch_screen_hook); LIST_HEAD (rp_quit_hook); LIST_HEAD (rp_restart_hook); LIST_HEAD (rp_delete_window_hook); +LIST_HEAD (rp_move_to_group_hook); LIST_HEAD (rp_new_window_hook); LIST_HEAD (rp_title_changed_hook); @@ -245,6 +246,7 @@ struct rp_hook_db_entry rp_hook_db[]= {"switchgroup", &rp_switch_group_hook}, {"switchscreen", &rp_switch_screen_hook}, {"deletewindow", &rp_delete_window_hook}, + {"movetogroup", &rp_move_to_group_hook}, {"quit", &rp_quit_hook}, {"restart", &rp_restart_hook}, {"newwindow", &rp_new_window_hook}, diff --git a/src/globals.h b/src/globals.h index 12ccffd..622fefd 100644 --- a/src/globals.h +++ b/src/globals.h @@ -183,6 +183,7 @@ extern struct list_head rp_switch_frame_hook; extern struct list_head rp_switch_group_hook; extern struct list_head rp_switch_screen_hook; extern struct list_head rp_delete_window_hook; +extern struct list_head rp_move_to_group_hook; extern struct list_head rp_quit_hook; extern struct list_head rp_restart_hook; extern struct list_head rp_new_window_hook; diff --git a/src/group.c b/src/group.c index 2bbfead..654f131 100644 --- a/src/group.c +++ b/src/group.c @@ -137,6 +137,7 @@ group_new (int number, char *name) g->numset = numset_new(); INIT_LIST_HEAD (&g->unmapped_windows); INIT_LIST_HEAD (&g->mapped_windows); + g->sframes = NULL; return g; } @@ -148,6 +149,7 @@ group_free (rp_group *g) free (g->name); numset_free (g->numset); numset_release (group_numset, g->number); + free (g->sframes); free (g); } @@ -595,6 +597,8 @@ group_move_window (rp_group *to, rp_window *win) /* and shove it into the other one. */ we->number = numset_request (to->numset); group_insert_window (&to->mapped_windows, we); + + hook_run (&rp_move_to_group_hook); } void @@ -637,6 +641,16 @@ set_current_group (rp_group *g) hook_run (&rp_switch_group_hook); } +void +store_current_group_frames (char *sframes) +{ + if (rp_current_group) + { + free (rp_current_group->sframes); + rp_current_group->sframes = sframes; + } +} + int group_delete_group (rp_group *g) { diff --git a/src/group.h b/src/group.h index 1081043..310d31a 100644 --- a/src/group.h +++ b/src/group.h @@ -68,6 +68,7 @@ void group_move_window (rp_group *to, rp_window *win); void groups_merge (rp_group *from, rp_group *to); void set_current_group (rp_group *g); +void store_current_group_frames (char *sframes); rp_window *group_last_window_by_class (rp_group *g, char *class); rp_window *group_last_window_by_class_complement (rp_group *g, char *class);