diff --git a/src/actions.c b/src/actions.c index cf08e79..8bb69e5 100644 --- a/src/actions.c +++ b/src/actions.c @@ -256,6 +256,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, @@ -273,6 +275,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); @@ -5055,6 +5059,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); } @@ -5062,6 +5067,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); } @@ -5069,6 +5075,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); } @@ -5078,6 +5085,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); } @@ -5158,13 +5166,100 @@ 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); + } + } + } + return cmd_groups (interactive, NULL); +} + /* Show all the groups, with the current one highlighted. */ cmdret * cmd_groups (int interactive, struct cmdarg **args UNUSED) @@ -5484,11 +5579,10 @@ cmd_set (int interactive UNUSED, struct cmdarg **args) } } -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; @@ -5513,13 +5607,20 @@ cmd_sfdump (int interactively UNUSED, struct cmdarg **args UNUSED) } } sbuf_chop (dump); - 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; @@ -5531,7 +5632,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) @@ -5589,6 +5690,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 d813bc9..608fced 100644 --- a/src/actions.h +++ b/src/actions.h @@ -130,6 +130,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); @@ -142,6 +143,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); @@ -233,6 +235,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 01a8f1a..5e286cb 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 1481a5c..ae8d1a9 100644 --- a/src/globals.c +++ b/src/globals.c @@ -233,6 +233,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); @@ -243,6 +244,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 2100a79..80136c3 100644 --- a/src/globals.h +++ b/src/globals.h @@ -187,6 +187,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 02d2073..9d23a73 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; } @@ -147,6 +148,7 @@ group_free (rp_group *g) free (g->name); numset_free (g->numset); numset_release (group_numset, g->number); + free (g->sframes); free (g); } @@ -600,6 +602,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 @@ -642,6 +646,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);