summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c83
-rw-r--r--src/actions.h3
-rw-r--r--src/events.c36
-rw-r--r--src/manage.c9
-rw-r--r--src/split.c30
-rw-r--r--src/split.h1
6 files changed, 125 insertions, 37 deletions
diff --git a/src/actions.c b/src/actions.c
index 39f2df0..a6e89e4 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -28,6 +28,7 @@
#include "ratpoison.h"
+
static rp_action *key_actions;
static int key_actions_last;
static int key_actions_table_size;
@@ -90,6 +91,7 @@ static user_command user_commands[] =
{"warp", cmd_warp, arg_STRING},
{"resize", cmd_resize, arg_STRING},
{"shrink", cmd_shrink, arg_VOID},
+ {"tmpwm", cmd_tmpwm, arg_STRING},
/*@end (tag required for genrpbindings) */
/* Commands to set default behavior. */
@@ -972,7 +974,7 @@ cmd_exec (int interactive, void *data)
}
-void
+int
spawn(void *data)
{
char *cmd = data;
@@ -1001,6 +1003,8 @@ spawn(void *data)
/* wait((int *) 0); */
PRINT_DEBUG (("spawned %s\n", cmd));
+
+ return pid;
}
/* Switch to a different Window Manager. Thanks to
@@ -2707,3 +2711,80 @@ cmd_warp (int interactive, void *data)
return NULL;
}
+
+/* Temporarily give control over to another window manager, reclaiming
+ control when that WM terminates. */
+char *
+cmd_tmpwm (int interactive, void *data)
+{
+ struct list_head *tmp, *iter;
+ rp_window *win = NULL;
+ int status;
+ int pid;
+ int i;
+
+ if (data == NULL)
+ {
+ message (" tmpwm: one argument required ");
+ return NULL;
+ }
+
+ /* Release event selection on the root windows, so the new WM can
+ have it. */
+ for (i=0; i<num_screens; i++)
+ XSelectInput(dpy, RootWindow (dpy, i), 0);
+
+ /* Don't listen for any events from any window. */
+ list_for_each_safe_entry (win, iter, tmp, &rp_mapped_window, node)
+ XSelectInput (dpy, win->w, 0);
+ list_for_each_safe_entry (win, iter, tmp, &rp_unmapped_window, node)
+ XSelectInput (dpy, win->w, 0);
+
+ XSync (dpy, False);
+
+ /* FIXME: drop all our windows. We shouldn't do this. */
+ list_for_each_safe_entry (win, iter, tmp, &rp_mapped_window, node)
+ {
+ rp_window_frame *frame;
+
+ /* Remove the window from the frame. */
+ frame = find_windows_frame (win);
+ if (frame) cleanup_frame (frame);
+ if (frame == win->scr->rp_current_frame) set_active_frame (frame);
+
+ /* put the window in the unmapped list. */
+ return_window_number (win->number);
+ list_move_tail(&win->node, &rp_unmapped_window);
+ }
+
+ /* Now that all the windows are in the unmapped list, unmanage them. */
+ list_for_each_safe_entry (win, iter, tmp, &rp_unmapped_window, node)
+ {
+ unmanage (win);
+ }
+
+ /* Launch the new WM and wait for it to terminate. */
+ pid = spawn ((char *)data);
+ waitpid (pid, &status, 0);
+
+ /* Enable the event selection on the root window. */
+ for (i=0; i<num_screens; i++)
+ {
+ XSelectInput(dpy, RootWindow (dpy, i),
+ PropertyChangeMask | ColormapChangeMask
+ | SubstructureRedirectMask | SubstructureNotifyMask);
+ }
+ XSync (dpy, False);
+
+ /* Pick up all the windows. */
+ for (i=0; i<num_screens; i++)
+ scanwins (&screens[i]);
+
+ /* If no window has focus, give the key_window focus. */
+ if (current_window() == NULL)
+ XSetInputFocus (dpy, current_screen()->key_window,
+ RevertToPointerRoot, CurrentTime);
+
+ /* And we're back in ratpoison. */
+ return NULL;
+}
diff --git a/src/actions.h b/src/actions.h
index 3446f12..e383f74 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -37,7 +37,7 @@ user_command
int argtype;
};
-void spawn(void *data);
+int spawn(void *data);
char * command (int interactive, char *data);
char * cmd_newwm(int interactive, void *which);
@@ -115,6 +115,7 @@ char *cmd_prevscreen (int interactive, void *data);
char *cmd_nextscreen (int interactive, void *data);
char *cmd_unalias (int interactive, void *data);
char *cmd_warp(int interactive, void *data);
+char *cmd_tmpwm (int interactive, void *data);
void initialize_default_keybindings (void);
rp_action* find_keybinding (KeySym keysym, int state);
diff --git a/src/events.c b/src/events.c
index 51f31d7..c66c938 100644
--- a/src/events.c
+++ b/src/events.c
@@ -65,36 +65,6 @@ new_window (XCreateWindowEvent *e)
}
}
-static void
-cleanup_frame (rp_window_frame *frame)
-{
- rp_window *last_win;
- rp_window *win;
-
- win = find_window_other ();
- if (win == NULL)
- {
- set_frames_window (frame, NULL);
- return;
- }
-
- last_win = set_frames_window (frame, win);
-
- maximize (win);
- unhide_window (win);
-
-
-#ifdef MAXSIZE_WINDOWS_ARE_TRANSIENTS
- if (!win->transient
- && !(win->hints->flags & PMaxSize
- && win->hints->max_width < win->scr->root_attr.width
- && win->hints->max_height < win->scr->root_attr.height))
-#else
- if (!win->transient)
-#endif
- hide_others (win);
-}
-
static void
unmap_notify (XEvent *ev)
{
@@ -406,7 +376,10 @@ handle_key (screen_info *s)
}
read_key (&keysym, &mod, NULL, 0);
+
XSetInputFocus (dpy, fwin, revert, CurrentTime);
+ if (rat_grabbed)
+ ungrab_rat();
if ((key_action = find_keybinding (keysym, x11_mask_to_rp_mask (mod))))
{
@@ -424,9 +397,6 @@ handle_key (screen_info *s)
marked_message_printf (0, 0, " %s unbound key ", keysym_name);
free (keysym_name);
}
-
- if (rat_grabbed)
- ungrab_rat();
}
static void
diff --git a/src/manage.c b/src/manage.c
index 9c62a66..451c809 100644
--- a/src/manage.c
+++ b/src/manage.c
@@ -320,11 +320,16 @@ scanwins(screen_info *s)
win = add_to_window_list (s, wins[i]);
- PRINT_DEBUG (("map_state: %d\n", attr.map_state));
+ PRINT_DEBUG (("map_state: %s\n",
+ attr.map_state == IsViewable ? "IsViewable":
+ attr.map_state == IsUnviewable ? "IsUnviewable" : "IsUnmapped"));
+ PRINT_DEBUG (("state: %s\n",
+ get_state(win) == IconicState ? "Iconic":
+ get_state(win) == NormalState ? "Normal" : "Other"));
/* Collect mapped and iconized windows. */
if (attr.map_state == IsViewable
- || (attr.map_state == IsUnmapped
+ || (attr.map_state == IsUnmapped
&& get_state (win) == IconicState))
map_window (win);
}
diff --git a/src/split.c b/src/split.c
index 1d276c4..64d5584 100644
--- a/src/split.c
+++ b/src/split.c
@@ -52,6 +52,36 @@ num_frames (screen_info *s)
return count;
}
+void
+cleanup_frame (rp_window_frame *frame)
+{
+ rp_window *last_win;
+ rp_window *win;
+
+ win = find_window_other ();
+ if (win == NULL)
+ {
+ set_frames_window (frame, NULL);
+ return;
+ }
+
+ last_win = set_frames_window (frame, win);
+
+ maximize (win);
+ unhide_window (win);
+
+
+#ifdef MAXSIZE_WINDOWS_ARE_TRANSIENTS
+ if (!win->transient
+ && !(win->hints->flags & PMaxSize
+ && win->hints->max_width < win->scr->root_attr.width
+ && win->hints->max_height < win->scr->root_attr.height))
+#else
+ if (!win->transient)
+#endif
+ hide_others (win);
+}
+
rp_window *
set_frames_window (rp_window_frame *frame, rp_window *win)
{
diff --git a/src/split.h b/src/split.h
index fe2d853..7bf56d3 100644
--- a/src/split.h
+++ b/src/split.h
@@ -24,6 +24,7 @@
int num_frames (screen_info *s);
rp_window *set_frames_window (rp_window_frame *frame, rp_window *win);
+void cleanup_frame (rp_window_frame *frame);
void maximize_all_windows_in_frame (rp_window_frame *frame);
void h_split_frame (rp_window_frame *frame, int pixels);
void v_split_frame (rp_window_frame *frame, int pixels);