diff options
-rw-r--r-- | src/ChangeLog | 15 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/bar.c | 7 | ||||
-rw-r--r-- | src/bar.h | 1 | ||||
-rw-r--r-- | src/conf.h | 16 | ||||
-rw-r--r-- | src/data.h | 16 | ||||
-rw-r--r-- | src/events.c | 162 | ||||
-rw-r--r-- | src/list.c | 51 | ||||
-rw-r--r-- | src/list.h | 2 | ||||
-rw-r--r-- | src/main.c | 12 | ||||
-rw-r--r-- | src/manage.c | 26 | ||||
-rw-r--r-- | src/ratpoison.h | 3 |
12 files changed, 97 insertions, 216 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4a60d19..ab37eac 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,18 @@ +2000-10-17 shawn <sabetts@vcn.bc.ca> + + * manage.c (scanwins): Now only maps visible windows + + * conf.h: Removed keystroke related defines + + * actions.c: Moved all key activated functions here. Added + key_actions array. + + * events.c (unmap_notify): now properly unmaps windows + + * data.h: added ignore_badwindow + + * main.c (handler): added ability to ignore BadWindow errors + 2000-10-15 shawn <sabetts@vcn.bc.ca> * main.c, data.h, events.c: Added ability to kill and hup running diff --git a/src/Makefile.am b/src/Makefile.am index d3af0be..0cc011e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,4 +2,4 @@ bin_PROGRAMS = ratpoison ratpoison_SOURCES = bar.c bar.h conf.h data.h events.c events.h \ input.c input.h list.c list.h main.c manage.c manage.h number.c \ -number.h ratpoison.h +number.h ratpoison.h actions.h actions.c @@ -59,13 +59,6 @@ show_bar (screen_info *s) return 0; } -/* Toggle the display of the program bar */ -void -toggle_bar (screen_info *s) -{ - if (!hide_bar (s)) show_bar (s); -} - static int calc_bar_width (XFontStruct *font) { @@ -21,7 +21,6 @@ #define _BAR_H void update_window_names (screen_info *s); -void toggle_bar (screen_info *s); int show_bar (screen_info *s); int hide_bar (screen_info *s); int bar_y (screen_info *s); @@ -17,22 +17,12 @@ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ +#include "data.h" +#include "actions.h" + #define KEY_PREFIX 't' #define MODIFIER_PREFIX ControlMask -#define KEY_XTERM 'c' -#define KEY_EMACS 'e' -#define KEY_PREVWINDOW 'p' -#define KEY_NEXTWINDOW 'n' -#define KEY_LASTWINDOW 't' /* key to toggle between the current window and the last visitted one */ -#define KEY_TOGGLEBAR 'w' /* key to toggle the display of the program bar */ -#define KEY_DELETE 'k' /* delete a window SHIFT+key will Destroy the window */ -#define KEY_WINBYNAME '\'' /* key to jump to a window by name */ -#define KEY_RENAME 'a' /* key to rename a window. */ - -#define TERM_PROG "xterm" /* command to boot an x term */ -#define EMACS_PROG "emacs" /* command to boot emacs */ - #define BAR_FG_COLOR "Gray60" #define BAR_BG_COLOR "Lightgreen" #define BAR_BOLD_COLOR "Black" /* To indicate the current window */ @@ -31,6 +31,7 @@ typedef struct rp_window rp_window; typedef struct screen_info screen_info; +typedef struct rp_action rp_action; struct rp_window { @@ -56,6 +57,14 @@ struct screen_info Colormap def_cmap; }; +struct rp_action +{ + int key; + int state; + void *data; /* misc data to be passed to the function */ + void (*func)(void *); +}; + extern rp_window *rp_window_head, *rp_window_tail; extern rp_window *rp_current_window; extern screen_info *screens; @@ -72,9 +81,10 @@ extern Atom wm_delete; extern Atom wm_take_focus; extern Atom wm_colormaps; -/* Set to 1 to indicate that the WM should exit at it's earliest - convenience. */ -extern int exit_signal; +/* When unmapping or deleting windows, it is sometimes helpful to + ignore a bad window when attempting to clean the window up. This + does just that when set to 1 */ +extern int ignore_badwindow; /* Arguments passed to ratpoison. */ extern char **myargv; diff --git a/src/events.c b/src/events.c index f40aed7..d7a2c1d 100644 --- a/src/events.c +++ b/src/events.c @@ -19,39 +19,17 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xatom.h> -#include <X11/keysymdef.h> +#include <X11/keysym.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <sys/wait.h> #include "ratpoison.h" extern Display *dpy; void -spawn(char *prog) -{ - /* - * ugly dance to avoid leaving zombies. Could use SIGCHLD, - * but it's not very portable. - */ - if (fork() == 0) { - if (fork() == 0) { - putenv(DisplayString(dpy)); - execlp(prog, prog, 0); - fprintf (stderr, "exec %s ", prog); - perror(" failed"); - exit(EXIT_FAILURE); - } - exit(0); - } - wait((int *) 0); - PRINT_DEBUG ("spawned %s\n", prog); -} - -void new_window (XCreateWindowEvent *e) { rp_window *win; @@ -81,11 +59,28 @@ unmap_notify (XEvent *ev) if (s && win) { + long data[2] = { WithdrawnState, None }; + /* Give back the window number. the window will get another one, if it in remapped. */ return_window_number (win->number); win->number = -1; win->state = STATE_UNMAPPED; + + /* Update the state of the actual window */ + XRemoveFromSaveSet (dpy, win->w); + XChangeProperty(dpy, win->w, wm_state, wm_state, 32, + PropModeReplace, (unsigned char *)data, 2); + + ignore_badwindow = 1; + XSync(dpy, False); + ignore_badwindow = 0; + + if (rp_current_window == win) + { + last_window (NULL); + } + update_window_names (s); } } @@ -165,7 +160,7 @@ destroy_window (XDestroyWindowEvent *ev) if (last_destroy_event && switch_window_pending) { - last_window (); + last_window (NULL); switch_window_pending = 0; } } @@ -200,7 +195,7 @@ configure_request (XConfigureRequestEvent *e) } else if (e->detail == Below && win == rp_current_window) { - last_window (); + last_window (NULL); } } @@ -208,33 +203,6 @@ configure_request (XConfigureRequestEvent *e) } } -void -delete_window () -{ - XEvent ev; - int status; - - if (rp_current_window == NULL) return; - - ev.xclient.type = ClientMessage; - ev.xclient.window = rp_current_window->w; - ev.xclient.message_type = wm_protocols; - ev.xclient.format = 32; - ev.xclient.data.l[0] = wm_delete; - ev.xclient.data.l[1] = CurrentTime; - - status = XSendEvent(dpy, rp_current_window->w, False, 0, &ev); - if (status == 0) fprintf(stderr, "ratpoison: delete window failed\n"); -} - -void -kill_window () -{ - if (rp_current_window == NULL) return; - - XKillClient(dpy, rp_current_window->w); -} - static void client_msg (XClientMessageEvent *ev) { @@ -255,19 +223,9 @@ client_msg (XClientMessageEvent *ev) } static void -goto_win_by_name (screen_info *s) -{ - char winname[100]; - - get_input (s, "Window: ", winname, 100); - PRINT_DEBUG ("user entered: %s\n", winname); - - goto_window_name (winname); -} - -static void handle_key (screen_info *s) { + const rp_action *i; int revert; Window fwin; XEvent ev; @@ -277,10 +235,29 @@ handle_key (screen_info *s) XGetInputFocus (dpy, &fwin, &revert); XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime); - XMaskEvent (dpy, KeyPressMask, &ev); + + do + { + XMaskEvent (dpy, KeyPressMask, &ev); + keysym = XLookupKeysym((XKeyEvent *) &ev, 0); + } while (keysym == XK_Shift_L + || keysym == XK_Shift_R + || keysym == XK_Control_L + || keysym == XK_Control_R + || keysym == XK_Caps_Lock + || keysym == XK_Shift_Lock + || keysym == XK_Meta_L + || keysym == XK_Meta_R + || keysym == XK_Alt_L + || keysym == XK_Alt_R + || keysym == XK_Super_L + || keysym == XK_Super_R + || keysym == XK_Hyper_L + || keysym == XK_Hyper_R); /* ignore modifier keypresses. */ + XSetInputFocus (dpy, fwin, revert, CurrentTime); - if (XLookupKeysym((XKeyEvent *) &ev, 0) == KEY_PREFIX && !ev.xkey.state) + if (keysym == KEY_PREFIX && !ev.xkey.state) { /* Generate the prefix keystroke for the app */ ev.xkey.window = fwin; @@ -290,54 +267,17 @@ handle_key (screen_info *s) return; } - keysym = XLookupKeysym((XKeyEvent *) &ev, 0); - - if (keysym == KEY_TOGGLEBAR) - { - toggle_bar (s); - return; - } - - /* All functions tested for after this point hide the program bar. */ + /* All functions hide the program bar. */ hide_bar (s); - if (keysym >= '0' && keysym <= '9') - { - goto_window_number (XLookupKeysym((XKeyEvent *) &ev, 0) - '0'); - hide_bar (s); - return; - } - - switch (keysym) + for (i = key_actions; i->key != 0; i++) { - case KEY_XTERM: - spawn (TERM_PROG); - break; - case KEY_EMACS: - spawn (EMACS_PROG); - break; - case KEY_PREVWINDOW: - prev_window (); - break; - case KEY_NEXTWINDOW: - next_window (); - break; - case KEY_LASTWINDOW: - last_window (); - break; - case KEY_WINBYNAME: - goto_win_by_name (s); - break; - case KEY_RENAME: - rename_current_window (); - break; - case KEY_DELETE: - if (ev.xkey.state & ShiftMask) kill_window (); - else delete_window (); - break; - default: - PRINT_DEBUG ("Unknown key command '%c'\n", (char)keysym); - break; + if (keysym == i->key) + if (i->state == -1 || ev.xkey.state == i->state) + { + (*i->func)(i->data); + break; + } } } @@ -435,7 +375,7 @@ delegate_event (XEvent *ev) break; case KeyPress: - PRINT_DEBUG ("KeyPress\n"); + PRINT_DEBUG ("KeyPress %d %d\n", ev->xkey.keycode, ev->xkey.state); key_press (ev); break; @@ -112,36 +112,6 @@ init_window_list () rp_current_window = NULL; } -void -next_window () -{ - if (rp_current_window != NULL) - { - rp_current_window = rp_current_window->next; - if (rp_current_window == NULL) - { - rp_current_window = rp_window_head; - } - if (rp_current_window->state == STATE_UNMAPPED) next_window (); - set_active_window (rp_current_window); - } -} - -void -prev_window () -{ - if (rp_current_window != NULL) - { - set_current_window (rp_current_window->prev); - if (rp_current_window == NULL) - { - rp_current_window = rp_window_tail; - } - if (rp_current_window->state == STATE_UNMAPPED) prev_window (); - set_active_window (rp_current_window); - } -} - rp_window * find_window_by_number (int n) { @@ -196,20 +166,6 @@ goto_window_name (char *name) set_active_window (rp_current_window); } -void -goto_window_number (int n) -{ - rp_window *win; - - if ((win = find_window_by_number (n)) == NULL) - { - return; - } - - rp_current_window = win; - set_active_window (rp_current_window); -} - rp_window * find_last_accessed_window () { @@ -240,13 +196,6 @@ find_last_accessed_window () } void -last_window () -{ - rp_current_window = find_last_accessed_window (); - set_active_window (rp_current_window); -} - -void set_active_window (rp_window *rp_w) { static int counter = 1; /* increments every time this function @@ -32,4 +32,6 @@ void set_active_window (rp_window *rp_w); void set_current_window (rp_window *win); void goto_window_number (int n); void goto_window_name (char *name); +rp_window *find_last_accessed_window (); +rp_window *find_window_by_number (int n); #endif /* _LIST_H */ @@ -45,8 +45,9 @@ Atom rp_kill; screen_info *screens; int num_screens; Display *dpy; -int exit_signal = 0; /* Set by the signal handler. if this - is set, quit. */ + +int ignore_badwindow = 0; + static XFontStruct *font; char **myargv; @@ -57,7 +58,7 @@ static struct option ratpoison_longopts[] = { {"help", no_argument, 0, 'h'}, {"restart", no_argument, 0, 'r'}, {"kill", no_argument, 0, 'k'}, {0, 0, 0, 0} }; -static char ratpoison_opts[] = "hv"; +static char ratpoison_opts[] = "hvrk"; void sighandler () @@ -145,11 +146,12 @@ handler (Display *d, XErrorEvent *e) exit(EXIT_FAILURE); } + if (ignore_badwindow && e->error_code == BadWindow) return 0; + XGetErrorText (d, e->error_code, error_msg, sizeof (error_msg)); fprintf (stderr, "ratpoison: %s!\n", error_msg); - return 0; - /* exit (EXIT_FAILURE); */ + exit (EXIT_FAILURE); } void diff --git a/src/manage.c b/src/manage.c index 592200a..9027b80 100644 --- a/src/manage.c +++ b/src/manage.c @@ -101,29 +101,6 @@ update_window_name (rp_window *win) return 1; } -void -rename_current_window () -{ - char winname[100]; - - if (rp_current_window == NULL) return; - - get_input (rp_current_window->scr, "Name: ", winname, 100); - PRINT_DEBUG ("user entered: %s\n", winname); - - free (rp_current_window->name); - rp_current_window->name = malloc (sizeof (char) * strlen (winname) + 1); - if (rp_current_window->name == NULL) - { - PRINT_ERROR ("Out of memory\n"); - exit (EXIT_FAILURE); - } - strcpy (rp_current_window->name, winname); - rp_current_window->named = 1; - - /* Update the program bar. */ - update_window_names (rp_current_window->scr); -} void manage (rp_window *win, screen_info *s) @@ -170,7 +147,8 @@ scanwins(screen_info *s) if (attr.override_redirect != True) { win = add_to_window_list (s, wins[i]); - if (attr.map_state != IsUnmapped) manage (win, s); + PRINT_DEBUG ("map_state: %d\n", attr.map_state); + if (attr.map_state == IsViewable) manage (win, s); } } XFree((void *) wins); /* cast is to shut stoopid compiler up */ diff --git a/src/ratpoison.h b/src/ratpoison.h index 089fcb9..e5d0a35 100644 --- a/src/ratpoison.h +++ b/src/ratpoison.h @@ -24,6 +24,9 @@ # include <config.h> #endif /* HAVE_CONFIG_H */ +#include <stdlib.h> +#include <stdio.h> + /* Some error reporting macros */ #define PRE_PRINT_LOCATION fprintf (stderr, "%s:%s():%d: ", __FILE__, __FUNCTION__, __LINE__); #define PRINT_ERROR(format, args...) \ |