diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/actions.c | 83 | ||||
-rw-r--r-- | src/actions.h | 3 | ||||
-rw-r--r-- | src/events.c | 36 | ||||
-rw-r--r-- | src/manage.c | 9 | ||||
-rw-r--r-- | src/split.c | 30 | ||||
-rw-r--r-- | src/split.h | 1 |
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); |