* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) @ 2023-07-13 13:00 Ihor Radchenko 2023-07-13 13:34 ` Eli Zaretskii 2023-07-13 17:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 2 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-13 13:00 UTC (permalink / raw) To: 64596 Hello, `force-mode-line-update' has the following FIXME: if (!NILP (all)) { update_mode_lines = 10; /* FIXME: This can't be right. */ current_buffer->prevent_redisplay_optimizations_p = true; } else if (buffer_window_count (current_buffer)) { bset_update_mode_line (current_buffer); current_buffer->prevent_redisplay_optimizations_p = true; } This FIXME has been introduced in 655ab9a3800, shortly after ecda65d4f7e, which moved this code from `set-buffer-modified-p'. AFAIU, the purpose of disabling redisplay optimizations is avoiding the situation when the modification flag is unset in the buffer, but the buffer was actually modified, and has to be redrawn. If my understanding is correct, current_buffer->prevent_redisplay_optimizations_p = true does not belong to `force-mode-line-update', but rather to `restore-buffer-modified-p'. I also grepped through src/display.c looking at the usage of update_mode_lines, and there seems to be no obvious situation where update_mode_lines being non-nil is ignored. In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38, cairo version 1.17.8) of 2023-07-06 built on localhost Repository revision: d97b77e6c66db46b198c696f83458aa141794727 Repository branch: master Windowing system distributor 'The X.Org Foundation', version 11.0.12101008 System Description: Gentoo Linux -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 13:00 bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) Ihor Radchenko @ 2023-07-13 13:34 ` Eli Zaretskii 2023-07-13 17:19 ` Ihor Radchenko 2023-07-14 11:53 ` Ihor Radchenko 2023-07-13 17:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-13 13:34 UTC (permalink / raw) To: Ihor Radchenko, Stefan Monnier; +Cc: 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Date: Thu, 13 Jul 2023 13:00:26 +0000 > > `force-mode-line-update' has the following FIXME: > > if (!NILP (all)) > { > update_mode_lines = 10; > /* FIXME: This can't be right. */ > current_buffer->prevent_redisplay_optimizations_p = true; > } > else if (buffer_window_count (current_buffer)) > { > bset_update_mode_line (current_buffer); > current_buffer->prevent_redisplay_optimizations_p = true; > } > > This FIXME has been introduced in 655ab9a3800, shortly after > ecda65d4f7e, which moved this code from `set-buffer-modified-p'. Yes, it was part of Stefan's effort to make redisplay less expensive by avoiding too thorough redisplay in as many use cases as possible. > AFAIU, the purpose of disabling redisplay optimizations is avoiding the > situation when the modification flag is unset in the buffer, but the > buffer was actually modified, and has to be redrawn. No, it's more subtle. In a nutshell, it is meant to prevent redisplay from applying certain optimizations (search xdisp.c for the uses of this flag). These optimizations are based on various assumptions, such as that the current glyph matrix of the window is up-to-date. Setting the prevent_redisplay_optimizations_p flag tells the display engine that those assumptions are (or might be) false. Updating the mode line usually requires more thorough redisplay, especially when the only reason for that is that some Lisp called force-mode-line-update -- without setting that flag, the display engine could easily decide that the window doesn't need to be redrawn. > If my understanding is correct, > current_buffer->prevent_redisplay_optimizations_p = true does not belong > to `force-mode-line-update', but rather to `restore-buffer-modified-p'. The purpose of force-mode-line-update is to do what its name says, regardless of whether the buffer was modified or not, and how it was modified. The idea is that Lisp programs which change something that they know must affect the mode line call this function to make sure the mode line is redrawn with up-to-date information. By contrast, buffer modifications could be such that don't affect redisplay at all, or allow redisplay to use some shortcuts and redraw only a very small portion of the window. > I also grepped through src/display.c looking at the usage of > update_mode_lines, and there seems to be no obvious situation where > update_mode_lines being non-nil is ignored. Stefan will tell, but I'm quite sure he wrote that FIXME because removing that line caused regression in some situation. I see that this flag is tested without also testing update_mode_lines in window-lines-pixel-dimensions, window-line-height, window-end, redisplay_window, try_window_id, and display_line. So I don't think I agree with your conclusion. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 13:34 ` Eli Zaretskii @ 2023-07-13 17:19 ` Ihor Radchenko 2023-07-13 19:03 ` Eli Zaretskii 2023-07-14 11:53 ` Ihor Radchenko 1 sibling, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-13 17:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> If my understanding is correct, >> current_buffer->prevent_redisplay_optimizations_p = true does not belong >> to `force-mode-line-update', but rather to `restore-buffer-modified-p'. > > The purpose of force-mode-line-update is to do what its name says, > regardless of whether the buffer was modified or not, and how it was > modified. The idea is that Lisp programs which change something that > they know must affect the mode line call this function to make sure > the mode line is redrawn with up-to-date information. I do not claim that I fully understand, but what is confusing is that a number of other places in code simply use bset_update_mode_line without disabling optimizations. In particular: 1. kill-all-local-variables 2. rename-buffer Also, `force-window-update' disable optimizations for a given window, but not when all windows should be updated - in contrast with the code in OP. So, `force-window-update' and `force-mode-line-update' are at least inconsistent. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 17:19 ` Ihor Radchenko @ 2023-07-13 19:03 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-13 19:03 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, 64596@debbugs.gnu.org > Date: Thu, 13 Jul 2023 17:19:29 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > > The purpose of force-mode-line-update is to do what its name says, > > regardless of whether the buffer was modified or not, and how it was > > modified. The idea is that Lisp programs which change something that > > they know must affect the mode line call this function to make sure > > the mode line is redrawn with up-to-date information. > > I do not claim that I fully understand Who does, when it comes to the display code? > but what is confusing is that a number of other places in code > simply use bset_update_mode_line without disabling optimizations. In > particular: > > 1. kill-all-local-variables > 2. rename-buffer bset_update_mode_line is for a single buffer, whereas the FIXME is for the case where force-mode-line-update is called with a non-nil ALL argument. > Also, `force-window-update' disable optimizations for a given window, > but not when all windows should be updated - in contrast with the code > in OP. When all the windows need to be updated, we force that via windows_or_buffers_changed, which is a somewhat stronger flag, as far as preventing optimizations goes. > So, `force-window-update' and `force-mode-line-update' are at least > inconsistent. Why should they be entirely consistent? They do different jobs. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 13:34 ` Eli Zaretskii 2023-07-13 17:19 ` Ihor Radchenko @ 2023-07-14 11:53 ` Ihor Radchenko 2023-07-14 12:25 ` Eli Zaretskii 2023-07-14 14:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-14 11:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> AFAIU, the purpose of disabling redisplay optimizations is avoiding the >> situation when the modification flag is unset in the buffer, but the >> buffer was actually modified, and has to be redrawn. > > No, it's more subtle. In a nutshell, it is meant to prevent redisplay > from applying certain optimizations (search xdisp.c for the uses of > this flag). These optimizations are based on various assumptions, > such as that the current glyph matrix of the window is up-to-date. > Setting the prevent_redisplay_optimizations_p flag tells the display > engine that those assumptions are (or might be) false. I'm afraid that the very existence of prevent_redisplay_optimizations_p flag is a mistake hiding bugs with redisplay optimizations logic. Currently, redisplay_internal has a number of conditions used to determine if one or another optimization is safe to use + assertion that !prevent_redisplay_optimizations_p. When some code outside xdisp.c sets this flag, it is nothing but a statement: "I was lazy enough to update xdisp.c properly, so I just force bypassing optimizations". > Updating the mode line usually requires more thorough redisplay, > especially when the only reason for that is that some Lisp called > force-mode-line-update -- without setting that flag, the display > engine could easily decide that the window doesn't need to be redrawn. I have explored xdisp a bit and AFAIU, once we are in redisplay_window, mode line will be updated as long as update_mode_line is set (at least to UPDATE_SOME), except when current window is MINI_WINDOW_P (this code branch is not prevented by prevent_redisplay_optimizations_p though) or when we give up redisplaying. Calling redisplay_window may be prevented via needs_no_redisplay, unless we have buffer->text->redisplay, which is set in bset_update_mode_line. [ setting buffer->text->redisplay is rather awkward way to single mode line update though ] redisplay_window may also be postponed for frames that are not visible or that are obscured, but it appears to be by design and not influenced by prevent_redisplay_optimizations_p anyway 😕 So, I see not why calling bset_update_mode_line is not sufficient to force mode line update in all windows associated with a single buffer. >> If my understanding is correct, >> current_buffer->prevent_redisplay_optimizations_p = true does not belong >> to `force-mode-line-update', but rather to `restore-buffer-modified-p'. > > The purpose of force-mode-line-update is to do what its name says, > regardless of whether the buffer was modified or not, and how it was > modified. The idea is that Lisp programs which change something that > they know must affect the mode line call this function to make sure > the mode line is redrawn with up-to-date information. By contrast, > buffer modifications could be such that don't affect redisplay at all, > or allow redisplay to use some shortcuts and redraw only a very small > portion of the window. Then, why do we need to call Fforce_mode_line_update in set-buffer-modified-p? Wouldn't calling bset_redisplay be better? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 11:53 ` Ihor Radchenko @ 2023-07-14 12:25 ` Eli Zaretskii 2023-07-14 13:48 ` Ihor Radchenko 2023-07-14 14:50 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 14:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-14 12:25 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, 64596@debbugs.gnu.org > Date: Fri, 14 Jul 2023 11:53:02 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > > No, it's more subtle. In a nutshell, it is meant to prevent redisplay > > from applying certain optimizations (search xdisp.c for the uses of > > this flag). These optimizations are based on various assumptions, > > such as that the current glyph matrix of the window is up-to-date. > > Setting the prevent_redisplay_optimizations_p flag tells the display > > engine that those assumptions are (or might be) false. > > I'm afraid that the very existence of prevent_redisplay_optimizations_p > flag is a mistake hiding bugs with redisplay optimizations logic. I think you should avoid making such comments until you have a better understanding of the redisplay logic, or else I will stop taking your posts in this matter seriously. > Currently, redisplay_internal has a number of conditions used to > determine if one or another optimization is safe to use + assertion that > !prevent_redisplay_optimizations_p. > > When some code outside xdisp.c sets this flag, it is nothing but a > statement: "I was lazy enough to update xdisp.c properly, so I just > force bypassing optimizations". No. The optimization in question, which is disabled when prevent_redisplay_optimizations_p flag is set for the current buffer, is described in the comment before the condition: /* Optimize the case that only the line containing the cursor in the selected window has changed. The prevent_redisplay_optimizations_p flag says, among other things, that we are not in that case, and it is tested early enough in order to prevent us from examining additional conditions which are just waste of CPU cycles (and some of them are relatively expensive). > > Updating the mode line usually requires more thorough redisplay, > > especially when the only reason for that is that some Lisp called > > force-mode-line-update -- without setting that flag, the display > > engine could easily decide that the window doesn't need to be redrawn. > > I have explored xdisp a bit and AFAIU, once we are in redisplay_window, > mode line will be updated as long as update_mode_line is set (at least > to UPDATE_SOME), except when current window is MINI_WINDOW_P (this code > branch is not prevented by prevent_redisplay_optimizations_p though) or > when we give up redisplaying. > > Calling redisplay_window may be prevented via needs_no_redisplay, unless > we have buffer->text->redisplay, which is set in bset_update_mode_line. > [ setting buffer->text->redisplay is rather awkward way to single mode > line update though ] > > redisplay_window may also be postponed for frames that are not visible > or that are obscured, but it appears to be by design and not influenced > by prevent_redisplay_optimizations_p anyway 😕 > > So, I see not why calling bset_update_mode_line is not sufficient to > force mode line update in all windows associated with a single buffer. The mode line displays quite a lot of information. It could also display information we don't know about (on the level of the redisplay code), because mode-line-format supports :eval, which can execute any Lisp. Therefore, there could be changes to the buffer that affect the mode line indirectly. One problem of this kind which we had relatively recently is when the changes in mode-line-format or some of its :eval forms yields a mode line that is significantly taller or smaller than the previously displayed one. Such changes in the mode-line height generally affect the window(s) as well, not just the mode line itself. Moreover, you will see in the wild that force-mode-line-update is used not just to update the mode line, but also to force a more thorough redisplay of one or more windows. Thus, this is not as simple a problem as you seem to think, and we need deeper analysis and more significant changes than simply deleting the code that you didn't understand and think is redundant. Please keep in mind that people who wrote that code (and I don't mean myself) were not stupid at all, and generally knew what they were doing! > >> If my understanding is correct, > >> current_buffer->prevent_redisplay_optimizations_p = true does not belong > >> to `force-mode-line-update', but rather to `restore-buffer-modified-p'. > > > > The purpose of force-mode-line-update is to do what its name says, > > regardless of whether the buffer was modified or not, and how it was > > modified. The idea is that Lisp programs which change something that > > they know must affect the mode line call this function to make sure > > the mode line is redrawn with up-to-date information. By contrast, > > buffer modifications could be such that don't affect redisplay at all, > > or allow redisplay to use some shortcuts and redraw only a very small > > portion of the window. > > Then, why do we need to call Fforce_mode_line_update in > set-buffer-modified-p? Wouldn't calling bset_redisplay be better? You have read the large comment there which attempts to answer this question, didn't you? ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 12:25 ` Eli Zaretskii @ 2023-07-14 13:48 ` Ihor Radchenko 2023-07-14 14:20 ` Eli Zaretskii 2023-07-14 14:50 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-14 13:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> I'm afraid that the very existence of prevent_redisplay_optimizations_p >> flag is a mistake hiding bugs with redisplay optimizations logic. > > I think you should avoid making such comments until you have a better > understanding of the redisplay logic, or else I will stop taking your > posts in this matter seriously. Your answer indicates that I missed something important after reading the top comment in xdisp.c, redisplay_internal, redisplay_window, and skimmed through a couple of other functions. But I still cannot figure out what. Note that I did not mean that previous committers had bad intentions. I just think that the idea of having "disable all optimizations" flag is causing the code quality that could be otherwise somewhat better (at least, more explicit about why redisplay should take long path). I think that replacing all the instances of setting this flag to more explicit alternatives would improve the display performance and also readability. >> Currently, redisplay_internal has a number of conditions used to >> determine if one or another optimization is safe to use + assertion that >> !prevent_redisplay_optimizations_p. >> >> When some code outside xdisp.c sets this flag, it is nothing but a >> statement: "I was lazy enough to update xdisp.c properly, so I just >> force bypassing optimizations". > > No. The optimization in question, which is disabled when > prevent_redisplay_optimizations_p flag is set for the current buffer, > is described in the comment before the condition: > > /* Optimize the case that only the line containing the cursor in the > selected window has changed. > > The prevent_redisplay_optimizations_p flag says, among other things, > that we are not in that case, and it is tested early enough in order > to prevent us from examining additional conditions which are just > waste of CPU cycles (and some of them are relatively expensive). Sure, but it is a very generic way to say this. It provides no detailed reason what exactly changed in the buffer/window/frame that makes us bypass this optimization. Is it not always possible to use the other, more specific, existing flags for redisplay to indicate that something important has been changed? >> So, I see not why calling bset_update_mode_line is not sufficient to >> force mode line update in all windows associated with a single buffer. > > The mode line displays quite a lot of information. It could also > display information we don't know about (on the level of the redisplay > code), because mode-line-format supports :eval, which can execute any > Lisp. Therefore, there could be changes to the buffer that affect the > mode line indirectly. But isn't :eval processed by display_mode_lines? Once we take care to call bset_update_mode_line, display_mode_lines is guaranteed to be executed, AFAIU. > One problem of this kind which we had relatively recently is when the > changes in mode-line-format or some of its :eval forms yields a mode > line that is significantly taller or smaller than the previously > displayed one. Such changes in the mode-line height generally affect > the window(s) as well, not just the mode line itself. Sure, and redisplay_window accounts for this when calling display_mode_lines: display_mode_lines (w); unbind_to (count1, Qnil); /* If mode line height has changed, arrange for a thorough immediate redisplay using the correct mode line height. */ if (window_wants_mode_line (w) && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w)) { f->fonts_changed = true; w->mode_line_height = -1; MATRIX_MODE_LINE_ROW (w->current_matrix)->height = DESIRED_MODE_LINE_HEIGHT (w); } > Moreover, you will see in the wild that force-mode-line-update is used > not just to update the mode line, but also to force a more thorough > redisplay of one or more windows. Why not `force-window-update'? > Thus, this is not as simple a problem as you seem to think, and we > need deeper analysis and more significant changes than simply deleting > the code that you didn't understand and think is redundant. Please > keep in mind that people who wrote that code (and I don't mean myself) > were not stupid at all, and generally knew what they were doing! I understand, which is why I looked into git history and found that the code in question is carried over during refactoring. Into a new function with different meaning. And I now looked deeper into the code, and see no obvious downsides of removing current_buffer->prevent_redisplay_optimizations_p = true; from force-mode-line-update specifically. `set-buffer-modified-p' may need to be re-considered though as it is the original place where setting prevent_redisplay_optimizations_p was done (for different reasons). >> > The purpose of force-mode-line-update is to do what its name says, >> ... >> Then, why do we need to call Fforce_mode_line_update in >> set-buffer-modified-p? Wouldn't calling bset_redisplay be better? > > You have read the large comment there which attempts to answer this > question, didn't you? Yup, I did. I thought bset_redisplay as an alternative, because it is smarter than bset_update_mode_line when the buffer is displayed in selected window (it is not necessary to assign DISPLAY_SOME flags). However, I did miss the docstring that explicitly says that `set-buffer-modified-p' forces mode line update. So, forcing mode line update here is simply following the docstring and should not be disputed. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 13:48 ` Ihor Radchenko @ 2023-07-14 14:20 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-14 14:20 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Fri, 14 Jul 2023 13:48:43 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> I'm afraid that the very existence of prevent_redisplay_optimizations_p > >> flag is a mistake hiding bugs with redisplay optimizations logic. > > > > I think you should avoid making such comments until you have a better > > understanding of the redisplay logic, or else I will stop taking your > > posts in this matter seriously. > > Your answer indicates that I missed something important after reading > the top comment in xdisp.c, redisplay_internal, redisplay_window, and > skimmed through a couple of other functions. But I still cannot figure > out what. Keep studying the code, is all I can suggest. There's much more there than meets the eye, IME. > Note that I did not mean that previous committers had bad intentions. I > just think that the idea of having "disable all optimizations" flag is > causing the code quality that could be otherwise somewhat better (at > least, more explicit about why redisplay should take long path). I agree that the underlying logic is somewhat subtle, and sometimes even mysterious, and I suggested a way to make this logic more explicit and better documented. But removing parts of display code because we don't always understand it is a bad idea, IME, and usually leads to bugs. So it is a non-starter, as far as I'm concerned. > I think that replacing all the instances of setting this flag to more > explicit alternatives would improve the display performance and also > readability. It's possible. But to consider such suggestions, I'd need to see a detailed proposal backed up by serious analysis. In any case, whether it will make performance better is not yet clear; the original motivation for this was not a performance issue at all. > > /* Optimize the case that only the line containing the cursor in the > > selected window has changed. > > > > The prevent_redisplay_optimizations_p flag says, among other things, > > that we are not in that case, and it is tested early enough in order > > to prevent us from examining additional conditions which are just > > waste of CPU cycles (and some of them are relatively expensive). > > Sure, but it is a very generic way to say this. It provides no detailed > reason what exactly changed in the buffer/window/frame that makes us > bypass this optimization. What detailed reasons would you like to see? > Is it not always possible to use the other, more specific, existing > flags for redisplay to indicate that something important has been changed? Which other flags? And why do you think they are more specific? At least some of them are actually _less_ specific. > >> So, I see not why calling bset_update_mode_line is not sufficient to > >> force mode line update in all windows associated with a single buffer. > > > > The mode line displays quite a lot of information. It could also > > display information we don't know about (on the level of the redisplay > > code), because mode-line-format supports :eval, which can execute any > > Lisp. Therefore, there could be changes to the buffer that affect the > > mode line indirectly. > > But isn't :eval processed by display_mode_lines? Once we take care to call > bset_update_mode_line, display_mode_lines is guaranteed to be executed, > AFAIU. Executed, but with what data? redisplay_window is a large function, and employs quite a few of shortcuts. If one of those shortcuts is taken when it shouldn't be, the data shown on the mode line might be inaccurate, because some of the variables affecting it were not updated. But let me turn the table and ask you: suppose that the prevent_redisplay_optimizations_p flag is not needed for updating the mode line per se -- what damage could it possibly do to redisplaying the mode line? why are you so eager to remove that setting from force-mode-line-update? > > One problem of this kind which we had relatively recently is when the > > changes in mode-line-format or some of its :eval forms yields a mode > > line that is significantly taller or smaller than the previously > > displayed one. Such changes in the mode-line height generally affect > > the window(s) as well, not just the mode line itself. > > Sure, and redisplay_window accounts for this when calling display_mode_lines: > > display_mode_lines (w); > unbind_to (count1, Qnil); > > /* If mode line height has changed, arrange for a thorough > immediate redisplay using the correct mode line height. */ > if (window_wants_mode_line (w) > && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w)) > { > f->fonts_changed = true; > w->mode_line_height = -1; > MATRIX_MODE_LINE_ROW (w->current_matrix)->height > = DESIRED_MODE_LINE_HEIGHT (w); > } And if you've read the relevant bug reports, this doesn't always work. But this is just an example, so even if you consider it to be solved, it tells us that there can be other issues like that. We are trying, slowly, to go from general flags to more specific ones, but we are not there yet, and removing code in this situation will just produce more buggy redisplay. I cannot agree to that. > > Moreover, you will see in the wild that force-mode-line-update is used > > not just to update the mode line, but also to force a more thorough > > redisplay of one or more windows. > > Why not `force-window-update'? Why does it matter? they both do almost the same (when the argument to force-window-update is a window). > And I now looked deeper into the code, and see no obvious downsides of > removing current_buffer->prevent_redisplay_optimizations_p = true; from > force-mode-line-update specifically. > `set-buffer-modified-p' may need to be re-considered though as it is the > original place where setting prevent_redisplay_optimizations_p was done > (for different reasons). Again, removing this is a non-starter, except if you want to do it locally. If we want to make any progress in this area in general, we should take one of the two approaches I described in my previous message. Anything else is simply irresponsible, and won't happen on my watch, sorry. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 12:25 ` Eli Zaretskii 2023-07-14 13:48 ` Ihor Radchenko @ 2023-07-14 14:50 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 0 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 14:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Ihor Radchenko, 64596 > Moreover, you will see in the wild that force-mode-line-update is used > not just to update the mode line, but also to force a more thorough > redisplay of one or more windows. AFAIK these are bugs and we should not hide them by making `force-mode-line-update` do more than what it's designed to do. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 11:53 ` Ihor Radchenko 2023-07-14 12:25 ` Eli Zaretskii @ 2023-07-14 14:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 15:56 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 14:20 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Eli Zaretskii, 64596 > I'm afraid that the very existence of prevent_redisplay_optimizations_p > flag is a mistake hiding bugs with redisplay optimizations logic. It's not that simple: the reliable way to do redisplay is to recompute the whole glyph matrix anew for all windows every time any change occurs. But that's unrealistic Instead, we decouple the redisplay from the buffer modifications. In addition we try to keep track of which parts may need to be redisplayed. For that we use various auxiliary variables which the code performing modifications can set to tell the redisplay about which parts may need to be redisplayed. Such variables include the `redisplay` and the `update_mode_line` bits, buffer vars that keep track of a buffer-interval outside of which there has not been any buffer changes, ... `prevent_redisplay_optimizations_p` is just another of those vars. The problem with that var is not its existence but the fact that by now noone knows what it means, so we can't touch that code, basically :-( > So, I see not why calling bset_update_mode_line is not sufficient to > force mode line update in all windows associated with a single buffer. I suspect the `prevent_redisplay_optimizations_p` is/was not meant to make sure the modeline is updated, but to make sure some other part of the window is/was also updated, but the code that decides whether to redraw that other part never looked at `update_mode_line`. E.g. maybe some code caused the mode-line or header-line to appear/disappear and thus called `force-mode-line-update` for that purpose, but the redisplay failed to notice that it needed to redraw parts of the buffer text in response o that change, so the "quick fix" was to set `prevent_redisplay_optimizations_p`? [ This is a completely hypothetical scenario, I have no idea how this code came about. ] > Then, why do we need to call Fforce_mode_line_update in > set-buffer-modified-p? I don't know if it's still needed, or (if it is) whether it's the best way to get the result nowadays, but I know why it's done: it's simply because Fforce_mode_line_update used not to exist and instead the standard way to force a mode-line update was to call `set-buffer-modified-p` (yeah, I know it's weird, but that was simply the cheapest operation exposed to ELisp that happened to set the needed flags for the redisplay). `force-mode-line-update` was introduced as a cleaner API (but still implemented by calling `set-buffer-modified-p`), so when I "straightened things out" by making `force-mode-line-update` set the redisplay flags directly, I made `set-buffer-modified-p` call `Fforce_mode_line_update` to be sure that any old code out there calling `set-buffer-modified-p` to force a mode line update would keep working as well as before. > Wouldn't calling bset_redisplay be better? Maybe (depends whether the redisplay code on its own checks stores the old modified-p value to detect when it has changed), tho I doubt it matters very much. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 14:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 15:56 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-14 15:56 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Fri, 14 Jul 2023 10:20:32 -0400 > > `prevent_redisplay_optimizations_p` is just another of those vars. > The problem with that var is not its existence but the fact that by now > noone knows what it means, so we can't touch that code, basically :-( I think we can touch that code, but we need to do it carefully, and we need to leave behind a "fire escape". If you look at its uses (not where the flag is set, but where it is checked), you will see that it either disables some optimization (example: in try_window_id), or sets other variables, like current_matrix_up_to_date_p. In the first case, we need to go over the places where the flag is set to true and think whether those setters indeed need to disable each particular optimization. In the second case, I think the flag is basically used to quickly disable optimizations conditioned by those other variables, in a way that prevents us to make more expensive tests. If we understand better each of these cases -- and there aren't so many of them -- we then could discuss whether to set the flag or not and whether to replace it with something else, whether those are other, more descriptive, flags or nothing. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 13:00 bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) Ihor Radchenko 2023-07-13 13:34 ` Eli Zaretskii @ 2023-07-13 17:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-13 19:08 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-13 17:20 UTC (permalink / raw) To: Ihor Radchenko; +Cc: 64596 > `force-mode-line-update' has the following FIXME: > > if (!NILP (all)) > { > update_mode_lines = 10; > /* FIXME: This can't be right. */ > current_buffer->prevent_redisplay_optimizations_p = true; > } > else if (buffer_window_count (current_buffer)) > { > bset_update_mode_line (current_buffer); > current_buffer->prevent_redisplay_optimizations_p = true; > } > > This FIXME has been introduced in 655ab9a3800, shortly after > ecda65d4f7e, which moved this code from `set-buffer-modified-p'. ecda65d4f7e changed `force-mode-line-update` from (if all (with-current-buffer (other-buffer))) (set-buffer-modified-p (buffer-modified-p))) to if (!NILP (all) || buffer_window_count (current_buffer)) { update_mode_lines = 10; current_buffer->prevent_redisplay_optimizations_p = 1; } That new code was (to the best of my knowledge) doing the same as what the old ELisp code did (I got to that code basically by taking the sum of the C code run by the original ELisp code and then simplifying it by eliminating those things which canceled each other). That code already had the same problem as the one I flagged with the FIXME: when we do (force-mode-line-update t) the effect should be global, so if `prevent_redisplay_optimizations_p` is needed in `current_buffer` it should be needed in other displayed buffers as well. > AFAIU, the purpose of disabling redisplay optimizations is avoiding the > situation when the modification flag is unset in the buffer, but the > buffer was actually modified, and has to be redrawn. > If my understanding is correct, > current_buffer->prevent_redisplay_optimizations_p = true does not belong > to `force-mode-line-update', but rather to `restore-buffer-modified-p'. I strongly suspect it doesn't belong in `force-mode-line-update`, indeed. > Stefan will tell, but I'm quite sure he wrote that FIXME because > removing that line caused regression in some situation. Nope. I put the FIXME simply because I realized that the code doesn't make sense: if that line is sometimes necessary, then I'm pretty sure it's not always sufficient. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 17:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-13 19:08 ` Eli Zaretskii 2023-07-13 21:00 ` Ihor Radchenko 2023-07-13 22:02 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-13 19:08 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > Cc: 64596@debbugs.gnu.org > Date: Thu, 13 Jul 2023 13:20:23 -0400 > From: Stefan Monnier via "Bug reports for GNU Emacs, > the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org> > > > AFAIU, the purpose of disabling redisplay optimizations is avoiding the > > situation when the modification flag is unset in the buffer, but the > > buffer was actually modified, and has to be redrawn. > > If my understanding is correct, > > current_buffer->prevent_redisplay_optimizations_p = true does not belong > > to `force-mode-line-update', but rather to `restore-buffer-modified-p'. > > I strongly suspect it doesn't belong in `force-mode-line-update`, indeed. To the ALL branch or to both of them? > > Stefan will tell, but I'm quite sure he wrote that FIXME because > > removing that line caused regression in some situation. > > Nope. I put the FIXME simply because I realized that the code doesn't > make sense: if that line is sometimes necessary, then I'm pretty sure it's > not always sufficient. Then I guess you or Ihor (or both) should try removing that line and run with that for a while. Alternatively, maybe in the case of ALL non-nil the code should set the prevent_redisplay_optimizations_p flag of all the buffers that are displayed in some window, since some redisplay optimizations are not eligible when the mode-line is about to be updated. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 19:08 ` Eli Zaretskii @ 2023-07-13 21:00 ` Ihor Radchenko 2023-07-13 22:02 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 0 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-13 21:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, 64596 [-- Attachment #1: Type: text/plain, Size: 348 bytes --] Eli Zaretskii <eliz@gnu.org> writes: > Then I guess you or Ihor (or both) should try removing that line and > run with that for a while. Yup. That's what I am already doing. See the attached diff. Beware though that I still haven't looked closely into your and Stefan's emails (it is late here) and I have no idea what I am doing in this diff. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: test.diff --] [-- Type: text/x-patch, Size: 1023 bytes --] diff --git a/src/buffer.c b/src/buffer.c index 0c46b201586..db7dc5c3c68 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1476,16 +1476,9 @@ DEFUN ("force-mode-line-update", Fforce_mode_line_update, (Lisp_Object all) { if (!NILP (all)) - { update_mode_lines = 10; - /* FIXME: This can't be right. */ - current_buffer->prevent_redisplay_optimizations_p = true; - } else if (buffer_window_count (current_buffer)) - { bset_update_mode_line (current_buffer); - current_buffer->prevent_redisplay_optimizations_p = true; - } return all; } @@ -1502,6 +1495,8 @@ DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p, { Frestore_buffer_modified_p (flag); + if (!flag) current_buffer->prevent_redisplay_optimizations_p = true; + /* Set update_mode_lines only if buffer is displayed in some window. Packages like jit-lock or lazy-lock preserve a buffer's modified state by recording/restoring the state around blocks of code. [-- Attachment #3: Type: text/plain, Size: 224 bytes --] -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply related [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 19:08 ` Eli Zaretskii 2023-07-13 21:00 ` Ihor Radchenko @ 2023-07-13 22:02 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 6:14 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-13 22:02 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > Then I guess you or Ihor (or both) should try removing that line and > run with that for a while. FWIW, I've been running without those two lines ever since I put this FIXME. > Alternatively, maybe in the case of ALL non-nil the code should set > the prevent_redisplay_optimizations_p flag of all the buffers that are > displayed in some window, since some redisplay optimizations are not > eligible when the mode-line is about to be updated. Any reason why the corresponding optimizations don't consult the `update_mode_lines` var (or the `update_mode_line` buffer flag), or maybe have redisplay start by propagating the `update_mode_line` buffer flag to `prevent_redisplay_optimizations_p`? Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-13 22:02 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 6:14 ` Eli Zaretskii 2023-07-14 14:31 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-14 6:14 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Thu, 13 Jul 2023 18:02:26 -0400 > > > Then I guess you or Ihor (or both) should try removing that line and > > run with that for a while. > > FWIW, I've been running without those two lines ever since I put this FIXME. I'd be happier with the alternative I proposed, which you cite below. Because bitter experience taught me that your, Stefan, usage patterns evidently exclude some use cases, because bug reports pop up after your similar changes where the display is not updated in some cases. I'm sure the same is true for the usage patterns of anyone of us, so doing this on a small number of systems is not enough. > > Alternatively, maybe in the case of ALL non-nil the code should set > > the prevent_redisplay_optimizations_p flag of all the buffers that are > > displayed in some window, since some redisplay optimizations are not > > eligible when the mode-line is about to be updated. > > Any reason why the corresponding optimizations don't consult the > `update_mode_lines` var (or the `update_mode_line` buffer flag), or > maybe have redisplay start by propagating the `update_mode_line` buffer > flag to `prevent_redisplay_optimizations_p`? Once again, prevent_redisplay_optimizations_p is NOT (just) about updating mode lines, it affects more optimizations. There's also windows_or_buffers_changed, which is even "stronger". For example, try_window_id checks the prevent_redisplay_optimizations_p flag and punts if it is set, although that optimization method AFAIK has nothing to do with redisplaying mode lines, it is only about updating the text area. It would be nice to analyze all those flags, make them more selective, and understand/document better what optimizations and optional processing are affected by each one of them. It is a large and somewhat ungrateful job, so if someone wants to do it by systematically examining the situations where we set each one of those flags and their effects on redisplay, I can offer my best help (though I cannot afford doing this job myself). Failing that, we could try disabling some portions of the code. This is not the best method of collecting such systematic information, IME, certainly not if just a couple of people do that, because experience teaches us that usage patterns differ wildly, and different window-systems and different window managers sometimes have significant effect on this stuff. So if we want to use this "phenomenological" approach, my suggestion is to allow disabling the relevant parts of the display-related code at run time, controlled by variables exposed to Lisp. We already have a bunch of inhibit-* variables that inhibit specific optimizations in xdisp.c; we could add more. Then we could set the defaults of these variables according to our best understanding, and if and when redisplay problems are reported, ask people to flip one or more of these inhibit-* variables and see if the problems go away. Again, this is not the best way, so if someone here is willing to do a thorough job regarding this, I encourage him or her to take the first way, although it is harder. The advantage is that we will have a much better understanding and documentation of these flags, and will probably be able to improve the ad-hoc set of flags we have today and make it easier to use and maintain. (Ideally, these flags should be a single bitmap with individual reasons representing the causes for disabling optimizations, and each optimization should examine the bits it cares about.) ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 6:14 ` Eli Zaretskii @ 2023-07-14 14:31 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 16:00 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 14:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 >> > Then I guess you or Ihor (or both) should try removing that line and >> > run with that for a while. >> FWIW, I've been running without those two lines ever since I put this FIXME. > I'd be happier with the alternative I proposed, which you cite below. I assume you assumed that my lack of problems would make me think removing those two lines is safe :-) I'm fully aware that when it comes to redisplay, one or two testers are definitely far from sufficient, don't worry. >> > Alternatively, maybe in the case of ALL non-nil the code should set >> > the prevent_redisplay_optimizations_p flag of all the buffers that are >> > displayed in some window, since some redisplay optimizations are not >> > eligible when the mode-line is about to be updated. >> >> Any reason why the corresponding optimizations don't consult the >> `update_mode_lines` var (or the `update_mode_line` buffer flag), or >> maybe have redisplay start by propagating the `update_mode_line` buffer >> flag to `prevent_redisplay_optimizations_p`? > > Once again, prevent_redisplay_optimizations_p is NOT (just) about > updating mode lines, it affects more optimizations. There's also I know. I didn't mean "consult `update_mode_lines` instead of `prevent_redisplay_optimizations_p`" but "consult `update_mode_lines` in addition to `prevent_redisplay_optimizations_p`". > It would be nice to analyze all those flags, make them more selective, > and understand/document better what optimizations and optional > processing are affected by each one of them. It is a large and > somewhat ungrateful job, so if someone wants to do it by > systematically examining the situations where we set each one of those > flags and their effects on redisplay, I can offer my best help (though > I cannot afford doing this job myself). I can't see it happening ever in such a systematic way. A more pragmatic approach is the one you propose afterwards: based on our vague understanding of how things work, make a few simplifications, expose them to our users and then see what bug reports we get in return. I suspect a single boolean variable (which we could call `internal--use-old-slow-redisplay`) to control those simplifications would be enough. We could set it to nil on `master` and to t in the release branch. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 14:31 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 16:00 ` Eli Zaretskii 2023-07-14 17:38 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-14 16:00 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Fri, 14 Jul 2023 10:31:23 -0400 > > > It would be nice to analyze all those flags, make them more selective, > > and understand/document better what optimizations and optional > > processing are affected by each one of them. It is a large and > > somewhat ungrateful job, so if someone wants to do it by > > systematically examining the situations where we set each one of those > > flags and their effects on redisplay, I can offer my best help (though > > I cannot afford doing this job myself). > > I can't see it happening ever in such a systematic way. I still hope it will. It's a good way of getting familiar with the display code, so maybe someone will step forward. > A more pragmatic approach is the one you propose afterwards: based on > our vague understanding of how things work, make a few simplifications, > expose them to our users and then see what bug reports we get in return. > > I suspect a single boolean variable (which we could call > `internal--use-old-slow-redisplay`) to control those simplifications > would be enough. No, one variable is not enough -- it will never tell us which of the potential flags or settings of the flag requires to be reinstated. We need to be able to investigate this at a finer granularity. And the variables should be called something like use-old-and-correct-redisplay-for-mode-line. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 16:00 ` Eli Zaretskii @ 2023-07-14 17:38 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 17:46 ` Ihor Radchenko 2023-07-14 19:05 ` Eli Zaretskii 0 siblings, 2 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 17:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > No, one variable is not enough -- it will never tell us which of the > potential flags or settings of the flag requires to be reinstated. We > need to be able to investigate this at a finer granularity. I doubt it. What we need in order to investigate is a somewhat reproducible test case and for that we need the bug to be exposed to as many users as possible to increase the chance that one of them bumps into a good recipe. The variable is not used to investigate, but to make it ethical to expose users to those potential bugs because they can set the var to recover the old behavior as soon as they're tired of playing the guinea pig. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 17:38 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-14 17:46 ` Ihor Radchenko 2023-07-14 19:06 ` Eli Zaretskii 2023-07-14 19:05 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-14 17:46 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, 64596 Stefan Monnier <monnier@iro.umontreal.ca> writes: > What we need in order to investigate is a somewhat reproducible test > case and for that we need the bug to be exposed to as many users as > possible to increase the chance that one of them bumps into > a good recipe. > > The variable is not used to investigate, but to make it ethical to > expose users to those potential bugs because they can set the var to > recover the old behavior as soon as they're tired of playing the > guinea pig. +1. Somewhat orthogonal, but related: if there are people who want to live dangerously (even more dangerously than on master), it might be interesting to have some kind of flip like "give me all the cutting edge experimental features enabled, even if not backward-compatible". -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 17:46 ` Ihor Radchenko @ 2023-07-14 19:06 ` Eli Zaretskii 2023-07-15 7:01 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-14 19:06 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Fri, 14 Jul 2023 17:46:09 +0000 > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > > What we need in order to investigate is a somewhat reproducible test > > case and for that we need the bug to be exposed to as many users as > > possible to increase the chance that one of them bumps into > > a good recipe. > > > > The variable is not used to investigate, but to make it ethical to > > expose users to those potential bugs because they can set the var to > > recover the old behavior as soon as they're tired of playing the > > guinea pig. > > +1. -1000 ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 19:06 ` Eli Zaretskii @ 2023-07-15 7:01 ` Eli Zaretskii 2023-07-15 7:22 ` Ihor Radchenko 2023-07-15 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-15 7:01 UTC (permalink / raw) To: yantar92, monnier; +Cc: 64596 > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Fri, 14 Jul 2023 22:06:38 +0300 > From: Eli Zaretskii <eliz@gnu.org> > > > From: Ihor Radchenko <yantar92@posteo.net> > > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > > Date: Fri, 14 Jul 2023 17:46:09 +0000 > > > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > > > > What we need in order to investigate is a somewhat reproducible test > > > case and for that we need the bug to be exposed to as many users as > > > possible to increase the chance that one of them bumps into > > > a good recipe. > > > > > > The variable is not used to investigate, but to make it ethical to > > > expose users to those potential bugs because they can set the var to > > > recover the old behavior as soon as they're tired of playing the > > > guinea pig. > > > > +1. > > -1000 Let me explain once again my position on this. We currently have quite a few flags that are used by various Emacs commands to give redisplay hints about what should be done: . redisplay flag of a buffer . redisplay flag of a window . redisplay flag of a frame . prevent_redisplay_optimizations_p flag of a buffer . clip_changed flag of a buffer . update_mode_line flag of a window . must_be_updated_p flag of a window . cursor_type_changed flag of a frame . face_change flag of a frame . update_mode_lines variable . windows_or_buffers_changed variable (There are a few more, but these are the bulk.) The 3 redisplay flags at the beginning of this list did not exist before Emacs 24, they were added in the hope to make the flags more selective and self-explanatory. But just knowing, for example, that a buffer's text was changed says almost nothing about which optimizations can and cannot be used, whether or not the mode line needs to be updated, nor even if the window(s) showing the buffer need to be redrawn (since the change could be in a portion of the buffer that is not visible in any of the windows). Anyway, we now have this dozen of flags and variables, and one of them is prevent_redisplay_optimizations_p. It makes absolutely no sense to me to try to "solve" the "problem" of this single flag in the single case that started this thread. Even if this flag should not be set in the particular place with a FIXME -- which was not convincingly demonstrated here -- so what? what harm can that possibly make in this specific case? None. What we have now might look untidy at best, but it does work, and works well. It took an effort to get here, but the current situation has been stable for several years: I don't remember any significant redisplay problems reported for the last several years. What we do need is to make some better order out of these flags, understand better what does each one of them tell the display engine, and perhaps make some of them more selective. And we need to document these understandings. So this is the deal: if someone wants to try to do this job, or even some part of it, you will have my full support, my attention, and any form of help I can practically provide. But I will not agree to random poking at this or that particular flag, unless there's convincing evidence that it causes a display bug or a significant performance problem. Because otherwise making changes in code that we don't sufficiently understand can only cause bugs, and guess who gets to work on fixing them. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 7:01 ` Eli Zaretskii @ 2023-07-15 7:22 ` Ihor Radchenko 2023-07-15 8:52 ` Eli Zaretskii 2023-07-15 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-15 7:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: > What we do need is to make some better order out of these flags, > understand better what does each one of them tell the display engine, > and perhaps make some of them more selective. And we need to document > these understandings. I agree. From my recent reading of the commentary in xdisp.c, one apparently missing summary is which window and frame components are considered by the redisplay code. "Glyph rows." section in the top comment talk about margins + text area, but the real redisplay_internal appears to consider (1) title bars; (2) menu bars; (3) header line; (4) tab line; (5) mode-line; (6) window text; (7) echo area (which is treated specially). > .... But I will not agree to > random poking at this or that particular flag, unless there's > convincing evidence that it causes a display bug or a significant > performance problem. Because otherwise making changes in code that we > don't sufficiently understand can only cause bugs, and guess who gets > to work on fixing them. That's understandable. But the general idea of having some kind of "experimental" flag might be still useful in other situations. Not necessarily redisplay. Of course, such experiments should be still weighed carefully. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 7:22 ` Ihor Radchenko @ 2023-07-15 8:52 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-15 8:52 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 07:22:59 +0000 > > >From my recent reading of the commentary in xdisp.c, one apparently > missing summary is which window and frame components are considered by > the redisplay code. Basically, all of them, I'd say. > "Glyph rows." section in the top comment talk about margins + text area, > but the real redisplay_internal appears to consider (1) title bars; (2) > menu bars; (3) header line; (4) tab line; (5) mode-line; (6) window > text; (7) echo area (which is treated specially). That section indeed mentions the text area and the margins, but only because the glyph rows distinguish between them. The other areas you mention either don't use our glyphs (title bar), or have no margin areas (mode line, header line, menu bar, etc.), only the text area. Echo area is displayed in a mini-window, which is just a window, albeit a special one. > > .... But I will not agree to > > random poking at this or that particular flag, unless there's > > convincing evidence that it causes a display bug or a significant > > performance problem. Because otherwise making changes in code that we > > don't sufficiently understand can only cause bugs, and guess who gets > > to work on fixing them. > > That's understandable. > But the general idea of having some kind of "experimental" flag might be > still useful in other situations. Not necessarily redisplay. > Of course, such experiments should be still weighed carefully. I'm okay with such experimental flags, and we did use them in the past (still have some of them in the current sources). I'm just saying those should be selective enough to allow enabling/disabling a small set of features, not all of them together. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 7:01 ` Eli Zaretskii 2023-07-15 7:22 ` Ihor Radchenko @ 2023-07-15 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 15:22 ` Eli Zaretskii 2023-07-16 10:22 ` Ihor Radchenko 1 sibling, 2 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 14:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > We currently have quite a few flags that are used by various Emacs > commands to give redisplay hints about what should be done: > > . redisplay flag of a buffer > . redisplay flag of a window > . redisplay flag of a frame > . update_mode_line flag of a window > . update_mode_lines variable > . windows_or_buffers_changed variable I can explain what these are supposed to represent (IOW, if there's a bug linked to them, I should be able to tell you whether the blame goes to the redisplay code (which "reads" these vars) or in the non-redisplay code (which sets these vars)). If you read their docs and have questions, I'd love to hear them so I can improve their doc. > . clip_changed flag of a buffer . beg_unchanged of a buffer_text . end_unchanged of a buffer_text I think their intended meaning is fairly clear. I haven't really played with the corresponding part of the code, so I don't know if the code really matches my expectations, but I have the impression that there shouldn't be too many surprises. > . cursor_type_changed flag of a frame > . face_change flag of a frame I can see what these are supposed to mean as well, but I'm less sure that that intended meaning really matches the code (e.g., I wouldn't be surprised to discover that one of them is also (ab)used for something else). > . prevent_redisplay_optimizations_p flag of a buffer > . must_be_updated_p flag of a window No idea what these mean. The name `must_be_updated_p` makes it sound to me like it's redundant with the `redisplay` flag above. > (There are a few more, but these are the bulk.) The 3 redisplay flags > at the beginning of this list did not exist before Emacs 24, they were > added in the hope to make the flags more selective and > self-explanatory. They were added exclusively to refine: . update_mode_lines variable . windows_or_buffers_changed variable since these have a global meaning whereas in most cases only a small number of the windows should be affected. [ IOW, the refinement targeted use cases where there are many windows. I often have a hundred windows or more :-) ] > performance problem. Because otherwise making changes in code that we > don't sufficiently understand can only cause bugs, It can introduce bugs, but in my experience when dealing with code I don't understand, it's by breaking the code that you learn how it works, so saying "can only cause bugs" doesn't make sense. The change can bring more clarity to the code, which is beneficial in the long term, and if it introduces bugs then presumably some users will see them, report them, and that will bring us better understanding of the code. That's eactly what happened when I introduced the 3 `redisplay` bits above: it did introduce a few bugs, but overall it made the code more clear. My experience has been very positive there, and I hope you wouldn't veto a similar change in the future. > and guess who gets to work on fixing them. AFAIK, for the bugs introduced by those `redisplay` bit: I did, as it should. And it wasn't terribly hard (largely because I indeed knew (because I had decided it myself) what meant what and hence where a problem should be fixed). Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 15:22 ` Eli Zaretskii 2023-07-15 16:01 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 10:22 ` Ihor Radchenko 1 sibling, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-15 15:22 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 10:49:37 -0400 > > > performance problem. Because otherwise making changes in code that we > > don't sufficiently understand can only cause bugs, > > It can introduce bugs, but in my experience when dealing with code > I don't understand, it's by breaking the code that you learn how it > works, so saying "can only cause bugs" doesn't make sense. It makes a lot of sense to me. So let's agree to disagree here. To reiterate my firm opinion: either someone steps forward to work on this seriously and systematically, or we should leave this code alone, for better and for worse. > The change can bring more clarity to the code, which is beneficial > in the long term, and if it introduces bugs then presumably some > users will see them, report them, and that will bring us better > understanding of the code. If someone wants to lead such a project for the next 10 years or so, maybe. But what happens in reality is that the breaking changes are made, and then the "guilty parties" disappear into thin air, or lose interest. And we are left with a broken redisplay and an unfinished project. > That's eactly what happened when I introduced the 3 `redisplay` bits > above: it did introduce a few bugs, but overall it made the code > more clear. No, that's not "exactly" what happened. Some of the bugs popped up much later, among other things. I agree that the added comments made the situation better, but you know as well as I do that some of the aspects of those variables are still somewhat mysterious: specifically the meaning of windows_or_buffers_changed and update_mode_lines for disabling optimizations and shortcuts. Which is exactly the focus of the current discussion. > > and guess who gets to work on fixing them. > > AFAIK, for the bugs introduced by those `redisplay` bit: I did, as > it should. Not all of them. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 15:22 ` Eli Zaretskii @ 2023-07-15 16:01 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 16:16 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 16:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > But what happens in reality is that the breaking changes are made, and > then the "guilty parties" disappear into thin air, or lose interest. > And we are left with a broken redisplay and an unfinished project. I didn't disappear into thin air, did I? Maybe I shouldn't take this personally, but my `redisplay-bit` changes are the only changes I'm aware of in this kind of vicinity, so I can't help but feel that this experience is an important point of reference for both of us. >> That's eactly what happened when I introduced the 3 `redisplay` bits >> above: it did introduce a few bugs, but overall it made the code >> more clear. > No, that's not "exactly" what happened. Some of the bugs popped up > much later, among other things. I agree that the added comments made > the situation better, but you know as well as I do that some of the > aspects of those variables are still somewhat mysterious: specifically > the meaning of windows_or_buffers_changed and update_mode_lines for > disabling optimizations and shortcuts. Which is exactly the focus of > the current discussion. Those aspects are not due to my changes. If they are mysterious it's because the remained mysterious, i.e. because I did not change them. [ Actually, I did change them a bit to help track them down: I changed those vars from booleans to integers where the integer is a "code" for the place where it has been "mysteriously set". And you can check `redisplay--all-windows-cause` and `redisplay--mode-lines-cause` to see how many times each of those "mysterious causes" has been used :-) ] This said, the meaning of those vars is clear, I think (they mean, that all the windows/modelines need to be updated). What still isn't clear at some places is the reason why they're set. >> > and guess who gets to work on fixing them. >> AFAIK, for the bugs introduced by those `redisplay` bit: I did, as >> it should. > Not all of them. Admittedly, sometimes it's difficult to know beforehand whether the bug may be due to those changes, so you may end up wasting your time before you can redirect the bug to the appropriate person, but this is another place where having that `internal--use-old-slow-redisplay` variable would help. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 16:01 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 16:16 ` Eli Zaretskii 2023-07-15 17:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 18:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-15 16:16 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 12:01:50 -0400 > > > But what happens in reality is that the breaking changes are made, and > > then the "guilty parties" disappear into thin air, or lose interest. > > And we are left with a broken redisplay and an unfinished project. > > I didn't disappear into thin air, did I? Let's not make this too personal. Suffice it to say that I saw more than once or twice changes in these areas which caused subtle redisplay problems several years later, and I did have to fix a few of them. So what I wrote is based on facts and actual experience. > >> That's eactly what happened when I introduced the 3 `redisplay` bits > >> above: it did introduce a few bugs, but overall it made the code > >> more clear. > > No, that's not "exactly" what happened. Some of the bugs popped up > > much later, among other things. I agree that the added comments made > > the situation better, but you know as well as I do that some of the > > aspects of those variables are still somewhat mysterious: specifically > > the meaning of windows_or_buffers_changed and update_mode_lines for > > disabling optimizations and shortcuts. Which is exactly the focus of > > the current discussion. > > Those aspects are not due to my changes. If they are mysterious it's > because the remained mysterious, i.e. because I did not change them. Indeed. The above wasn't written to accuse, but to convey the fact that we are not yet where we want to be in this regard. > This said, the meaning of those vars is clear, I think (they mean, that > all the windows/modelines need to be updated). Not entirely true, AFAIU. For example, what does update_mode_lines have to do with preparing the menu bar? static void prepare_menu_bars (void) { bool all_windows = windows_or_buffers_changed || update_mode_lines; bool some_windows = REDISPLAY_SOME_P (); or a similar reference in update_menu_bar. Or why redisplay_internal does this: consider_all_windows_p = (update_mode_lines || windows_or_buffers_changed); And a couple of more "questionable" uses of that variable. > What still isn't clear at some places is the reason why they're set. Yes, that too. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 16:16 ` Eli Zaretskii @ 2023-07-15 17:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 19:04 ` Eli Zaretskii 2023-07-16 10:38 ` Ihor Radchenko 2023-07-15 18:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 17:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > Not entirely true, AFAIU. For example, what does update_mode_lines > have to do with preparing the menu bar? > > static void > prepare_menu_bars (void) > { > bool all_windows = windows_or_buffers_changed || update_mode_lines; > bool some_windows = REDISPLAY_SOME_P (); Indeed `update_mode_lines` means more than just mode-lines. It includes of course header-lines (of course), frame names (less obvious), and also the menu-bar, and some of those links are indeed not 100% clear. WDYT about the patch below? I'll try to update the docs to clarify this. Stefan diff --git a/src/window.h b/src/window.h index 2f793ebe438..48d3fd3dc82 100644 --- a/src/window.h +++ b/src/window.h @@ -1114,9 +1114,12 @@ #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ extern Lisp_Object echo_area_window; -/* Non-zero if we should redraw the mode lines on the next redisplay. +/* Non-zero if we should redraw the mode line*s* on the next redisplay. Usually set to a unique small integer so we can track the main causes of - full redisplays in `redisplay--mode-lines-cause'. */ + full redisplays in `redisplay--mode-lines-cause'. + Here "mode lines" includes also header-lines and frame names, and + apparently also menu-bars. The link with header-lines is clear, + but a bit less so for frame names and the menu-bar. */ extern int update_mode_lines; @@ -1134,6 +1137,11 @@ #define WINDOW_TEXT_TO_FRAME_PIXEL_X(W, X) \ extern void wset_redisplay (struct window *w); extern void fset_redisplay (struct frame *f); extern void bset_redisplay (struct buffer *b); + +/* Routines to indicate that the mode-lines might need to be redisplayed. + Just as for `update_mode_lines`, this includes header-lines, frame names + and menu-bars, and the link with frame names and menu-bars is still + unclear. */ extern void bset_update_mode_line (struct buffer *b); extern void wset_update_mode_line (struct window *w); /* Call this to tell redisplay to look for other windows than selected-window ^ permalink raw reply related [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 17:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 19:04 ` Eli Zaretskii 2023-07-16 10:38 ` Ihor Radchenko 1 sibling, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-15 19:04 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 13:15:39 -0400 > > > Not entirely true, AFAIU. For example, what does update_mode_lines > > have to do with preparing the menu bar? > > > > static void > > prepare_menu_bars (void) > > { > > bool all_windows = windows_or_buffers_changed || update_mode_lines; > > bool some_windows = REDISPLAY_SOME_P (); > > Indeed `update_mode_lines` means more than just mode-lines. It includes > of course header-lines (of course), frame names (less obvious), and also > the menu-bar, and some of those links are indeed not 100% clear. > > WDYT about the patch below? That's an improvement, thanks. But it still isn't everything. For example, what about resize_echo_area_exactly: why does it set this variable? Also, this variable is tested in update_tool_bar and update_tab_bar, so the comment you suggest should mention tool bar and tab bar as well. Unless you know the answers to these questions, I guess more digging is in order. And I'd be happier if, instead of a single variable for so many purposes we would have either several separate variables or make this one a bitmap, where each bit says something very specific about the part of the display that needs updating. Any takers? > -/* Non-zero if we should redraw the mode lines on the next redisplay. > +/* Non-zero if we should redraw the mode line*s* on the next redisplay. > Usually set to a unique small integer so we can track the main causes of > - full redisplays in `redisplay--mode-lines-cause'. */ > + full redisplays in `redisplay--mode-lines-cause'. > + Here "mode lines" includes also header-lines and frame names, and > + apparently also menu-bars. The link with header-lines is clear, > + but a bit less so for frame names and the menu-bar. */ Btw, we need some function to show the information in redisplay--mode-lines-cause in human-readable format, or at least a documentation for how to examine it. Without that, this variable is probably useful only to a very small group of people. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 17:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 19:04 ` Eli Zaretskii @ 2023-07-16 10:38 ` Ihor Radchenko 2023-07-16 11:26 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 10:38 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, 64596 Stefan Monnier <monnier@iro.umontreal.ca> writes: > -/* Non-zero if we should redraw the mode lines on the next redisplay. > +/* Non-zero if we should redraw the mode line*s* on the next redisplay. > Usually set to a unique small integer so we can track the main causes of > - full redisplays in `redisplay--mode-lines-cause'. */ > + full redisplays in `redisplay--mode-lines-cause'. > + Here "mode lines" includes also header-lines and frame names, and > + apparently also menu-bars. The link with header-lines is clear, > + but a bit less so for frame names and the menu-bar. */ It would be even better if *-mode-lines functions were renamed to something more explicit. It is very disorienting that "mode-line" may mean actual mode-line, but sometimes more than that. A clarifying comment is an improvement, but does not make the code in other places more readable. Maybe use a term like "info-lines" to avoid confusion of using the same term for multiple different meanings? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 10:38 ` Ihor Radchenko @ 2023-07-16 11:26 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 11:26 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 10:38:14 +0000 > > It would be even better if *-mode-lines functions were renamed to > something more explicit. It is very disorienting that "mode-line" may > mean actual mode-line, but sometimes more than that. > A clarifying comment is an improvement, but does not make the code in > other places more readable. If we want to do this, the job is larger yet. We also have this: struct glyph_row { [...] /* True means row is a mode or header/tab-line. */ bool_bf mode_line_p : 1; /* True means row is a tab-line. */ bool_bf tab_line_p : 1; struct it { [...] /* True means window has a tab line at its top. */ bool_bf tab_line_p : 1; /* True means window has a mode line at its top. */ bool_bf header_line_p : 1; struct glyph_matrix { [...] /* True means window displayed in this matrix has a tab line. */ bool_bf tab_line_p : 1; /* True means window displayed in this matrix has a header line. */ bool_bf header_line_p : 1; and the code which deals with these. (Note that the bits are inconsistent between glyph_row and the other two structures, and all of them mention only 2 out of 3 attributes.) ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 16:16 ` Eli Zaretskii 2023-07-15 17:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 18:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 19:18 ` Eli Zaretskii 2023-07-15 19:28 ` Eli Zaretskii 1 sibling, 2 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 18:15 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > Or why redisplay_internal does this: > > consider_all_windows_p = (update_mode_lines > || windows_or_buffers_changed); Sorry, I skipped this part in my previous email. I understand the above code, but I'm not sure what explanation might be needed so you can understand it as well. Maybe the problem is the name `consider_all_windows_p` which suggests that all windows will be updated, but it only says that we should loop through all the windows to try and find those which need to be updated. Would the patch below help? Stefan diff --git a/src/xdisp.c b/src/xdisp.c index a3464c2c375..385569d9309 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -16491,7 +16491,9 @@ redisplay_internal (void) int garbaged_frame_retries = 0; /* True means redisplay has to consider all windows on all - frames. False, only selected_window is considered. */ + frames. False, only selected_window is considered. + If true, the set of windows we try to update is further limited + according to the `redisplay` bits in buffers/windows/frames. */ bool consider_all_windows_p; /* True means redisplay has to redisplay the miniwindow. */ ^ permalink raw reply related [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 18:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 19:18 ` Eli Zaretskii 2023-07-15 19:28 ` Eli Zaretskii 1 sibling, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-15 19:18 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 14:15:41 -0400 > > > Or why redisplay_internal does this: > > > > consider_all_windows_p = (update_mode_lines > > || windows_or_buffers_changed); > > Sorry, I skipped this part in my previous email. > I understand the above code, but I'm not sure what explanation might > be needed so you can understand it as well. Maybe the problem is the > name `consider_all_windows_p` which suggests that all windows will be > updated, but it only says that we should loop through all the windows to > try and find those which need to be updated. > > Would the patch below help? It probably would. (The meaning of the variable was clear to me before this, but maybe it will help others.) Thanks. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 18:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 19:18 ` Eli Zaretskii @ 2023-07-15 19:28 ` Eli Zaretskii 2023-07-15 19:43 ` Ihor Radchenko 2023-07-15 22:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-15 19:28 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 14:15:41 -0400 > > > Or why redisplay_internal does this: > > > > consider_all_windows_p = (update_mode_lines > > || windows_or_buffers_changed); > > Sorry, I skipped this part in my previous email. > I understand the above code, but I'm not sure what explanation might > be needed so you can understand it as well. Maybe the problem is the > name `consider_all_windows_p` which suggests that all windows will be > updated, but it only says that we should loop through all the windows to > try and find those which need to be updated. The actual issue with the above is different: it implies that update_mode_lines _always_ indicates that more than a single mode line should be updated (which is why we need to "consider all windows"). But is that actually true, i.e. does every place that assigns non-zero to update_mode_lines indeed perform a change which makes it _necessary_ to consider non-selected windows? ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 19:28 ` Eli Zaretskii @ 2023-07-15 19:43 ` Ihor Radchenko 2023-07-15 23:10 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 4:57 ` Eli Zaretskii 2023-07-15 22:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-15 19:43 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stefan Monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: > The actual issue with the above is different: it implies that > update_mode_lines _always_ indicates that more than a single mode line > should be updated (which is why we need to "consider all windows"). > But is that actually true, i.e. does every place that assigns non-zero > to update_mode_lines indeed perform a change which makes it > _necessary_ to consider non-selected windows? At least, when the current buffer is only displayed in a single, selected window, checking every window should not be necessary. Compare bset_redisplay and bset_update_mode_line. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 19:43 ` Ihor Radchenko @ 2023-07-15 23:10 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 4:57 ` Eli Zaretskii 1 sibling, 0 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 23:10 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Eli Zaretskii, 64596 >> The actual issue with the above is different: it implies that >> update_mode_lines _always_ indicates that more than a single mode line >> should be updated (which is why we need to "consider all windows"). >> But is that actually true, i.e. does every place that assigns non-zero >> to update_mode_lines indeed perform a change which makes it >> _necessary_ to consider non-selected windows? > > At least, when the current buffer is only displayed in a single, > selected window, checking every window should not be necessary. Indeed, we have a special case for that. Before my change, it was either "just the selected window" or "all windows". > Compare bset_redisplay and bset_update_mode_line. Indeed the old code updated all windows after a call to `force-mode-line-update` even if the current buffer is only displayed in the selected window and I somewhat preserved that :-( Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 19:43 ` Ihor Radchenko 2023-07-15 23:10 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 4:57 ` Eli Zaretskii 2023-07-16 5:49 ` Ihor Radchenko 2023-07-16 8:26 ` martin rudalics 1 sibling, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 4:57 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 19:43:17 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > > The actual issue with the above is different: it implies that > > update_mode_lines _always_ indicates that more than a single mode line > > should be updated (which is why we need to "consider all windows"). > > But is that actually true, i.e. does every place that assigns non-zero > > to update_mode_lines indeed perform a change which makes it > > _necessary_ to consider non-selected windows? > > At least, when the current buffer is only displayed in a single, > selected window, checking every window should not be necessary. The code which sets update_mode_lines doesn't know whether the current buffer will be displayed in a single window by the time redisplay kicks in. It doesn't even know whether it will still be the current buffer by that time. Because the Lisp program that is running and making the changes which cause update_mode_lines to be set can change these things before it finishes. These global variables come from the time when the Emacs redisplay was much less selective. It basically has only two modes: either redisplay only the selected window, or redisplay all the windows on all the frames. (Here "redisplay" means "examine for redisplay and decide whether and which parts need that", not necessarily "actually redraw".) When the various 'redisplay' flags were added, the intent was to make redisplay more selective, so that it could completely refrain from examining windows on a certain frame, for example. The right way to keep advancing in that direction is to extend these flags and maybe introduce more flags that will describe the need to redisplay in more detail. Global variables such as update_mode_lines can do that only if they provide specific values to describe each required aspect of redisplay. But in any case, the code which sets the variable cannot make decisions for redisplay, it can only describe the changes for redisplay to consider. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 4:57 ` Eli Zaretskii @ 2023-07-16 5:49 ` Ihor Radchenko 2023-07-16 7:15 ` Eli Zaretskii 2023-07-16 8:26 ` martin rudalics 1 sibling, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 5:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> At least, when the current buffer is only displayed in a single, >> selected window, checking every window should not be necessary. > > The code which sets update_mode_lines doesn't know whether the current > buffer will be displayed in a single window by the time redisplay > kicks in. It doesn't even know whether it will still be the current > buffer by that time. Because the Lisp program that is running and > making the changes which cause update_mode_lines to be set can change > these things before it finishes. If the selected window changes for any reason, redisplaying the previously selected window will be queued by select_window: if (NILP (norecord) || EQ (norecord, Qmark_for_redisplay)) { /* Mark the window for redisplay since the selected-window has a different mode-line. */ wset_redisplay (XWINDOW (selected_window)); wset_redisplay (w); } else redisplay_other_windows (); -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 5:49 ` Ihor Radchenko @ 2023-07-16 7:15 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 7:15 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 05:49:45 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> At least, when the current buffer is only displayed in a single, > >> selected window, checking every window should not be necessary. > > > > The code which sets update_mode_lines doesn't know whether the current > > buffer will be displayed in a single window by the time redisplay > > kicks in. It doesn't even know whether it will still be the current > > buffer by that time. Because the Lisp program that is running and > > making the changes which cause update_mode_lines to be set can change > > these things before it finishes. > > If the selected window changes for any reason, redisplaying the > previously selected window will be queued by select_window: Yes, but what does this have to do with what I wrote? My point is that where we set update_mode_lines we cannot yet know whether only the selected window will have to be redisplayed. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 4:57 ` Eli Zaretskii 2023-07-16 5:49 ` Ihor Radchenko @ 2023-07-16 8:26 ` martin rudalics 2023-07-16 8:40 ` Ihor Radchenko 2023-07-16 8:50 ` Eli Zaretskii 1 sibling, 2 replies; 90+ messages in thread From: martin rudalics @ 2023-07-16 8:26 UTC (permalink / raw) To: Eli Zaretskii, Ihor Radchenko; +Cc: monnier, 64596 > These global variables come from the time when the Emacs redisplay was > much less selective. It basically has only two modes: either > redisplay only the selected window, or redisplay all the windows on > all the frames. (Here "redisplay" means "examine for redisplay and > decide whether and which parts need that", not necessarily "actually > redraw".) When the various 'redisplay' flags were added, the intent > was to make redisplay more selective, so that it could completely > refrain from examining windows on a certain frame, for example. The > right way to keep advancing in that direction is to extend these flags > and maybe introduce more flags that will describe the need to > redisplay in more detail. Global variables such as update_mode_lines > can do that only if they provide specific values to describe each > required aspect of redisplay. But in any case, the code which sets > the variable cannot make decisions for redisplay, it can only describe > the changes for redisplay to consider. From the POV of window management the situation is simple: When the size of a window or a decoration changes, it would like to tell redisplay about it. But redisplay would have to tell it first which kind of changes it's able to accept. For example, I don't even know whether, when running without window matrices, redisplay is capable of doing something reasonable with the fact that the border between two adjacent windows shifted and a third window not affected by that shift can be spared by redisplay. So from the POV of window management, redisplay would have to offer a list of such flags it is able to handle and do something reasonable about. As an example: one of the worst things the window code does is saving a window configuration, reading something from the minibuffer and restoring the window configuration when done. In nine out of ten cases the restored configuration will not have changed and redisplay wouldn't have to do anything. Now Fset_window_configuration is awful in the regard that it deletes all windows on the frame regardless of whether the configuration changed only to "restore" them later (including that n_leaf_windows allocation hack to find out which glyph matrices can be safely freed). While it is fairly easy to fix that, it's by no means clear what and how to tell redisplay that some window did change in one of those rare cases where it did. Try the following simple scenario which currently breaks redisplay: (let (config) (set-frame-parameter nil 'left-fringe 50) (y-or-n-p "?") (setq config (current-window-configuration)) (setq left-fringe-width 0) (set-window-buffer nil (window-buffer)) (y-or-n-p "?") (set-window-configuration config)) Here 'set-window-configuration' should be able to tell redisplay that it should redisplay the window but it should be able to tell that iff the fringe really changed which is fairly easy to find out. Once it found out, which kind of flag would it set? martin ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 8:26 ` martin rudalics @ 2023-07-16 8:40 ` Ihor Radchenko 2023-07-16 8:56 ` Eli Zaretskii 2023-07-16 8:50 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 8:40 UTC (permalink / raw) To: martin rudalics; +Cc: Eli Zaretskii, monnier, 64596 martin rudalics <rudalics@gmx.at> writes: > Here 'set-window-configuration' should be able to tell redisplay that it > should redisplay the window but it should be able to tell that iff the > fringe really changed which is fairly easy to find out. Once it found > out, which kind of flag would it set? May someone list all the possible displayed elements Emacs considers? I think that it might be a good new API to have a single function that marks things for redisplay. That function will accept arguments indicating what exactly may need to be redisplayed: CURRENT_TEXT_LINE, FRINGE, LINE_NUMBERS, CURRENT_BUFFER_TEXT, CURRENT_BUFFER_MODELINES, ALL_MODELINES, CURRENT_FRAME, etc. Then, every place where we request redisplay will call that single API function, while being very explicit what kind of redisplay it has in mind. That API function may be implemented in backwards-compatible way - we can just hide the existing logic inside for now and simplify later instead of directly manipulating global and local flag variables. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 8:40 ` Ihor Radchenko @ 2023-07-16 8:56 ` Eli Zaretskii 2023-07-16 9:41 ` Ihor Radchenko 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 8:56 UTC (permalink / raw) To: Ihor Radchenko; +Cc: rudalics, monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Eli Zaretskii <eliz@gnu.org>, monnier@iro.umontreal.ca, > 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 08:40:38 +0000 > > martin rudalics <rudalics@gmx.at> writes: > > > Here 'set-window-configuration' should be able to tell redisplay that it > > should redisplay the window but it should be able to tell that iff the > > fringe really changed which is fairly easy to find out. Once it found > > out, which kind of flag would it set? > > May someone list all the possible displayed elements Emacs considers? What do you mean by "display element" here? The Emacs display engine already has a term "display element", but I think it means something very different: character glyphs, images, compositions, etc. See the function get_next_display_element in xdisp.c. So we had better agreed on clear terminology here to avoid terrible confusion. > I think that it might be a good new API to have a single function that > marks things for redisplay. That function will accept arguments > indicating what exactly may need to be redisplayed: CURRENT_TEXT_LINE, > FRINGE, LINE_NUMBERS, CURRENT_BUFFER_TEXT, CURRENT_BUFFER_MODELINES, > ALL_MODELINES, CURRENT_FRAME, etc. The first step is to identify the changes in which the display engine is interested, and design the flag(s) to communicate this information to it. The actual API, whether a single function or a set of macros or something else, comes later, and is not a complicated decision to make. Please note that whether current text line needs to be redisplayed, or if line numbers need to be redisplayed, or if mode line needs to be redisplayed, is in many cases a decision that only the display engine can make. So you seem to be thinking in terms that are not entirely correct. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 8:56 ` Eli Zaretskii @ 2023-07-16 9:41 ` Ihor Radchenko 2023-07-16 10:30 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 9:41 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> May someone list all the possible displayed elements Emacs considers? > > What do you mean by "display element" here? The Emacs display engine > already has a term "display element", but I think it means something > very different: character glyphs, images, compositions, etc. See the > function get_next_display_element in xdisp.c. > > So we had better agreed on clear terminology here to avoid terrible > confusion. Fair point. The top commentary in xdisp.c defines "display elements" as elements in glyph matrix. These include characters (possibly composed) and images. However, not everything drawn in Emacs frame is represented by display elements : 1. Title bar is not using glyphs at all 2. Same for scroll bars 3. and menu bars 4. and tool bars 5. and window boundaries 6. and things like fill-column-indicator (AFAIU) Further, some display elements are grouped: 1. per frame 2. per window 3. within fringes 4. within mode-line 5. within buffer text area 6. within a line of text 7. within header line 8. within tab-line I think that the flags should provide a way to mark each of the groups or individual glyphs for future redisplay. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 9:41 ` Ihor Radchenko @ 2023-07-16 10:30 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 10:30 UTC (permalink / raw) To: Ihor Radchenko; +Cc: rudalics, monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: rudalics@gmx.at, monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 09:41:28 +0000 > > The top commentary in xdisp.c defines "display elements" as elements in > glyph matrix. These include characters (possibly composed) and images. They include more than that, see enum glyph_type in dispextern.h. > However, not everything drawn in Emacs frame is represented by display > elements : > > 1. Title bar is not using glyphs at all > 2. Same for scroll bars These two are window-system/toolkit widgets. > 3. and menu bars This is either a toolkit widget or an Emacs-produced text; in the latter case it does use our glyphs. > 4. and tool bars Depending on whether the tool bar is "external" or not, this could be a special kind of window with our glyphs. > 5. and window boundaries On TTY frames, these are character glyphs. > 6. and things like fill-column-indicator (AFAIU) Those are fringe bitmaps, so they belong to the fringe. > Further, some display elements are grouped: > 1. per frame > 2. per window > 3. within fringes > 4. within mode-line > 5. within buffer text area > 6. within a line of text > 7. within header line > 8. within tab-line The latter 5 are in display-engine realm, and some of them are only calculated as part of redisplay, so other code should not try to handle that. But yes, we definitely need (and already have) buffer flags, window flags, and frame flags. > I think that the flags should provide a way to mark each of the groups > or individual glyphs for future redisplay. Nothing knows (or should know) about glyphs except the display code. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 8:26 ` martin rudalics 2023-07-16 8:40 ` Ihor Radchenko @ 2023-07-16 8:50 ` Eli Zaretskii 2023-07-17 8:30 ` martin rudalics 1 sibling, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 8:50 UTC (permalink / raw) To: martin rudalics; +Cc: yantar92, monnier, 64596 > Date: Sun, 16 Jul 2023 10:26:04 +0200 > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > From: martin rudalics <rudalics@gmx.at> > > From the POV of window management the situation is simple: When the size > of a window or a decoration changes, it would like to tell redisplay > about it. But redisplay would have to tell it first which kind of > changes it's able to accept. I don't think this is required. The information flow is unidirectional: the functions which change the windows should tell what they changed, and redisplay will then decide what that requires. For example, if some windows changed their dimensions, redisplay would need to know which dimension changed. > For example, I don't even know whether, when running without window > matrices, redisplay is capable of doing something reasonable with > the fact that the border between two adjacent windows shifted and a > third window not affected by that shift can be spared by redisplay. If the third window displays a buffer that didn't change in any way, then yes, the display engine should be capable of doing the above. On TTY frames, the display engine considers the entire frame, so it should see that the portion corresponding to that third window didn't change, and refrain from redrawing it. > As an example: one of the worst things the window code does is saving a > window configuration, reading something from the minibuffer and > restoring the window configuration when done. In nine out of ten cases > the restored configuration will not have changed and redisplay wouldn't > have to do anything. Now Fset_window_configuration is awful in the > regard that it deletes all windows on the frame regardless of whether > the configuration changed only to "restore" them later (including that > n_leaf_windows allocation hack to find out which glyph matrices can be > safely freed). While it is fairly easy to fix that, it's by no means > clear what and how to tell redisplay that some window did change in one > of those rare cases where it did. We need to add flags that convey the information about which windows changed what dimensions. > (let (config) > (set-frame-parameter nil 'left-fringe 50) > (y-or-n-p "?") > (setq config (current-window-configuration)) > (setq left-fringe-width 0) > (set-window-buffer nil (window-buffer)) > (y-or-n-p "?") > (set-window-configuration config)) > > Here 'set-window-configuration' should be able to tell redisplay that it > should redisplay the window but it should be able to tell that iff the > fringe really changed which is fairly easy to find out. Once it found > out, which kind of flag would it set? I'm not even sure it must find that out. It could simply tell redisplay that the fringe really changed. The rest is up to the display engine to decide. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 8:50 ` Eli Zaretskii @ 2023-07-17 8:30 ` martin rudalics 0 siblings, 0 replies; 90+ messages in thread From: martin rudalics @ 2023-07-17 8:30 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, monnier, 64596 > The information flow is > unidirectional: the functions which change the windows should tell > what they changed, and redisplay will then decide what that requires. > For example, if some windows changed their dimensions, redisplay would > need to know which dimension changed. The window code should have all necessary information at hand (but for the final height of the mode lines) when redisplay starts but would have to know what redisplay wants it to tell. It would be easy to reserve one bit on each window to tell that its width, left scroll bar, left margin, left fringe, body width, right fringe, right margin, right scroll bar or the height, header, tab, mode line, body and scroll bar height changed. And one bit for each of font, line spacing, start and point position and the scrolling statuses of the window. Maybe also one bit for the left and top edge within the frame and the left and top body edge of the window. Once it has been established what redisplay wants to know, it would be easy to transfer practically all notifications currently performed by frame.c to window.c. That is, gui_set_left_fringe would no longer SET_FRAME_GARBAGED because the window code would decide whether the width of any left fringe of any window affected should really change and set the left_fringe_width_changed, the body_width_changed and maybe also the left_body_edge_changed bit accordingly. In addition there would probably be one window_changed bit per window to tell redisplay that one of the bits above changed and one frame_changed bit to tell redisplay that at least one window has its window_changed bit set. Then we probably should try to remove any special treatment of the selected window in this regard, since with all our excursions, code can never tell anyway which window will be the selected one at the time redisplay starts. Finally, redisplay would have to merge in all buffer text and position changes for each window showing that buffer mostly as it does now and separately consider a few frame changes like visibility. Information flow would still be bidirectional for the mode lines: As soon as redisplay has calculated their respective heights and these should change (a rare case), the window code would have to be informed about that, store the new heights, adjust the body height, recalculate scroll bar dimensions and leave it to redisplay to decide whether to calculate mode line heights again to avoid infinite recursion. martin ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 19:28 ` Eli Zaretskii 2023-07-15 19:43 ` Ihor Radchenko @ 2023-07-15 22:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 5:17 ` Eli Zaretskii 2023-07-16 5:52 ` Ihor Radchenko 1 sibling, 2 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-15 22:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 >> Sorry, I skipped this part in my previous email. >> I understand the above code, but I'm not sure what explanation might >> be needed so you can understand it as well. Maybe the problem is the >> name `consider_all_windows_p` which suggests that all windows will be >> updated, but it only says that we should loop through all the windows to >> try and find those which need to be updated. > > The actual issue with the above is different: it implies that > update_mode_lines _always_ indicates that more than a single mode line > should be updated (which is why we need to "consider all windows"). How 'bout the wording below, then? Stefan diff --git a/src/xdisp.c b/src/xdisp.c index a3464c2c375..13f4fbca074 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -16490,8 +16490,10 @@ redisplay_internal (void) enum {MAX_GARBAGED_FRAME_RETRIES = 2 }; int garbaged_frame_retries = 0; - /* True means redisplay has to consider all windows on all - frames. False, only selected_window is considered. */ + /* False, means that only the selected_window needs to be updated. + True means that other windows may need to be updated as well, + so we need to consult the `redisplay` bits of + all windows/buffer/frames. */ bool consider_all_windows_p; /* True means redisplay has to redisplay the miniwindow. */ ^ permalink raw reply related [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 22:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 5:17 ` Eli Zaretskii 2023-07-16 5:52 ` Ihor Radchenko 1 sibling, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 5:17 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sat, 15 Jul 2023 18:53:19 -0400 > > > The actual issue with the above is different: it implies that > > update_mode_lines _always_ indicates that more than a single mode line > > should be updated (which is why we need to "consider all windows"). > > How 'bout the wording below, then? OK, provided that you remove that redundant comma > + /* False, means that only the selected_window needs to be updated. ^ there. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 22:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 5:17 ` Eli Zaretskii @ 2023-07-16 5:52 ` Ihor Radchenko 2023-07-16 7:16 ` Eli Zaretskii 2023-07-16 14:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 2 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 5:52 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, 64596 Stefan Monnier <monnier@iro.umontreal.ca> writes: > - /* True means redisplay has to consider all windows on all > - frames. False, only selected_window is considered. */ > + /* False, means that only the selected_window needs to be updated. > + True means that other windows may need to be updated as well, > + so we need to consult the `redisplay` bits of > + all windows/buffer/frames. */ > bool consider_all_windows_p; BTW, is there any particular reason why windows_or_buffers_changed is not a queue of windows/buffer to be re-displayed? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 5:52 ` Ihor Radchenko @ 2023-07-16 7:16 ` Eli Zaretskii 2023-07-16 7:28 ` Ihor Radchenko 2023-07-16 14:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 7:16 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 05:52:04 +0000 > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > > - /* True means redisplay has to consider all windows on all > > - frames. False, only selected_window is considered. */ > > + /* False, means that only the selected_window needs to be updated. > > + True means that other windows may need to be updated as well, > > + so we need to consult the `redisplay` bits of > > + all windows/buffer/frames. */ > > bool consider_all_windows_p; > > BTW, is there any particular reason why windows_or_buffers_changed is > not a queue of windows/buffer to be re-displayed? Why do we need such a queue, when the redisplay flags of buffers and windows are supposed to tell us that already? ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 7:16 ` Eli Zaretskii @ 2023-07-16 7:28 ` Ihor Radchenko 2023-07-16 7:35 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 7:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> BTW, is there any particular reason why windows_or_buffers_changed is >> not a queue of windows/buffer to be re-displayed? > > Why do we need such a queue, when the redisplay flags of buffers and > windows are supposed to tell us that already? To not loop over all the existing windows and frames in xdisp.c:506 redisplay branch. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 7:28 ` Ihor Radchenko @ 2023-07-16 7:35 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 7:35 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 07:28:09 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> BTW, is there any particular reason why windows_or_buffers_changed is > >> not a queue of windows/buffer to be re-displayed? > > > > Why do we need such a queue, when the redisplay flags of buffers and > > windows are supposed to tell us that already? > > To not loop over all the existing windows and frames in xdisp.c:506 > redisplay branch. Someone will have to demonstrate that this is worth our while. Testing a single boolean flag is not an expensive operation, while maintaining that queue also takes CPU. Also, some changes in a window can affect other windows on the same frame, for example if the window is resized. IOW, maybe it's a good idea and maybe it isn't, but it definitely doesn't affect the most expensive parts of redisplay. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 5:52 ` Ihor Radchenko 2023-07-16 7:16 ` Eli Zaretskii @ 2023-07-16 14:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 14:27 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 14:04 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Eli Zaretskii, 64596 >> - /* True means redisplay has to consider all windows on all >> - frames. False, only selected_window is considered. */ >> + /* False, means that only the selected_window needs to be updated. >> + True means that other windows may need to be updated as well, >> + so we need to consult the `redisplay` bits of >> + all windows/buffer/frames. */ >> bool consider_all_windows_p; > > BTW, is there any particular reason why windows_or_buffers_changed is > not a queue of windows/buffer to be re-displayed? FWIW, I suspect that the loop over all windows is always insignificant, so (in theory) we could get rid of the optimization that looks only at the selected window in most cases and we wouldn't notice any slowdown or measurable increase in CPU use. So, replacing the `redisplay` bits with a queue is probably not a great idea (especially since setting a bit is much faster than adding an element to a queue where you need to try and avoid adding the same element a hundred times). Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 14:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 14:27 ` Eli Zaretskii 2023-07-16 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 14:27 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 10:04:30 -0400 > > >> - /* True means redisplay has to consider all windows on all > >> - frames. False, only selected_window is considered. */ > >> + /* False, means that only the selected_window needs to be updated. > >> + True means that other windows may need to be updated as well, > >> + so we need to consult the `redisplay` bits of > >> + all windows/buffer/frames. */ > >> bool consider_all_windows_p; > > > > BTW, is there any particular reason why windows_or_buffers_changed is > > not a queue of windows/buffer to be re-displayed? > > FWIW, I suspect that the loop over all windows is always > insignificant, so (in theory) we could get rid of the optimization that > looks only at the selected window in most cases and we wouldn't notice > any slowdown or measurable increase in CPU use. True, but with one caveat: the loop over all windows will not trivially return from redisplay_window if the window's frame has its redisplay flag set. So it is enough for the frame to have this flag set, for redisplay to have to consider all of its windows, even if the redisplay flag of each and every one of that frame's windows is reset. And once we decided not to return immediately after entering redisplay_window, the processing is not insignificant, since it involves making the window's buffer the current one, and as result setting all the values of buffer-local variables. So it sounds like we should make sure we don't set the frame's redisplay flag unless most or all of its windows actually need to be considered. Is this so with the current code? > So, replacing the `redisplay` bits with a queue is probably not a great > idea (especially since setting a bit is much faster than adding an > element to a queue where you need to try and avoid adding the same > element a hundred times). Agreed. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 14:27 ` Eli Zaretskii @ 2023-07-16 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 0 replies; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 14:49 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > So it sounds like we should make sure we don't set the frame's > redisplay flag unless most or all of its windows actually need to be > considered. Is this so with the current code? Indeed, the frame's `redisplay` bit means "*all* windows in that frame need to be redisplayed", so it should be set with care. But since the code before that only had a single boolean for "redisplay all windows on all frames", I was often happy enough to replace the global redisplay with `fset_redisplay` even though it might be possible to be more specific. `fset_redisplay` is typically used when windows are added/deleted/resized, because it's hard at that point to know which windows really need to be updated. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-15 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 15:22 ` Eli Zaretskii @ 2023-07-16 10:22 ` Ihor Radchenko 2023-07-16 10:37 ` Eli Zaretskii 2023-07-16 19:27 ` Eli Zaretskii 1 sibling, 2 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 10:22 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, 64596 Stefan Monnier <monnier@iro.umontreal.ca> writes: >> . prevent_redisplay_optimizations_p flag of a buffer >> . must_be_updated_p flag of a window > > No idea what these mean. > The name `must_be_updated_p` makes it sound to me like it's redundant > with the `redisplay` flag above. I agree about must_be_updated_p. I had exactly same though that it is redundant with redisplay flag when reading the code. prevent_redisplay_optimizations_p is intuitively logical, but I still feel confused because it appears to be redundant upon seeing redisplay flag in the buffer. It raises a question what redisplay flag really means - it is causing redisplay of a window/buffer or not necessarily? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 10:22 ` Ihor Radchenko @ 2023-07-16 10:37 ` Eli Zaretskii 2023-07-16 10:47 ` Ihor Radchenko 2023-07-16 19:27 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 10:37 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 10:22:38 +0000 > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > >> . prevent_redisplay_optimizations_p flag of a buffer > >> . must_be_updated_p flag of a window > > > > No idea what these mean. > > The name `must_be_updated_p` makes it sound to me like it's redundant > > with the `redisplay` flag above. > > I agree about must_be_updated_p. I had exactly same though that it is > redundant with redisplay flag when reading the code. Look closer, please. The name of the flag might suggest what you say, but its usage suggests otherwise. > prevent_redisplay_optimizations_p is intuitively logical, but I still > feel confused because it appears to be redundant upon seeing redisplay > flag in the buffer. It raises a question what redisplay flag really > means - it is causing redisplay of a window/buffer or not necessarily? Neither. The redisplay flag means that a window or a buffer or a frame need to be _considered_ for potential redisplay. (Whether the consideration will conclude there's a need to actually redraw the corresponding part of the Emacs display is another matter -- it could conclude that all, some parts of, or none of the objects marked for redisplay actually need it.) prevent_redisplay_optimizations_p says that while considering which parts of the buffer need to cause redisplay, certain shortcuts and optimizations designed to make redisplay faster and less expensive must not be taken/used. IOW, prevent_redisplay_optimizations_p must come with the redisplay flag set on the buffer/window/frame, but after that it says a different thing. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 10:37 ` Eli Zaretskii @ 2023-07-16 10:47 ` Ihor Radchenko 2023-07-16 11:31 ` Eli Zaretskii 2023-07-16 14:26 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 2 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 10:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> I agree about must_be_updated_p. I had exactly same though that it is >> redundant with redisplay flag when reading the code. > > Look closer, please. The name of the flag might suggest what you say, > but its usage suggests otherwise. Do I understand correctly that prevent_display_optimizations_p in buffer, must_be_updated_p in window, and garbaged in frames all serve the same purpose of forcing the redisplay? >> prevent_redisplay_optimizations_p is intuitively logical, but I still >> feel confused because it appears to be redundant upon seeing redisplay >> flag in the buffer. It raises a question what redisplay flag really >> means - it is causing redisplay of a window/buffer or not necessarily? > > Neither. > > The redisplay flag means that a window or a buffer or a frame need to > be _considered_ for potential redisplay. (Whether the consideration > will conclude there's a need to actually redraw the corresponding part > of the Emacs display is another matter -- it could conclude that all, > some parts of, or none of the objects marked for redisplay actually > need it.) > > prevent_redisplay_optimizations_p says that while considering which > parts of the buffer need to cause redisplay, certain shortcuts and > optimizations designed to make redisplay faster and less expensive > must not be taken/used. > > IOW, prevent_redisplay_optimizations_p must come with the redisplay > flag set on the buffer/window/frame, but after that it says a > different thing. Then, why not use uniform naming scheme and have the buffer/window/frame flags names as maybe_redisplay and must_redisplay instead of different flag name for different object type? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 10:47 ` Ihor Radchenko @ 2023-07-16 11:31 ` Eli Zaretskii 2023-07-16 14:26 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 11:31 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 10:47:55 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> I agree about must_be_updated_p. I had exactly same though that it is > >> redundant with redisplay flag when reading the code. > > > > Look closer, please. The name of the flag might suggest what you say, > > but its usage suggests otherwise. > > Do I understand correctly that prevent_display_optimizations_p in > buffer, must_be_updated_p in window, and garbaged in frames all serve > the same purpose of forcing the redisplay? They all force redisplay, yes, but in different ways. For example, the frame's garbaged flag means the entire frame with all its windows and decorations might need to be redrawn. By contrast, prevent_redisplay_optimizations_p just means "don't use some of the redisplay optimizations that we otherwise could be tempted to try". IOW, not redisplaying a window at all is not an "optimization". > > IOW, prevent_redisplay_optimizations_p must come with the redisplay > > flag set on the buffer/window/frame, but after that it says a > > different thing. > > Then, why not use uniform naming scheme and have the buffer/window/frame > flags names as maybe_redisplay and must_redisplay instead of different > flag name for different object type? Historical reasons. But such naming convention is of secondary importance, IME. As long as the names are not completely misleading, and their effects are well documented, 90% of the job is done. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 10:47 ` Ihor Radchenko 2023-07-16 11:31 ` Eli Zaretskii @ 2023-07-16 14:26 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 14:45 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 14:26 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Eli Zaretskii, 64596 >>> I agree about must_be_updated_p. I had exactly same though that it is >>> redundant with redisplay flag when reading the code. >> Look closer, please. The name of the flag might suggest what you say, >> but its usage suggests otherwise. > Do I understand correctly that prevent_display_optimizations_p in > buffer, must_be_updated_p in window, and garbaged in frames all serve > the same purpose of forcing the redisplay? My understanding of the redisplay code is that it's split into 3 part: 1- decide which windows may need to be updated. 2- update the glyph matrix of a window. 3- update the glass by comparing the old glyph matrix and the new one. [ The point between 1 and 2 is made visible to ELisp via `pre-redisplay-function`. ] The `redisplay` bits belong to step (1). The `prevent_display_optimizations_p` OTOH belong to step 2, AFAIU. BTW, I wish those 3 steps were exposed to ELisp, so the top-level of redisplay could be moved to ELisp. This would allow for example `follow-mode` to pick a more appropriate order in which to process the windows at step 2. > Then, why not use uniform naming scheme and have the buffer/window/frame > flags names as maybe_redisplay and must_redisplay instead of different > flag name for different object type? For that someone first needs to have a clear idea of what these things do and how they relate to each other :-) Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 14:26 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 14:45 ` Eli Zaretskii 2023-07-16 16:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 14:45 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 10:26:10 -0400 > > My understanding of the redisplay code is that it's split into 3 part: > > 1- decide which windows may need to be updated. More accurately: 1a - decide whether all the windows need to be considered, or just the selected window 1b - if all the windows need to be considered, decide for each frame whether it needs to be considered, and if so, consider all of that frame's windows Considering a window can sometimes decide very quickly that the window doesn't need to be redisplayed, but, as I mentioned elsewhere, when its frame's redisplay flag is set, we never decide that, and the frame's redisplay flag is what causes us to consider a frame in the first place. > 2- update the glyph matrix of a window. This update can be partial -- that's one of the redisplay optimizations. That is, we update only a very small part of the glyph matrix, as small as a single glyph row (= screen line). > 3- update the glass by comparing the old glyph matrix and the new one. > > [ The point between 1 and 2 is made visible to ELisp via > `pre-redisplay-function`. ] > > The `redisplay` bits belong to step (1). > The `prevent_display_optimizations_p` OTOH belong to step 2, AFAIU. Yes. > BTW, I wish those 3 steps were exposed to ELisp, so the top-level of > redisplay could be moved to ELisp. This would allow for example > `follow-mode` to pick a more appropriate order in which to process the > windows at step 2. follow-mode needs much more than that. But if you want to be able to tell redisplay "update only this window and nothing else", I think it should be easy to accomplish by adding a single function and no other changes: all you need is to call 'redisplay' (which is already exposed) after setting the redisplay flag of a single window. > > Then, why not use uniform naming scheme and have the buffer/window/frame > > flags names as maybe_redisplay and must_redisplay instead of different > > flag name for different object type? > > For that someone first needs to have a clear idea of what these things > do and how they relate to each other :-) Right. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 14:45 ` Eli Zaretskii @ 2023-07-16 16:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 17:11 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 16:44 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 >> 1- decide which windows may need to be updated. > > More accurately: > > 1a - decide whether all the windows need to be considered, or just > the selected window > 1b - if all the windows need to be considered, decide for each frame > whether it needs to be considered, and if so, consider all of > that frame's windows > > Considering a window can sometimes decide very quickly that the window > doesn't need to be redisplayed, but, as I mentioned elsewhere, when > its frame's redisplay flag is set, we never decide that, and the > frame's redisplay flag is what causes us to consider a frame in the > first place. Hmm... I'm not sure why you're saying frame's redisplay flag is what causes us to consider a frame in the first place. AFAICT the main place where we check a frame's `redisplay` bit is in `needs_no_redisplay` which operates on a window. In most cases a frame's `redisplay` bit should not be set, tho some of its windows' `redisplay` bits may be set, and we will consider this frame and all its windows (to find those that need to be updated). >> BTW, I wish those 3 steps were exposed to ELisp, so the top-level of >> redisplay could be moved to ELisp. This would allow for example >> `follow-mode` to pick a more appropriate order in which to process the >> windows at step 2. > > follow-mode needs much more than that. If the redisplay toplevel could be hacked in ELisp, follow-mode could call the `update-window-glyph-matrix` on the "main window" of its window-set first, then get the resulting window-end/start and use that to adjust/scroll its next/prev windows, and then call `update-window-glyph-matrix` on them, thus propagating the information in the right direction and avoiding unnecessary redisplay computations. > But if you want to be able to tell redisplay "update only this window > and nothing else", I think it should be easy to accomplish by adding > a single function and no other changes: all you need is to call > 'redisplay' (which is already exposed) after setting the redisplay > flag of a single window. That won't avoid redisplaying the other windows whose `redisplay` bits had been set already for other reasons. I guess we could try to "save the redisplay bit" of other windows/buffers/frames, and restore them afterwards. Also, it would be good to be able to compute the glyph matrices of the various affected windows before we do the actual glass update (especially if we want to handle iteration where some part of the redisplay (e.g. jit-lock, evaluation of mode-lines and menu bars, point moving out of scope forcing a scroll, you name it) causes changes which require recomputing a glyph matrix we just computed). Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 16:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 17:11 ` Eli Zaretskii 2023-07-16 17:20 ` Eli Zaretskii 2023-07-16 18:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 2 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 17:11 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 12:44:08 -0400 > > > 1a - decide whether all the windows need to be considered, or just > > the selected window > > 1b - if all the windows need to be considered, decide for each frame > > whether it needs to be considered, and if so, consider all of > > that frame's windows > > > > Considering a window can sometimes decide very quickly that the window > > doesn't need to be redisplayed, but, as I mentioned elsewhere, when > > its frame's redisplay flag is set, we never decide that, and the > > frame's redisplay flag is what causes us to consider a frame in the > > first place. > > Hmm... I'm not sure why you're saying > > frame's redisplay flag is what causes us to consider a frame in the > first place. Because fset_redisplay does this: void fset_redisplay (struct frame *f) { redisplay_other_windows (); f->redisplay = true; } and redisplay_other_windows sets windows_or_buffers_changed, which then causes consider_all_windows_p to be true upon the next redisplay cycle: consider_all_windows_p = (update_mode_lines || windows_or_buffers_changed); > If the redisplay toplevel could be hacked in ELisp, follow-mode could > call the `update-window-glyph-matrix` on the "main window" of its > window-set first, then get the resulting window-end/start and use that > to adjust/scroll its next/prev windows, and then call > `update-window-glyph-matrix` on them, thus propagating the information > in the right direction and avoiding unnecessary redisplay computations. > > > But if you want to be able to tell redisplay "update only this window > > and nothing else", I think it should be easy to accomplish by adding > > a single function and no other changes: all you need is to call > > 'redisplay' (which is already exposed) after setting the redisplay > > flag of a single window. > > That won't avoid redisplaying the other windows whose `redisplay` bits > had been set already for other reasons. Yes, it will: when a window is redisplayed by redisplay_window, its redisplay flag is reset, and it will not be redisplayed during this cycle. So if you have a way to redisplay a single window, you can do that in any order you want, one window at a time, and those windows which you redisplayed in this way will not be redisplayed until the next cycle. As for update-window-glyph-matrix, I don't see why that would help, because updating the matrix without calling update_window fairly soon after that will not produce the effect that you want. > I guess we could try to "save the redisplay bit" of other > windows/buffers/frames, and restore them afterwards. What for? > Also, it would be good to be able to compute the glyph matrices of > the various affected windows before we do the actual glass update > (especially if we want to handle iteration where some part of the > redisplay (e.g. jit-lock, evaluation of mode-lines and menu bars, > point moving out of scope forcing a scroll, you name it) causes > changes which require recomputing a glyph matrix we just computed). Sounds like an unnecessary complication to me, and for some situations I'm not even sure how you can handle them, unless you thoroughly redesign the display code. IOW, this is not just a matter of exposing a small number of functions to Lisp, IMO. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 17:11 ` Eli Zaretskii @ 2023-07-16 17:20 ` Eli Zaretskii 2023-07-16 18:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 1 sibling, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 17:20 UTC (permalink / raw) To: monnier; +Cc: yantar92, 64596 > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 20:11:24 +0300 > From: Eli Zaretskii <eliz@gnu.org> > > > > But if you want to be able to tell redisplay "update only this window > > > and nothing else", I think it should be easy to accomplish by adding > > > a single function and no other changes: all you need is to call > > > 'redisplay' (which is already exposed) after setting the redisplay > > > flag of a single window. Another easy-to-implement idea: give redisplay_internal a list of windows in the order you want them redisplayed, in which case it will follow that order instead of the current depth-first order implemented by redisplay_windows. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 17:11 ` Eli Zaretskii 2023-07-16 17:20 ` Eli Zaretskii @ 2023-07-16 18:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 19:06 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 18:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 >> Hmm... I'm not sure why you're saying >> >> frame's redisplay flag is what causes us to consider a frame in the >> first place. > > Because fset_redisplay does this: > > void > fset_redisplay (struct frame *f) > { > redisplay_other_windows (); > f->redisplay = true; > } > > and redisplay_other_windows sets windows_or_buffers_changed, which > then causes consider_all_windows_p to be true upon the next redisplay > cycle: > > consider_all_windows_p = (update_mode_lines > || windows_or_buffers_changed); Yes, most calls to `[fbw]set_redisplay` will call `redisplay_other_windows` and once that function has been called, all the frames will be "considered", but that happens regardless of the `redisplay` bit of any particular frame. The `redisplay` bit is consulted later, once we loop over all the windows in all those frames, where we decide which of those windows are updated depending on the `redisplay` bits of the window, the window's buffer, and the window's frame. Are you maybe confused by the name of the `FRAME_REDISPLAY_P` macro, which does *not* pay attention to the `redisplay` bit? > IOW, this is not just a matter of exposing a small number of functions > to Lisp, IMO. I'm sorry if I made you think I suggested it would be a simple matter. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 18:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 19:06 ` Eli Zaretskii 2023-07-16 22:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 19:06 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 14:53:03 -0400 > > >> Hmm... I'm not sure why you're saying > >> > >> frame's redisplay flag is what causes us to consider a frame in the > >> first place. > > > > Because fset_redisplay does this: > > > > void > > fset_redisplay (struct frame *f) > > { > > redisplay_other_windows (); > > f->redisplay = true; > > } > > > > and redisplay_other_windows sets windows_or_buffers_changed, which > > then causes consider_all_windows_p to be true upon the next redisplay > > cycle: > > > > consider_all_windows_p = (update_mode_lines > > || windows_or_buffers_changed); > > Yes, most calls to `[fbw]set_redisplay` will call > `redisplay_other_windows` and once that function has been called, all > the frames will be "considered", but that happens regardless of the > `redisplay` bit of any particular frame. If we always set these flags by calling these functions, then we will end up doing more in redisplay than needed, because update_mode_lines and windows_or_buffers_changed also disable certain optimizations. When someone writes code that calls fset_redisplay, he or she are likely to think that all this does is set the redisplay flag. Which is not true. If every call to fset_redisplay indeed needs to disable those optimizations, we should have more flags, and should probably not call the function fset_redisplay, but something else. > The `redisplay` bit is consulted later, once we loop over all the > windows in all those frames, where we decide which of those windows are > updated depending on the `redisplay` bits of the window, the window's > buffer, and the window's frame. That's not all of the uses of this flag. Here's one example of other uses: if (some_windows && !f->redisplay && !w->redisplay && !XBUFFER (w->contents)->text->redisplay) continue; (This avoids updating the tool bar and the tab bar of the frame, and there's a similar condition that avoids updating the frame's title.) > Are you maybe confused by the name of the `FRAME_REDISPLAY_P` macro, > which does *not* pay attention to the `redisplay` bit? No, I don't think I'm confused about that. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 19:06 ` Eli Zaretskii @ 2023-07-16 22:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-17 11:20 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-16 22:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 > That's not all of the uses of this flag. Here's one example of other > uses: > > if (some_windows > && !f->redisplay > && !w->redisplay > && !XBUFFER (w->contents)->text->redisplay) > continue; > > (This avoids updating the tool bar and the tab bar of the frame, and > there's a similar condition that avoids updating the frame's title.) Right, but notice that what we're fundamentally checking is whether `w` (which is the frame's selected window here) needs to be updated, because that's the one currently "occupying" the tool-bar. FWIW, I don't know why we don't also check `XBUFFER(w->contents)->redisplay` here. Also, I still don't see why that makes you think: frame's redisplay flag is what causes us to consider a frame in the first place. Indeed, a frame's redisplay flag may be such a reason, but a window's flag or its text buffer's may be the reason instead. A frame's `redisplay` flag does not need to be set for us to consider it. Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 22:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-17 11:20 ` Eli Zaretskii 2023-07-17 12:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-17 11:20 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 18:19:57 -0400 > > > That's not all of the uses of this flag. Here's one example of other > > uses: > > > > if (some_windows > > && !f->redisplay > > && !w->redisplay > > && !XBUFFER (w->contents)->text->redisplay) > > continue; > > > > (This avoids updating the tool bar and the tab bar of the frame, and > > there's a similar condition that avoids updating the frame's title.) > > Right, but notice that what we're fundamentally checking is whether `w` > (which is the frame's selected window here) needs to be updated, because > that's the one currently "occupying" the tool-bar. But testing the frame's redisplay flag will produce false positives, because many changes that require to redraw the frame's windows don't affect the tool bar or the frame's title. > FWIW, I don't know why we don't also check > `XBUFFER(w->contents)->redisplay` here. We do: if (some_windows && !f->redisplay && !w->redisplay && !XBUFFER (w->contents)->text->redisplay) <<<<<<<<<<< continue; > Also, I still don't see why that makes you think: > > frame's redisplay flag is what causes us to consider a frame in the > first place. > > Indeed, a frame's redisplay flag may be such a reason, but a window's > flag or its text buffer's may be the reason instead. A frame's > `redisplay` flag does not need to be set for us to consider it. No, my point is that fset_redisplay shouldn't set windows_or_buffers_changed. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-17 11:20 ` Eli Zaretskii @ 2023-07-17 12:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-17 13:07 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-17 12:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, 64596 >> > That's not all of the uses of this flag. Here's one example of other >> > uses: >> > >> > if (some_windows >> > && !f->redisplay >> > && !w->redisplay >> > && !XBUFFER (w->contents)->text->redisplay) >> > continue; >> > >> > (This avoids updating the tool bar and the tab bar of the frame, and >> > there's a similar condition that avoids updating the frame's title.) >> Right, but notice that what we're fundamentally checking is whether `w` >> (which is the frame's selected window here) needs to be updated, because >> that's the one currently "occupying" the tool-bar. > But testing the frame's redisplay flag will produce false positives, > because many changes that require to redraw the frame's windows don't > affect the tool bar or the frame's title. Of course, we have loads of false positives. The point of the `redisplay` flags is just to rule out things we can easily rule out. It's very coarse. It could be made finer, of course. > No, my point is that fset_redisplay shouldn't set > windows_or_buffers_changed. Setting `windows_or_buffers_changed` there is currently necessary in order to make sure we look at the `redisplay` bits (as opposed to updating only the selected window). Stefan ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-17 12:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-07-17 13:07 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-17 13:07 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Mon, 17 Jul 2023 08:53:00 -0400 > > > No, my point is that fset_redisplay shouldn't set > > windows_or_buffers_changed. > > Setting `windows_or_buffers_changed` there is currently necessary in > order to make sure we look at the `redisplay` bits (as opposed to > updating only the selected window). I understand; I was suggesting a possible cleanup, since this discussion is mainly about such cleanups. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 10:22 ` Ihor Radchenko 2023-07-16 10:37 ` Eli Zaretskii @ 2023-07-16 19:27 ` Eli Zaretskii 2023-07-16 20:12 ` Ihor Radchenko 1 sibling, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-16 19:27 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 10:22:38 +0000 > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > >> . prevent_redisplay_optimizations_p flag of a buffer > >> . must_be_updated_p flag of a window > > > > No idea what these mean. > > The name `must_be_updated_p` makes it sound to me like it's redundant > > with the `redisplay` flag above. > > I agree about must_be_updated_p. I had exactly same though that it is > redundant with redisplay flag when reading the code. Actually, the must_be_updated_p flag is not for xdisp.c, i.e. not for redisplay_window and its subroutines. It is for update_window, which is the last, 3rd, stage of a redisplay cycle, most of the code of which is in dispnew.c. That's where the newly computed glyph matrix of a window is compared to its current matrix, and Emacs decides what, if anything, should be actually written to the glass. What happens with this flag is that redisplay_window and friends _set_ this flag for windows that dispnew.c _must_ update. The flag is tested in dispnew.c, see there for its use and comments. So it was wrong for me to include that flag in the list which started this sub-thread. Sorry about that. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 19:27 ` Eli Zaretskii @ 2023-07-16 20:12 ` Ihor Radchenko 2023-07-17 2:23 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-16 20:12 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> From: Ihor Radchenko <yantar92@posteo.net> >> Cc: Eli Zaretskii <eliz@gnu.org>, 64596@debbugs.gnu.org >> Date: Sun, 16 Jul 2023 10:22:38 +0000 >> >> Stefan Monnier <monnier@iro.umontreal.ca> writes: >> >> >> . prevent_redisplay_optimizations_p flag of a buffer >> >> . must_be_updated_p flag of a window >> > >> > No idea what these mean. >> > The name `must_be_updated_p` makes it sound to me like it's redundant >> > with the `redisplay` flag above. >> >> I agree about must_be_updated_p. I had exactly same though that it is >> redundant with redisplay flag when reading the code. > > Actually, the must_be_updated_p flag is not for xdisp.c, i.e. not for > redisplay_window and its subroutines. It is for update_window, which > is the last, 3rd, stage of a redisplay cycle, most of the code of > which is in dispnew.c. That's where the newly computed glyph matrix > of a window is compared to its current matrix, and Emacs decides what, > if anything, should be actually written to the glass. What happens > with this flag is that redisplay_window and friends _set_ this flag > for windows that dispnew.c _must_ update. The flag is tested in > dispnew.c, see there for its use and comments. I see. I have to say that these flag names are very disorienting. I have first seen this flag while reading xdisp.c, and it was not obvious at all what it does. The name must_be_updated has no link with glyph matrix terminology, and it is only explained in the commentary in window.h. But then, at the point of reading commentary I was not yet familiar with xdisp... -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-16 20:12 ` Ihor Radchenko @ 2023-07-17 2:23 ` Eli Zaretskii 2023-07-17 9:22 ` Ihor Radchenko 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-17 2:23 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Sun, 16 Jul 2023 20:12:34 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Actually, the must_be_updated_p flag is not for xdisp.c, i.e. not for > > redisplay_window and its subroutines. It is for update_window, which > > is the last, 3rd, stage of a redisplay cycle, most of the code of > > which is in dispnew.c. That's where the newly computed glyph matrix > > of a window is compared to its current matrix, and Emacs decides what, > > if anything, should be actually written to the glass. What happens > > with this flag is that redisplay_window and friends _set_ this flag > > for windows that dispnew.c _must_ update. The flag is tested in > > dispnew.c, see there for its use and comments. > > I see. > > I have to say that these flag names are very disorienting. > I have first seen this flag while reading xdisp.c, and it was not obvious > at all what it does. Well, update_frame and update_window are the relevant functions in dispnew.c, so "must_be_updated_p" kind-of points to them. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-17 2:23 ` Eli Zaretskii @ 2023-07-17 9:22 ` Ihor Radchenko 2023-07-17 11:54 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-17 9:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> > Actually, the must_be_updated_p flag is not for xdisp.c, i.e. not for >> > redisplay_window and its subroutines. It is for update_window, which >> > is the last, 3rd, stage of a redisplay cycle, most of the code of >> > which is in dispnew.c... >> >> I have to say that these flag names are very disorienting. >> I have first seen this flag while reading xdisp.c, and it was not obvious >> at all what it does. > > Well, update_frame and update_window are the relevant functions in > dispnew.c, so "must_be_updated_p" kind-of points to them. This does not help the confusion, unfortunately. Or maybe the terms "redisplay" and "update" should be explained better somewhere near the top of xdisp.c. They clearly have different meaning, but not for untrained eye. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-17 9:22 ` Ihor Radchenko @ 2023-07-17 11:54 ` Eli Zaretskii 2023-07-17 12:00 ` Ihor Radchenko 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-17 11:54 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Mon, 17 Jul 2023 09:22:07 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> > Actually, the must_be_updated_p flag is not for xdisp.c, i.e. not for > >> > redisplay_window and its subroutines. It is for update_window, which > >> > is the last, 3rd, stage of a redisplay cycle, most of the code of > >> > which is in dispnew.c... > >> > >> I have to say that these flag names are very disorienting. > >> I have first seen this flag while reading xdisp.c, and it was not obvious > >> at all what it does. > > > > Well, update_frame and update_window are the relevant functions in > > dispnew.c, so "must_be_updated_p" kind-of points to them. > > This does not help the confusion, unfortunately. > Or maybe the terms "redisplay" and "update" should be explained better > somewhere near the top of xdisp.c. They clearly have different meaning, > but not for untrained eye. "Update" is the general name of the 3rd step of "redisplay cycle". It takes its name from the function which enters this step: update_frame. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-17 11:54 ` Eli Zaretskii @ 2023-07-17 12:00 ` Ihor Radchenko 2023-07-17 12:22 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-17 12:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> This does not help the confusion, unfortunately. >> Or maybe the terms "redisplay" and "update" should be explained better >> somewhere near the top of xdisp.c. They clearly have different meaning, >> but not for untrained eye. > > "Update" is the general name of the 3rd step of "redisplay cycle". It > takes its name from the function which enters this step: update_frame. May someone then detail these steps in the top commentary in xdisp.c + highlight that redisplay term is generally used when deciding if we need to update. And update is an actual process of putting desired matrix onto the glass. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-17 12:00 ` Ihor Radchenko @ 2023-07-17 12:22 ` Eli Zaretskii 2023-07-18 9:52 ` Ihor Radchenko 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-17 12:22 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Mon, 17 Jul 2023 12:00:02 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> This does not help the confusion, unfortunately. > >> Or maybe the terms "redisplay" and "update" should be explained better > >> somewhere near the top of xdisp.c. They clearly have different meaning, > >> but not for untrained eye. > > > > "Update" is the general name of the 3rd step of "redisplay cycle". It > > takes its name from the function which enters this step: update_frame. > > May someone then detail these steps in the top commentary in xdisp.c + > highlight that redisplay term is generally used when deciding if we need > to update. It's already in the large commentary at the beginning of xdisp.c (search for "update_window" to find the description of "update"). It just "drowns" in the sea of the information there > And update is an actual process of putting desired matrix onto the > glass. That's a very simplistic description of what "update" does. Even the comment in xdisp.c says more. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-17 12:22 ` Eli Zaretskii @ 2023-07-18 9:52 ` Ihor Radchenko 2023-07-18 11:51 ` Eli Zaretskii 2023-07-21 2:41 ` Richard Stallman 0 siblings, 2 replies; 90+ messages in thread From: Ihor Radchenko @ 2023-07-18 9:52 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> May someone then detail these steps in the top commentary in xdisp.c + >> highlight that redisplay term is generally used when deciding if we need >> to update. > > It's already in the large commentary at the beginning of xdisp.c > (search for "update_window" to find the description of "update"). It > just "drowns" in the sea of the information there I saw this. But "update" is not used consistently across that commentary. If we read at the very beginning: /* New redisplay written by Gerd Moellmann <gerd@gnu.org>. Redisplay. Emacs separates the task of updating the display from code modifying global state, e.g. buffer text. ... Updating the display is triggered by the Lisp interpreter when it decides it's time to do it.... Which immediately creates an impression that "redisplay" and "update" are referring to the same thing. It would be nice the highlight the distinction rightaway there. Further, You will find a lot of redisplay optimizations when you start looking at the innards of redisplay. The overall goal of all these optimizations is to make redisplay fast because it is done frequently. Some of these optimizations are implemented by the following functions: focuses on optimizations related to window, but says nothing about checking frames. It talks not about buffers displayed in multiple windows either. The rest of the commentary is diving deep into the "update" part. Redisplay and its optimizations are not described in sufficient detail. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-18 9:52 ` Ihor Radchenko @ 2023-07-18 11:51 ` Eli Zaretskii 2023-07-19 10:11 ` Ihor Radchenko 2023-07-21 2:41 ` Richard Stallman 1 sibling, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-18 11:51 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Tue, 18 Jul 2023 09:52:28 +0000 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> May someone then detail these steps in the top commentary in xdisp.c + > >> highlight that redisplay term is generally used when deciding if we need > >> to update. > > > > It's already in the large commentary at the beginning of xdisp.c > > (search for "update_window" to find the description of "update"). It > > just "drowns" in the sea of the information there > > I saw this. But "update" is not used consistently across that > commentary. Tough. "Update" is too general a word to limit is use. Sorry. > If we read at the very beginning: > > /* New redisplay written by Gerd Moellmann <gerd@gnu.org>. > > Redisplay. > > Emacs separates the task of updating the display from code > modifying global state, e.g. buffer text. ... > > Updating the display is triggered by the Lisp interpreter when it > decides it's time to do it.... > > Which immediately creates an impression that "redisplay" and "update" > are referring to the same thing. There's no practical way to avoid all the possible misinterpretations of this large and complex text, especially when it is read for the first time. > It would be nice the highlight the distinction rightaway there. If someone wants to work on making this commentary more clear, please do. But in general, I think we are splitting hair here. This commentary is intended as an introduction to reading the code and some kind of general guidelines. It doesn't pretend to be a detailed and comprehensive documentation of everything that happens in the display engine. Rest assured that there are important aspects and algorithms of the display engine that are completely absent from this commentary. > You will find a lot of redisplay optimizations when you start > looking at the innards of redisplay. The overall goal of all these > optimizations is to make redisplay fast because it is done > frequently. Some of these optimizations are implemented by the > following functions: > > focuses on optimizations related to window, but says nothing about > checking frames. Because nothing interesting happens on frames that can be described as "redisplay optimizations". The only situation where some important optimizations do happen there is on TTY frames, and that _is_ covered: see the section headed "Frame matrices". > It talks not about buffers displayed in multiple > windows either. Again, no redisplay optimizations consider multiple windows; they all work on a single window. And the text doesn't describe many more other things. Like I said: this is intended to be an introduction and a "guide for the perplexed", not a full and detailed documentation -- that would be a much larger job and a much longer text. Informative additions to this commentary are welcome, of course. > The rest of the commentary is diving deep into the "update" part. > Redisplay and its optimizations are not described in sufficient detail. This is a misunderstanding: where that part talks about "updating the display", it actually means updating the window's glyph matrix. The only "optimization" in the "update" part is that we write to the glass only the portions where the current and the desired glyph matrices differ, and cannot be made identical by moving pixels on the screen (as opposed to actually displaying new pixels). ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-18 11:51 ` Eli Zaretskii @ 2023-07-19 10:11 ` Ihor Radchenko 2023-07-19 14:55 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-19 10:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 [-- Attachment #1: Type: text/plain, Size: 940 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> I saw this. But "update" is not used consistently across that >> commentary. > > Tough. "Update" is too general a word to limit is use. Sorry. May it be replaced by another, more precise, term then? >> If we read at the very beginning: >> >> /* New redisplay written by Gerd Moellmann <gerd@gnu.org>. >> >> Redisplay. >> >> Emacs separates the task of updating the display from code >> modifying global state, e.g. buffer text. ... >> >> Updating the display is triggered by the Lisp interpreter when it >> decides it's time to do it.... >> >> Which immediately creates an impression that "redisplay" and "update" >> are referring to the same thing. > > There's no practical way to avoid all the possible misinterpretations > of this large and complex text, especially when it is read for the > first time. What about the attached patch? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-src-xdisp.c-Clarify-the-meaning-of-update-term-in-co.patch --] [-- Type: text/x-patch, Size: 1331 bytes --] From 2be256093307246f8a3a62a5613467ceb6e7e9b8 Mon Sep 17 00:00:00 2001 Message-ID: <2be256093307246f8a3a62a5613467ceb6e7e9b8.1689761362.git.yantar92@posteo.net> From: Ihor Radchenko <yantar92@posteo.net> Date: Wed, 19 Jul 2023 13:08:54 +0300 Subject: [PATCH] * src/xdisp.c: Clarify the meaning of "update" term in commentary See bug#64596. --- src/xdisp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/xdisp.c b/src/xdisp.c index a3464c2c375..b306159c2f9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -75,6 +75,13 @@ Copyright (C) 1985-2023 Free Software Foundation, Inc. and to make these changes visible. Preferably it would do that in a moderately intelligent way, i.e. fast. + To be as fast as possible, redisplay code tries hard to avoid + updating unchanged parts of the display on the glass. Redisplay + process starts from examining what has been changed since the + previous redisplay and only running the glass _update_ action when + necessary. In the code below, functions and variables related to + updating on the glass will have _update_ in their names. + Changes in buffer text can be deduced from window and buffer structures, and from some global variables like `beg_unchanged' and `end_unchanged'. The contents of the display are additionally -- 2.41.0 [-- Attachment #3: Type: text/plain, Size: 224 bytes --] -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply related [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-19 10:11 ` Ihor Radchenko @ 2023-07-19 14:55 ` Eli Zaretskii 2023-07-19 15:50 ` Ihor Radchenko 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-19 14:55 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Wed, 19 Jul 2023 10:11:19 +0000 > > >> I saw this. But "update" is not used consistently across that > >> commentary. > > > > Tough. "Update" is too general a word to limit is use. Sorry. > > May it be replaced by another, more precise, term then? Already done. > What about the attached patch? Thanks, I installed a more detailed overview of the redisplay cycle, which I hope will make the commentary more clear. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-19 14:55 ` Eli Zaretskii @ 2023-07-19 15:50 ` Ihor Radchenko 2023-07-19 16:30 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-19 15:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: > Thanks, I installed a more detailed overview of the redisplay cycle, > which I hope will make the commentary more clear. Thanks! Several nitpicks: https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=86f2d6d62fce90d19815503e3e99ac9c4d4585af + . decide which windows on which frames need their windows ^buffers? + considered for redisplay + For buffer parts that have been changed since the last redisplay, + `redisplay_window' __constructs__ a second glyph matrix ___is constructed___, + part of the display by scrolling lines. The actual update of the + display of each window ___by comparing the desired and the current + matrix___ is done by `update_window', which calls functions which draw maybe put that clause after by `update_window'. + to the glass (those functions are specific to the type of the + window's frame: X, w32, NS, etc.). -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-19 15:50 ` Ihor Radchenko @ 2023-07-19 16:30 ` Eli Zaretskii 2023-07-20 9:40 ` Ihor Radchenko 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-19 16:30 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Wed, 19 Jul 2023 15:50:20 +0000 > > + . decide which windows on which frames need their windows > ^buffers? > + considered for redisplay Not buffers, windows. Redisplay works by windows, not by buffers. When it decides to work on a window, it temporarily makes that window's buffer current. > + For buffer parts that have been changed since the last redisplay, > + `redisplay_window' __constructs__ a second glyph matrix ___is constructed___, Fixed. > + part of the display by scrolling lines. The actual update of the > + display of each window ___by comparing the desired and the current > + matrix___ is done by `update_window', which calls functions which draw > > maybe put that clause after by `update_window'. I added commas instead. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-19 16:30 ` Eli Zaretskii @ 2023-07-20 9:40 ` Ihor Radchenko 2023-07-20 10:23 ` Eli Zaretskii 0 siblings, 1 reply; 90+ messages in thread From: Ihor Radchenko @ 2023-07-20 9:40 UTC (permalink / raw) To: Eli Zaretskii; +Cc: monnier, 64596 Eli Zaretskii <eliz@gnu.org> writes: >> + . decide which windows on which frames need their windows >> ^buffers? >> + considered for redisplay > > Not buffers, windows. Redisplay works by windows, not by buffers. > When it decides to work on a window, it temporarily makes that > window's buffer current. Then, the sentence is a big confusing. . decide which windows ... need their windows considered ... How can windows have "their windows"? -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92> ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-20 9:40 ` Ihor Radchenko @ 2023-07-20 10:23 ` Eli Zaretskii 0 siblings, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-20 10:23 UTC (permalink / raw) To: Ihor Radchenko; +Cc: monnier, 64596 > From: Ihor Radchenko <yantar92@posteo.net> > Cc: monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Thu, 20 Jul 2023 09:40:19 +0000 > > Then, the sentence is a big confusing. > > . decide which windows ... need their windows considered ... > > How can windows have "their windows"? Fixed, thanks. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-18 9:52 ` Ihor Radchenko 2023-07-18 11:51 ` Eli Zaretskii @ 2023-07-21 2:41 ` Richard Stallman 2023-07-21 5:48 ` Eli Zaretskii 1 sibling, 1 reply; 90+ messages in thread From: Richard Stallman @ 2023-07-21 2:41 UTC (permalink / raw) To: Ihor Radchenko; +Cc: eliz, monnier, 64596 [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > Which immediately creates an impression that "redisplay" and "update" > are referring to the same thing. > It would be nice the highlight the distinction rightaway there. For me, they are two ways of thinking about the same action. Redisplay is a little more terse and a little more technical in feel, but concretely it means "updating the screen". -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-21 2:41 ` Richard Stallman @ 2023-07-21 5:48 ` Eli Zaretskii 2023-07-23 3:01 ` Richard Stallman 0 siblings, 1 reply; 90+ messages in thread From: Eli Zaretskii @ 2023-07-21 5:48 UTC (permalink / raw) To: rms; +Cc: yantar92, monnier, 64596 > From: Richard Stallman <rms@gnu.org> > Cc: eliz@gnu.org, monnier@iro.umontreal.ca, 64596@debbugs.gnu.org > Date: Thu, 20 Jul 2023 22:41:01 -0400 > > > Which immediately creates an impression that "redisplay" and "update" > > are referring to the same thing. > > It would be nice the highlight the distinction rightaway there. > > For me, they are two ways of thinking about the same action. > Redisplay is a little more terse and a little more technical in feel, > but concretely it means "updating the screen". Yes, it does. "Redisplay" is actually the name of the entire process, which includes "update_frame" as its last step. I have modified the commentary in xdisp.c to make this "30KFt view" of redisplay more clear at first reading. ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-21 5:48 ` Eli Zaretskii @ 2023-07-23 3:01 ` Richard Stallman 0 siblings, 0 replies; 90+ messages in thread From: Richard Stallman @ 2023-07-23 3:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: yantar92, monnier, 64596 [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > I have modified the commentary in xdisp.c to make this "30KFt view" of > redisplay more clear at first reading. Thanks for clarifying it. -- Dr Richard Stallman (https://stallman.org) Chief GNUisance of the GNU Project (https://gnu.org) Founder, Free Software Foundation (https://fsf.org) Internet Hall-of-Famer (https://internethalloffame.org) ^ permalink raw reply [flat|nested] 90+ messages in thread
* bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) 2023-07-14 17:38 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 17:46 ` Ihor Radchenko @ 2023-07-14 19:05 ` Eli Zaretskii 1 sibling, 0 replies; 90+ messages in thread From: Eli Zaretskii @ 2023-07-14 19:05 UTC (permalink / raw) To: Stefan Monnier; +Cc: yantar92, 64596 > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: yantar92@posteo.net, 64596@debbugs.gnu.org > Date: Fri, 14 Jul 2023 13:38:11 -0400 > > > No, one variable is not enough -- it will never tell us which of the > > potential flags or settings of the flag requires to be reinstated. We > > need to be able to investigate this at a finer granularity. > > I doubt it. > > What we need in order to investigate is a somewhat reproducible test > case and for that we need the bug to be exposed to as many users as > possible to increase the chance that one of them bumps into > a good recipe. > > The variable is not used to investigate, but to make it ethical to > expose users to those potential bugs because they can set the var to > recover the old behavior as soon as they're tired of playing the > guinea pig. That's not what I had in mind when I proposed this approach. What I had in mind was to investigate the need for every one of the variables we use to disable redisplay optimizations in the various cases: the prevent_redisplay_optimizations_p flag, the update_mode_lines variable, the windows_or_buffers_changed variable, etc. -- in the places in xdisp.c where these are heeded. The purpose was to understand better which ones should be used where and why. This cannot be done with a single variable. So if you want a single variable for some "ethical" pseudo-investigation, I guess we deeply disagree here. I'm not interested in such "investigation". ^ permalink raw reply [flat|nested] 90+ messages in thread
end of thread, other threads:[~2023-07-23 3:01 UTC | newest] Thread overview: 90+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-07-13 13:00 bug#64596: 30.0.50; On FIXME: in src/buffer.c:1481 (force-mode-line-update) Ihor Radchenko 2023-07-13 13:34 ` Eli Zaretskii 2023-07-13 17:19 ` Ihor Radchenko 2023-07-13 19:03 ` Eli Zaretskii 2023-07-14 11:53 ` Ihor Radchenko 2023-07-14 12:25 ` Eli Zaretskii 2023-07-14 13:48 ` Ihor Radchenko 2023-07-14 14:20 ` Eli Zaretskii 2023-07-14 14:50 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 14:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 15:56 ` Eli Zaretskii 2023-07-13 17:20 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-13 19:08 ` Eli Zaretskii 2023-07-13 21:00 ` Ihor Radchenko 2023-07-13 22:02 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 6:14 ` Eli Zaretskii 2023-07-14 14:31 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 16:00 ` Eli Zaretskii 2023-07-14 17:38 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-14 17:46 ` Ihor Radchenko 2023-07-14 19:06 ` Eli Zaretskii 2023-07-15 7:01 ` Eli Zaretskii 2023-07-15 7:22 ` Ihor Radchenko 2023-07-15 8:52 ` Eli Zaretskii 2023-07-15 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 15:22 ` Eli Zaretskii 2023-07-15 16:01 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 16:16 ` Eli Zaretskii 2023-07-15 17:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 19:04 ` Eli Zaretskii 2023-07-16 10:38 ` Ihor Radchenko 2023-07-16 11:26 ` Eli Zaretskii 2023-07-15 18:15 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-15 19:18 ` Eli Zaretskii 2023-07-15 19:28 ` Eli Zaretskii 2023-07-15 19:43 ` Ihor Radchenko 2023-07-15 23:10 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 4:57 ` Eli Zaretskii 2023-07-16 5:49 ` Ihor Radchenko 2023-07-16 7:15 ` Eli Zaretskii 2023-07-16 8:26 ` martin rudalics 2023-07-16 8:40 ` Ihor Radchenko 2023-07-16 8:56 ` Eli Zaretskii 2023-07-16 9:41 ` Ihor Radchenko 2023-07-16 10:30 ` Eli Zaretskii 2023-07-16 8:50 ` Eli Zaretskii 2023-07-17 8:30 ` martin rudalics 2023-07-15 22:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 5:17 ` Eli Zaretskii 2023-07-16 5:52 ` Ihor Radchenko 2023-07-16 7:16 ` Eli Zaretskii 2023-07-16 7:28 ` Ihor Radchenko 2023-07-16 7:35 ` Eli Zaretskii 2023-07-16 14:04 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 14:27 ` Eli Zaretskii 2023-07-16 14:49 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 10:22 ` Ihor Radchenko 2023-07-16 10:37 ` Eli Zaretskii 2023-07-16 10:47 ` Ihor Radchenko 2023-07-16 11:31 ` Eli Zaretskii 2023-07-16 14:26 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 14:45 ` Eli Zaretskii 2023-07-16 16:44 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 17:11 ` Eli Zaretskii 2023-07-16 17:20 ` Eli Zaretskii 2023-07-16 18:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-16 19:06 ` Eli Zaretskii 2023-07-16 22:19 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-17 11:20 ` Eli Zaretskii 2023-07-17 12:53 ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors 2023-07-17 13:07 ` Eli Zaretskii 2023-07-16 19:27 ` Eli Zaretskii 2023-07-16 20:12 ` Ihor Radchenko 2023-07-17 2:23 ` Eli Zaretskii 2023-07-17 9:22 ` Ihor Radchenko 2023-07-17 11:54 ` Eli Zaretskii 2023-07-17 12:00 ` Ihor Radchenko 2023-07-17 12:22 ` Eli Zaretskii 2023-07-18 9:52 ` Ihor Radchenko 2023-07-18 11:51 ` Eli Zaretskii 2023-07-19 10:11 ` Ihor Radchenko 2023-07-19 14:55 ` Eli Zaretskii 2023-07-19 15:50 ` Ihor Radchenko 2023-07-19 16:30 ` Eli Zaretskii 2023-07-20 9:40 ` Ihor Radchenko 2023-07-20 10:23 ` Eli Zaretskii 2023-07-21 2:41 ` Richard Stallman 2023-07-21 5:48 ` Eli Zaretskii 2023-07-23 3:01 ` Richard Stallman 2023-07-14 19:05 ` Eli Zaretskii
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git 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).