ch11ng / exwm

Emacs X Window Manager
2.86k stars 137 forks source link

scroll-other-window for non-emacs windows #920

Open tarustdev opened 10 months ago

tarustdev commented 10 months ago

Hello!

Is it possible to scroll non-emacs window (Chromium browser for example) when emacs window is active?

With 2 emacs windows opened I can scroll other (non-active) window with commands scroll-other-window and scroll-other-window-down.

I added next code to exwm-input-global-keys and now I can scroll non-active emacs window when non-emacs window is active (for example scroll non-active text buffer when Chromium is active).

([?\C-\M-v] . scroll-other-window)
([?\C-\M-\S-v] . scroll-other-window-down)

Also I added next code to exwm-input-simulation-keys and now i can scroll non-emacs window when it is active.

([?\M-v] . [prior])
([?\C-v] . [next])

But this setup doesn't work for scrolling non-active non-emacs windows (Always getting "Beginning of buffer" or "End of buffer" even if this window scrolling correctly when it is active). Am I doing something wrong or are there any limitations for desired behavior?

Thanks!

medranocalvo commented 10 months ago

Hello @tarustdev,

as you see, supporting scroll-other-window from an X window can be made by passing those key events to the underlying exwm-mode buffer. That's what exwm-input-global-keys does. Mapping M-v and C-v to PageUp and PageDown in the X window can be done with exwm-input-simulation-keys. That might be intuitive for you. The missing part, scrolling the X window from an Emacs buffer, is not supported at the moment, but can be implemented as follows:

(defun medranocalvo-exwm-scroll-up-command (&optional arg)
  (interactive "^P")
  (cond
   ((eq arg '-)
    (medranocalvo-exwm-scroll-down-command nil))
   ((< (prefix-numeric-value arg) 0)
    (medranocalvo-exwm-scroll-down-command (- (prefix-numeric-value arg))))
   (t
    (exwm-input--fake-key (pcase exwm-class-name
                            ("XTerm" 'S-next)
                            (t 'next))))))

(defun medranocalvo-exwm-scroll-down-command (&optional arg)
  (interactive "^P")
  (cond
   ((eq arg '-)
    (medranocalvo-exwm-scroll-up-command nil))
   ((< (prefix-numeric-value arg) 0)
    (medranocalvo-exwm-scroll-up-command (- (prefix-numeric-value arg))))
   (t
    (exwm-input--fake-key (pcase exwm-class-name
                            ("XTerm" 'S-prior)
                            (t 'prior))))))

(keymap-set exwm-mode-map "<remap> <scroll-up-command>" #'medranocalvo-exwm-scroll-up-command)
(keymap-set exwm-mode-map "<remap> <scroll-down-command>" #'medranocalvo-exwm-scroll-down-command)

With the code above I was able to scroll an XTerm window (after enabling "Allow SendEvents"; via XTerm's C- menu).

I wonder whether this functionality should be provided by EXWM by default. For me, EXWM extends Emacs concepts to X windows, so scroll-other-window should indeed apply to X windows as well. What do others think about it? If that's something we'd like to do, we have to think how to deal with different applications using different keys for scrolling (for example XTerm above). Additionally, we should collect all such missing functions to ensure the mechanism is valid for all of them. I could quickly find beginning-of-buffer-other-window and end-of-buffer-other-window, which are similar to the scrolling commands but, are there other Emacs commands that control other windows applicable to X windows?

Another issue I'm wondering about is whether we should export the internal function exwm-input--fake-key and, if so, whether the current API is good.

tarustdev commented 10 months ago

@medranocalvo thanks a lot for the explanation and implementation example! It works correctly in my case.

medranocalvo commented 10 months ago

You are welcome.

I would appreciate input on the thoughts above (from everyone):

eval-on-point commented 10 months ago

I don't know about scroll-other-window, because that is a feature that I do not use. A similar idea that I have had before is something like evil-collection for EXWM. The idea would be to provide a curated set of simulation keys for commonly used applications such as Chromium, XTerm, Firefox, Discord, Slack, etc. Maybe this could be designed in a way such that it is simple to implement things like scroll-other-window for each of these applications.

I don't have the time to commit to helping with this, but I think it is an interesting idea.

medranocalvo commented 9 months ago

Thank you for your thoughts @eval-on-point.

The fact that the keybinding is not standard across applications suggests that it might indeed belong in such a collaborative configuration project and not in EXWM itself.

I find the exwm-collection idea interesting as well. I wonder whether there is a small set of Emacs commands generally applicable to X applications which we can configure via exwm-manage-configurations. (Thinking about it, exwm-manage-configurations might be a good place to configure the per-application simulation key for scroll-other-window commands...).