emacs-exwm / exwm

Emacs X Window Manager
https://elpa.gnu.org/packages/exwm.html
GNU General Public License v3.0
189 stars 7 forks source link

Using polybar with EXWM causes Corfu to popup incorrectly. #31

Open LemonBreezes opened 3 months ago

LemonBreezes commented 3 months ago

Today I have been testing various status bar solutions for EXWM and have noticed that while using polybar, the Corfu popup covers the text I am typing:

image

LemonBreezes commented 3 months ago

It seems like adding the height of the polybar to corfu--make-frame (see the (+ 17 y)) fixes the positioning:

image

minad commented 3 months ago

Today I have been testing various status bar solutions for EXWM and have noticed that while using polybar, the Corfu popup covers the text I am typing:

Off topic, but my recommendation for a status bar is to use the Emacs tab-bar. This is the best solution since you can also tweak it in Elisp. ;)

minad commented 3 months ago

Regarding Corfu, I suspect that the problem is similar to the problem of multi monitor setups, where we should take the position of the parent frame on the correct monitor into account. Without EXWM this is not a problem, since we do not unparent the Corfu child frame and as such stay always relative to the Emacs parent frame. See https://github.com/minad/corfu/discussions/408.

LemonBreezes commented 3 months ago

Regarding Corfu, I suspect that the problem is similar to the problem of multi monitor setups, where we should take the position of the parent frame on the correct monitor into account. Without EXWM this is not a problem, since we do not unparent the Corfu child frame and as such stay always relative to the Emacs parent frame. See minad/corfu#408.

Yes actually! So what I had to do was add the x and y of (frame-position) to the x and y used in corfu--make-frame in an advice manner. I combined it with the advice from there:

(defun get-focused-monitor-geometry ()
  "Get the geometry of the monitor displaying the selected frame in EXWM."
  (let* ((monitor-attrs (frame-monitor-attributes))
         (workarea (assoc 'workarea monitor-attrs))
         (geometry (cdr workarea)))
    (list (nth 0 geometry) ; X
          (nth 1 geometry) ; Y
          (nth 2 geometry) ; Width
          (nth 3 geometry) ; Height
          )))

(defun advise-corfu-make-frame-with-monitor-awareness (orig-fun frame x y width height buffer)
  "Advise `corfu--make-frame` to be monitor-aware, adjusting X and Y according to the focused monitor."

  ;; Get the geometry of the currently focused monitor
  (let* ((monitor-geometry (get-focused-monitor-geometry))
         (monitor-x (nth 0 monitor-geometry))
         (monitor-y (nth 1 monitor-geometry))
         (selected-frame-position (frame-position))
         (selected-frame-x (car selected-frame-position))
         (selected-frame-y (cdr selected-frame-position))
         (new-x (+ monitor-x selected-frame-x x))
         (new-y (+ monitor-y selected-frame-y y)))

    ;; Call the original function with potentially adjusted coordinates
    (funcall orig-fun frame new-x new-y width height buffer)))

(advice-add 'corfu--make-frame :around #'advise-corfu-make-frame-with-monitor-awareness)

Also, regarding the tab-bar, I PR'd some documentation for using i3bar.el with EXWM, https://github.com/Stebalien/i3bar.el/pull/10, but in my opinion it's possible to do better with a standalone polybar-like package for using the tab-bar as a status bar. Polybar seems good enough for me right now though, and already has a segment for controlling MPD.

minad commented 3 months ago

Oh, interesting! I wasn't aware of @Stebalien's i3bar. What I am doing is different. I have all the status elements implemented in Elisp (or most of the ones also supported by i3bar). That's maybe not as efficient but nicely extensible. Also my music player is in Elisp, so I don't miss music player integration. But even with mpd, it is easy enough to access directly from Emacs. There exist at least ten Emacs mpd clients. ;)

LemonBreezes commented 3 months ago

Oh, interesting! I wasn't aware of @Stebalien's i3bar. What I am doing is different. I have all the status elements implemented in Elisp (or most of the ones also supported by i3bar). That's maybe not as efficient but nicely extensible. Also my music player is in Elisp, so I don't miss music player integration. But even with mpd, it is easy enough to access directly from Emacs. There exist at least ten Emacs mpd clients. ;)

What do you use for music? I mostly use a combination of EMMS and MPD. I have a transient for jumping to some of my music directories (https://github.com/lemonbreezes/cae-emacs/blob/master/modules/cae/misc-applications/autoload/emms.el#L21) and I wrote a trivial command to jump to a random line in the current buffer (https://github.com/lemonbreezes/cae-emacs/blob/master/autoload/cae-editor.el#L432). So I jump to a music directory, jump to a random line, and play what I land on mostly.

I also set up a few Dired keybindings for my music directory in a .dir-locals.el, https://github.com/lemonbreezes/cae-emacs/blob/master/dir-local-files/music-dir.el.

minad commented 3 months ago

What do you use for music?

Just a small custom thingy based on mpv. It can play directly in Dired or other buffers (whatever format) via an Embark-style target finder. It basically turns arbitrary buffers into playlists.