diff options
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | doc/ratpoison.1 | 28 | ||||
-rw-r--r-- | doc/ratpoison.texi | 39 | ||||
-rw-r--r-- | src/actions.c | 116 | ||||
-rw-r--r-- | src/actions.h | 9 | ||||
-rw-r--r-- | src/frame.c | 8 | ||||
-rw-r--r-- | src/main.c | 31 | ||||
-rw-r--r-- | src/ratpoison.h | 1 | ||||
-rw-r--r-- | src/split.c | 55 | ||||
-rw-r--r-- | src/split.h | 1 |
10 files changed, 300 insertions, 17 deletions
@@ -1,5 +1,34 @@ +2006-09-26 Bernhard R. Link <brlink@debian.org> + + * src/actions.c (cmd_execa,cmd_execf): new functions + (spawn): new argument to set frame for client_info + (cmd_exec): give spawn current_frame() + (cmd_verbexec): give spawn current_frame() + (cmd_tmpwm): give spawn NULL + (init_user_commands): add execa and execf commands + + * src/actions.h (spawn): new argument added to prototype + (cmd_execa,cmd_execf): new prototypes + +2006-09-26 Bernhard R. Link <brlink@debian.org> + + * src/split.c, src/split.h: new function exchange_with_frame + + * src/actions.c, src/actions.h: add cmd_exchange_left,cmd_exchange_right,cmd_exchange_up,cmd_exchange_down, + add new keybindings C-Left,C-Right,C-Up,C-Down to those. + + * doc/ratpoison.1: document the new functions and keybindings. + 2006-09-26 Shawn Betts <sabetts@vcn.bc.ca> + * src/frame.c (read_slot): use strtok_ws + (frame_read): likewise + + * src/actions.c (command): dont use strtok. manually pull out the + command and the rest. + + * src/main.c (strtok_ws): new function + * src/manage.c (update_window_name): return 1 if anything changed. 0 otherwise. * src/events.c (property_notify): only update the window names if diff --git a/doc/ratpoison.1 b/doc/ratpoison.1 index 98dc999..ab2f234 100644 --- a/doc/ratpoison.1 +++ b/doc/ratpoison.1 @@ -1,4 +1,4 @@ -.TH RATPOISON 1 2005-01-28 +.TH RATPOISON 1 2006-06-07 \# This man page is free software; you can redistribute it and/or modify \# it under the terms of the GNU General Public License as published by \# the Free Software Foundation; either version 2, or (at your option) @@ -143,6 +143,9 @@ running as window manager for the given display/screen for this to work. Do not forget to quote the command if it contains spaces. +For example: +.br +\fBratpoison \-c "echo hallo world"\fP .SH KEY BINDINGS To avoid conflicts with other programs, all default ratpoison key bindings start with an escape key, per default @@ -199,8 +202,10 @@ is called. Possible events are: .ta 10 .br +\fBdeletewindow\fP Run after a window is withdrawn. +.br \fBkey\fP Run whenever a top level key is pressed. -(by default \fBC-t\fP) +(by default \fBC\-t\fP) .br \fBquit\fP Run before exiting ratpoison. .br @@ -293,8 +298,25 @@ to \fIkey\fP without modifiers or \fBC\-\fP\fIkey\fP if \fIkey\fP has no modifiers. (If \fBset topkmap\fP was called with an argument other than \fBtop\fP that will be used instead of \fBtop\fP.) +.cmd exchangedown ( C\-t C\-Down ) +Exchange the window in the current frame with the window in the frame below the current frame. +.cmd exchangeleft ( C\-t C\-Left ) +Exchange the window in the current frame with the window in the frame left of the current frame. +.cmd exchangeright ( C\-t C\-Right ) +Exchange the window in the current frame with the window in the frame right of the current frame. +.cmd exchangeup ( C\-t C\-Up ) +Exchange the window in the current frame with the window in the frame above the current frame. .cmd exec shell\-command ( C\-t ! ) Spawn a shell executing \fIshell\-command\fP. +.cmd execa shell\-command +Spawn a shell executing \fIshell\-command\fP, without remembering +the current frame, so that _NET_WM_PID declaring programs will be +placed into the frame active when they open a window instead of +the frame active when ratpoison gets this command. +.cmd execf frame shell\-command +Spawn a shell executing \fIshell\-command\fP, showing _NET_WM_PID +supporting programs in the given frame instead of the frame selected +when this program is run. .cmd fdump [ screenno ] Output the defining data for all frames of the current screen, or for screen number \fIscreenno\fP if this is specified. @@ -459,7 +481,7 @@ To show it is waiting for a key, ratpoison will change the rat cursor to a square if \fBwaitcursor\fP is set. This command is perhaps best described with its usage in the default -configuration: By pressing \fBC-t\fP, which is the only key in the keymap +configuration: By pressing \fBC\-t\fP, which is the only key in the keymap \fBtop\fP, the command "\fBreadkey root\fP" is executed. The next key then executes the command in keymap \fBroot\fP belonging to this command. .cmd redisplay ( C\-t l ) diff --git a/doc/ratpoison.texi b/doc/ratpoison.texi index f0579b2..adc013f 100644 --- a/doc/ratpoison.texi +++ b/doc/ratpoison.texi @@ -1196,6 +1196,18 @@ Move to the frame right of the current frame. @item C-t Up Move to the frame above the current frame. +@item C-t C-Down +Exchange the window in the current frame with the window in the frame below it. + +@item C-t C-Left +Exchange the window in the current frame with the window in the frame to the left of it. + +@item C-t C-Right +Exchange the window in the current frame with the window in the frame to the rigth of it. + +@item C-t C-Up +Exchange the window in the current frame with the window in the frame above it. + @end table @node Hooks, The Status Bar, Keystrokes, Top @@ -1435,10 +1447,37 @@ Set the prefix to @var{key}. For example @samp{escape C-b} sets the prefix key to @key{C-b}. @end deffn +@deffn Command exchangedown +Exchange the current frame with the one below it. +@end deffn + +@deffn Command exchangeleft +Exchange the current frame with the one to the left of it. +@end deffn + +@deffn Command exchangeright +Exchange the current frame with the one to the right of it. +@end deffn + +@deffn Command exchangeup +Exchange the current frame with the one above it. +@end deffn + @deffn Command exec @var{command} Execute a shell command. By default, @kbd{C-t !} does this. @end deffn +@deffn Command execa @var{command} +Execute a shell command but don't record which frame it was executed +from. The client's windows will pop up in whatever frame is current. +@end deffn + +@deffn Command execf @var{command} @var{frame} +Execute a shell command and choose which frame the client's first +window will open in. The client must be netwm compliant for this to +work. +@end deffn + @deffn Command getenv @var{env} Display the value of the environment variable, @var{env}. @end deffn diff --git a/src/actions.c b/src/actions.c index a455b26..87991fb 100644 --- a/src/actions.c +++ b/src/actions.c @@ -187,11 +187,23 @@ init_user_commands(void) "Key: ", arg_KEY); add_command ("exec", cmd_exec, 1, 1, 1, "/bin/sh -c ", arg_SHELLCMD); + add_command ("execa", cmd_execa, 1, 1, 1, + "/bin/sh -c ", arg_SHELLCMD); + add_command ("execf", cmd_execf, 2, 2, 2, + "frame to execute in:", arg_FRAME, + "/bin/sh -c ", arg_SHELLCMD); add_command ("fdump", cmd_fdump, 1, 0, 0, "", arg_NUMBER); add_command ("focus", cmd_next_frame, 0, 0, 0); add_command ("focusprev", cmd_prev_frame, 0, 0, 0); add_command ("focusdown", cmd_focusdown, 0, 0, 0); + add_command ("exchangeup", cmd_exchangeup, 0, 0, 0); + add_command ("exchangedown", cmd_exchangedown, 0, 0, 0); + add_command ("exchangeleft", cmd_exchangeleft, 0, 0, 0); + add_command ("exchangeright", cmd_exchangeright, 0, 0, 0); + add_command ("swap", cmd_swap, 2, 1, 1, + "destination frame: ", arg_FRAME, + "source frame: ", arg_FRAME); add_command ("focuslast", cmd_focuslast, 0, 0, 0); add_command ("focusleft", cmd_focusleft, 0, 0, 0); add_command ("focusright", cmd_focusright, 0, 0, 0); @@ -720,6 +732,10 @@ initialize_default_keybindings (void) add_keybinding (XK_S, RP_CONTROL_MASK, "hsplit", map); add_keybinding (XK_Tab, 0, "focus", map); add_keybinding (XK_Tab, RP_META_MASK, "focuslast", map); + add_keybinding (XK_Left, RP_CONTROL_MASK, "exchangeleft", map); + add_keybinding (XK_Right, RP_CONTROL_MASK, "exchangeright", map); + add_keybinding (XK_Up, RP_CONTROL_MASK, "exchangeup", map); + add_keybinding (XK_Down, RP_CONTROL_MASK, "exchangedown", map); add_keybinding (XK_Left, 0, "focusleft", map); add_keybinding (XK_Right, 0, "focusright", map); add_keybinding (XK_Up, 0, "focusup", map); @@ -2318,16 +2334,26 @@ command (int interactive, char *data) /* get a writable copy for strtok() */ input = xstrdup (data); - cmd = strtok (input, " "); + cmd = input; + /* skip beginning whitespace. */ + while (*cmd && isspace (*cmd)) cmd++; + rest = cmd; + /* skip til we get to whitespace */ + while (*rest && !isspace (*rest)) rest++; + /* mark that spot as the end of the command and make rest point to + the rest of the string. */ + if (*rest) + { + *rest = 0; + rest++; + } if (cmd == NULL) { - result = cmdret_new (RET_FAILURE, NULL); + result = cmdret_new (RET_FAILURE, NULL); goto done; } - rest = strtok (NULL, "\0"); - PRINT_DEBUG (("cmd==%s rest==%s\n", cmd, rest?rest:"NULL")); /* Look for it in the aliases, first. */ @@ -2457,12 +2483,26 @@ cmd_colon (int interactive, struct cmdarg **args) cmdret * cmd_exec (int interactive, struct cmdarg **args) { - spawn (ARG_STRING(0), 0); + spawn (ARG_STRING(0), 0, current_frame()); + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_execa (int interactive, struct cmdarg **args) +{ + spawn (ARG_STRING(0), 0, NULL); + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_execf (int interactive, struct cmdarg **args) +{ + spawn (ARG_STRING(1), 0, ARG(0,frame)); return cmdret_new (RET_SUCCESS, NULL); } int -spawn(char *cmd, int raw) +spawn(char *cmd, int raw, rp_frame *frame) { rp_child_info *child; int pid; @@ -2496,7 +2536,7 @@ spawn(char *cmd, int raw) child->cmd = strdup (cmd); child->pid = pid; child->terminated = 0; - child->frame = current_frame(); + child->frame = frame; child->group = rp_current_group; child->screen = current_screen(); child->window_mapped = 0; @@ -3910,6 +3950,64 @@ cmd_focusright (int interactive, struct cmdarg **args) } cmdret * +cmd_exchangeup (int interactive, struct cmdarg **args) +{ + rp_frame *frame; + + if ((frame = find_frame_up (current_frame()))) + exchange_with_frame (current_screen(), current_frame(), frame); + + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_exchangedown (int interactive, struct cmdarg **args) +{ + rp_frame *frame; + + if ((frame = find_frame_down (current_frame()))) + exchange_with_frame (current_screen(), current_frame(), frame); + + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_exchangeleft (int interactive, struct cmdarg **args) +{ + rp_frame *frame; + + if ((frame = find_frame_left (current_frame()))) + exchange_with_frame (current_screen(), current_frame(), frame); + + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_exchangeright (int interactive, struct cmdarg **args) +{ + rp_frame *frame; + + if ((frame = find_frame_right (current_frame()))) + exchange_with_frame (current_screen(), current_frame(), frame); + + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * +cmd_swap (int interactive, struct cmdarg **args) +{ + rp_frame *dest_frame; + rp_frame *src_frame; + + dest_frame = ARG(0, frame); + src_frame = args[1] ? ARG (1, frame) : current_frame(); + + exchange_with_frame (current_screen(), src_frame, dest_frame); + + return cmdret_new (RET_SUCCESS, NULL); +} + +cmdret * cmd_restart (int interactive, struct cmdarg **args) { hup_signalled = 1; @@ -4286,7 +4384,7 @@ cmd_tmpwm (int interactive, struct cmdarg **args) /* Disable our SIGCHLD handler */ set_sig_handler (SIGCHLD, SIG_IGN); /* Launch the new WM and wait for it to terminate. */ - pid = spawn (ARG_STRING(0), 0); + pid = spawn (ARG_STRING(0), 0, NULL); PRINT_DEBUG (("spawn pid: %d\n", pid)); do { @@ -4504,7 +4602,7 @@ cmdret * cmd_verbexec (int interactive, struct cmdarg **args) { marked_message_printf(0, 0, "Running %s", ARG_STRING(0)); - spawn (ARG_STRING(0), 0); + spawn (ARG_STRING(0), 0, current_frame()); return cmdret_new (RET_SUCCESS, NULL); } diff --git a/src/actions.h b/src/actions.h index d17c6d3..8567805 100644 --- a/src/actions.h +++ b/src/actions.h @@ -96,7 +96,7 @@ user_command struct list_head node; }; -int spawn(char *data, int raw); +int spawn(char *data, int raw, rp_frame *frame); cmdret *command (int interactive, char *data); /* command function prototypes. */ @@ -115,12 +115,19 @@ RP_CMD (delete); RP_CMD (echo); RP_CMD (escape); RP_CMD (exec); +RP_CMD (execa); +RP_CMD (execf); RP_CMD (fdump); RP_CMD (focusdown); RP_CMD (focuslast); RP_CMD (focusleft); RP_CMD (focusright); RP_CMD (focusup); +RP_CMD (exchangeup); +RP_CMD (exchangedown); +RP_CMD (exchangeleft); +RP_CMD (exchangeright); +RP_CMD (swap); RP_CMD (frestore); RP_CMD (fselect); RP_CMD (gdelete); diff --git a/src/frame.c b/src/frame.c index 3a6b82e..9328326 100644 --- a/src/frame.c +++ b/src/frame.c @@ -190,7 +190,7 @@ frame_dump (rp_frame *frame, rp_screen *screen) } /* Used only by frame_read */ -#define read_slot(x) do { tmp = strtok (NULL, " "); x = strtol(tmp,NULL,10); } while(0) +#define read_slot(x) do { tmp = strtok_ws (NULL); x = strtol(tmp,NULL,10); } while(0) rp_frame * frame_read (char *str, rp_screen *screen) @@ -209,7 +209,7 @@ frame_read (char *str, rp_screen *screen) PRINT_DEBUG(("parsing '%s'\n", str)); dup = xstrdup(str); - tmp = strtok (dup, " "); + tmp = strtok_ws (dup); /* Verify it starts with '(frame ' */ if (strcmp(tmp, "(frame")) @@ -220,7 +220,7 @@ frame_read (char *str, rp_screen *screen) return NULL; } /* NOTE: there is no check to make sure each field was filled in. */ - tmp = strtok(NULL, " "); + tmp = strtok_ws(NULL); while (tmp) { if (!strcmp(tmp, ":number")) @@ -256,7 +256,7 @@ frame_read (char *str, rp_screen *screen) else PRINT_ERROR(("Unknown slot %s\n", tmp)); /* Read the next token. */ - tmp = strtok(NULL, " "); + tmp = strtok_ws(NULL); } if (tmp) PRINT_ERROR(("Frame has trailing garbage\n")); @@ -151,6 +151,37 @@ xsprintf (char *fmt, ...) return buffer; } +/* strtok but do it for whitespace and be locale compliant. */ +char * +strtok_ws (char *s) +{ + char *nonws; + static char *pointer = NULL; + + printf ("pointer: %p\n", pointer); + + if (s) + pointer = s; + + /* skip to first non-whitespace char. */ + while (*pointer && isspace (*pointer)) pointer++; + + /* If we reached the end of the string here then there is no more + data. */ + if (*pointer == 0) + return NULL; + + /* Now skip to the end of the data. */ + nonws = pointer; + while (*pointer && !isspace (*pointer)) pointer++; + if (*pointer) + { + *pointer = 0; + pointer++; + } + return nonws; +} + /* A case insensitive strncmp. */ int str_comp (char *s1, char *s2, int len) diff --git a/src/ratpoison.h b/src/ratpoison.h index 639c9b9..e0052f2 100644 --- a/src/ratpoison.h +++ b/src/ratpoison.h @@ -103,6 +103,7 @@ char *xstrdup (char *s); char *xsprintf (char *fmt, ...); char *xvsprintf (char *fmt, va_list ap); int str_comp (char *s1, char *s2, int len); +char *strtok_ws (char *s); /* Needed in cmd_tmpwm */ void check_child_procs (void); void chld_handler (int signum); diff --git a/src/split.c b/src/split.c index 93cfe03..93da642 100644 --- a/src/split.c +++ b/src/split.c @@ -872,6 +872,61 @@ set_active_frame (rp_frame *frame) } void +exchange_with_frame (rp_screen *s, rp_frame *cur, rp_frame *frame) +{ + rp_window *win,*last_win; + + /* As a frame does not tell which screen it belongs to, + * we could only make sure the frames are not on different + * screens when xinerama is not available, if both have + * windows in it. As this is not enough the caller will + * have to check this. As I only plan to implement + * exchange_{left,right,up,down}, this will be a nop...*/ + if (frame == NULL || frame == cur) return; + + /* Exchange the windows in the frames */ + win = find_window_number (cur->win_number); + last_win = set_frames_window (frame, win); + set_frames_window (cur, last_win); + + /* Make sure the windows comes up full screen */ + if (last_win) + maximize (last_win); + if (win) + { + maximize (win); + /* Make sure the program bar is always on the top */ + update_window_names (win->scr, defaults.window_fmt); + } + + /* Make the switch */ + update_last_access (frame); + + if (s->current_frame == cur->number) + { + s->current_frame = frame->number; + /* mark it as active */ + show_frame_indicator(); + } + + update_bar (s); + + + XSync (dpy, False); + + hook_run (&rp_switch_frame_hook); + + /* FIXME: Remaining problems: + * - if one of the window is transient, the windows in the + * background could cause problems. + * + * - how to implement correct mouse-warping? + * (is it needed at all?) + */ +} + + +void blank_frame (rp_frame *frame) { rp_screen *s; diff --git a/src/split.h b/src/split.h index 1236656..2dc4fcf 100644 --- a/src/split.h +++ b/src/split.h @@ -41,6 +41,7 @@ rp_window *current_window (void); void init_frame_lists (void); void init_frame_list (rp_screen *screen); void set_active_frame (rp_frame *frame); +void exchange_with_frame (rp_screen *s, rp_frame *cur, rp_frame *frame); void blank_frame (rp_frame *frame); void show_frame_indicator (void); void hide_frame_indicator (void); |