ch11ng / exwm

Emacs X Window Manager
2.85k stars 136 forks source link

How to send a paste key to google-chrome-stable #387

Closed QiangF closed 6 years ago

QiangF commented 6 years ago

The idea is to send a string to chrome's text input area with a command (exwmx-sendstring--send). It works very well for all other applications but google chrome. See https://github.com/tumashu/exwm-x/issues/8

(defvar exwmx-sendstring-default-paste-key "C-v")

(defun exwmx-sendstring--send (string)
"Send `string' to clipboard and then send paste key to
application to trigger paste operation, `string' will be
inserted into the application."
(if (derived-mode-p 'exwm-mode)
    (let ((paste-key
                exwmx-sendstring-default-paste-key))
        (kill-new string)
        (dolist (key (string-to-list (kbd paste-key)))
        (exwm-input--fake-key key))
        (setq kill-ring (cdr kill-ring)))
    (insert string)))

(defun exwm-input--fake-key (event)
"Fake a key event equivalent to Emacs event EVENT."
(let* ((keysym (xcb:keysyms:event->keysym exwm--connection event))
        keycode id)
    (when (= 0 (car keysym))
    (user-error "[EXWM] Invalid key: %s" (single-key-description event)))
    (setq keycode (xcb:keysyms:keysym->keycode exwm--connection
                                            (car keysym)))
    (when (/= 0 keycode)
    (setq id (exwm--buffer->id (window-buffer (selected-window))))
    (dolist (class '(xcb:KeyPress xcb:KeyRelease))
        (xcb:+request exwm--connection
            (make-instance 'xcb:SendEvent
                        :propagate 0 :destination id
                        :event-mask xcb:EventMask:NoEvent
                        :event (xcb:marshal
                                (make-instance class
                                                :detail keycode
                                                :time xcb:Time:CurrentTime
                                                :root exwm--root :event id
                                                :child 0
                                                :root-x 0 :root-y 0
                                                :event-x 0 :event-y 0
                                                :state (cdr keysym)
                                                :same-screen 1)
                                exwm--connection)))))
    (xcb:flush exwm--connection)))
ch11ng commented 6 years ago

It's worth investigating whether it's because the string is not copied to clipboard, or the action of sending fake key failed. Actually we can use XELB to access clipboard directly.

QiangF commented 6 years ago

The string is copied to clipboard, the paste key works. It will be cool if the sending paste key step can be bypassed. That is the key step for using emacs for text editing everywhere.

QiangF commented 6 years ago

Many users need to send unicode code characters, so the author of the original function uses the clipboard.

QiangF commented 6 years ago

The original discussion is at https://github.com/ch11ng/exwm/issues/258

ch11ng commented 6 years ago

Maybe it's a security feature of Chrome?

QiangF commented 6 years ago

Fake key also doesn't work for Chromium. Isn't all keyboard input filtered by the window manager?

ch11ng commented 6 years ago

Fake key works, or simulation key won't. Perhaps Chromium has some restriction on clipboard.

QiangF commented 6 years ago

"C-v" (typed on keyboard) does paste the clipboard into the input field.

QiangF commented 6 years ago

I tried xdotool, it work sometimes.

(defun mysend ()
    (interactive)
    (start-process-shell-command "xdo" nil "xdotool key ctrl+v")
)
QiangF commented 6 years ago

OK this one works 100% of the times.

(defun mysend ()
    (interactive)
    (start-process-shell-command "slock" nil "xdotool key --delay 40 ctrl+v")
)

Also some reference for simulating hardware keypress
https://github.com/boppreh/keyboard https://vizible.wordpress.com/2009/08/15/linux-how-to-simulate-key-press/

QiangF commented 6 years ago

Also stumpwm can send unicode! See https://gist.github.com/ahungry/d8be8dca688aae05824ddee4122e90cd

ch11ng commented 6 years ago

Both xdotool and the CLX code use the XTEST extension which is also available in XELB. But I highly doubt the possibility to send every unicode directly with XTEST.