anchor.diff:  (defparameter *quit* (compile-shortcut :shift #\q) "Shortcut to quit")
   (defparameter *move* (compile-shortcut :mod-1 1) "Mouse button to move a window")
   (defparameter *resize* (compile-shortcut :mod-1 3) "Mouse button to resize a window")
  -(defparameter *close* (compile-shortcut :control :mod-1 2)
  -  "Mouse button to close a window")
  +(defparameter *close* (compile-shortcut :control :mod-1 2) "Mouse button to close a window")
   
   (defun send-prefix (window)
     (send-event window :key-press (make-event-mask :key-press)
                        :window window
                        :code (code *prefix*)
  -                     :state (state *prefix*)))
  +                     :state (first (states *prefix*))))
  +
  +(defun grab-it (shortcut &key inverse-p)
  +  "Grab a given key or button shortcut in all its
  +states. Use :inverse-p key to ungrab. "
  +  (let ((code (code shortcut)))
  +    (if (< code 4)                      ;it's a mouse button
  +	(if inverse-p
  +            (dolist (s (states shortcut))
  +              (ungrab-button *root* code :modifiers s))
  +            (dolist (s (states shortcut))
  +              (grab-button *root* code '(:button-press) :modifiers s)))
  +        (let ((grab/ungrab (if inverse-p #'ungrab-key #'grab-key)))
  +          (dolist (s (states shortcut))
  +            (funcall grab/ungrab *root* code :modifiers s))))))
   
   (defun grab-all ()
     "Grab prefix and mouse buttons on root."
  -  (grab-key *root* (code *prefix*) :modifiers (state *prefix*))
  +  (grab-it *prefix*)
     (dolist (b (list *move* *resize* *close*))
  -    (grab-button *root* (code b) '(:button-press) :modifiers (state b))))
  +    (grab-it b)))
   
   (defun ungrab-all ()
     (dolist (b (list *move* *resize* *close*))
  -    (ungrab-button *root* (code b) :modifiers (state b)))
  -  (ungrab-key *root* (code *prefix*) :modifiers (state *prefix*)))
  +    (grab-it b :inverse-p t))
  +  (grab-it *prefix* :inverse-p t))
   
   (defun load-rc ()
     (ungrab-all)
  
positive.code:                           #'(lambda (w) (search "Gimp" (xclass w) :test #'char-equal)))
    "List of predicates against which windows are grouped")
  
  (defstruct (shortcut (:conc-name)) (state 0) (code 0))
  
  (defmethod print-object ((sc shortcut) stream)
    (let ((state (make-state-keys (state sc)))
          (code (keycode->character *display* (code sc) 0)))
      (format stream "(~{~s ~}~s)" state code)))
  
  (defun compile-shortcut (&rest l)
    "Compile a shortcut. Usage: (compile-shortcut :control #\t) for a
  keyboard shortcut or (compile-shortcut :mod-1 1) for a mouse
  shortcut."
    (let ((k (car (last l)))
          (state (apply #'make-state-mask (butlast l))))
      (if (characterp k)
          (let ((code (car (last (multiple-value-list
                                  (keysym->keycodes *display* (car (character->keysyms k))))))))
            (make-shortcut :state state :code code))
          (make-shortcut :state state :code k))))
  
  (defun sc= (sc state code) (and (= (code sc) code) (= (state sc) state)))
  (defun sc-equal (sc1 sc2) (equalp sc1 sc2))
  
  (defmacro defshortcut (key &body body)
  
negative.code:            (cond ((sc= *quit* state code) 'quit)
                   (t
                    (cond ((sc= *prefix* state code) (focus *last*))
                          ((= code (code *prefix*)) (send-prefix *curr*))
                          (t (let ((fn (cdr (assoc-if #'(lambda (sc) (sc= sc state code))
                                                      *shortcuts*))))
                               (when (functionp fn) (funcall fn)))))
  