diff options
Diffstat (limited to 'src')
-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 |
7 files changed, 207 insertions, 14 deletions
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); |