Re: rpws and sfdump/sfrestore (was: select patch)
Johannes Altmanninger <[email protected]> Wed, 02 Jul 2014 22:10:22 +0200
| Newsgroups | gmane.comp.window-managers.ratpoison.devel |
|---|---|
| Message-ID | <20140702201022.28560.74913@jakiro> |
I took the patch from [1] and adapted it to work with the git HEAD. It works as described in the mail, a usage example is there too [2]. This should fix the issues addressed in the bug and it also is a much cleaner implementation of workspaces (the user only has to add hooks that restore and clean frames when switching groups) Johannes [1] http://lists.nongnu.org/archive/html/ratpoison-devel/2013-10/msg00000.html [2] http://lists.nongnu.org/archive/html/ratpoison-devel/2013-10/txtWpZPBxO_TL.txt Quoting Jeff Abrahamson (2014-07-02 11:22:25) > I'm moving this to a separate thread for sanity. > > I proposed doing this in 42224 <https://savannah.nongnu.org/bugs/?42224>. > I still mean to, but some professional things have gotten in the way the > last couple months. I am not a jealous person, should you want to have a > go. ;-) Otherwise, I'm sure I will get to this later this Summer, as it > annoys me. > > I strongly believe that ditching rpws in favor of an internal > implementation is the right thing to do. WS switching should be instant, > and it is currently far from instant. > > -Jeff > > > On 2 July 2014 09:32, Johannes Altmanninger <[email protected]> wrote: > > > If sfdump is fixed now, you could change the rpws script to use > > sfdump/sfrestore instead of fdump/frestore, although builtin workspaces > > [1] would probably make more sense. (I do not use workspaces myself but > > rpws seems a bit hacky) > > > > [1] > > http://lists.nongnu.org/archive/html/ratpoison-devel/2013-10/msg00000.html > > > > Jeff Abrahamson > +33 6 24 40 01 57 <-- brièvement indisponible le 4 juillet > +44 7920 594 255 <-- will change 18 July > > http://jeff.purple.com/ > http://blog.purple.com/jeff/ _______________________________________________ Ratpoison-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/ratpoison-devel
builtin_workspaces.patch
(text/x-diff, 10.2 KB)
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; i<num_screens; i++)
+ {
+ tmp = xsprintf ("(frame :number %d :x %d :y %d :width %d :height %d :screenw %d :screenh %d :window %ld :last-access %d :dedicated %d) %d%s",
+ 0, 0, 0,
+ screen_width(&screens[i]), screen_height(&screens[i]),
+ screens[i].width, screens[i].height,
+ 0, 0, 0,
+ (rp_have_xinerama)?(screens[i].xine_screen_num):(screens[i].screen_num),
+ /* don't add a comma to the last screen */
+ (i < num_screens-1)?(","):(""));
+
+ sbuf_concat (s, tmp);
+ free (tmp);
+ }
+ tmp = sbuf_free_struct(s);
+ ret = sfrestore (tmp);
+ free (tmp);
+ }
+ }
+ else
+ return cmd_groups (interactive, NULL);
+
+ /* return success or failure according to what sfrestore returned */
+ return ret;
+}
+
+/* Clean screens by blanking frames containing windows not in the current
+ group. */
+cmdret *
+cmd_gclean (int interactive, struct cmdarg **args)
+{
+ rp_group *g;
+ rp_window *win;
+ rp_frame *cur;
+ int i;
+
+ if (args[0])
+ g = find_group (ARG_STRING(0));
+ else
+ g = rp_current_group;
+
+ if (g)
+ {
+ for (i=0; i<num_screens; i++)
+ {
+ list_for_each_entry (cur, &(screens[i].frames), node)
+ {
+ win = find_window_number (cur->win_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);