Fix input & input focus issues

* exwm-manage.el (exwm-manage--manage-window): Only grab left/middle/right
  buttons.

* exwm-input.el (exwm-input--on-ButtonPress): Only perform click-to-focus on
  unfocused X windows.

* exwm-input.el (exwm-input--update-focus): Do not focus an X window on
  another workspace, but instead keep focusing on the current one and set
  exwm--urgency parameter on that frame.

* exwm-input.el (exwm-input--fake-key): Send KeyRelease event (some
  applications reply on it).
This commit is contained in:
Chris Feng 2015-09-20 10:51:58 +08:00
parent 81478de9e6
commit 9f30672b15
2 changed files with 37 additions and 27 deletions

View file

@ -114,7 +114,14 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(when exwm-input--focus-window (when exwm-input--focus-window
(with-current-buffer (window-buffer exwm-input--focus-window) (with-current-buffer (window-buffer exwm-input--focus-window)
(if (eq major-mode 'exwm-mode) (if (eq major-mode 'exwm-mode)
(progn (if (not (eq exwm--frame exwm-workspace--current))
;; Do not focus X windows on other workspace
(progn
(set-frame-parameter exwm--frame 'exwm--urgency t)
(setq exwm-workspace--switch-history-outdated t)
(force-mode-line-update)
;; The application may have changed its input focus
(exwm-workspace-switch exwm-workspace-current-index t))
(when exwm--floating-frame (when exwm--floating-frame
(redirect-frame-focus exwm--floating-frame nil) (redirect-frame-focus exwm--floating-frame nil)
(select-frame-set-input-focus exwm--floating-frame t)) (select-frame-set-input-focus exwm--floating-frame t))
@ -180,7 +187,9 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(exwm-floating--start-moveresize event)) (exwm-floating--start-moveresize event))
(t (t
;; Click to focus ;; Click to focus
(select-window (get-buffer-window (exwm--id->buffer event) t)) (let ((window (get-buffer-window (exwm--id->buffer event) t)))
(unless (eq window (selected-window))
(select-window window)))
;; The event should be replayed ;; The event should be replayed
(setq mode xcb:Allow:ReplayPointer)))) (setq mode xcb:Allow:ReplayPointer))))
(xcb:+request exwm--connection (xcb:+request exwm--connection
@ -360,21 +369,22 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(keycode (xcb:keysyms:keysym->keycode exwm--connection (car keysym))) (keycode (xcb:keysyms:keysym->keycode exwm--connection (car keysym)))
(id (exwm--buffer->id (window-buffer (selected-window))))) (id (exwm--buffer->id (window-buffer (selected-window)))))
(when keycode (when keycode
(xcb:+request exwm--connection (dolist (class '(xcb:KeyPress xcb:KeyRelease))
(make-instance 'xcb:SendEvent (xcb:+request exwm--connection
:propagate 0 :destination id (make-instance 'xcb:SendEvent
:event-mask xcb:EventMask:NoEvent :propagate 0 :destination id
:event (xcb:marshal :event-mask xcb:EventMask:NoEvent
(make-instance 'xcb:KeyPress :event (xcb:marshal
:detail keycode (make-instance class
:time xcb:Time:CurrentTime :detail keycode
:root exwm--root :event id :time xcb:Time:CurrentTime
:child 0 :root exwm--root :event id
:root-x 0 :root-y 0 :child 0
:event-x 0 :event-y 0 :root-x 0 :root-y 0
:state (cadr keysym) :event-x 0 :event-y 0
:same-screen 1) :state (cadr keysym)
exwm--connection)))) :same-screen 1)
exwm--connection)))))
(xcb:flush exwm--connection))) (xcb:flush exwm--connection)))
;;;###autoload ;;;###autoload

View file

@ -145,16 +145,16 @@ corresponding buffer.")
(make-instance 'xcb:ConfigureWindow (make-instance 'xcb:ConfigureWindow
:window id :value-mask xcb:ConfigWindow:BorderWidth :window id :value-mask xcb:ConfigWindow:BorderWidth
:border-width 0)) :border-width 0))
(xcb:+request exwm--connection ;grab buttons for set focus/move/resize (dolist (button ;grab buttons to set focus / move / resize
(make-instance 'xcb:GrabButton (list xcb:ButtonIndex:1 xcb:ButtonIndex:2 xcb:ButtonIndex:3))
:owner-events 0 :grab-window id (xcb:+request-checked+request-check exwm--connection
:event-mask xcb:EventMask:ButtonPress (make-instance 'xcb:GrabButton
:pointer-mode xcb:GrabMode:Sync :owner-events 0 :grab-window id
:keyboard-mode xcb:GrabMode:Async :event-mask xcb:EventMask:ButtonPress
:confine-to xcb:Window:None :pointer-mode xcb:GrabMode:Sync
:cursor xcb:Cursor:None :keyboard-mode xcb:GrabMode:Async
:button xcb:ButtonIndex:Any :confine-to xcb:Window:None :cursor xcb:Cursor:None
:modifiers xcb:ModMask:Any)) :button button :modifiers xcb:ModMask:Any)))
(xcb:+request exwm--connection ;update _NET_CLIENT_LIST (xcb:+request exwm--connection ;update _NET_CLIENT_LIST
(make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST (make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST
:window exwm--root :window exwm--root