unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* How can I force updating mini window's header line when mode line is updated?
@ 2018-04-25 12:41 Amos Bird
  2018-04-25 16:10 ` Eli Zaretskii
  2018-04-25 16:20 ` Stefan Monnier
  0 siblings, 2 replies; 9+ messages in thread
From: Amos Bird @ 2018-04-25 12:41 UTC (permalink / raw)
  To: help-gnu-emacs

Dear community,

I'm trying to setup one mode line per frame. Here is what I've 
done.

1. turn on the head line of mini window by tweaking 
window_wants_header_line.
2. change shrink_mini_window so that it shrinks mini window to two 
lines instead of one.
3. (setq-default header-line-format mode-line-format)

Here is what I got https://la.wentropy.com/48Yx.png

However the header line doesn't get updated at all. It seems 
xdisp.c only provides ways to update mode line, and I've reached 
the limit of my emacs-fu. How can I achieve this without hacking 
tons of the display logic? Many thanks!

regards,

--
Amos Bird
amosbird@gmail.com



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
  2018-04-25 12:41 How can I force updating mini window's header line when mode line is updated? Amos Bird
@ 2018-04-25 16:10 ` Eli Zaretskii
  2018-04-25 17:12   ` Amos Bird
  2018-04-25 16:20 ` Stefan Monnier
  1 sibling, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2018-04-25 16:10 UTC (permalink / raw)
  To: help-gnu-emacs

> From: Amos Bird <amosbird@gmail.com>
> Date: Wed, 25 Apr 2018 20:41:09 +0800
> 
> Dear community,
> 
> I'm trying to setup one mode line per frame. Here is what I've 
> done.
> 
> 1. turn on the head line of mini window by tweaking 
> window_wants_header_line.
> 2. change shrink_mini_window so that it shrinks mini window to two 
> lines instead of one.
> 3. (setq-default header-line-format mode-line-format)

It's great to hear someone hacks the display code to add features.
However, these issues are best discussed on emacs-devel, not here.
Who knows, we could even ask you to contribute the code ;-)

> However the header line doesn't get updated at all. It seems 
> xdisp.c only provides ways to update mode line, and I've reached 
> the limit of my emacs-fu. How can I achieve this without hacking 
> tons of the display logic? Many thanks!

I think you need to modify window_wants_header_line, it currently has
hard-wired knowledge that a minibuffer window will never display a
header line.

Once that is done, the feature should work, because the same triggers
that update the mode line also update the header line, so this:

> It seems xdisp.c only provides ways to update mode line

is inaccurate.  See the part of redisplay_window immediately following
the 'done' label: it calls display_mode_lines, which displays both the
mode line and the header line.



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
  2018-04-25 12:41 How can I force updating mini window's header line when mode line is updated? Amos Bird
  2018-04-25 16:10 ` Eli Zaretskii
@ 2018-04-25 16:20 ` Stefan Monnier
  2018-04-25 17:16   ` Amos Bird
  1 sibling, 1 reply; 9+ messages in thread
From: Stefan Monnier @ 2018-04-25 16:20 UTC (permalink / raw)
  To: help-gnu-emacs

> 3. (setq-default header-line-format mode-line-format)

Hmm... this would put a header-line on all windows, whereas IIUC you
want a header-line only for the mini-window, right?

> However the header line doesn't get updated at all.

A window's header-line (and mode-line) will normally only be
updated if something happens in this window that would require
updating it.  Part of this detection of when update is needed is
automatic, tho not all of it (so Elisp code sometimes has to call
force-mode-line-update).

In your case, the header-line belongs to the mini-window, so this
detection (and most of existing Elisp code calling
force-mode-line-update) won't help because it will only detect a need
for update when the *mini-window* is affected, whereas you most likely
want to update it in many other cases.

So you'll probably want to add some `post-command-hook` (and/or other
related hooks) to try and detect when an update is needed, at which
point you'll need to do

    (with-current-buffer <mini-window-buffer> (force-mode-line-update))

> It seems xdisp.c only
> provides ways to update mode line, and I've reached the limit of my
> emacs-fu. How can I achieve this without hacking tons of the display logic?

AFAIK the redisplay doesn't really distinguish the mode-line from the
header-line in this respect (e.g. force-mode-line-update will cause both
the mode-line and the header-line to be refreshed).


        Stefan




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
  2018-04-25 16:10 ` Eli Zaretskii
@ 2018-04-25 17:12   ` Amos Bird
  0 siblings, 0 replies; 9+ messages in thread
From: Amos Bird @ 2018-04-25 17:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: help-gnu-emacs


Thanks for the kind help. I've made some progress and I'll report 
it on emacs-devel :)

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Amos Bird <amosbird@gmail.com>
>> Date: Wed, 25 Apr 2018 20:41:09 +0800
>>
>> Dear community,
>>
>> I'm trying to setup one mode line per frame. Here is what I've
>> done.
>>
>> 1. turn on the head line of mini window by tweaking
>> window_wants_header_line.
>> 2. change shrink_mini_window so that it shrinks mini window to 
>> two
>> lines instead of one.
>> 3. (setq-default header-line-format mode-line-format)
>
> It's great to hear someone hacks the display code to add 
> features.
> However, these issues are best discussed on emacs-devel, not 
> here.
> Who knows, we could even ask you to contribute the code ;-)
>
>> However the header line doesn't get updated at all. It seems
>> xdisp.c only provides ways to update mode line, and I've 
>> reached
>> the limit of my emacs-fu. How can I achieve this without 
>> hacking
>> tons of the display logic? Many thanks!
>
> I think you need to modify window_wants_header_line, it 
> currently has
> hard-wired knowledge that a minibuffer window will never display 
> a
> header line.
>
> Once that is done, the feature should work, because the same 
> triggers
> that update the mode line also update the header line, so this:
>
>> It seems xdisp.c only provides ways to update mode line
>
> is inaccurate.  See the part of redisplay_window immediately 
> following
> the 'done' label: it calls display_mode_lines, which displays 
> both the
> mode line and the header line.


--
Amos Bird
amosbird@gmail.com



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
  2018-04-25 16:20 ` Stefan Monnier
@ 2018-04-25 17:16   ` Amos Bird
  0 siblings, 0 replies; 9+ messages in thread
From: Amos Bird @ 2018-04-25 17:16 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: help-gnu-emacs


Thanks!

Um I'm afraid post-command-hook might not help here. Emacs code 
has deep assumption of mini window having only one line. After I 
turn on the header line, things become messy. I'll try collecting 
all the hard-coded logic and see if this route indeed works.

Here is what I've achieved so far 
https://la.wentropy.com/WYjq.webm

regards,

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> 3. (setq-default header-line-format mode-line-format)
>
> Hmm... this would put a header-line on all windows, whereas IIUC 
> you
> want a header-line only for the mini-window, right?
>
>> However the header line doesn't get updated at all.
>
> A window's header-line (and mode-line) will normally only be
> updated if something happens in this window that would require
> updating it.  Part of this detection of when update is needed is
> automatic, tho not all of it (so Elisp code sometimes has to 
> call
> force-mode-line-update).
>
> In your case, the header-line belongs to the mini-window, so 
> this
> detection (and most of existing Elisp code calling
> force-mode-line-update) won't help because it will only detect a 
> need
> for update when the *mini-window* is affected, whereas you most 
> likely
> want to update it in many other cases.
>
> So you'll probably want to add some `post-command-hook` (and/or 
> other
> related hooks) to try and detect when an update is needed, at 
> which
> point you'll need to do
>
>     (with-current-buffer <mini-window-buffer> 
>     (force-mode-line-update))
>
>> It seems xdisp.c only
>> provides ways to update mode line, and I've reached the limit 
>> of my
>> emacs-fu. How can I achieve this without hacking tons of the 
>> display logic?
>
> AFAIK the redisplay doesn't really distinguish the mode-line 
> from the
> header-line in this respect (e.g. force-mode-line-update will 
> cause both
> the mode-line and the header-line to be refreshed).
>
>
>         Stefan


--
Amos Bird
amosbird@gmail.com



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
@ 2018-04-26  7:04 martin rudalics
  2018-04-27  2:52 ` Amos Bird
  2018-06-27 15:14 ` John Yates
  0 siblings, 2 replies; 9+ messages in thread
From: martin rudalics @ 2018-04-26  7:04 UTC (permalink / raw)
  To: amosbird; +Cc: help-gnu-emacs

 > Emacs code has deep assumption of mini window having only one line.

This is not entirely correct.  As long as other windows on the same
frame fit, a minibuffer window can get quite large (see
'max-mini-window-height').  But in some parts of the window and
redisplay code we assume that minibuffer windows behave like pseudo
windows (those used for displaying the tool bar or the menu bar on
some platforms) or internal windows - they can't have dividers, a mode
or a header line because these are simply not counted when displaying
the window or calculating its height.  That's why you observe that

 > After I turn on the header line, things become messy.

For example, 'window_wants_header_line' in window.c cannot deal with
that.

 > I'll try
 > collecting all the hard-coded logic and see if this route indeed
 > works.

Good idea.  Note that I'm currently changing a number of things
related to minibuffer windows which, among others, should allow them
to appear anywhere on a frame or even not being displayed at all.  So
I do not think that displaying the mode line of a frame within the
minibuffer window is a good idea in the first place.  Even presently,
people who use standalone minibuffer frames might not be very
enthralled by the idea that they have to look on their minibuffer
frame for consulting the mode line contents.

I think that if we want frame-local modelines which, IIUC should
display the mode line contents of the frame's selected window, it
might be a better idea to add a new kind of pseudo window on top or
bottom of a frame for that.

martin



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
  2018-04-26  7:04 martin rudalics
@ 2018-04-27  2:52 ` Amos Bird
  2018-06-27 15:14 ` John Yates
  1 sibling, 0 replies; 9+ messages in thread
From: Amos Bird @ 2018-04-27  2:52 UTC (permalink / raw)
  To: martin rudalics; +Cc: help-gnu-emacs


Yeah, I think using mini window's header line is indeed a nasty 
idea,
but it somehow fits my need (both in GUI and terminal emacs).

I've hacked some xdisp code and it works now.

https://github.com/amosbird/emacs/tree/onemodeline

Here is what I've done.

1. turn on the head line of mini window by tweaking 
window_wants_header_line.
2. change a bunch of functions that initialize mini-window size to 
2 instead of 1.
3. hide normal window's mode line if it's at bottom
4. always use inactive mode line format and empty string content 
for normal window
(used to build horizontal divider in terminal)
5. refresh mini window's header line on every window's redisplay 
action.
6. make sure mode line format uses previous-window if mini window 
is selected

It seems to cover all the corner cases I can reach in both GUI and 
terminal.
(minibuffer resizing, frame/window switching, frame 
creation/deletion...)

Here is a demo screencast in terminal emacs.

https://youtu.be/OSv5JCIlPZA

regards,

martin rudalics <rudalics@gmx.at> writes:

>> Emacs code has deep assumption of mini window having only one 
>> line.
>
> This is not entirely correct.  As long as other windows on the 
> same
> frame fit, a minibuffer window can get quite large (see
> 'max-mini-window-height').  But in some parts of the window and
> redisplay code we assume that minibuffer windows behave like 
> pseudo
> windows (those used for displaying the tool bar or the menu bar 
> on
> some platforms) or internal windows - they can't have dividers, 
> a mode
> or a header line because these are simply not counted when 
> displaying
> the window or calculating its height.  That's why you observe 
> that
>
>> After I turn on the header line, things become messy.
>
> For example, 'window_wants_header_line' in window.c cannot deal 
> with
> that.
>
>> I'll try
>> collecting all the hard-coded logic and see if this route 
>> indeed
>> works.
>
> Good idea.  Note that I'm currently changing a number of things
> related to minibuffer windows which, among others, should allow 
> them
> to appear anywhere on a frame or even not being displayed at 
> all.  So
> I do not think that displaying the mode line of a frame within 
> the
> minibuffer window is a good idea in the first place.  Even 
> presently,
> people who use standalone minibuffer frames might not be very
> enthralled by the idea that they have to look on their 
> minibuffer
> frame for consulting the mode line contents.
>
> I think that if we want frame-local modelines which, IIUC should
> display the mode line contents of the frame's selected window, 
> it
> might be a better idea to add a new kind of pseudo window on top 
> or
> bottom of a frame for that.
>
> martin


--
Amos Bird
amosbird@gmail.com



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
  2018-04-26  7:04 martin rudalics
  2018-04-27  2:52 ` Amos Bird
@ 2018-06-27 15:14 ` John Yates
  2018-06-28  7:37   ` martin rudalics
  1 sibling, 1 reply; 9+ messages in thread
From: John Yates @ 2018-06-27 15:14 UTC (permalink / raw)
  To: martin rudalics; +Cc: help-gnu-emacs, amosbird

On Thu, Apr 26, 2018 at 3:05 AM martin rudalics <rudalics@gmx.at> wrote:
> Note that I'm currently changing a number of things
> related to minibuffer windows which, among others, should allow them
> to appear anywhere on a frame or even not being displayed at all.

That's great news.  Availability of such support will go a long ways
toward allowing me to achieve (at least experiment with) the layout
I long for.  The other feature would be positioning the modeline at
the top of windows, above even any header line.  Any chance of that
happening?

/john



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: How can I force updating mini window's header line when mode line is updated?
  2018-06-27 15:14 ` John Yates
@ 2018-06-28  7:37   ` martin rudalics
  0 siblings, 0 replies; 9+ messages in thread
From: martin rudalics @ 2018-06-28  7:37 UTC (permalink / raw)
  To: John Yates; +Cc: help-gnu-emacs, amosbird

 > The other feature would be positioning the modeline at
 > the top of windows, above even any header line.  Any chance of that
 > happening?

That's fairly trivial and works here already.

martin



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-06-28  7:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-04-25 12:41 How can I force updating mini window's header line when mode line is updated? Amos Bird
2018-04-25 16:10 ` Eli Zaretskii
2018-04-25 17:12   ` Amos Bird
2018-04-25 16:20 ` Stefan Monnier
2018-04-25 17:16   ` Amos Bird
  -- strict thread matches above, loose matches on Subject: below --
2018-04-26  7:04 martin rudalics
2018-04-27  2:52 ` Amos Bird
2018-06-27 15:14 ` John Yates
2018-06-28  7:37   ` martin rudalics

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).