gonewest818 / dimmer.el

Interactively highlight which buffer is active by dimming the others.
GNU General Public License v3.0
267 stars 14 forks source link

Compatibility with ctrlf, lsp-ui, doom-modeline, and ediff frames #65

Open goldfita opened 2 years ago

goldfita commented 2 years ago

Is it possible to make this work with ctrlf? It doesn't dim the buffer when using builtin incremental search. I tried the following but no luck.

(defun ctrlf-active-p () ctrlf--active-p)
(with-no-warnings
  (add-to-list
    'dimmer-prevent-dimming-predicates 'ctrlf-active-p))
goldfita commented 2 years ago

I also noticed that dimmer interferes with doom-modeline when I move focus to another application. It should be a solid color.

dimmer-doom-modeline-emacs-lose-focus

Also, the lsp-ui doc-frame causes the parent window to dim. Maybe this can be fixed with dimmer-prevent-dimming-predicate. I will try and let you know.

gonewest818 commented 2 years ago

With ctrlf and lsp-ui you're on the right track with those config settings... I would be thrilled if we had a more robust and reliable way of doing this, but I haven't found a way. And in these situations what I end up doing is creating a temporary config (as I don't use ctrlf normally) and see if I can come up with something

With your doom-modeline, I assume that pink/magenta background color is wrong? What does the modeline look like when emacs has focus?

goldfita commented 2 years ago

Ctrlf: I couldn't figure out what the issue is. While ctrlf is active, I can switch back to the window I'm searching, and even when I'm in that window, it's still dimmed. I wonder if it has something to do with recursive-editing or recursive minibuffers. I checked the value of ctrl--active-p, and it does what I would expect.

Lsp-ui: It sort of make sense that the background window would be dimmed while in the doc-frame. But because these are initiated by a mouse pointer hover, I think it will probably get annoying really fast when the window is frequently changing colors as I move the mouse around the screen.

Doom-modeline: The entire mode-line is the magenta color for the active window. It's the dark color for inactive windows. I think this makes sense. It's trying to achieve something similar to dimmer. I only wish they would they would give you some control over the color. For people like me who use dark themes, bright colors are painful. When I have dimmer enabled and move the focus to another application, something is clearly going wrong. Not that it's a big deal since I'm in another application anyway.

goldfita commented 1 year ago

Another thing I noticed, each time I move the cursor, it leaves behind a mark of undimmed background in the fringe of the treemacs window. The icon background colors are also wrong. I have cursor disabled in unselected windows, but it doesn't seem to work for treemacs. treemacs_background

Actually the behavior in the fringe is a bit hard to pin down. When I switch to scratch, only the fringe is undimmed. Then if I switch back to my init.el and then select the treemacs window, only the fringe is dimmed.

This may be more of a treemacs issues. Without being intimately familiar with the code, it's hard to know which package has ownership of boundary behavior between packages.

goldfita commented 1 year ago

I've noticed that ctrlf does work as expected in certain buffers, e.g. scratch and messages.

goldfita commented 1 year ago

Actually, my last comment is only true depending on the window configuration. I partially understand the issue now.

When you activate the minibuffer, dimmer-process-all is called twice. The first time it gets called by dimmer-command-handler. This works correctly, ignore is t and force is nil, so nothing changes, and the buffer you were in is not dimmed. But then it gets called again by dimmer-config-change-handler due to the change in window configuration. This time ignore is still t but force is t. The selected buffer is the minibuffer, so it dims all other buffers except the minibuffer. Ignore has no effect.

There are two predicates in the ignore list by default: which-key--popup-showing-p and window-minibuffer-p. Which-keys doesn't change the buffer, so we don't have the problem above. The code below will prevent the which-keys buffer from being dimmed. Switching to the minibuffer does have the problem above, and in fact, activating the minibuffer causes the current buffer to be dimmed. I'm not sure if this is intentional or not. However, if you move to another buffer (Ctrl-o) and then back to the minibuffer, it will leave the last active buffer before visiting the minibuffer un-dimmed. So it would seem that this is probably the desired behavior and the initial dimming of the buffer is a bug.

(if (or (eq buf selected)
                (and force (not (memq buf filtbufs))))
            (dimmer-restore-buffer buf)

Note that if you make the following change to dimmer-config-change-handler, the problem goes away. But this will probably break other things.

(defun dimmer-config-change-handler ()
  "Process all buffers if window configuration has changed."
  (dimmer--dbg-buffers 1 "dimmer-config-change-handler")
  (dimmer-process-all nil))
goldfita commented 1 year ago

I've started working on the lsp-ui issue. The following should do it.

(add-to-list
 'dimmer-prevent-dimming-predicates #'lsp-ui-doc--visible-p)

But it doesn't work. The function dimmer-config-change-handler is a hook on window-configuration-change-hook. It's getting called before lsp-ui-doc--visible-p becomes true. I'm not sure why this is. It could have something to do with the order in which the hooks are called. But I suspect it's because lsp-ui makes an asynchronous call to a language server. So displaying the frame is delayed.

Similarly, the function dimmer-command-handler should see that dimmer-last-buffer does not match the current buffer, but it gets called before the change takes place.

goldfita commented 1 year ago

I have a crummy workaround for lsp-ui-doc, but it seems to get the job done. It might be possible to add advice to lsp-ui-doc to create a predicate in such a way that there are no race conditions, but I don't want to spend three weeks on this.

  (defun dimmer-config-change-handler-patch (orig-fun &rest args)
    (run-at-time 0.2 nil #'apply orig-fun args))
  (advice-add 'dimmer-config-change-handler :around #'dimmer-config-change-handler-patch)
goldfita commented 1 year ago

The following configuration is a workaround for the modeline.

:custom
(dimmer-watch-frame-focus-events nil)
goldfita commented 1 year ago

I've also run into a problem with ediff in another frame. I added an exclusion predicate, which initially seemed to work. But as soon as I click on the other frame, it breaks. So, I'm guessing dimmer is not frame aware. Ultimately I disabled dimmer until the ediff frame is closed, which is a good-enough solution.