Location: lg@xxxxxxxxxxxxxx http://arch.xwem.org/2005/
Revision: xwem--main--2.1--patch-9
Archive: lg@xxxxxxxxxxxxxx
Creator: Zajcev Evgeny <lg@xxxxxxxx>
Date: Sun Jan 30 23:53:05 MSK 2005
Standard-date: 2005-01-30 20:53:05 GMT
Modified-files: Makefile extra/xwem-smartmods.el
lisp/xwem-clgen.el lisp/xwem-clients.el
lisp/xwem-edmacro.el lisp/xwem-focus.el
lisp/xwem-help.el lisp/xwem-keyboard.el
lisp/xwem-keydefs.el lisp/xwem-keymacro.el
lisp/xwem-misc.el lisp/xwem-strokes.el
New-patches: lg@xxxxxxxxxxxxxx/xwem--main--2.1--patch-9
Summary: Keyboard macroses enhancements, EXPERIMENTAL. Minor bug fixes.
Keywords: keymacros, synth, experiment
* lisp/xwem-clgen.el (xwem-clgen-apply-state): [bug fix] Reparent only
when there is real need.
* lisp/xwem-clients.el (xwem-dummy-client-init): [bug fix] Set manage
type to 'dummy for dummy client.
* lisp/xwem-edmacro.el (xwem-edmacro-store): [fix] use
`xwem-keymacro-macros-stack' now.
* lisp/xwem-edmacro.el (xwem-edmacro-edit-kbd-macro): [fix] Ditto.
* lisp/xwem-keyboard.el (xwem-keyboard-use-syth-events): [new] New
variable to customize keys sending mechanism. Set it to non-nil to use
XSendEvent.
* lisp/xwem-keyboard.el (xwem-kbd-initialize-modifiers): [fixes]
According to X PROTO Shift, Lock, Control modifiers bits are fixated,
so any key, not only Control_L and Control_R can be a control modifier.
* lisp/xwem-keyboard.el (xwem-key-send-xtest-internal): [new] Old
xwem-key-sendseq-internal.
* lisp/xwem-keyboard.el (xwem-key-send-xtest): [new] Send emacs keys
using XTEST sending mechanism.
* lisp/xwem-keyboard.el (xwem-key-send-synth): [new] Send emacs keys
using XSendEvent sending mechanism.
* lisp/xwem-keyboard.el (xwem-kbd-add-pending-keys): [new] Add pending
keys input to some client.
* lisp/xwem-keyboard.el (xwem-cl-apply-pending-keys): [new] Deffered
applier for `xwem-kbd-add-pending-keys'.
* lisp/xwem-keyboard.el (xwem-kbd-apply-grabbing): [bug fix] Use dummy
client to grab keyboard on.
* lisp/xwem-keydefs.el (bindings): [new] `H-x 4 H-[', `H-x 4 H-]', `H-o
H-[', `H-o H-]' for clswi commands on other window.
* lisp/xwem-keymacro.el (xwem-keymacro-show-macro): [change] nil now.
* lisp/xwem-keymacro.el (xwem-keymacro-last-kbd-macro): [removed]
* lisp/xwem-keymacro.el (xwem-keymacro-macros-stack): [new] Keyboard
macroses stack.
* lisp/xwem-keymacro.el (xwem-keymacro-macros-depth): [new] Current depth
in `xwem-keymacro-macros-stack'.
* lisp/xwem-keymacro.el (xwem-keymacro-execute-keys): [change]
Non-deffered variant. NOTE: needs workaround xwem minibuffer reading
blocking.
* lisp/xwem-keymacro.el (xwem-keymacro-play-last): [fix] Now we can play
keyboard macro while recording keyboard macro.
* lisp/xwem-keymacro.el (xwem-keymacro-init): [addon] Advise
`xwem-key-send-xtest-internal' to disable/enable recording context
while recording keyboard macro.
* lisp/xwem-misc.el (xwem-misc-init): [addon] Advise `XReparentWindow' to
save last xparent for xwindow.
* lisp/xwem-misc.el (xwem-misc-xwin-last-xparent): [new] Return last
xparent for XWIN.
* added files
{arch}/xwem/xwem--main/xwem--main--2.1/lg@xxxxxxxxxxxxxx/patch-log/patch-9
* modified files
--- orig/Makefile
+++ mod/Makefile
@@ -220,5 +220,6 @@
#### DEPS
lisp/xwem-frame.elc: lisp/xwem-struct.elc lisp/xwem-misc.elc
+extra/xwem-smartmods.elc: lisp/xwem-keyboard.elc
.PHONY: clean distclean ./lisp/xwem-version.el
--- orig/extra/xwem-smartmods.el
+++ mod/extra/xwem-smartmods.el
@@ -129,7 +129,7 @@
(setq sm (assq (X-Event-xkey-keycode xev)
xwem-smart-modifiers)))
;; Send smart keycode
- (xwem-key-sendseq-1
+ (xwem-key-send-xtest-internal
(list (cons X-Xtest-KeyPress (cdr sm))
(cons X-Xtest-KeyRelease (cdr sm)))))
--- orig/lisp/xwem-clgen.el
+++ mod/lisp/xwem-clgen.el
@@ -35,6 +35,7 @@
(require 'xwem-load)
(require 'xwem-manage)
+(require 'xwem-misc)
;;; Customisation
(defgroup xwem-clgen nil
@@ -306,13 +307,18 @@
(xwem-clgen-refit cl)
(xwem-cl-apply-xgeom cl))
+;;; NOTE: make sure XReparentWindow adviced by xwem-misc to save last
+;; xparent.
(define-xwem-deffered xwem-clgen-apply-state (cl)
"Apply CL's state to life for generic client CL."
(when (and (xwem-cl-p cl)
(eq (xwem-cl-manage-type cl) 'generic))
(cond ((eq (xwem-cl-state cl) 'active)
(xwem-clgen-refit cl)
- (when (xwem-cl-frame cl)
+ (when (and (xwem-cl-frame cl)
+ (not (X-Win-equal
+ (xwem-misc-xwin-last-xparent (xwem-cl-xwin cl))
+ (xwem-frame-xwin (xwem-cl-frame cl)))))
(XReparentWindow (xwem-dpy) (xwem-cl-xwin cl)
(xwem-frame-xwin (xwem-cl-frame cl))
(X-Geom-x (xwem-cl-xgeom cl))
@@ -322,16 +328,20 @@
(XMapWindow (xwem-dpy) (xwem-cl-xwin cl)))
((eq (xwem-cl-state cl) 'inactive)
- (XReparentWindow (xwem-dpy) (xwem-cl-xwin cl)
- (xwem-cl-xparent cl) 0 0)
- (XLowerWindow (xwem-dpy) (xwem-cl-xwin cl))
- (XUnmapWindow (xwem-dpy) (xwem-cl-xwin cl)))
+ (unless (X-Win-equal (xwem-misc-xwin-last-xparent (xwem-cl-xwin cl))
+ (xwem-cl-xparent cl))
+ (XReparentWindow (xwem-dpy) (xwem-cl-xwin cl)
+ (xwem-cl-xparent cl) 0 0)
+ (XLowerWindow (xwem-dpy) (xwem-cl-xwin cl))
+ (XUnmapWindow (xwem-dpy) (xwem-cl-xwin cl))))
((eq (xwem-cl-state cl) 'iconified)
- (XReparentWindow (xwem-dpy) (xwem-cl-xwin cl)
- (xwem-cl-xparent cl) 0 0)
- (XLowerWindow (xwem-dpy) (xwem-cl-xwin cl))
- (XUnmapWindow (xwem-dpy) (xwem-cl-xwin cl))))
+ (unless (X-Win-equal (xwem-misc-xwin-last-xparent (xwem-cl-xwin cl))
+ (xwem-cl-xparent cl))
+ (XReparentWindow (xwem-dpy) (xwem-cl-xwin cl)
+ (xwem-cl-xparent cl) 0 0)
+ (XLowerWindow (xwem-dpy) (xwem-cl-xwin cl))
+ (XUnmapWindow (xwem-dpy) (xwem-cl-xwin cl)))))
))
(defun xwem-activate-generic (cl &optional type)
--- orig/lisp/xwem-clients.el
+++ mod/lisp/xwem-clients.el
@@ -1581,7 +1581,7 @@
(progn
(xwem-kbd-stop-grabbing)
(xwem-kbd-force-mods-release)
- (xwem-key-send-ekeys msg))
+ (xwem-kbd-add-pending-keys msg))
(xwem-message 'info "%s" msg))))
@@ -2133,6 +2133,7 @@
(XCreateWindow (xwem-dpy) nil 0 0 1 1 0 nil nil nil
(make-X-Attr :override-redirect t))
'(dummy-client-p t ignore-has-input-p t)))
+ (setf (xwem-cl-manage-type xwem-dummy-client) 'dummy)
(XSelectInput (xwem-dpy) (xwem-cl-xwin xwem-dummy-client)
(Xmask-or XM-KeyPress XM-KeyRelease
--- orig/lisp/xwem-edmacro.el
+++ mod/lisp/xwem-edmacro.el
@@ -77,8 +77,8 @@
(defun xwem-edmacro-store (mac)
"Store new keyboard macro MAC."
(setq mac (key-sequence-list-description mac))
- (cond ((eq xwem-edmacro-store-place 'xwem-keymacro-last-kbd-macro)
- (setq xwem-keymacro-last-kbd-macro mac)
+ (cond ((eq xwem-edmacro-store-place 'xwem-keymacro-macros-stack)
+ (setcar xwem-keymacro-macros-stack mac)
(xwem-message 'info "New keymacro stored to `%S'"
xwem-edmacro-store-place))
@@ -117,8 +117,8 @@
(setq xwem-evs (cond ((eq xwem-cmd 'xwem-keymacro-play-last)
(setq xwem-edmacro-store-place
- 'xwem-keymacro-last-kbd-macro)
- (or xwem-keymacro-last-kbd-macro []))
+ 'xwem-keymacro-macros-stack)
+ (or (car xwem-keymacro-macros-stack) []))
((vectorp xwem-cmd)
(setq xwem-edmacro-store-place xwem-keys)
--- orig/lisp/xwem-focus.el
+++ mod/lisp/xwem-focus.el
@@ -65,11 +65,13 @@
"Pop value from `xwem-focus-stack'."
(pop xwem-focus-stack))
+;;;###xwem-autoload
(defun xwem-focus-push-set (xwin)
"Push current focus to `xwem-focus-stack' and set focus to XWIN."
(xwem-focus-push)
(XSetInputFocus (xwem-dpy) xwin X-RevertToParent))
+;;;###xwem-autoload
(defun xwem-focus-pop-set ()
"Pop from `xwem-focus-stack' and set focus."
(let ((xwin (xwem-focus-pop)))
--- orig/lisp/xwem-help.el
+++ mod/lisp/xwem-help.el
@@ -272,7 +272,7 @@
dfn (sorted-key-descriptions keys))
(format "%s is not on any keys" dfn))))
(if paste
- (xwem-key-send-ekeys msg)
+ (xwem-kbd-add-pending-keys msg)
(xwem-message 'info msg))))
--- orig/lisp/xwem-keyboard.el
+++ mod/lisp/xwem-keyboard.el
@@ -160,6 +160,17 @@
:group 'xwem-keyboard
:group 'xwem-hooks)
+(defcustom xwem-keyboard-use-syth-events nil
+ "*Non-nil mean use XSendEvent instead of XTEST's FakeInput.
+Useful to set it to non-nil when using sticky modifiers or in any
+other case when xwem can't properly force modifiers releasing.
+However if having `xwem-keyboard-use-syth-events' to non-nil, make
+sure you've configured clients to accept synthetic X events (f.i. set
+`x-allow-sendevents' to non-nil to make XEmacs accept synthetic
+events)."
+ :type 'boolean
+ :group 'xwem-keyboard)
+
;;; Internal variables
;;;###autoload
@@ -189,8 +200,9 @@
Internal variable, do not modify.")
(defvar xwem-xmods-mapping nil
- "X ModifierMapping fetched from X server.
-Internal variable, do not modify.")
+ "List of keycodes for modifiers.
+Corresponds to Shift, Lock,Control, Mod1, Mod2, Mod3, Mod4, and Mod5, in order.
+INTERNAL VARIABLE, do not modify.")
;;;###xwem-autoload
(defvar xwem-event-client nil "Client where last key/mouse event occured.")
@@ -417,7 +429,7 @@
(if (= (length xwem-this-command-keys) 1)
;; Self insert command allowed only for normal clients
(unless (xwem-dummy-client-p (xwem-cl-selected))
- (xwem-key-send-ekeys
+ (xwem-kbd-add-pending-keys
(make-vector (prefix-numeric-value arg) xwem-last-event)))
(error 'xwem-error (format "%s is undefined" (key-description
xwem-this-command-keys)))))
@@ -620,11 +632,7 @@
;;;###xwem-autoload
(defun xwem-kbd-kcode-modifier-p (kcode)
"Return non-nil if key code KCODE is modifier."
- (let ((mods (car (last xwem-xmods-mapping))))
- (while (and mods
- (not (member kcode (car mods))))
- (setq mods (cdr mods)))
- (car mods)))
+ (member kcode (apply 'append xwem-xmods-mapping)))
(defun xwem-kbd-adjust-keycode (keycode modifiers)
"Convert KEYCODE to keysym according to MODIFIERS."
@@ -758,13 +766,9 @@
;;{{{ [-] Sending
-(defvar xwem-private-xtest-keycode-sequence nil)
-
-;; Sending(using XTEST)
-(defun xwem-key-sendseq-1 (&optional keycode-seq)
+;; Sending (using XTEST)
+(defun xwem-key-send-xtest-internal (&optional keycode-seq)
"Emulate key presses/releases of KEYCODE-SEQ sequence using XTEST extension."
- (unless keycode-seq
- (setq keycode-seq xwem-private-xtest-keycode-sequence ))
(mapc (lambda (ksel)
(let ((ktype (car ksel))
(kcode nil)
@@ -775,21 +779,9 @@
(t (setq kcode (cdr ksel))
(setq ktime X-CurrentTime)))
(X-XTest-FakeInput (xwem-dpy) ktype kcode X-None 0 0 ktime)))
- keycode-seq)
-
- (when (eq keycode-seq xwem-private-xtest-keycode-sequence)
- (setq xwem-private-xtest-keycode-sequence nil)))
-
-(defun xwem-key-sendseq (keycode-seq)
- "Emulate KEYCODE-SEQ.
-KEYCODE-SEQ is list of cons cells where car is event type and cdr is keycode.
-Supported event types are `X-Xtest-KeyPress' and `X-Xtest-KeyRelease'."
- (setq xwem-private-xtest-keycode-sequence
- (append xwem-private-xtest-keycode-sequence keycode-seq))
- (xwem-add-hook-post-deffering 'xwem-key-sendseq-1 t))
+ keycode-seq))
-;;;###xwem-autoload
-(defun xwem-key-send-ekeys (keys)
+(defun xwem-key-send-xtest (keys)
"Send Emacs key sequence KEYS using XTEST extension."
(let (lseq)
(mapc (lambda (key)
@@ -798,27 +790,66 @@
(xwem-kbd-emod->kcode mm))
(butlast key)))
- ;; Now calculade key CODE maybe add shift modifier
- (setq code (xwem-kbd-xksym->xkcode
- (xwem-kbd-emacs->xksym (car (last key)))))
- (setq mods (nconc mods (mapcar (lambda (mm)
- (xwem-kbd-emod->kcode mm))
- (cdr code))))
- (setq code (car code))
-
- (mapc (lambda (mod)
- (setq lseq (cons (cons X-Xtest-KeyPress mod) lseq)))
- mods)
- (setq lseq (cons (cons X-Xtest-KeyPress code) lseq))
- (setq lseq (cons (cons X-Xtest-KeyRelease code) lseq))
- (mapc (lambda (mod)
- (setq lseq (cons (cons X-Xtest-KeyRelease mod) lseq)))
- mods)
- ))
+ ;; Now calculade key CODE maybe add shift modifier
+ (setq code (xwem-kbd-xksym->xkcode
+ (xwem-kbd-emacs->xksym (car (last key)))))
+ (setq mods (nconc mods (mapcar (lambda (mm)
+ (xwem-kbd-emod->kcode mm))
+ (cdr code))))
+ (setq code (car code))
+
+ (mapc (lambda (mod)
+ (setq lseq (cons (cons X-Xtest-KeyPress mod) lseq)))
+ mods)
+ (setq lseq (cons (cons X-Xtest-KeyPress code) lseq))
+ (setq lseq (cons (cons X-Xtest-KeyRelease code) lseq))
+ (mapc (lambda (mod)
+ (setq lseq (cons (cons X-Xtest-KeyRelease mod) lseq)))
+ mods)
+ ))
(key-sequence-list-description keys))
(setq lseq (nreverse lseq))
- (xwem-key-sendseq lseq)))
+ (xwem-key-send-xtest-internal lseq)))
+
+;; Sending (using XSendEvent)
+(defun xwem-key-send-synth (keys &optional client)
+ "Send synthesize KEYS to CLIENT.
+If CLIENT is ommited, selected client is used."
+ (unless client
+ (setq client (xwem-cl-selected)))
+
+ (when (xwem-cl-alive-p client)
+ ;; Fix KEYS
+ (setq keys (key-sequence-list-description keys))
+
+ (let (keycode keymods)
+ (mapc (lambda (key)
+ (setq keymods (butlast key))
+ ;; Now calculade key KEYCODE maybe add shift modifier
+ (setq keycode (xwem-kbd-xksym->xkcode
+ (xwem-kbd-emacs->xksym (car (last key)))))
+ (setq keymods (nconc keymods (cdr keycode)))
+ (setq keycode (car keycode))
+
+ (XSendEvent (xwem-dpy) (xwem-cl-xwin client)
+ nil XM-KeyPress
+ (X-Create-message
+ (list [1 X-KeyPress] ;type
+ [1 keycode] ;detail
+ [2 2806] ; XXX seq
+ [4 X-CurrentTime] ; time
+ [4 (X-Win-id (xwem-rootwin))] ; root
+ [4 (X-Win-id (xwem-cl-xwin client))] ; event
+ [4 X-None] ; child
+ [2 0] ; root-x
+ [2 0] ; root-y
+ [2 0] ; event-x
+ [2 0] ; event-y
+ [2 (xwem-kbd-emods->xmodmask keymods)] ; state
+ [1 t] ; same-screen
+ [1 nil]))))
+ keys))))
;;;###xwem-autoload
(defun xwem-kbd-wait-key-release (keycode)
@@ -847,22 +878,65 @@
;;;###xwem-autoload
-(defun xwem-kbd-force-mods-release ()
- "Force release of some modifiers."
- (let* ((xmods (car (last xwem-xmods-mapping)))
- (mods (list (nth 0 xmods) ; shift
- (nth 2 xmods) ; control
- (nth 3 xmods) ; meta
- (nth 5 xmods) ; hyper
- (nth 6 xmods)))) ; super
- (xwem-key-sendseq-1
- (mapcar (lambda (el) (cons X-Xtest-KeyRelease el))
- (delete 0 (mapcar 'car mods))))))
+(defun xwem-kbd-force-mods-release (&optional mods)
+ "Force release of MODS modifiers."
+ (xwem-key-send-xtest-internal
+ (mapcar (lambda (el) (cons X-Xtest-KeyRelease el))
+ (apply 'append
+ (mapcar (lambda (mod)
+ (get mod 'x-key-codes))
+ (or mods '(shift control meta super hyper)))))))
(defun xwem-kbd-wait-button-release (button)
"Wait for BUTTON for release."
)
+(define-xwem-deffered xwem-cl-apply-pending-keys (cl)
+ "Apply pending keys to CL."
+ (when (and (xwem-cl-alive-p cl)
+ (xwem-cl-get-sys-prop cl 'pending-keys))
+ (if xwem-keyboard-use-syth-events
+ ;; Using XSendEvent
+ (xwem-key-send-synth (xwem-cl-get-sys-prop cl 'pending-keys) cl)
+
+ ;; Using XTEST
+ (let ((xattr (XGetWindowAttributes (xwem-dpy) (xwem-cl-xwin cl)))
+ qt)
+ (unless (= (X-Attr-mapstate xattr) X-Viewable)
+ (setq qt (XQueryTree (xwem-dpy) (xwem-cl-xwin cl)))
+ ;; Make CL viewable
+ (XReparentWindow (xwem-dpy) (xwem-cl-xwin cl)
+ (xwem-cl-xwin (xwem-dummy-client)) 0 0)
+ (XMapWindow (xwem-dpy) (xwem-cl-xwin cl)))
+
+ (xwem-focus-push-set (xwem-cl-xwin cl))
+ (xwem-key-send-xtest (xwem-cl-get-sys-prop cl 'pending-keys))
+ (xwem-focus-pop-set)
+ (XFlush (xwem-dpy))
+
+ (unless (= (X-Attr-mapstate xattr) X-Viewable)
+ ;; Restore mapping
+ (when (= (X-Attr-mapstate xattr) X-Unmapped)
+ (XUnmapWindow (xwem-dpy) (xwem-cl-xwin cl)))
+ ;; Restore parent back to its parent
+ (XReparentWindow (xwem-dpy) (xwem-cl-xwin cl) (nth 3 qt)
+ (X-Geom-x (xwem-cl-xgeom cl))
+ (X-Geom-y (xwem-cl-xgeom cl))))))
+
+ ;; Remove pending keys
+ (xwem-cl-rem-sys-prop cl 'pending-keys)))
+
+;;;###xwem-autoload
+(defun xwem-kbd-add-pending-keys (keys &optional cl)
+ "Add KEYS as pending to be pressed in CL.
+If CL is ommited selected client considered."
+ (unless cl
+ (setq cl (xwem-cl-selected)))
+ (xwem-cl-put-sys-prop cl 'pending-keys
+ (vconcat (xwem-cl-get-sys-prop cl 'pending-keys)
+ keys))
+ (xwem-cl-apply-pending-keys cl))
+
;;}}}
;;{{{ [-] keypress/KeyRelease processing
@@ -1139,7 +1213,8 @@
(cond ((or (vectorp lkm) (stringp lkm))
;; Keyboard macro.
;; Wait for keyrelease, ungrab keyboard, than play it.
- (when (= (X-Event-type xwem-last-xevent) X-KeyPress)
+ (when (and (X-Event-p xwem-last-xevent)
+ (= (X-Event-type xwem-last-xevent) X-KeyPress))
(xwem-kbd-wait-key-release (X-Event-xkey-keycode
xwem-last-xevent)))
(xwem-kbd-stop-grabbing)
(xwem-keymacro-internal-play lkm (prefix-numeric-value
xwem-prefix-arg)))
@@ -1271,7 +1346,9 @@
"Start/stop grabbing according to `xwem-kbd-now-grabbing'."
(if xwem-kbd-now-grabbing
(unless xwem-executing-kbd-macro
- (XGrabKeyboard (xwem-dpy) (or (xwem-focus-xcurrent) (xwem-rootwin))
nil)
+ (XGrabKeyboard (xwem-dpy) (or (xwem-cl-xwin (xwem-dummy-client))
+ (xwem-rootwin))
+ nil)
(xwem-mouse-grab xwem-kbd-now-grabbing)
(XAllowEvents (xwem-dpy) X-SyncBoth))
(unless xwem-executing-kbd-macro
@@ -1328,15 +1405,10 @@
"Create internal modifier representation to speedup futher work.
Also update `xwem-kbd-evilmasks' if `xwem-kbd-evillocks' is non-nil."
(setq xwem-xmods-mapping
- (XGetModifierMapping (xwem-dpy)))
+ (car (last (XGetModifierMapping (xwem-dpy)))))
- (let* ((ctrls (list (car (xwem-kbd-xksym->xkcode XK-Control-L))
- (car (xwem-kbd-xksym->xkcode XK-Control-R))))
- (alts (list (car (xwem-kbd-xksym->xkcode XK-Alt-L))
+ (let* ((alts (list (car (xwem-kbd-xksym->xkcode XK-Alt-L))
(car (xwem-kbd-xksym->xkcode XK-Alt-R))))
- (locks (list (car (xwem-kbd-xksym->xkcode XK-Caps-Lock))))
- (shifts (list (car (xwem-kbd-xksym->xkcode XK-Shift-L))
- (car (xwem-kbd-xksym->xkcode XK-Shift-R))))
(metas (list (car (xwem-kbd-xksym->xkcode XK-Meta-L))
(car (xwem-kbd-xksym->xkcode XK-Meta-R))))
(hypers (list (car (xwem-kbd-xksym->xkcode XK-Hyper-L))
@@ -1345,33 +1417,46 @@
(car (xwem-kbd-xksym->xkcode XK-Super-R))))
(numlocks (list (car (xwem-kbd-xksym->xkcode XK-NumLock))))
(evils (mapcar (lambda (ks)
- (car (xwem-kbd-xksym->xkcode ks)))
xwem-kbd-evillocks))
- (mlist (mapcar 'truncate (list X-Shift X-Lock X-Control X-Mod1 X-Mod2
- X-Mod3 X-Mod4 X-Mod5)))
- (slist (car (last xwem-xmods-mapping))))
+ (car (xwem-kbd-xksym->xkcode ks)))
+ xwem-kbd-evillocks))
+ (mlist (list X-Mod1 X-Mod2 X-Mod3 X-Mod4 X-Mod5))
+ (slist (nthcdr 3 xwem-xmods-mapping)))
;; Clear modifiers info
(mapc (lambda (mod-sym)
(put mod-sym 'x-key-codes nil)
(put mod-sym 'x-mod-mask nil))
'(shift lock control alt meta hyper super numlock))
-
+
+ ;; Shift
+ (put 'shift 'x-key-codes (nth 0 xwem-xmods-mapping))
+ (put 'shift 'x-mod-mask X-Shift)
+ ;; Lock
+ (put 'lock 'x-key-codes (nth 1 xwem-xmods-mapping))
+ (put 'lock 'x-mod-mask X-Lock)
+ ;; Control
+ (put 'control 'x-key-codes (nth 2 xwem-xmods-mapping))
+ (put 'control 'x-mod-mask X-Control)
+
(while slist
;; Update some private modifier mask
(mapc (lambda (mods mod-sym)
- (when (intersection (car slist) mods)
- (put mod-sym 'x-key-codes mods)
- (put mod-sym 'x-mod-mask (Xmask-or (car mlist)
- (or (get mod-sym
'x-mod-mask) 0)))))
- (list shifts locks ctrls alts metas hypers supers numlocks)
- '(shift lock control alt meta hyper super numlock))
+ (let ((ism (intersection (car slist) mods)))
+ (when ism
+ (put mod-sym 'x-key-codes
+ (nconc ism (get mod-sym 'x-key-codes)))
+ (put mod-sym 'x-mod-mask
+ (Xmask-or (car mlist)
+ (or (get mod-sym 'x-mod-mask) 0))))))
+ (list alts metas hypers supers numlocks)
+ (list 'alt 'meta 'hyper 'super 'numlock))
;; Update Evil locks
(when (intersection (car slist) evils)
(push (car mlist) xwem-kbd-evilmasks))
- (setq slist (cdr slist))
- (setq mlist (cdr mlist)))
+ (setq slist (cdr slist)
+ mlist (cdr mlist)))
;; Hack over Alt-Meta problem
(when (eql (get 'alt 'x-mod-mask) (get 'meta 'x-mod-mask))
--- orig/lisp/xwem-keydefs.el
+++ mod/lisp/xwem-keydefs.el
@@ -356,6 +356,10 @@
(define-key xwem-global-map (xwem-kbd "H-[") 'xwem-clswi-prev)
(define-key xwem-global-map (xwem-kbd "H-}") 'xwem-clswi-next-other-window)
(define-key xwem-global-map (xwem-kbd "H-{") 'xwem-clswi-prev-other-window)
+(define-key xwem-global-map (xwem-kbd "H-x 4 H-]")
'xwem-clswi-next-other-window)
+(define-key xwem-global-map (xwem-kbd "H-x 4 H-[")
'xwem-clswi-prev-other-window)
+(define-key xwem-global-map (xwem-kbd "H-o H-]") 'xwem-clswi-next-other-window)
+(define-key xwem-global-map (xwem-kbd "H-o H-[") 'xwem-clswi-prev-other-window)
;; Cutbuffers
(define-key xwem-global-map (xwem-kbd "H-w") 'xwem-copy-cutbuffer)
--- orig/lisp/xwem-keymacro.el
+++ mod/lisp/xwem-keymacro.el
@@ -90,7 +90,7 @@
:type 'boolean
:group 'xwem-keyboard)
-(defcustom xwem-keymacro-show-macro t
+(defcustom xwem-keymacro-show-macro nil
"*Non-nil mean show keyboard macro in minibuffer, while executing."
:type 'boolean
:group 'xwem-keyboard)
@@ -109,7 +109,12 @@
"Non-nil when executing keyboard macro.")
;;;###xwem-autoload
-(defvar xwem-keymacro-last-kbd-macro nil "Last KBD macro.")
+(defvar xwem-keymacro-macros-stack nil
+ "List of defined keyboard macroses.")
+
+(defvar xwem-keymacro-macros-depth nil
+ "Current depth of keyboard macro execution.
+INTERNAL VARIABLE.")
(defvar xwem-keymacro-default-command 'xwem-keymacro-default
"Default command while recording/playing macro.
@@ -151,33 +156,50 @@
;; events.
(let ((xrec-ext (X-XRecordQueryVersion (xwem-dpy)))
(xtest-ext (XQueryExtension (xwem-dpy) "XTEST")))
- (if (or (null (car xrec-ext))
- (null (car xtest-ext)))
- ;; No XRECORD or XTEST extension support
- (xwem-message 'warning "No XRECORD or XTEST extension on dpy, you
can't use keyboard macros saving.")
-
- ;; (xwem-dpy) supports XRECORD extension
- (setq xwem-keymacro-rcontext (make-X-RecordContext :dpy (xwem-dpy) :id
(X-Dpy-get-id (xwem-dpy))))
- (setq xwem-keymacro-rranges
- ;; We are only interested in KeyPrees/KeyRelease events
- (list (make-X-RecordRange :device-events (cons X-KeyPress
X-KeyRelease))))
-
- (setq xwem-keymacro-rclient (float X-XRecordAllClients))
- (setq xwem-keymacro-rcontext (X-XRecordCreateContext
- (xwem-dpy) xwem-keymacro-rcontext 0
- (list xwem-keymacro-rclient)
- xwem-keymacro-rranges))
- (X-XRecordRegisterClients (xwem-dpy) xwem-keymacro-rcontext 0
- (list xwem-keymacro-rclient)
- xwem-keymacro-rranges)
-
- (setq xwem-keymacro-dpy (XOpenDisplay
- (format "%s:%d" (X-Dpy-name (xwem-dpy))
- (X-Dpy-default-screen (xwem-dpy)))))
- (when xwem-keymacro-debug
- (setf (X-Dpy-log-buffer xwem-keymacro-dpy) "XREC.log"))
+ (when (or (null (car xrec-ext))
+ (null (car xtest-ext)))
+ ;; No XRECORD or XTEST extension support
+ (error 'xwem-error "RECORD or XTEST extension missing"))
+
+ ;; (xwem-dpy) supports XRECORD extension
+ (setq xwem-keymacro-rcontext (make-X-RecordContext
+ :dpy (xwem-dpy)
+ :id (X-Dpy-get-id (xwem-dpy))))
+ (setq xwem-keymacro-rranges
+ ;; We are only interested in KeyPrees/KeyRelease events
+ (list (make-X-RecordRange
+ :device-events (cons X-KeyPress X-KeyRelease))))
+
+ (setq xwem-keymacro-rclient (float X-XRecordAllClients))
+ (setq xwem-keymacro-rcontext (X-XRecordCreateContext
+ (xwem-dpy) xwem-keymacro-rcontext 0
+ (list xwem-keymacro-rclient)
+ xwem-keymacro-rranges))
+ (X-XRecordRegisterClients (xwem-dpy) xwem-keymacro-rcontext 0
+ (list xwem-keymacro-rclient)
+ xwem-keymacro-rranges)
+
+ (setq xwem-keymacro-dpy (XOpenDisplay
+ (format "%s:%d" (X-Dpy-name (xwem-dpy))
+ (X-Dpy-default-screen (xwem-dpy)))))
+ (when xwem-keymacro-debug
+ (setf (X-Dpy-log-buffer xwem-keymacro-dpy) "XREC.log"))
+
+ ;; Advice `xwem-key-send-xtest-internal' to work with macroses.
+ (defadvice xwem-key-send-xtest-internal
+ (around enable-disable-record-context activate)
+ "Disable/enable recording context while executing keyboard macro."
+ (when xwem-keymacro-saving
+ (X-XRecordDisableContext (xwem-dpy) xwem-keymacro-rcontext))
+
+ ad-do-it
+
+ (when xwem-keymacro-saving
+ (XFlush (xwem-dpy))
+ (X-XRecordEnableContext xwem-keymacro-dpy xwem-keymacro-rcontext)
+ (XFlush xwem-keymacro-dpy)))
- (setq xwem-keymacro-initialized t))))
+ (setq xwem-keymacro-initialized t)))
(defun xwem-keymacro-extract (xevs &optional cutlen)
"Extract keyboard macro from X-Events list XEVS.
@@ -198,10 +220,20 @@
;;;###xwem-autoload
(defun xwem-keymacro-execute-keys (keys)
"Execute keyboard macro KEYS."
- (enqueue-eval-event 'xwem-keymacro-start-executing-keys t)
- (mapc 'xwem-unread-command-event keys)
- (enqueue-eval-event 'xwem-keymacro-stop-executing-keys t)
- )
+ (xwem-keymacro-start-executing-keys)
+
+ (let ((xwem-keymacro-keys keys)
+ (xwem-keymacro-keys-index 0))
+ (xwem-unwind-protect
+ (while (< xwem-keymacro-keys-index (length xwem-keymacro-keys))
+ (xwem-dispatch-command-event
+ (aref xwem-keymacro-keys xwem-keymacro-keys-index))
+ (incf xwem-keymacro-keys-index))
+ (xwem-keymacro-stop-executing-keys))))
+; (enqueue-eval-event 'xwem-keymacro-start-executing-keys t)
+; (mapc 'xwem-unread-command-event keys)
+; (enqueue-eval-event 'xwem-keymacro-stop-executing-keys t)
+; )
(defun xwem-keymacro-start-recording ()
"Start recording Keys."
@@ -240,20 +272,8 @@
(xwem-message 'warning "Already defining macro...")
(xwem-message 'macro "Defining KBD macro ...")
-
- ;; Clear events queue and enable context
- (setf (X-Dpy-evq xwem-keymacro-dpy) nil)
- (X-XRecordEnableContext xwem-keymacro-dpy xwem-keymacro-rcontext)
-
- ;; Change xwem's minibuffer background
- (when xwem-keymacro-minib-bg
- (setq xwem-keymacro-minib-old-bg
- (face-background-name 'default (xwem-minib-frame xwem-minibuffer)))
- (set-face-property 'default 'background xwem-keymacro-minib-bg
- (xwem-minib-frame xwem-minibuffer)))
-
(setq xwem-keymacro-prefix-arg arg)
- (setq xwem-keymacro-saving t)))
+ (xwem-keymacro-start-recording)))
;;;###autoload(autoload 'xwem-keymacro-end "xwem-keymacro" nil t)
(define-xwem-command xwem-keymacro-end (arg)
@@ -274,7 +294,7 @@
(length xwem-this-command-keys))))
(if (not xwem-keymacro-prefix-arg)
;; Save last keyboard macro
- (setq xwem-keymacro-last-kbd-macro kmacro)
+ (push kmacro xwem-keymacro-macros-stack)
(let ((key (xwem-read-key "Enter character to bind: ")))
(define-key 'xwem-user-macros-prefix (events-to-keys (vector key))
kmacro))))
@@ -293,14 +313,22 @@
(setq xwem-prefix-arg nil)
(when xwem-keymacro-show-macro
- (xwem-message 'macro "Executing macro: '%s'" (key-description keys)))
+ (xwem-message 'macro "Executing macro: '%s'%s"
+ (key-description keys)
+ (if (> times 1)
+ (format " %d times" times)
+ "")))
;; Force release of modifiers
(xwem-kbd-force-mods-release)
- (mapc (lambda (keyseq)
- (xwem-keymacro-execute-keys keyseq))
- (make-list times keys)))
+ ;; Adjust KEYS acording to TIMES argument
+ (let ((key-sequence []))
+ (while (> times 0)
+ (setq key-sequence (vconcat key-sequence keys))
+ (decf times))
+ ;; Finally execute keys
+ (xwem-keymacro-execute-keys key-sequence)))
;; Commands to be used in `xwem-keymacro-user-macros'
;;;###autoload(autoload 'xwem-keymacro-undefined "xwem-keymacro" nil t)
@@ -308,21 +336,32 @@
"Undefined macro command."
(xwem-interactive)
- (xwem-message 'warning "Macro key `%s' is not defined" (key-description
xwem-this-command-keys)))
+ (xwem-message 'warning "Macro key `%s' is not defined"
+ (key-description xwem-this-command-keys)))
;;;###autoload(autoload 'xwem-keymacro-play-last "xwem-keymacro")
(define-xwem-command xwem-keymacro-play-last (arg)
"Play last KBD macro ARG times."
(xwem-interactive "*_p")
- (if xwem-keymacro-saving
- (xwem-message 'warning "Can't play macro while recording.")
-
- (if (not xwem-keymacro-last-kbd-macro)
- (xwem-message 'macro "No KBD macros have been saved.")
+ (when (null xwem-keymacro-macros-stack)
+ (error 'xwem-error "No KBD macros defined"))
- (xwem-keymacro-internal-play xwem-keymacro-last-kbd-macro arg))
- ))
+ (if (null xwem-keymacro-macros-depth)
+ (setq xwem-keymacro-macros-depth 0)
+ (when (>= xwem-keymacro-macros-depth
+ (1- (length xwem-keymacro-macros-stack)))
+ (error 'xwem-error (format "Can't play macro of %d depth"
+ (1+ xwem-keymacro-macros-depth))))
+ (incf xwem-keymacro-macros-depth))
+
+ (xwem-unwind-protect
+ (xwem-keymacro-internal-play
+ (nth xwem-keymacro-macros-depth xwem-keymacro-macros-stack) arg)
+
+ (if (zerop xwem-keymacro-macros-depth)
+ (setq xwem-keymacro-macros-depth nil)
+ (decf xwem-keymacro-macros-depth))))
;;;###autoload(autoload 'xwem-keymacro-recursive-edit "xwem-keymacro" nil t)
(define-xwem-command xwem-keymacro-recursive-edit (arg)
--- orig/lisp/xwem-misc.el
+++ mod/lisp/xwem-misc.el
@@ -712,6 +712,12 @@
(pushnew 'xwem-misc-xerr-hook (X-Dpy-error-hooks (xwem-dpy)))
(xwem-cursors-init)
+ ;; Advice XReparentWindow to save last xparent
+ (defadvice XReparentWindow (after save-last-parent-window
+ (xdpy win parwin &rest args) activate)
+ "Save last parent on every `XReparentWindow'."
+ (X-Win-put-prop win 'last-xparent parwin))
+
(xwem-message 'init "Initializing masking ...")
;; Depth 1 pixmap, gcs
(setq xwem-misc-mask-pixmap
@@ -921,7 +927,7 @@
(setq values (cons (eval expr) values))
(if arg
- (xwem-key-send-ekeys (prin1-to-string (car values)))
+ (xwem-kbd-add-pending-keys (prin1-to-string (car values)))
(xwem-deffered-funcall
'xwem-message 'info "%S => %S" expr (car values))))
@@ -934,7 +940,7 @@
(with-xwem-read-from-minibuffer
(let ((retval (execute-extended-command arg)))
(when arg
- (xwem-key-send-ekeys (pp retval))))))
+ (xwem-kbd-add-pending-keys (pp retval))))))
;;;###autoload(autoload 'xwem-shell-command "xwem-misc" nil t)
(define-xwem-command xwem-shell-command (command arg)
@@ -962,8 +968,10 @@
shell-command-switch command)
(if arg
- (xwem-key-send-ekeys (buffer-substring (point-min)
- (- (point-max) (if (> (prefix-numeric-value arg) 4) 1 0))))
+ (xwem-kbd-add-pending-keys
+ (buffer-substring
+ (point-min) (- (point-max)
+ (if (> (prefix-numeric-value arg) 4) 1 0))))
(if (= 1 (count-lines (point-min) (point-max)))
(xwem-message 'info (buffer-substring (point-min) (point-max)))
@@ -985,7 +993,7 @@
(let ((result (calc-eval expr)))
(if arg
- (xwem-key-send-ekeys result)
+ (xwem-kbd-add-pending-keys result)
(xwem-message 'info "%s = %s" expr result))))
;;;###autoload(autoload 'xwem-misc-make-screenshot "xwem-misc" nil t)
@@ -1580,6 +1588,15 @@
(let ((print-level 3)) ; XXX Restrict huge output
(apply 'X-Dpy-log (xwem-dpy) routine fmt fmt-args)))
+;;;###xwem-autoload
+(defun xwem-misc-xwin-last-xparent (xwin)
+ "Return last xparent for XWIN."
+ (let ((rxp (X-Win-get-prop xwin 'last-xparent)))
+ (unless (X-Win-p rxp)
+ (setq rxp (nth 3 (XQueryTree (X-Win-dpy xwin) xwin)))
+ (X-Win-put-prop xwin 'last-xparent rxp))
+ rxp))
+
(provide 'xwem-misc)
--- orig/lisp/xwem-strokes.el
+++ mod/lisp/xwem-strokes.el
@@ -225,7 +225,8 @@
(if (xwem-strokes-cmd-valid-p cmd)
(cond ((stringp cmd)
(xwem-deffered-funcall 'xwem-kbd-force-mods-release)
- (xwem-deffered-funcall 'xwem-key-send-ekeys cmd))
+ (xwem-deffered-funcall
+ 'xwem-kbd-add-pending-keys cmd (xwem-cl-selected)))
((vectorp cmd)
(xwem-kbd-force-mods-release)
|