emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question about minibuffer and child frames (Posframe)


From: Gerd Möllmann
Subject: Re: Question about minibuffer and child frames (Posframe)
Date: Mon, 07 Oct 2024 10:00:11 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

Feng Shu <tumashu@163.com> writes:

> Gerd Möllmann <gerd.moellmann@gmail.com> writes:
>
>>> in posframe, cursor just a space with face of cursor.
>>
>> So Po Lu was remembering right!
>>
>> Do you perhaps know where that is done? I can't find it.
>>
>> Because it's definitely not working on ttys ATM. I mean the cursor in
>> the parent frame's minibuffer doesn't bother me too much. But I would
>> love it if something like a cursor appeared on the posframe.
>
> Sorry, I remeber wrong, in vertico-posframe, we use real cursor, see
> cursor-type in below function.
>
> (defun vertico-posframe--show (buffer window-point)
>   "`posframe-show' of vertico-posframe.
>
> BUFFER will be showed by `posframe-show'.  After `posframe-show'
> is called, window-point will be set to WINDOW-POINT."
>   (let ((posframe
>          ;; Some posframe poshandlers need infos of last-window.
>          (with-selected-window (vertico-posframe-last-window)
>            (apply #'posframe-show
>                   buffer
>
>                   ...
>
>                   (funcall (buffer-local-value 
> 'vertico-posframe-size-function buffer) buffer)))))
>     ;; NOTE: `posframe-show' will force set window-point to 0, so we
>     ;; need reset it again after `posframe-show'.
>     (when (numberp window-point)
>       (let ((window (frame-root-window posframe)))
>         (when (window-live-p window)
>           (set-window-point window window-point))))
>     ;; NOTE: posframe will hide cursor, so we need let it show again.
>     (with-current-buffer buffer
>       (setq-local cursor-type t)
>       (setq-local cursor-in-non-selected-windows 'box))))

Ahhhh, thanks! That explains it, because on ttys we have only one
cursor, the one of the terminal, and cursor-type is not implemented in
any way.

> But in ivy-posframe, we use space emular cursor instead:
>
> (defun ivy-posframe--add-prompt (fn &rest args)
>   "Add the ivy prompt to the posframe.  Advice FN with ARGS."
>   (apply fn args)
>   (when (and (display-graphic-p)
>              (not ivy-posframe--ignore-prompt))
>     (with-current-buffer (window-buffer (active-minibuffer-window))
>       (let ((point (point))
>             (prompt (buffer-string)))
>         (remove-text-properties 0 (length prompt) '(read-only nil) prompt)
>         (with-current-buffer ivy-posframe-buffer
>           (goto-char (point-min))
>           (delete-region (point) (line-beginning-position 2))
>           (insert prompt "  \n")
>           (add-text-properties point (1+ point) '(face 
> ivy-posframe-cursor))))))

Nice! I haven't tried it, but that should probably work fine on ttys. I
guess Vertico-posframe could do something similar.

I think I'll leave that alone for now, since the same problem occurs in
Vertico without Posframe.

>
>>
>>>> frame's minibuffer this time contains the prompt and the cursor, too.
>>>
>>> Maybe the below hack is not work well in tty
>>>
>>>    (set-window-vscroll minibuffer-window 100)
>>
>> Yes, that's it. It's a no-op on terminals. 
>>
>>> In my opinion, hide minibuffer's content just hack way, I can not find a
>>> better way to hide minibuffer window's content.
>>
>> Well, nobody could forsee that there would ever be child frames on tty
>> ;-). 
>
> Yes, I have tried many way to hide minibuffer's content, for example:
> creating a new posframe to mask minibuffer window, let minibuffer
> forecolor = backgroundcolor, but vscroll way is most stable, vertico's
> author tell me this way:

Yes, it's good. Nothing to say against it.

>> P.S.:
>>
>> As an aside, because that might affect Posframe maybe in the future. I
>> also implemented borders around child frames now, but in a strange way,
>> with the 'undecorated' frame parameter. If a tty child frame is not
>> undecorated, a border is drawn around it, otherwise it isn't.
>>
>> The reason for this strange way of doing things is that I quit in a rage
>> when trying to add the normal border handling for tty frames. Works for
>> me. Just mentioning it so that others can comment how terrible that is
>> :-).
>
> OK, border setting in posframe is not simple, by the way, how to handle
> border width in tty?

The corresponding frame parameters are completely ignored on ttys with
what I have. They always were ignored because they made no sense on
ttys. When I tried to add them for child frames, which I think would
admittedly be the right thing, I finally gave up after 2 hours.
Everything stopped working or crashed. Don't know if I pick that up
again. It cost me anough nerves that I finally git reset --hard :-/.

> ------------------------------------------------------------------
>
> By default, posframe shows no borders, but users can specify
> borders by setting BORDER-WIDTH to a positive number.  Border
> color can be specified by BORDER-COLOR.
>
> INTERNAL-BORDER-WIDTH and INTERNAL-BORDER-COLOR are same as
> BORDER-WIDTH and BORDER-COLOR, but do not suggest to use for the
> reason:
>
>    Add distinct controls for child frames' borders (Bug#45620)
>    
> http://git.savannah.gnu.org/cgit/emacs.git/commit/?id=ff7b1a133bfa7f2614650f8551824ffaef13fadc

My workaround for now (which I added because I wanted borders :-)) is
that redisplay adds borders to child frames, unless (undecored . nil) is
specified. It's basically acting like a window manager on X that adds
decorations. No changes to frame positions or size are necessary for a
user, everything works as befoer, except that one needs the frame
parameter.

The color of the border can be specified with the 'border' face. Haven't
checked yet if the border-color frame param works, but I believe it
does. Border widths can't be changed, they are always 1. The glyphs
displayed can be changed with display-table entries like so:

    (when (and (featurep 'tty-child-frames)
               (get 'box-vertical 'display-table-slot))
      (set-display-table-slot standard-display-table
                              'box-vertical (make-glyph-code #x2502))
      (set-display-table-slot standard-display-table
                              'box-horizontal (make-glyph-code #x2500))
      (set-display-table-slot standard-display-table
                              'box-down-right (make-glyph-code #x250c))
      (set-display-table-slot standard-display-table
                              'box-down-left (make-glyph-code #x2510))
      (set-display-table-slot standard-display-table
                              'box-up-right (make-glyph-code #x2514))
      (set-display-table-slot standard-display-table
                              'box-up-left (make-glyph-code #x2518))))

That's make it use Unicode box-drawing chars instead of +-|. Maybe
Unicode should be the default... Don't know.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]