i used to use ratpoison on a slow netbook with an even slower ssd drive and found that under a high system load, spawning out to the rpws shell script to switch between workspaces often was unbearably slow.
to remedy that, i integrated virtual workspaces into the source so that switching workspaces was much quicker. i've been running this for quite a long time and figured i'd send it out in case anyone wants to formally integrate it or at least run it locally. it adds a "virtuals" config option which specifies how many workspaces there are (defaults to 5), a "vinit" command to initialize those workspaces, a "vselect" command to switch to a given workspace, and "vdump" command to print out the workspace/frame config for each one. it basically runs the same commands that rpws did and uses groups, just does so internally. diff --git a/src/actions.c b/src/actions.c index bda8002..91f86a2 100644 --- a/src/actions.c +++ b/src/actions.c @@ -76,6 +76,7 @@ static cmdret * set_topkmap (struct cmdarg **args); static cmdret * set_historysize (struct cmdarg **args); static cmdret * set_historycompaction (struct cmdarg **args); static cmdret * set_historyexpansion (struct cmdarg **args); +static cmdret * set_virtuals (struct cmdarg **args); LIST_HEAD(set_vars); @@ -145,6 +146,7 @@ init_set_vars(void) add_set_var ("historysize", set_historysize, 1, "", arg_NUMBER); add_set_var ("historycompaction", set_historycompaction, 1, "", arg_NUMBER); add_set_var ("historyexpansion", set_historyexpansion, 1, "", arg_NUMBER); + add_set_var ("virtuals", set_virtuals, 1, "", arg_NUMBER); } /* rp_keymaps is ratpoison's list of keymaps. */ @@ -361,6 +363,10 @@ init_user_commands(void) add_command ("verbexec", cmd_verbexec, 1, 1, 1, "/bin/sh -c ", arg_SHELLCMD); add_command ("version", cmd_version, 0, 0, 0); + add_command ("vdump", cmd_vdump, 0, 0, 0); + add_command ("vinit", cmd_vinit, 0, 0, 0); + add_command ("vselect", cmd_vselect, 1, 1, 1, + "Virtual Workspace: ", arg_NUMBER); add_command ("vsplit", cmd_v_split, 1, 0, 0, "Split: ", arg_STRING); add_command ("warp", cmd_warp, 1, 1, 1, @@ -4111,6 +4117,22 @@ set_bwcolor (struct cmdarg **args) return cmdret_new (RET_SUCCESS, NULL); } +static cmdret * +set_virtuals (struct cmdarg **args) +{ + int i; + + if (args[0] == NULL) + return cmdret_new (RET_SUCCESS, "%d", defaults.virtuals); + + if (ARG(0,number) < 0) + return cmdret_new (RET_FAILURE, "virtuals: invalid argument"); + + defaults.virtuals = ARG(0,number); + + return cmdret_new (RET_SUCCESS, NULL); +} + cmdret * cmd_setenv (int interactive UNUSED, struct cmdarg **args) { @@ -5856,6 +5878,133 @@ cmd_getsel (int interactive UNUSED, struct cmdarg **args UNUSED) return ret; } +cmdret * +cmd_vdump (int interactive, struct cmdarg **args) +{ + char *input; + struct cmdarg *arg; + int which = ARG(0, number); + + rp_virtual *cur; + rp_screen *screen = current_screen(); + + arg = xmalloc (sizeof(struct cmdarg)); + + PRINT_DEBUG (("virtual workspace config:\n")); + + list_for_each_entry (cur, &rp_virtuals, node) { + PRINT_DEBUG ((" %d: %s\n", cur->number, cur->fconfig)); + } + + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_vinit (int interactive, struct cmdarg **args) +{ + int x; + char *input; + struct cmdarg *arg; + rp_screen *screen = current_screen(); + rp_virtual *first; + + INIT_LIST_HEAD (&rp_virtuals); + + /* select - */ + PRINT_DEBUG (("vinit: selecting -\n")); + arg = xmalloc (sizeof(struct cmdarg)); + (arg)->type = arg_STRING; + input = xstrdup("-"); + (arg)->string = input; + cmd_select (0, &arg); + + PRINT_DEBUG (("vinit: only\n")); + cmd_only (0, NULL); + + /* create a new group for each virtual space and init frame config */ + for (x = 1; x <= defaults.virtuals; x++) { + rp_virtual *v; + + if (x == 1) + input = xstrdup ("default"); + else + input = xsprintf ("virtual%d", x); + + PRINT_DEBUG (("vinit: creating space %d (%s)\n", x, input)); + + (arg)->string = input; + cmd_gnew (0, &arg); + + v = xmalloc (sizeof (rp_virtual)); + v->number = x; + v->fconfig = fdump (screen); + + rp_current_virtual = v; + + list_add_tail (&v->node, &rp_virtuals); + } + + /* start in workspace 1 */ + PRINT_DEBUG (("vinit: selecting default\n")); + input = xstrdup ("default"); + (arg)->string = input; + cmd_gselect (0, &arg); + list_first (first, &rp_virtuals, node); + if (first) { + rp_current_virtual = first; + + /* restore the frames */ + PRINT_DEBUG (("vinit: restoring frame config\n")); + frestore (first->fconfig, screen); + } else + PRINT_DEBUG (("vinit: no first virtual?!\n")); + + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_vselect (int interactive, struct cmdarg **args) +{ + char *input; + struct cmdarg *arg; + int which = ARG(0, number); + + rp_virtual *cur; + rp_screen *screen = current_screen(); + + arg = xmalloc (sizeof(struct cmdarg)); + + if (rp_current_virtual->number == which) + /* don't bother */ + return cmdret_new (RET_SUCCESS, NULL); + + /* store the current frame config */ + rp_current_virtual->fconfig = fdump (screen); + + list_for_each_entry (cur, &rp_virtuals, node) { + if (cur->number == which) { + if (which == 1) + input = xstrdup ("default"); + else + input = xsprintf ("virtual%d", cur->number); + + PRINT_DEBUG (("selecting %s\n", input)); + + (arg)->string = input; + cmd_gselect (0, &arg); + + /* restore this space's frame config */ + frestore (cur->fconfig, screen); + + rp_current_virtual = cur; + + return cmdret_new (RET_SUCCESS, NULL); + } + } + + return cmdret_new (RET_FAILURE, "vselect: no such virtual workspace"); +} + /* This is a command that restores old commands that have been recently depricated. */ cmdret * diff --git a/src/actions.h b/src/actions.h index 5db4a56..b3cae5b 100644 --- a/src/actions.h +++ b/src/actions.h @@ -187,6 +187,9 @@ RP_CMD (unsetenv); RP_CMD (v_split); RP_CMD (verbexec); RP_CMD (version); +RP_CMD (vdump); +RP_CMD (vinit); +RP_CMD (vselect); RP_CMD (warp); RP_CMD (windows); RP_CMD (readkey); diff --git a/src/data.h b/src/data.h index 541ca9e..634523b 100644 --- a/src/data.h +++ b/src/data.h @@ -40,6 +40,7 @@ typedef struct rp_keymap rp_keymap; typedef struct rp_frame rp_frame; typedef struct rp_child_info rp_child_info; typedef struct rp_group rp_group; +typedef struct rp_virtual rp_virtual; typedef struct rp_window_elem rp_window_elem; typedef struct rp_completions rp_completions; typedef struct rp_input_line rp_input_line; @@ -149,6 +150,14 @@ struct rp_group struct list_head node; }; +struct rp_virtual +{ + char *fconfig; + int number; + + struct list_head node; +}; + struct rp_screen { GC normal_gc, inverse_gc; @@ -274,6 +283,9 @@ struct rp_defaults /* Frame indicator format */ char *frame_fmt; + + /* Number of virtual workspaces */ + int virtuals; }; /* Information about a child process. */ diff --git a/src/globals.c b/src/globals.c index 9ebc8e3..88dd71c 100644 --- a/src/globals.c +++ b/src/globals.c @@ -60,6 +60,9 @@ rp_screen *screens; int num_screens; Display *dpy; +rp_virtual *rp_current_virtual; +LIST_HEAD (rp_virtuals); + rp_group *rp_current_group; LIST_HEAD (rp_groups); LIST_HEAD (rp_children); diff --git a/src/globals.h b/src/globals.h index 00af94d..06577e0 100644 --- a/src/globals.h +++ b/src/globals.h @@ -90,6 +90,9 @@ extern struct list_head rp_children; extern struct rp_defaults defaults; +extern rp_virtual *rp_current_virtual; +extern struct list_head rp_virtuals; + /* Cached font info. */ extern int rp_font_ascent, rp_font_descent, rp_font_width; diff --git a/src/main.c b/src/main.c index 417fc1a..7c022a4 100644 --- a/src/main.c +++ b/src/main.c @@ -567,6 +567,8 @@ init_defaults (void) defaults.history_expansion = False; defaults.frame_selectors = xstrdup (""); defaults.maxundos = 20; + + defaults.virtuals = 5; } int _______________________________________________ Ratpoison-devel mailing list Ratpoison-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/ratpoison-devel