summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c116
-rw-r--r--src/actions.h9
-rw-r--r--src/frame.c8
-rw-r--r--src/main.c31
-rw-r--r--src/ratpoison.h1
-rw-r--r--src/split.c55
-rw-r--r--src/split.h1
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"));
diff --git a/src/main.c b/src/main.c
index 05e09f6..c8582f0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);