ch11ng / exwm

Emacs X Window Manager
2.85k stars 134 forks source link

Duplicate echo message on workspaces #637

Closed QiangF closed 5 years ago

QiangF commented 5 years ago

Many people have the idea of combining the modeline and the minibuffer. In exwm we can auto hide the echo area, you constantly have the flash during the hide and show of the minibuffer. A much better approach is show some of the modeline in the minibuffer. I found emacs-mini-modeline to be the best. https://github.com/kiennq/emacs-mini-modeline

You can try the package with my settings: https://gist.github.com/QiangF/00a0e1d1625f7a005f5d6aaffd2931b9

However, the echo area is duplicated across exwm workspace on different monitors. emacs-mini-modeline uses a function named mini-modeline-display to do the work. In that function, the string to be displayed is inserted this way:

        (with-current-buffer (window-buffer (minibuffer-window))
              ;; write to minibuffer
              (erase-buffer)
              (insert (car mini-modeline--cache)))

The minibuffer-window is default to be the minibuffer on the current frame, it's supposed to be different on different workspaces. The intended behavior is:

  1. the minibuffer of two unique workspaces on different monitor should have their own mini-modeline regards to buffer local info
  2. different monitors should have seperate mini-modeline definiton, so we don't need to duplicate the display of other information like system time and networkspeeds. (less important)

I am closing https://github.com/ch11ng/exwm/issues/631 because I think this is much better.

ch11ng commented 5 years ago

In EXWM each monitor has its own detachable minibuffer frame so I suppose your requirement is possible. You may set message accordingly by detecting the exwm-active frame parameter when a workspace frame get/lose focus.

QiangF commented 5 years ago

Both of the following are t

(frame-parameter (elt exwm-workspace--list 0) 'minibuffer)
(frame-parameter (elt exwm-workspace--list 1) 'minibuffer)

But the minibuffers of two frames appears to be the same.

(with-current-buffer (window-buffer (minibuffer-window (elt exwm-workspace--list 0)))
  (erase-buffer)
  (insert "hello"))

(with-current-buffer (window-buffer (minibuffer-window (elt exwm-workspace--list 1)))
  (erase-buffer)
  (insert "world"))

the inserted text appear in both.

ch11ng commented 5 years ago

The problem is you were actually manipulating the echo area, and it's shared by all frames.

QiangF commented 5 years ago

The emacs manual is misleading

A frame normally contains its own echo area and minibuffer, but you can make frames that don't have these--they use the echo area and minibuffer of another frame.

A shared echo area is not its own.

QiangF commented 5 years ago

I still have two questions:

  1. how to set two different faces for the echo area of two different workspaces, just to show the active workspace
  2. how to make other workspace frames except the main one minibuffer-less
ch11ng commented 5 years ago

The problem is you were actually manipulating the echo area, and it's shared by all frames.

I think I got this wrong. You were making change to the same minibuffer buffer (perhaps *Minibuf-0*). The echo areas on different frames are not the same it seems.

QiangF commented 5 years ago

Both " Minibuf-0" and " Minibuf-1" exist :

(get-buffer " *Minibuf-0*")
(get-buffer " *Minibuf-1*")

How can I get the active minibuffer? This doesn 't work :

(window-buffer (minibuffer-window exwm-workspace--current))

Minibuffer of all frames seem to be the same " Minibuf-0". I can 't see " Minibuf-1" :

(with-current-buffer " *Minibuf-1*"
  (erase-buffer)
  (insert "hello"))
QiangF commented 5 years ago

" Minibuf-1" doesn 't have a window. I can 't change workspace 1 's minibuffer parameter.

(set-frame-parameter (elt exwm-workspace--list 1) 'minibuffer (get-buffer-window " *Minibuf-1*"))
ch11ng commented 5 years ago

how to set two different faces for the echo area of two different workspaces, just to show the active workspace

This is no more relevant I suppose.

how to make other workspace frames except the main one minibuffer-less

Just detach the minibuffer at first and reattach it afterwards. Note that there'd be some blank space left out on inactive monitors so you may want to adjust the color of the backgroud to match that of the minibuffer to hide it (if you ever care).

QiangF commented 5 years ago

The question is how to assiciate " Minibuf-0" to (elt exwm-workspace--list 0) and " Minibuf-1" to (elt exwm-workspace--list 1) .

ch11ng commented 5 years ago

They are used internally. I don't see any interface for manipulating them. And what if you have three or more monitors?

QiangF commented 5 years ago

According to Stefan Monnier:

Usually there are 2 minibufs: Minibuf-0 (IIUC that's the buffer displayed when the minibuffer is inactive, i.e. it's normally empty) and Minibuf-1 which is the main minibuffer buffer.

source https://gnu.emacs.help.narkive.com/6a6bsNg8/when-deleting-in-minibuffer-don-t-change-kill-ring