summaryrefslogtreecommitdiff
path: root/src/actions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/actions.c')
-rw-r--r--src/actions.c481
1 files changed, 463 insertions, 18 deletions
diff --git a/src/actions.c b/src/actions.c
index e334de1..fee6e77 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -120,6 +120,19 @@ static user_command user_commands[] =
{"vsplit", cmd_v_split, arg_STRING},
{"warp", cmd_warp, arg_STRING},
{"windows", cmd_windows, arg_VOID},
+ {"cnext", cmd_cnext, arg_VOID},
+ {"cother", cmd_cother, arg_VOID},
+ {"cprev", cmd_cprev, arg_VOID},
+ {"dedicate", cmd_dedicate, arg_VOID},
+ {"describekey", cmd_describekey, arg_STRING},
+ {"focusprev", cmd_prev_frame, arg_VOID},
+ {"inext", cmd_inext, arg_VOID},
+ {"iother", cmd_iother, arg_VOID},
+ {"iprev", cmd_iprev, arg_VOID},
+ {"prompt", cmd_prompt, arg_STRING},
+ {"sdump", cmd_sdump, arg_VOID},
+ {"sfdump", cmd_sfdump, arg_VOID},
+ {"undo", cmd_undo, arg_STRING},
/*@end (tag required for genrpbindings) */
/* Commands to help debug ratpoison. */
@@ -161,8 +174,10 @@ static char * set_bgcolor (char *data);
static char * set_barpadding (char *data);
static char * set_winliststyle (char *data);
static char * set_framesels (char *data);
+static char * set_maxundos (char *data);
static struct set_var set_vars[] =
{ {"resizeunit", set_resizeunit},
+ {"maxundos", set_maxundos},
{"wingravity", set_wingravity},
{"transgravity", set_transgravity},
{"maxsizegravity", set_maxsizegravity},
@@ -192,6 +207,35 @@ static alias_t *alias_list;
static int alias_list_size;
static int alias_list_last;
+static char *frestore (char *data, rp_screen *s);
+static char *fdump (rp_screen *screen);
+
+static void
+push_frame_undo(rp_screen *screen)
+{
+ rp_frame_undo *cur;
+ if (rp_num_frame_undos > defaults.maxundos)
+ {
+ /* Delete the oldest node */
+ list_last (cur, &rp_frame_undos, node);
+ pop_frame_undo (cur);
+ }
+ cur = xmalloc (sizeof(rp_frame_undo));
+ cur->frames = fdump (screen);
+ cur->screen = screen;
+ list_add (&cur->node, &rp_frame_undos);
+ rp_num_frame_undos++; /* increment counter */
+}
+
+void
+pop_frame_undo (rp_frame_undo *u)
+{
+ if (!u) return;
+ if (u->frames) free (u->frames);
+ list_del (&(u->node));
+ rp_num_frame_undos--; /* decrement counter */
+}
+
rp_action*
find_keybinding_by_action (char *action, rp_keymap *map)
{
@@ -483,6 +527,7 @@ initialize_default_keybindings (void)
add_keybinding (XK_r, 0, "resize", map);
add_keybinding (XK_r, RP_CONTROL_MASK, "resize", map);
add_keybinding (XK_question, 0, "help " ROOT_KEYMAP, map);
+ add_keybinding (XK_underscore, RP_CONTROL_MASK, "undo", map);
add_alias ("unbind", "definekey " ROOT_KEYMAP);
add_alias ("bind", "definekey " ROOT_KEYMAP);
@@ -504,6 +549,7 @@ initialize_default_keybindings (void)
add_alias ("defbarpadding", "set barpadding");
add_alias ("defwinliststyle", "set winliststyle");
add_alias ("defframesels", "set framesels");
+ add_alias ("defmaxundos", "set maxundos");
}
void
@@ -922,7 +968,7 @@ cmd_other (int interactive, char *data)
if (!w)
message (MESSAGE_NO_OTHER_WINDOW);
else
- set_active_window (w);
+ set_active_window_force (w);
return NULL;
}
@@ -1674,6 +1720,7 @@ cmd_v_split (int interactive, char *data)
rp_frame *frame;
int pixels;
+ push_frame_undo (current_screen()); /* fdump to stack */
frame = current_frame();
/* Default to dividing the frame in half. */
@@ -1696,6 +1743,7 @@ cmd_h_split (int interactive, char *data)
rp_frame *frame;
int pixels;
+ push_frame_undo (current_screen()); /* fdump to stack */
frame = current_frame();
/* Default to dividing the frame in half. */
@@ -1715,6 +1763,7 @@ cmd_h_split (int interactive, char *data)
char *
cmd_only (int interactive, char *data)
{
+ push_frame_undo (current_screen()); /* fdump to stack */
remove_all_splits();
maximize (current_window());
@@ -1727,6 +1776,8 @@ cmd_remove (int interactive, char *data)
rp_screen *s = current_screen();
rp_frame *frame;
+ push_frame_undo (current_screen()); /* fdump to stack */
+
if (num_frames(s) <= 1)
{
message (" remove: cannot remove only frame ");
@@ -1748,6 +1799,7 @@ cmd_remove (int interactive, char *data)
char *
cmd_shrink (int interactive, char *data)
{
+ push_frame_undo (current_screen()); /* fdump to stack */
resize_shrink_to_window (current_frame());
return NULL;
}
@@ -2036,9 +2088,9 @@ cmd_license (int interactive, char *data)
int y = 10;
int i;
int max_width = 0;
- char *license_text[] = { PACKAGE " " VERSION,
+ char *license_text[] = { PACKAGE " " VERSION, "(built " __DATE__ " " __TIME__ ")",
"",
- "Copyright (C) 2000, 2001 Shawn Betts",
+ "Copyright (C) 2000-2004 Shawn Betts",
"",
"ratpoison is free software; you can redistribute it and/or modify ",
"it under the terms of the GNU General Public License as published by ",
@@ -3418,6 +3470,7 @@ cmd_tmpwm (int interactive, char *data)
int pid;
int i;
+ push_frame_undo (current_screen()); /* fdump to stack */
if (data == NULL)
{
message (" tmpwm: one argument required ");
@@ -3642,17 +3695,8 @@ cmd_fselect (int interactive, char *data)
frame = find_frame_number (fnum);
if (frame)
{
- char *s;
- struct sbuf *sb;
-
- /* Return the frame number that was selected. */
- sb = sbuf_new(0);
- sbuf_printf (sb, "%d", fnum);
- s = sbuf_get(sb);
- free (sb);
-
set_active_frame (frame);
- return s;
+ return xsprintf("%d", frame->number);
}
else
{
@@ -3661,8 +3705,8 @@ cmd_fselect (int interactive, char *data)
}
}
-char *
-cmd_fdump (int interactively, char *data)
+static char *
+fdump (rp_screen *screen)
{
struct sbuf *s;
char *tmp;
@@ -3671,7 +3715,7 @@ cmd_fdump (int interactively, char *data)
s = sbuf_new (0);
/* FIXME: Oooh, gross! there's a trailing comma, yuk! */
- list_for_each_entry (cur, &current_screen()->frames, node)
+ list_for_each_entry (cur, &(screen->frames), node)
{
char *tmp;
@@ -3687,9 +3731,33 @@ cmd_fdump (int interactively, char *data)
}
char *
-cmd_frestore (int interactively, char *data)
+cmd_fdump (int interactively, char *data)
+{
+ if (!data)
+ {
+ return fdump (current_screen());
+ }
+ else
+ {
+ /* assert (NULL != data); */
+ int snum;
+ if (1 != sscanf (data, "%d", &snum)
+ || snum < 0
+ || num_screens <= snum)
+ {
+ message (" fdump: invalid argument ");
+ return NULL;
+ }
+ else
+ {
+ return fdump (&screens[snum]);
+ }
+ }
+}
+
+static char *
+frestore (char *data, rp_screen *s)
{
- rp_screen *s = current_screen();
char *token;
char *dup;
rp_frame *new, *cur;
@@ -3791,6 +3859,13 @@ cmd_frestore (int interactively, char *data)
}
char *
+cmd_frestore (int interactively, char *data)
+{
+ push_frame_undo (current_screen()); /* fdump to stack */
+ return frestore (data, current_screen());
+}
+
+char *
cmd_verbexec (int interactive, char *data)
{
char msg[100]="Running ";
@@ -4517,3 +4592,373 @@ cmd_set (int interactive, char *data)
free (rest);
return NULL;
}
+
+char *
+cmd_sfdump (int interactively, char *data)
+{
+ struct sbuf *s;
+ char *tmp, *tmp2;
+ rp_frame *cur;
+
+ s = sbuf_new (0);
+
+ register int i;
+ for (i=0; i<num_screens; i++)
+ {
+ tmp2 = xsprintf (" %d,", (rp_have_xinerama)?(screens[i].xine_screen_num):(screens[i].screen_num));
+
+ /* FIXME: Oooh, gross! there's a trailing comma, yuk! */
+ list_for_each_entry (cur, &(screens[i].frames), node)
+ {
+ char *tmp;
+
+ tmp = frame_dump (cur);
+ sbuf_concat (s, tmp);
+ sbuf_concat (s, tmp2);
+ free (tmp);
+ }
+
+ free (tmp2);
+ }
+ tmp = sbuf_get (s);
+ free (s);
+ return tmp;
+}
+
+char *
+cmd_sdump (int interactive, char *data)
+{
+ /* assert(!data); */
+ struct sbuf *s;
+ char *tmp;
+ register int i;
+
+ s = sbuf_new (0);
+ for (i=0; i<num_screens; ++i)
+ {
+ tmp = screen_dump (&screens[i]);
+ sbuf_concat (s, tmp);
+ if (i + 1 != num_screens) /* No trailing comma. */
+ sbuf_concat (s, ",");
+ free (tmp);
+ }
+
+ tmp = sbuf_get (s);
+ free (s);
+ return tmp;
+}
+
+static char *
+set_maxundos (char *data)
+{
+ int tmp;
+ rp_frame_undo *cur;
+
+ if (!data)
+ return xsprintf ("%d", defaults.maxundos);
+
+ if (1 != sscanf (data, "%d", &tmp) || tmp < 0)
+ {
+ message (" defmaxundos: invalid argument ");
+ return NULL;
+ }
+
+ defaults.maxundos = tmp;
+
+ /* Delete any superfluous undos */
+ while (rp_num_frame_undos > defaults.maxundos)
+ {
+ /* Delete the oldest node */
+ list_last (cur, &rp_frame_undos, node);
+ pop_frame_undo (cur);
+ }
+
+ return NULL;
+}
+
+char *
+cmd_cnext (int interactive, char *data)
+{
+ rp_window *cur, *last, *win;
+
+ cur = current_window();
+ if (!cur || !cur->res_class) /* Can't be done. */
+ return cmd_next (interactive, data);
+
+ /* CUR !in cycle list, so LAST marks last node. */
+ last = group_prev_window (rp_current_group, cur);
+
+ if (last)
+ for (win = group_next_window (rp_current_group, cur);
+ win;
+ win = group_next_window (rp_current_group, win))
+ {
+ if (win->res_class
+ && strcmp (cur->res_class, win->res_class))
+ {
+ set_active_window_force (win);
+ return NULL;
+ }
+
+ if (win == last) break;
+ }
+
+ message (MESSAGE_NO_OTHER_WINDOW);
+ return NULL;
+}
+
+char *
+cmd_cprev (int interactive, char *data)
+{
+ rp_window *cur, *last, *win;
+
+ cur = current_window();
+ if (!cur || !cur->res_class) /* Can't be done. */
+ return cmd_next (interactive, data);
+
+ /* CUR !in cycle list, so LAST marks last node. */
+ last = group_next_window (rp_current_group, cur);
+
+ if (last)
+ for (win = group_prev_window (rp_current_group, cur);
+ win;
+ win = group_prev_window (rp_current_group, win))
+ {
+ if (win->res_class
+ && strcmp (cur->res_class, win->res_class))
+ {
+ set_active_window_force (win);
+ return NULL;
+ }
+
+ if (win == last) break;
+ }
+
+ message (MESSAGE_NO_OTHER_WINDOW);
+ return NULL;
+}
+
+char *
+cmd_inext (int interactive, char *data)
+{
+ rp_window *cur, *last, *win;
+
+ cur = current_window();
+ if (!cur || !cur->res_class) /* Can't be done. */
+ return cmd_next (interactive, data);
+
+ /* CUR !in cycle list, so LAST marks last node. */
+ last = group_prev_window (rp_current_group, cur);
+
+ if (last)
+ for (win = group_next_window (rp_current_group, cur);
+ win;
+ win = group_next_window (rp_current_group, win))
+ {
+ if (win->res_class
+ && !strcmp (cur->res_class, win->res_class))
+ {
+ set_active_window_force (win);
+ return NULL;
+ }
+
+ if (win == last) break;
+ }
+
+ message (MESSAGE_NO_OTHER_WINDOW);
+ return NULL;
+}
+
+char *
+cmd_iprev (int interactive, char *data)
+{
+ rp_window *cur, *last, *win;
+
+ cur = current_window();
+ if (!cur || !cur->res_class) /* Can't be done. */
+ return cmd_next (interactive, data);
+
+ /* CUR !in cycle list, so LAST marks last node. */
+ last = group_next_window (rp_current_group, cur);
+
+ if (last)
+ for (win = group_prev_window (rp_current_group, cur);
+ win;
+ win = group_prev_window (rp_current_group, win))
+ {
+ if (win->res_class
+ && !strcmp (cur->res_class, win->res_class))
+ {
+ set_active_window_force (win);
+ return NULL;
+ }
+
+ if (win == last) break;
+ }
+
+ message (MESSAGE_NO_OTHER_WINDOW);
+ return NULL;
+}
+
+char *
+cmd_cother (int interactive, char *data)
+{
+ rp_window *cur, *w;
+
+ cur = current_window();
+ w = group_last_window_by_class (rp_current_group, cur->res_class);
+
+ if (!w)
+ message (MESSAGE_NO_OTHER_WINDOW);
+ else
+ set_active_window_force (w);
+
+ return NULL;
+}
+
+char *
+cmd_iother (int interactive, char *data)
+{
+ rp_window *cur, *w;
+
+ cur = current_window();
+ w = group_last_window_by_class_complement (rp_current_group, cur->res_class);
+
+ if (!w)
+ message (MESSAGE_NO_OTHER_WINDOW);
+ else
+ set_active_window_force (w);
+
+ return NULL;
+}
+
+char *
+cmd_undo (int interactive, char *data)
+{
+ rp_frame_undo *cur;
+
+ list_first (cur, &rp_frame_undos, node);
+ if (!cur)
+ {
+ message (" No more undo information available ");
+ return NULL;
+ }
+ else
+ {
+ char *ret;
+
+ ret = frestore (cur->frames, cur->screen);
+ /* Delete the newest node */
+ pop_frame_undo (cur);
+ return ret;
+ }
+}
+
+char *
+cmd_prompt (int interactive, char *data)
+{
+ char *query, *ret, *prefix;
+
+ if (interactive) return NULL;
+
+ if (NULL == data)
+ ret = get_input(MESSAGE_PROMPT_COMMAND, trivial_completions);
+ else
+ {
+ prefix = strchr (data, ':');
+ if (prefix)
+ {
+ prefix++; /* Don't return the colon. */
+ query = xmalloc (prefix - data + 1);
+ strncpy (query, data, prefix - data);
+ query[prefix - data] = 0; /* null terminate */
+ ret = get_more_input (query, prefix, trivial_completions);
+ free (query);
+ }
+ else
+ {
+ ret = get_input (data, trivial_completions);
+ }
+ }
+ return ret;
+}
+
+char *
+cmd_describekey (int interactive, char *data)
+{
+ char *keysym_name;
+ rp_action *key_action;
+ KeySym keysym; /* Key pressed */
+ unsigned int mod; /* Modifiers */
+ int rat_grabbed = 0;
+ rp_keymap *map;
+
+ if (data == NULL)
+ {
+ message (" readkey: keymap expected ");
+ return NULL;
+ }
+
+ map = find_keymap (data);
+ if (map == NULL)
+ {
+ marked_message_printf (0, 0, " readkey: Unknown keymap '%s' ", data);
+ return NULL;
+ }
+
+ XGrabKeyboard (dpy, current_screen()->key_window, False, GrabModeSync, GrabModeAsync, CurrentTime);
+
+ /* Change the mouse icon to indicate to the user we are waiting for
+ more keystrokes */
+ if (defaults.wait_for_key_cursor)
+ {
+ grab_rat();
+ rat_grabbed = 1;
+ }
+
+ read_key (&keysym, &mod, NULL, 0);
+ XUngrabKeyboard (dpy, CurrentTime);
+
+ if (rat_grabbed)
+ ungrab_rat();
+
+ if ((key_action = find_keybinding (keysym, x11_mask_to_rp_mask (mod), map)))
+ {
+ char *result;
+ result = cmd_echo (1, key_action->data);
+
+ /* Gobble the result. */
+ if (result)
+ free (result);
+ }
+ else
+ {
+ /* No key match, notify user. */
+ keysym_name = keysym_to_string (keysym, x11_mask_to_rp_mask (mod));
+ marked_message_printf (0, 0, " %s unbound key ", keysym_name);
+ free (keysym_name);
+ }
+
+ return NULL;
+}
+
+char *
+cmd_dedicate (int interactive, char *data)
+{
+ rp_frame *f;
+
+ f = current_frame();
+ if (!f) return NULL;
+
+ if (data)
+ /* Whatever you set it to. */
+ f->dedicated = atoi(data);
+ else
+ /* Just toggle it, rather than on or off. */
+ f->dedicated = !(f->dedicated);
+
+ marked_message_printf (0, 0, " Consider this frame %s. ", (f->dedicated)?"chaste":"promiscuous");
+
+ return NULL;
+}
+