mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-27 14:57:59 +01:00
Grab global keys on top-level X windows
* exwm-input.el (exwm-input--on-CreateNotify): New function for grabbing global keys on newly created X windows. (exwm-input--update-global-prefix-keys): Grab global keys on top-level X windows instead of the root window. (exwm-input--grab-global-prefix-keys): New function for grabbing global keys on X windows. (exwm-input--release-keyboard): Grab global keys in char-mode. (exwm-input--init): Select CreateNotify events. * exwm-core.el (exwm--unlock): * exwm-input.el (exwm-input--on-FocusIn, exwm-input--init): Do not handle FocusIn events on the root window.
This commit is contained in:
parent
86f2215be3
commit
6200417697
2 changed files with 41 additions and 42 deletions
|
@ -93,8 +93,7 @@
|
||||||
:window exwm--root
|
:window exwm--root
|
||||||
:value-mask xcb:CW:EventMask
|
:value-mask xcb:CW:EventMask
|
||||||
:event-mask (eval-when-compile
|
:event-mask (eval-when-compile
|
||||||
(logior xcb:EventMask:FocusChange
|
(logior xcb:EventMask:SubstructureRedirect
|
||||||
xcb:EventMask:SubstructureRedirect
|
|
||||||
xcb:EventMask:StructureNotify))))
|
xcb:EventMask:StructureNotify))))
|
||||||
(xcb:flush exwm--connection))
|
(xcb:flush exwm--connection))
|
||||||
|
|
||||||
|
|
|
@ -212,16 +212,6 @@ ARGS are additional arguments to CALLBACK."
|
||||||
(cdr exwm-input--timestamp-callback))
|
(cdr exwm-input--timestamp-callback))
|
||||||
(setq exwm-input--timestamp-callback nil)))))
|
(setq exwm-input--timestamp-callback nil)))))
|
||||||
|
|
||||||
(defun exwm-input--on-FocusIn (data _synthetic)
|
|
||||||
"Handle FocusIn events."
|
|
||||||
(let ((obj (make-instance 'xcb:FocusIn)))
|
|
||||||
(xcb:unmarshal obj data)
|
|
||||||
(with-slots (mode) obj
|
|
||||||
;; Revert input focus back to Emacs frame / X window when it's set on
|
|
||||||
;; the root window.
|
|
||||||
(x-focus-frame exwm-workspace--current)
|
|
||||||
(select-window (frame-selected-window exwm-workspace--current)))))
|
|
||||||
|
|
||||||
(defun exwm-input--on-EnterNotify (data _synthetic)
|
(defun exwm-input--on-EnterNotify (data _synthetic)
|
||||||
"Handle EnterNotify events."
|
"Handle EnterNotify events."
|
||||||
(let ((evt (make-instance 'xcb:EnterNotify))
|
(let ((evt (make-instance 'xcb:EnterNotify))
|
||||||
|
@ -428,42 +418,51 @@ ARGS are additional arguments to CALLBACK."
|
||||||
(funcall exwm--on-KeyPress obj data)
|
(funcall exwm--on-KeyPress obj data)
|
||||||
(exwm-input--on-KeyPress-char-mode obj))))
|
(exwm-input--on-KeyPress-char-mode obj))))
|
||||||
|
|
||||||
|
(defun exwm-input--on-CreateNotify (data _synthetic)
|
||||||
|
"Handle CreateNotify events."
|
||||||
|
(let ((evt (make-instance 'xcb:CreateNotify)))
|
||||||
|
(xcb:unmarshal evt data)
|
||||||
|
(with-slots (window) evt
|
||||||
|
(exwm-input--grab-global-prefix-keys window))))
|
||||||
|
|
||||||
(defun exwm-input--update-global-prefix-keys ()
|
(defun exwm-input--update-global-prefix-keys ()
|
||||||
"Update `exwm-input--global-prefix-keys'."
|
"Update `exwm-input--global-prefix-keys'."
|
||||||
(when exwm--connection
|
(when exwm--connection
|
||||||
(let ((original exwm-input--global-prefix-keys)
|
(let ((original exwm-input--global-prefix-keys))
|
||||||
keysym keycode grab-key)
|
|
||||||
(setq exwm-input--global-prefix-keys nil)
|
(setq exwm-input--global-prefix-keys nil)
|
||||||
(dolist (i exwm-input--global-keys)
|
(dolist (i exwm-input--global-keys)
|
||||||
(cl-pushnew (elt i 0) exwm-input--global-prefix-keys))
|
(cl-pushnew (elt i 0) exwm-input--global-prefix-keys))
|
||||||
;; Stop here if the global prefix keys are update-to-date and
|
|
||||||
;; there's no new workspace.
|
|
||||||
(unless (equal original exwm-input--global-prefix-keys)
|
(unless (equal original exwm-input--global-prefix-keys)
|
||||||
(setq grab-key (make-instance 'xcb:GrabKey
|
(apply #'exwm-input--grab-global-prefix-keys
|
||||||
:owner-events 0
|
(slot-value (xcb:+request-unchecked+reply exwm--connection
|
||||||
:grab-window exwm--root
|
(make-instance 'xcb:QueryTree
|
||||||
:modifiers nil
|
:window exwm--root))
|
||||||
:key nil
|
'children))))))
|
||||||
:pointer-mode xcb:GrabMode:Async
|
|
||||||
:keyboard-mode xcb:GrabMode:Async))
|
(defun exwm-input--grab-global-prefix-keys (&rest xwins)
|
||||||
(dolist (k exwm-input--global-prefix-keys)
|
(let ((req (make-instance 'xcb:GrabKey
|
||||||
(setq keysym (xcb:keysyms:event->keysym exwm--connection k)
|
:owner-events 0
|
||||||
keycode (xcb:keysyms:keysym->keycode exwm--connection
|
:grab-window nil
|
||||||
(car keysym)))
|
:modifiers nil
|
||||||
(setf (slot-value grab-key 'modifiers) (cdr keysym)
|
:key nil
|
||||||
(slot-value grab-key 'key) keycode)
|
:pointer-mode xcb:GrabMode:Async
|
||||||
(when (or (= 0 keycode)
|
:keyboard-mode xcb:GrabMode:Async))
|
||||||
(xcb:+request-checked+request-check exwm--connection
|
keysym keycode)
|
||||||
grab-key)
|
(dolist (k exwm-input--global-prefix-keys)
|
||||||
;; Also grab this key with num-lock mask set.
|
(setq keysym (xcb:keysyms:event->keysym exwm--connection k)
|
||||||
(when (/= 0 xcb:keysyms:num-lock-mask)
|
keycode (xcb:keysyms:keysym->keycode exwm--connection
|
||||||
(setf (slot-value grab-key 'modifiers)
|
(car keysym)))
|
||||||
(logior (cdr keysym)
|
(setf (slot-value req 'modifiers) (cdr keysym)
|
||||||
xcb:keysyms:num-lock-mask))
|
(slot-value req 'key) keycode)
|
||||||
(xcb:+request-checked+request-check exwm--connection
|
(dolist (xwin xwins)
|
||||||
grab-key)))
|
(setf (slot-value req 'grab-window) xwin)
|
||||||
(user-error "[EXWM] Failed to grab key: %s"
|
(xcb:+request exwm--connection req)
|
||||||
(single-key-description k))))))))
|
;; Also grab this key with num-lock mask set.
|
||||||
|
(when (/= 0 xcb:keysyms:num-lock-mask)
|
||||||
|
(setf (slot-value req 'modifiers)
|
||||||
|
(logior (cdr keysym) xcb:keysyms:num-lock-mask))
|
||||||
|
(xcb:+request exwm--connection req))))
|
||||||
|
(xcb:flush exwm--connection)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun exwm-input-set-key (key command)
|
(defun exwm-input-set-key (key command)
|
||||||
|
@ -635,6 +634,7 @@ called interactively. Only invoke it non-interactively in configuration."
|
||||||
:grab-window id
|
:grab-window id
|
||||||
:modifiers xcb:ModMask:Any))
|
:modifiers xcb:ModMask:Any))
|
||||||
(exwm--log "Failed to release keyboard for #x%x" id))
|
(exwm--log "Failed to release keyboard for #x%x" id))
|
||||||
|
(exwm-input--grab-global-prefix-keys id)
|
||||||
(with-current-buffer (exwm--id->buffer id)
|
(with-current-buffer (exwm--id->buffer id)
|
||||||
(setq exwm--on-KeyPress #'exwm-input--on-KeyPress-char-mode))))
|
(setq exwm--on-KeyPress #'exwm-input--on-KeyPress-char-mode))))
|
||||||
|
|
||||||
|
@ -877,13 +877,13 @@ Its usage is the same with `exwm-input-set-simulation-keys'."
|
||||||
;; Attach event listeners
|
;; Attach event listeners
|
||||||
(xcb:+event exwm--connection 'xcb:PropertyNotify
|
(xcb:+event exwm--connection 'xcb:PropertyNotify
|
||||||
#'exwm-input--on-PropertyNotify)
|
#'exwm-input--on-PropertyNotify)
|
||||||
|
(xcb:+event exwm--connection 'xcb:CreateNotify #'exwm-input--on-CreateNotify)
|
||||||
(xcb:+event exwm--connection 'xcb:KeyPress #'exwm-input--on-KeyPress)
|
(xcb:+event exwm--connection 'xcb:KeyPress #'exwm-input--on-KeyPress)
|
||||||
(xcb:+event exwm--connection 'xcb:ButtonPress #'exwm-input--on-ButtonPress)
|
(xcb:+event exwm--connection 'xcb:ButtonPress #'exwm-input--on-ButtonPress)
|
||||||
(xcb:+event exwm--connection 'xcb:ButtonRelease
|
(xcb:+event exwm--connection 'xcb:ButtonRelease
|
||||||
#'exwm-floating--stop-moveresize)
|
#'exwm-floating--stop-moveresize)
|
||||||
(xcb:+event exwm--connection 'xcb:MotionNotify
|
(xcb:+event exwm--connection 'xcb:MotionNotify
|
||||||
#'exwm-floating--do-moveresize)
|
#'exwm-floating--do-moveresize)
|
||||||
(xcb:+event exwm--connection 'xcb:FocusIn #'exwm-input--on-FocusIn)
|
|
||||||
(when mouse-autoselect-window
|
(when mouse-autoselect-window
|
||||||
(xcb:+event exwm--connection 'xcb:EnterNotify
|
(xcb:+event exwm--connection 'xcb:EnterNotify
|
||||||
#'exwm-input--on-EnterNotify))
|
#'exwm-input--on-EnterNotify))
|
||||||
|
|
Loading…
Reference in a new issue