unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
@ 2021-12-19 20:42 Markus Triska
  2021-12-20  9:18 ` martin rudalics
  2021-12-20 15:11 ` Eli Zaretskii
  0 siblings, 2 replies; 14+ messages in thread
From: Markus Triska @ 2021-12-19 20:42 UTC (permalink / raw)
  To: 52666

Dear all,

to reproduce this issue, please put the following form in a new file
flicker.el:

    (while t
      (let ((f (make-frame `((parent-frame . ,(selected-frame))
                             (left . 200)
                             (top . 200)))))
        (set-frame-width f 200 nil t)
        (set-frame-height f 200 nil t)
        (sit-for 0.3)
        (delete-frame f)))

and then invoke Emacs with:

    $ emacs -Q -l flicker.el

The form repeatedly creates and destroys a child frame, offset 200
pixels both horizontally and vertically from the top left corner of the
frame.

Unexpectedly, the mode line flickers in many (though apparently not all)
iterations, starting at 200 pixels horizontally from the left, even
though the frame does not overlap the mode line in any way.

Ideally, the creation of the frame should not have any visible effect on
the mode line.

Could the pleasant double buffering feature I have read about help to
remove this flickering when creating child frames? Please let me know if
you can reproduce the issue or need any further information. I can
reproduce the flickering both on OSX and on Debian.

Thank you a lot!
Markus

In GNU Emacs 27.0.50 (build 1, x86_64-apple-darwin18.0.0, X toolkit, Xaw scroll bars)
 of 2018-11-15 built on mts-mac
Repository revision: b4eb908f858284a7962851fd99c94598f76afa6f
Windowing system distributor 'The X.Org Foundation', version 11.0.11804000
System Description:  Mac OS X 10.14.2


Configured using:
 'configure --prefix=/opt/local --without-ns --without-dbus
 --without-gconf --without-libotf --without-m17n-flt --without-gpm
 --with-gnutls --with-xml2 --with-modules --infodir
 /opt/local/share/info/emacs --with-json --with-x-toolkit=lucid
 --without-xaw3d --without-imagemagick --with-xpm --with-jpeg
 --with-tiff --with-gif --with-png --with-lcms2 --without-rsvg
 --with-xft 'CFLAGS=-pipe -Os
 ...

Configured features:
XPM JPEG TIFF GIF PNG NOTIFY KQUEUE ACL GNUTLS LIBXML2 FREETYPE XFT ZLIB
TOOLKIT_SCROLL_BARS LUCID X11 XDBE XIM MODULES THREADS JSON LCMS2 GMP






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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-19 20:42 bug#52666: 27.0.50; Unexpected mode line flickering when creating frames Markus Triska
@ 2021-12-20  9:18 ` martin rudalics
  2021-12-20 15:11 ` Eli Zaretskii
  1 sibling, 0 replies; 14+ messages in thread
From: martin rudalics @ 2021-12-20  9:18 UTC (permalink / raw)
  To: Markus Triska, 52666

 > to reproduce this issue, please put the following form in a new file
 > flicker.el:
 >
 >      (while t
 >        (let ((f (make-frame `((parent-frame . ,(selected-frame))
 >                               (left . 200)
 >                               (top . 200)))))
 >          (set-frame-width f 200 nil t)
 >          (set-frame-height f 200 nil t)
 >          (sit-for 0.3)
 >          (delete-frame f)))
 >
 > and then invoke Emacs with:
 >
 >      $ emacs -Q -l flicker.el
 >
 > The form repeatedly creates and destroys a child frame, offset 200
 > pixels both horizontally and vertically from the top left corner of the
 > frame.
 >
 > Unexpectedly, the mode line flickers in many (though apparently not all)
 > iterations, starting at 200 pixels horizontally from the left, even
 > though the frame does not overlap the mode line in any way.
 >
 > Ideally, the creation of the frame should not have any visible effect on
 > the mode line.

I can reproduce the flickering with a GTK build where the child frame
never appears at all.  I cannot reproduce it with a Lucid build where
the child frame appears shortly and gets deleted as expected.  In either
case the mode line is redrawn because it changes from active to inactive
and back.

 > Could the pleasant double buffering feature I have read about help to
 > remove this flickering when creating child frames? Please let me know if
 > you can reproduce the issue or need any further information. I can
 > reproduce the flickering both on OSX and on Debian.

The (sit-for 0.3) might conflict with 'x-wait-for-event-timeout' so
playing around with the latter could help.  BTW is yours really a Lucid
build on a Mac?

martin





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-19 20:42 bug#52666: 27.0.50; Unexpected mode line flickering when creating frames Markus Triska
  2021-12-20  9:18 ` martin rudalics
@ 2021-12-20 15:11 ` Eli Zaretskii
  2021-12-20 17:21   ` martin rudalics
  1 sibling, 1 reply; 14+ messages in thread
From: Eli Zaretskii @ 2021-12-20 15:11 UTC (permalink / raw)
  To: Markus Triska, martin rudalics; +Cc: 52666

> From: Markus Triska <triska@metalevel.at>
> Date: Sun, 19 Dec 2021 21:42:21 +0100
> 
>     (while t
>       (let ((f (make-frame `((parent-frame . ,(selected-frame))
>                              (left . 200)
>                              (top . 200)))))
>         (set-frame-width f 200 nil t)
>         (set-frame-height f 200 nil t)
>         (sit-for 0.3)
>         (delete-frame f)))
> 
> and then invoke Emacs with:
> 
>     $ emacs -Q -l flicker.el
> 
> The form repeatedly creates and destroys a child frame, offset 200
> pixels both horizontally and vertically from the top left corner of the
> frame.
> 
> Unexpectedly, the mode line flickers in many (though apparently not all)
> iterations, starting at 200 pixels horizontally from the left, even
> though the frame does not overlap the mode line in any way.

I think the child frame is first placed in some location determined by
the WM, and then moved to the place the code says.  Martin, is that
so?

If I'm right, then the flickering of the parent frame is when the
child frame intersects some of its elements.





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-20 15:11 ` Eli Zaretskii
@ 2021-12-20 17:21   ` martin rudalics
  2021-12-20 18:23     ` Markus Triska
  0 siblings, 1 reply; 14+ messages in thread
From: martin rudalics @ 2021-12-20 17:21 UTC (permalink / raw)
  To: Eli Zaretskii, Markus Triska; +Cc: 52666

 > I think the child frame is first placed in some location determined by
 > the WM, and then moved to the place the code says.  Martin, is that
 > so?

Not really - the frame should be placed correctly from the outset.  The
code has two problems: Using 'set-frame-width' and 'set-frame-height'
immediately after the frame has been created is bad karma and should be
avoided at all costs.  The right approach is

(while t
   (let ((f (make-frame `((parent-frame . ,(selected-frame))
                          (left . 200)
                          (top . 200)
			 (width . 200)
			 (height . 200)))))
     (sit-for 0.3)
     (delete-frame f)))

 > If I'm right, then the flickering of the parent frame is when the
 > child frame intersects some of its elements.

This is the second problem: 200 x 200 is way too large for the parent
frame so the WM has to clip the child frame and where it overlaps with
the parent frame it probably induces some sort of expose event that
eventually causes the flicker.

martin





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-20 17:21   ` martin rudalics
@ 2021-12-20 18:23     ` Markus Triska
  2021-12-20 18:30       ` martin rudalics
  0 siblings, 1 reply; 14+ messages in thread
From: Markus Triska @ 2021-12-20 18:23 UTC (permalink / raw)
  To: martin rudalics; +Cc: 52666

martin rudalics <rudalics@gmx.at> writes:

> immediately after the frame has been created is bad karma and should be
> avoided at all costs.  The right approach is
>
> (while t
>   (let ((f (make-frame `((parent-frame . ,(selected-frame))
>                          (left . 200)
>                          (top . 200)
> 			 (width . 200)
> 			 (height . 200)))))

This seems not equivalent to what I posted: In the original snippet, I
set the width and height to 200 pixels, by specifying pixelwise as t.

In contrast, this version now sets the width and height to 200 columns
and rows, respectively, yielding a much larger frame.

> This is the second problem: 200 x 200 is way too large for the parent
> frame so the WM has to clip the child frame and where it overlaps with

On my configuration, a frame of 200x200 pixels fits well within the
parent frame at the given position, so this should not be a problem.

You can evaluate the following form in isolation to see that the frame
that is created with the original snippet fits within the parent frame:

  (let ((f (make-frame `((parent-frame . ,(selected-frame))
                         (left . 200)
                         (top . 200)))))
    (set-frame-width f 200 nil t)
    (set-frame-height f 200 nil t))

If you execute it repeatedly, you will sometimes see the flickering in
the mode line, and sometimes not. Putting this in a loop as in the
original snippet lets you easily observe the flickering.

Is there a way to set the pixelwise frame hight and width already when
the frame is created?

Thank you and all the best,
Markus






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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-20 18:23     ` Markus Triska
@ 2021-12-20 18:30       ` martin rudalics
  2021-12-20 18:41         ` Markus Triska
  0 siblings, 1 reply; 14+ messages in thread
From: martin rudalics @ 2021-12-20 18:30 UTC (permalink / raw)
  To: Markus Triska; +Cc: 52666

 > Is there a way to set the pixelwise frame hight and width already when
 > the frame is created?

Please try with

(while t
   (let ((f (make-frame `((parent-frame . ,(selected-frame))
                          (left . 200)
                          (top . 200)
			 (width . (text-pixels . 200))
			 (height . (text-pixels . 200))))))
         (sit-for 0.3)
         (delete-frame f)))

martin





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-20 18:30       ` martin rudalics
@ 2021-12-20 18:41         ` Markus Triska
  2021-12-21 10:32           ` martin rudalics
  0 siblings, 1 reply; 14+ messages in thread
From: Markus Triska @ 2021-12-20 18:41 UTC (permalink / raw)
  To: martin rudalics; +Cc: 52666

martin rudalics <rudalics@gmx.at> writes:

> Please try with
>
> (while t
>   (let ((f (make-frame `((parent-frame . ,(selected-frame))
>                          (left . 200)
>                          (top . 200)
> 			 (width . (text-pixels . 200))
> 			 (height . (text-pixels . 200))))))
>         (sit-for 0.3)
>         (delete-frame f)))

That's perfect, thank you a lot for this! With this I get no mode line
flickering at all, neither on OSX nor on Debian.

Yes, I am always using the Lucid build in all platforms, also on OSX!

Do you still observe the mode line flickering you mentioned in the Gtk
build also with this version? If not, then this solves all issues I
reported, thank you again!

All the best,
Markus





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-20 18:41         ` Markus Triska
@ 2021-12-21 10:32           ` martin rudalics
  2021-12-21 20:44             ` Markus Triska
  0 siblings, 1 reply; 14+ messages in thread
From: martin rudalics @ 2021-12-21 10:32 UTC (permalink / raw)
  To: Markus Triska; +Cc: 52666

 > Do you still observe the mode line flickering you mentioned in the Gtk
 > build also with this version?

I later found out that with my GTK-3 build the child frame never became
visible with your original recipe when I moved the mouse into the area
reserved for it.  Maybe this is related to my focus follows mouse
settings maybe it's something else.

I can explain the mode line flickering as follows: This

       (let ((f (make-frame `((parent-frame . ,(selected-frame))
                              (left . 200)
                              (top . 200)))))

creates a child frame at a 200 . 200 pixels offset from the top-left
corner of the parent's native frame.  Since the size of the child frame
is by default that of its parent, the child frame will thus draw over
the entire area of the parent frame (including mode line and scroll
bars) to the right of and below that position.  Next you do

         (set-frame-width f 200 nil t)

which will expose the part of the parent frame to the right of a ~400
pixels X-position and then you do

         (set-frame-height f 200 nil t)

which will expose the part of the parent frame below a ~400 pixels
Y-position.  With all possible delays involved when setting width and
height ('x-wait-for-event-timeout' might come into play here too) such
flickering should not come as a surprise here.

martin





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-21 10:32           ` martin rudalics
@ 2021-12-21 20:44             ` Markus Triska
  2021-12-22  9:22               ` martin rudalics
  0 siblings, 1 reply; 14+ messages in thread
From: Markus Triska @ 2021-12-21 20:44 UTC (permalink / raw)
  To: martin rudalics; +Cc: 52666

martin rudalics <rudalics@gmx.at> writes:

> I later found out that with my GTK-3 build the child frame never became
> visible with your original recipe when I moved the mouse into the area
> reserved for it.  Maybe this is related to my focus follows mouse
> settings maybe it's something else.

I also noticed this: When the mouse is in the area where the new frame
arises, then the new frame is selected on all platforms I tried. I have
set focus-follows-mouse to nil (the default). Ideally, I would like the
existing frame to reliably retain the focus, and the new frame to not be
selected when it is created. Is there any way to reliably ensure this?

> corner of the parent's native frame.  Since the size of the child frame
> is by default that of its parent, the child frame will thus draw over
> the entire area of the parent frame (including mode line and scroll

I think this is the part that can be counterintuitive, since the Elisp
documentation states:

    39.2 Forcing Redisplay
    ======================

    Emacs normally tries to redisplay the screen whenever it waits for
    input.

In the example that exhibits the flickering, there is no waiting for
input between the creation of the frame and the change of its width and
height. Therefore, it is unexpected that the frame is drawn over the
entire area of the parent frame. I expected it to be drawn only for the
area it is configured, when Emacs waits for input.

Thank you and all the best,
Markus





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-21 20:44             ` Markus Triska
@ 2021-12-22  9:22               ` martin rudalics
  2021-12-22 13:37                 ` Eli Zaretskii
  2021-12-22 16:33                 ` Markus Triska
  0 siblings, 2 replies; 14+ messages in thread
From: martin rudalics @ 2021-12-22  9:22 UTC (permalink / raw)
  To: Markus Triska; +Cc: 52666

 > I also noticed this: When the mouse is in the area where the new frame
 > arises, then the new frame is selected on all platforms I tried.

Are you sure that the new frame is _not_ selected when the mouse is _not_
in that area?

 > I have
 > set focus-follows-mouse to nil (the default). Ideally, I would like the
 > existing frame to reliably retain the focus, and the new frame to not be
 > selected when it is created. Is there any way to reliably ensure this?

Not in my experience.  Conceptually, it should be possible by setting
the 'no-focus-on-map' or temporarily (that is until the frame has become
visible) the 'no-accept-focus' window parameter but I haven't yet seen a
WM strictly adhering to that discipline.  It worked best on Windows XP.

 >> corner of the parent's native frame.  Since the size of the child frame
 >> is by default that of its parent, the child frame will thus draw over
 >> the entire area of the parent frame (including mode line and scroll
 >
 > I think this is the part that can be counterintuitive, since the Elisp
 > documentation states:
 >
 >      39.2 Forcing Redisplay
 >      ======================
 >
 >      Emacs normally tries to redisplay the screen whenever it waits for
 >      input.
 >
 > In the example that exhibits the flickering, there is no waiting for
 > input between the creation of the frame and the change of its width and
 > height.

Maybe that line is confusing.  Emacs may have to redisplay whenever it
receives a corresponding event (like Map, Visibility, Expose and Focus
notifications).  Waiting for user input is only a tangential aspect
there.  What that chapter tries to describe is that an application can
try to force additional redisplays by using the means described there.
Inhibiting redisplay (via setting 'inhibit-redisplay') is in general not
supported and might have no effect either.

 > Therefore, it is unexpected that the frame is drawn over the
 > entire area of the parent frame. I expected it to be drawn only for the
 > area it is configured, when Emacs waits for input.

Emacs does not necessarily "wait for input" in that case.  Depending on
the underlying windowing system it might rather wait for a MapNotify or
ConfigureNotify event.

martin





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-22  9:22               ` martin rudalics
@ 2021-12-22 13:37                 ` Eli Zaretskii
  2021-12-22 16:33                 ` Markus Triska
  1 sibling, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2021-12-22 13:37 UTC (permalink / raw)
  To: martin rudalics; +Cc: triska, 52666

> Cc: Eli Zaretskii <eliz@gnu.org>, 52666@debbugs.gnu.org
> From: martin rudalics <rudalics@gmx.at>
> Date: Wed, 22 Dec 2021 10:22:57 +0100
> 
>  >      39.2 Forcing Redisplay
>  >      ======================
>  >
>  >      Emacs normally tries to redisplay the screen whenever it waits for
>  >      input.
>  >
>  > In the example that exhibits the flickering, there is no waiting for
>  > input between the creation of the frame and the change of its width and
>  > height.
> 
> Maybe that line is confusing.

Not really.  It says "normally", and that is accurate.  There are
other situations where Emacs does redisplay, either because some Lisp
program forced it to do so, or for other reasons.

The ELisp manual has limitations if treated as documentation of the
Emacs internals -- that's not its purpose.

> Emacs may have to redisplay whenever it
> receives a corresponding event (like Map, Visibility, Expose and Focus
> notifications).  Waiting for user input is only a tangential aspect
> there.

Not entirely, or at least not always: Emacs ("normally") reads events
when it waits for input.





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-22  9:22               ` martin rudalics
  2021-12-22 13:37                 ` Eli Zaretskii
@ 2021-12-22 16:33                 ` Markus Triska
  2021-12-23 14:46                   ` martin rudalics
  1 sibling, 1 reply; 14+ messages in thread
From: Markus Triska @ 2021-12-22 16:33 UTC (permalink / raw)
  To: martin rudalics; +Cc: 52666

martin rudalics <rudalics@gmx.at> writes:

> Are you sure that the new frame is _not_ selected when the mouse is _not_
> in that area?

Yes, the new frame is *not* selected in that case! I have constructed
the following test case to reproduce this:

    (let ((f (make-frame `((parent-frame . ,(selected-frame))
                           (left . 200)
                           (width . (text-pixels . 200))
                           (height . (text-pixels . 200))
                           (top . 200)))))
      (eq f (selected-frame)))

When I evaluate it, and the mouse is far away from the window, I get
"nil" as the result, showing that f is not the selected frame. I get
this with the Lucid build on OSX and Debian.

In fact, also if the mouse is within the area where the new frame
appears, I still get "nil", and the new frame is not selected: The
existing frame remains the selected frame, independent of the position
of the mouse.

I previously thought that the new frame is selected, but that was
apparently mistaken: It only appeared to be selected because when
entering text, the new (smaller) frame also shows the new text, even
though it is entered in the existing frame which is selected.

For my specific use case, this behaviour is ideal: I would like to show
information in a new frame, but not select the frame. I am surprised to
hear that in your configuration, the new frame is indeed selected. Do
you accordingly get t as the result of evaluating the above form?

Thank you and all the best,
Markus





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-22 16:33                 ` Markus Triska
@ 2021-12-23 14:46                   ` martin rudalics
  2021-12-23 16:23                     ` Markus Triska
  0 siblings, 1 reply; 14+ messages in thread
From: martin rudalics @ 2021-12-23 14:46 UTC (permalink / raw)
  To: Markus Triska; +Cc: 52666

 > For my specific use case, this behaviour is ideal: I would like to show
 > information in a new frame, but not select the frame. I am surprised to
 > hear that in your configuration, the new frame is indeed selected. Do
 > you accordingly get t as the result of evaluating the above form?

No.  I'm getting nil here too.  And apparently the child frame gets
selected if and only if I click into it.

If all issues have been resolved, please close this bug.

Thanks, martin





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

* bug#52666: 27.0.50; Unexpected mode line flickering when creating frames
  2021-12-23 14:46                   ` martin rudalics
@ 2021-12-23 16:23                     ` Markus Triska
  0 siblings, 0 replies; 14+ messages in thread
From: Markus Triska @ 2021-12-23 16:23 UTC (permalink / raw)
  To: martin rudalics; +Cc: 52666

martin rudalics <rudalics@gmx.at> writes:

> No.  I'm getting nil here too.  And apparently the child frame gets
> selected if and only if I click into it.

Perfect, thank you a lot. Yes, please close this issue, it works
perfectly now with the approach you showed!

Thank you and all the best,
Markus





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

end of thread, other threads:[~2021-12-23 16:23 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-19 20:42 bug#52666: 27.0.50; Unexpected mode line flickering when creating frames Markus Triska
2021-12-20  9:18 ` martin rudalics
2021-12-20 15:11 ` Eli Zaretskii
2021-12-20 17:21   ` martin rudalics
2021-12-20 18:23     ` Markus Triska
2021-12-20 18:30       ` martin rudalics
2021-12-20 18:41         ` Markus Triska
2021-12-21 10:32           ` martin rudalics
2021-12-21 20:44             ` Markus Triska
2021-12-22  9:22               ` martin rudalics
2021-12-22 13:37                 ` Eli Zaretskii
2021-12-22 16:33                 ` Markus Triska
2021-12-23 14:46                   ` martin rudalics
2021-12-23 16:23                     ` Markus Triska

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).