For example, I am trying to copy the URL line from Firefox into an org mode buffer. The usual cut and paste keys for Firefox (C-c C-v) do not work, and neither does (M-w C-y).

To copy from Firefox (in this example), I have to use the right mouse button context menu and select "Copy" which is suboptimal to say the least.

I've googled and gone through the documentation but can't seem to find any reference to the kill buffer.

Any help would be appreciated.


Long answer:

There are three modes* in EXWM.

I. Sending all the keys to the apps except the global bindings (for e.g. this is a global (exwm-input-set-key (kbd "s-c") #'list-processes). EXWM calls this char-mode

II. Sending all the keys to the apps with some simulations. EXWM calls this line-mode. You can define simulations like.

 '(([?\C-b] . left)
  ([?\C-f] . right)))

Now in this mode if I press C-f apps receive right arrow key.

III. Not sending any key to the apps, instead Emacs receives all the keys. So you can use normal operations like C-x 2 or C-x 3 to split the window.EXWM calls this line-mode too.

C-c and C-v doesn't work because you're in mode III. Here are some of the helper functions that I use.

(defun fhd/exwm-input-line-mode ()
  "Set exwm window to line-mode and show mode line"
  (call-interactively #'exwm-input-grab-keyboard)

(defun fhd/exwm-input-char-mode ()
  "Set exwm window to char-mode and hide mode line"
  (call-interactively #'exwm-input-release-keyboard)

(defun fhd/exwm-input-toggle-mode ()
  "Toggle between line- and char-mode"
  (with-current-buffer (window-buffer)
    (when (eq major-mode 'exwm-mode)
      (if (equal (second (second mode-line-process)) "line")

To make it globally available with s-i

(exwm-input-set-key (kbd "s-i") #'fhd/exwm-input-toggle-mode)

This toggles between modes I and either mode II or III. Switching between mode II and mode III depends on exwm-input-line-mode-passthrough. Another helper function I use:

(defun fhd/toggle-exwm-input-line-mode-passthrough ()
  (if exwm-input-line-mode-passthrough
      (setq exwm-input-line-mode-passthrough nil)
      (message "App receives all the keys now (with some simulation)"))
     (setq exwm-input-line-mode-passthrough t)
     (message "emacs receives all the keys now")))

And to bind it globally

(exwm-input-set-key (kbd "s-p") 'fhd/toggle-exwm-input-line-mode-passthrough)

I used (force-mode-line-update) in this function since I have an indicator in my mode-line to show if emacs receives all the keys (mode III) or apps receive all the keys with some simulations (mode II) if mode-line is hidden it means we are in mode I and apps receive all the keys without any simulations. To make sure apps open in mode II you can use (setq exwm-input-line-mode-passthrough nil).

If you want all the apps to open in mode I (that is char-mode in EXWM terminology) you can use:

(add-hook 'exwm-manage-finish-hook
  (lambda () (call-interactively #'exwm-input-release-keyboard)

*The word "mode" is used loosely, it doesn't mean in EXWM there are actually three modes.

Short answer

Call exwm-input-release-keyboard function. It switches to char-mode which means firefox receives all the key events.

  • 1
    Thanks fhdsni, that's just what I'm after. Much appreciated.
    – Andomonir
    Jun 6 '17 at 7:57

I'm reading the guide and seems it's also possible to prefix all the usual shortcuts with C-c C-q (exwm-input-send-next-key) without switching to char-mode. So instead of C-a/C-c/C-v use C-c-q-a/C-c-q-c/C-c-q-v.


If the above approach don't work for you(mine did not), try it this way. First, we set to open all application in char-mode by default.

;; The code from user - fhdhsni
(add-hook 'exwm-manage-finish-hook
  (lambda () (call-interactively #'exwm-input-release-keyboard)

Then if you want to go back to line-mode, just do exwm-reset. The default keybinding is - s-r

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.