diff options
Diffstat (limited to 'src/events.c')
-rw-r--r-- | src/events.c | 162 |
1 files changed, 51 insertions, 111 deletions
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; |