diff options
author | sabetts <sabetts> | 2003-02-24 07:44:20 +0000 |
---|---|---|
committer | sabetts <sabetts> | 2003-02-24 07:44:20 +0000 |
commit | 74feea3aa793b13a3582fc25329701a45de01b64 (patch) | |
tree | 62791cbc8dfa5407ea5aa7e7492de4b515b89649 | |
parent | 49ca20c9fc7807d612ef9925c110e8da6c3c1a8f (diff) | |
download | ratpoison-74feea3aa793b13a3582fc25329701a45de01b64.zip |
* src/split.h (cleanup_frame): new protoype
* src/manage.c (scanwins): added better debugging output
* src/events.c (cleanup_frame): move to split.c
(handle_key): ungrab the rat right after we read the key.
* src/actions.h (cmd_tmpwm): new prototype.
* src/actions.c (spawn): return the pid of the child
process. prototype updated.
(cmd_tmpwm): new function
(user_commands): new command, tmp_wm.
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | doc/ratpoison.texi | 8 | ||||
-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 |
9 files changed, 153 insertions, 37 deletions
@@ -1,3 +1,19 @@ +2003-02-23 Shawn Betts <sabetts@sfu.ca> + + * src/split.h (cleanup_frame): new protoype + + * src/manage.c (scanwins): added better debugging output + + * src/events.c (cleanup_frame): move to split.c + (handle_key): ungrab the rat right after we read the key. + + * src/actions.h (cmd_tmpwm): new prototype. + + * src/actions.c (spawn): return the pid of the child + process. prototype updated. + (cmd_tmpwm): new function + (user_commands): new command, tmp_wm. + 2003-02-22 Shawn Betts <sabetts@sfu.ca> * configure.in: don't check for variable argument support in @@ -1,6 +1,10 @@ ratpoison NEWS --- history of user-visible changes. -*- outline -*- * Changes since 1.1.1 +** new command 'tmpwm' +temporarily run a different window manager, then come back to +ratpoison once it has terminated. + ** error and debug reporting The format has been changed to the more standard format used by C compilers. diff --git a/doc/ratpoison.texi b/doc/ratpoison.texi index c5749a1..1e5e16e 100644 --- a/doc/ratpoison.texi +++ b/doc/ratpoison.texi @@ -739,6 +739,14 @@ Turn on or off the startup_message. This is most useful in your When called non-interactively with no arguments, the current setting is returned. +@item tmpwm @var{WM} +Gives control over to another window manager and regains control once +it has terminated. @var{WM} is the path to the new window +manager. This command is useful when you want to temporarily take a +look at another window manager, or program under a different window +manager, but you want to come back to ratpoison when you've finished +your investigation. + @item time Show current time. Disappears after 5 seconds, like all other info bars. In the default setup, the @kbd{C-t a} keystroke is bound to this command. 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); |