unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#65217: 29.1; set-frame-size gets confused and drops calls
@ 2023-08-10 23:07 Ash
       [not found] ` <handler.65217.B.169170885617684.ack@debbugs.gnu.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Ash @ 2023-08-10 23:07 UTC (permalink / raw)
  To: 65217

 From emacs -Q:

(setq my/frame
(make-frame `((left . 500)
(top . 5)
(parent-frame . ,(selected-frame)))))

(defun my/twiddle (width height)
(set-frame-size my/frame 10 10)
(set-frame-size my/frame width height)
(message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))

Then call (my/twiddle 20 20). It prints "20 20", but the actual frame
size is 10x10. However, if you recreate the frame and then call
(my/twiddle 40 40) (or any size other than 20x20), the size is set 
correctly.

I'm running under Wayland using sway.


In GNU Emacs 29.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.38,
cairo version 1.16.0)
System Description: NixOS 23.11 (Tapir)

Configured using:
'configure
--prefix=/nix/store/wc5fv03d7fdrhm76zgjji4n32zh3qqjd-emacs-pgtk-29.1
--disable-build-details --with-modules --with-pgtk
--with-native-compilation --with-tree-sitter --with-xwidgets'

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG JSON
LIBSELINUX LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER
PGTK PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS
TREE_SITTER WEBP XIM XWIDGETS GTK3 ZLIB

Important settings:
value of $LANG: en_US.UTF-8
locale-coding-system: utf-8-unix

Major mode: ELisp/d

Minor modes in effect:
tooltip-mode: t
global-eldoc-mode: t
eldoc-mode: t
show-paren-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
tool-bar-mode: t
menu-bar-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
line-number-mode: t
indent-tabs-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media puny dired
dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068
epg-config gnus-util text-property-search time-date mm-decode mm-bodies
mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail
rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils help-fns
radix-tree cl-print byte-opt debug backtrace find-func cl-loaddefs comp
comp-cstr warnings icons subr-x rx cl-seq cl-macs gv cl-extra help-mode
bytecomp byte-compile cl-lib rmc iso-transl tooltip cconv eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/pgtk-win pgtk-win term/common-win pgtk-dnd tool-bar dnd fontset
image regexp-opt fringe tabulated-list replace newcomment text-mode
lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch
easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads xwidget-internal dbusbind
inotify dynamic-setting system-font-setting font-render-setting cairo
gtk pgtk multi-tty make-network-process native-compile emacs)

Memory information:
((conses 16 86128 9402)
(symbols 48 7551 0)
(strings 32 21356 1429)
(string-bytes 1 678192)
(vectors 16 17914)
(vector-slots 8 361954 18429)
(floats 8 35 48)
(intervals 56 286 0)
(buffers 984 14))





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
       [not found] ` <handler.65217.B.169170885617684.ack@debbugs.gnu.org>
@ 2023-08-10 23:16   ` Ash
  2023-08-17  9:49     ` Eli Zaretskii
  2023-08-18 13:26     ` Gregory Heytings
  0 siblings, 2 replies; 26+ messages in thread
From: Ash @ 2023-08-10 23:16 UTC (permalink / raw)
  To: 65217

Sorry, I forgot to add that you have to set the frame's size to 20x20 to 
get the bug to occur:


(setq my/frame

       (make-frame `((left . 500)
                 (top . 5)
                 (width . 20)
                 (height . 20)
                     (parent-frame . ,(selected-frame)))))

(defun my/twiddle (width height)
   (set-frame-size my/frame 10 10)
   (set-frame-size my/frame width height)
   (message (format "%s %s" (frame-width my/frame) (frame-height 
my/frame))))


Then (my/twiddle 20 20).






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-10 23:16   ` Ash
@ 2023-08-17  9:49     ` Eli Zaretskii
  2023-08-17 16:44       ` martin rudalics
  2023-08-18 13:26     ` Gregory Heytings
  1 sibling, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2023-08-17  9:49 UTC (permalink / raw)
  To: Ash, martin rudalics; +Cc: 65217

> Date: Thu, 10 Aug 2023 16:16:30 -0700
> From: Ash <ext0l@catgirl.ai>
> 
> Sorry, I forgot to add that you have to set the frame's size to 20x20 to 
> get the bug to occur:
> 
> 
> (setq my/frame
> 
>        (make-frame `((left . 500)
>                  (top . 5)
>                  (width . 20)
>                  (height . 20)
>                      (parent-frame . ,(selected-frame)))))
> 
> (defun my/twiddle (width height)
>    (set-frame-size my/frame 10 10)
>    (set-frame-size my/frame width height)
>    (message (format "%s %s" (frame-width my/frame) (frame-height 
> my/frame))))
> 
> 
> Then (my/twiddle 20 20).

Martin, any comments or ideas?





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-17  9:49     ` Eli Zaretskii
@ 2023-08-17 16:44       ` martin rudalics
  2023-08-18  1:13         ` Ash
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2023-08-17 16:44 UTC (permalink / raw)
  To: Eli Zaretskii, Ash; +Cc: 65217

 >> (setq my/frame
 >>
 >>         (make-frame `((left . 500)
 >>                   (top . 5)
 >>                   (width . 20)
 >>                   (height . 20)
 >>                       (parent-frame . ,(selected-frame)))))
 >>
 >> (defun my/twiddle (width height)
 >>     (set-frame-size my/frame 10 10)
 >>     (set-frame-size my/frame width height)
 >>     (message (format "%s %s" (frame-width my/frame) (frame-height
 >> my/frame))))
 >>
 >>
 >> Then (my/twiddle 20 20).
 >
 > Martin, any comments or ideas?

Many.  Basically it's a bad idea to do the above.  Setting up one size,
changing it to another one and then back to the initial one ...  But
both 'set-frame-size' calls might be hidden in larger functions and so
the above can be seen as some kind of abstraction of a larger idea.

What happens is that the (set-frame-size my/frame 10 10) has not been
yet processed by us at the time we run (set-frame-size my/frame 20 20):
Obviously so, since we run Lisp and do not process any configure events
in between.  This means that the

       if (outer_width != gwidth || outer_height != gheight)

check in gtkutil.c's xg_frame_set_char_size will tell that the window
already has the desired size and we do not send a second
gtk_window_resize request.  In fact, when replacing the above line by

       if (true) // outer_width != gwidth || outer_height != gheight)

the second request is processed and everything looks OK.  Now that check
is not utterly necessary but omitting it might, if child frames should
be hidden during resizing, provoke flickering.  Such flickering can be
already seen here with a Lucid build when running my/twiddle (otherwise
Lucid handles everything as expected).  In the case at hand it's normal,
but if the frame should not change size, it should be ideally avoided.

Unfortunately, the story does not end here.  Suppose I do

(setq my/frame
       (make-frame `((left . 500)
                     (top . 5)
                     (width . 20)
                     (height . 20))))

(defun my/twiddle (width height)
   (set-frame-size my/frame 10 10)
   (set-frame-size my/frame width height)
   (sit-for 0)
   (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))

(my/twiddle 20 20)

instead, that is my/frame is shown in a completely normal top-level
window.  In this case, the second resize request apparently gets ignored
(likely in gtk_window_move_resize but the real cause might be nested
somewhere else in the depths of GTK) and I get 10 as final width and
height which are also reported as such.  Again, Lucid has no problem
processing this scenario as expected.

As a final note, putting a (sit-for 0) in between the two
'set-frame-size' calls so that the configure event gets processed in
between, fixes both scenarios on GTK builds here.

Hence, many comments but few good ideas.  It would be interesting,
however, whether others can observe different behaviors with these
set-ups.

Thanks for your attention, martin





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-17 16:44       ` martin rudalics
@ 2023-08-18  1:13         ` Ash
  2023-08-18  5:56           ` Eli Zaretskii
  0 siblings, 1 reply; 26+ messages in thread
From: Ash @ 2023-08-18  1:13 UTC (permalink / raw)
  To: martin rudalics, Eli Zaretskii; +Cc: 65217


On 8/17/23 09:44, martin rudalics wrote:
> >> (setq my/frame
> >>
> >>         (make-frame `((left . 500)
> >>                   (top . 5)
> >>                   (width . 20)
> >>                   (height . 20)
> >>                       (parent-frame . ,(selected-frame)))))
> >>
> >> (defun my/twiddle (width height)
> >>     (set-frame-size my/frame 10 10)
> >>     (set-frame-size my/frame width height)
> >>     (message (format "%s %s" (frame-width my/frame) (frame-height
> >> my/frame))))
> >>
> >>
> >> Then (my/twiddle 20 20).
> >
> > Martin, any comments or ideas?
>
> Many.  Basically it's a bad idea to do the above.  Setting up one size,
> changing it to another one and then back to the initial one ... But
> both 'set-frame-size' calls might be hidden in larger functions and so
> the above can be seen as some kind of abstraction of a larger idea.
>
> What happens is that the (set-frame-size my/frame 10 10) has not been
> yet processed by us at the time we run (set-frame-size my/frame 20 20):
> Obviously so, since we run Lisp and do not process any configure events
> in between.  This means that the
>
>       if (outer_width != gwidth || outer_height != gheight)
>
> check in gtkutil.c's xg_frame_set_char_size will tell that the window
> already has the desired size and we do not send a second
> gtk_window_resize request.  In fact, when replacing the above line by
>
>       if (true) // outer_width != gwidth || outer_height != gheight)
>
> the second request is processed and everything looks OK.  Now that check
> is not utterly necessary but omitting it might, if child frames should
> be hidden during resizing, provoke flickering.  Such flickering can be
> already seen here with a Lucid build when running my/twiddle (otherwise
> Lucid handles everything as expected).  In the case at hand it's normal,
> but if the frame should not change size, it should be ideally avoided.
>
> Unfortunately, the story does not end here.  Suppose I do
>
> (setq my/frame
>       (make-frame `((left . 500)
>                     (top . 5)
>                     (width . 20)
>                     (height . 20))))
>
> (defun my/twiddle (width height)
>   (set-frame-size my/frame 10 10)
>   (set-frame-size my/frame width height)
>   (sit-for 0)
>   (message (format "%s %s" (frame-width my/frame) (frame-height 
> my/frame))))
>
> (my/twiddle 20 20)
>
> instead, that is my/frame is shown in a completely normal top-level
> window.  In this case, the second resize request apparently gets ignored
> (likely in gtk_window_move_resize but the real cause might be nested
> somewhere else in the depths of GTK) and I get 10 as final width and
> height which are also reported as such.  Again, Lucid has no problem
> processing this scenario as expected.
>
> As a final note, putting a (sit-for 0) in between the two
> 'set-frame-size' calls so that the configure event gets processed in
> between, fixes both scenarios on GTK builds here.
>
> Hence, many comments but few good ideas.  It would be interesting,
> however, whether others can observe different behaviors with these
> set-ups.
>
> Thanks for your attention, martin


https://github.com/casouri/eldoc-box/issues/68#issuecomment-1672313454

https://github.com/casouri/eldoc-box/blob/2663fd8834b7f2f5c659dc3b01006742a4922648/eldoc-box.el#L412

For the record, this is the context of how this bug was discovered. In 
this specific case it was just a workaround for an issue related to 
window-text-pixel-size and a '(space :width text) display prop, but we 
(the eldoc-box maintainer and I) figured out another approach that 
doesn't involve a spurious set-frame-size call.

Anyway, thanks for the investigation :) I figured it was something along 
those lines, but I'm not experienced in GTK or emacs's codebase.






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  1:13         ` Ash
@ 2023-08-18  5:56           ` Eli Zaretskii
  2023-08-18  6:04             ` Ash
  0 siblings, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2023-08-18  5:56 UTC (permalink / raw)
  To: Ash; +Cc: rudalics, 65217

> Date: Thu, 17 Aug 2023 18:13:31 -0700
> Cc: 65217@debbugs.gnu.org
> From: Ash <ext0l@catgirl.ai>
> 
> > Hence, many comments but few good ideas.  It would be interesting,
> > however, whether others can observe different behaviors with these
> > set-ups.
> >
> > Thanks for your attention, martin
> 
> 
> https://github.com/casouri/eldoc-box/issues/68#issuecomment-1672313454
> 
> https://github.com/casouri/eldoc-box/blob/2663fd8834b7f2f5c659dc3b01006742a4922648/eldoc-box.el#L412
> 
> For the record, this is the context of how this bug was discovered. In 
> this specific case it was just a workaround for an issue related to 
> window-text-pixel-size and a '(space :width text) display prop, but we 
> (the eldoc-box maintainer and I) figured out another approach that 
> doesn't involve a spurious set-frame-size call.
> 
> Anyway, thanks for the investigation :) I figured it was something along 
> those lines, but I'm not experienced in GTK or emacs's codebase.

Can we close this bug, or is there anything left to do here?





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  5:56           ` Eli Zaretskii
@ 2023-08-18  6:04             ` Ash
  2023-08-18  6:37               ` Eli Zaretskii
  0 siblings, 1 reply; 26+ messages in thread
From: Ash @ 2023-08-18  6:04 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, 65217

[-- Attachment #1: Type: text/plain, Size: 191 bytes --]


On 8/17/23 22:56, Eli Zaretskii wrote:
> Can we close this bug, or is there anything left to do here?
IMO the fact that a set-frame-size call can fail to have an effect is 
absolutely a bug.

[-- Attachment #2: Type: text/html, Size: 580 bytes --]

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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  6:04             ` Ash
@ 2023-08-18  6:37               ` Eli Zaretskii
  2023-08-18  7:23                 ` Ash
                                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Eli Zaretskii @ 2023-08-18  6:37 UTC (permalink / raw)
  To: Ash; +Cc: rudalics, 65217

> Date: Thu, 17 Aug 2023 23:04:06 -0700
> Cc: rudalics@gmx.at, 65217@debbugs.gnu.org
> From: Ash <ext0l@catgirl.ai>
> 
> On 8/17/23 22:56, Eli Zaretskii wrote: 
> 
>  Can we close this bug, or is there anything left to do here?
> 
> IMO the fact that a set-frame-size call can fail to have an effect is absolutely a bug.

I disagree.  It is a consequence of the fact that the actual resizing
is performed by the window manager, and that Emacs must wait for the
window-system response event to perform the resize correctly.  Lisp
programs that perform several such operations in a row must inject
short wait periods to allow for the processing of the window-system
events.  That's what Martin meant by saying that using sit-for solves
the problems.

So this isn't a bug, but a limitation caused by the way Emacs's
interaction with the GUI systems is designed.  If by "bug" you mean
that design, then it is pointless to keep such "bugs" open, since no
one is working on redesigning that aspect of Emacs, nor intends to do
so any time soon.





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  6:37               ` Eli Zaretskii
@ 2023-08-18  7:23                 ` Ash
  2023-08-18  8:25                 ` martin rudalics
  2023-08-18  8:34                 ` Gregory Heytings
  2 siblings, 0 replies; 26+ messages in thread
From: Ash @ 2023-08-18  7:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, 65217


On 8/17/23 23:37, Eli Zaretskii wrote:
>> Date: Thu, 17 Aug 2023 23:04:06 -0700
>> Cc: rudalics@gmx.at, 65217@debbugs.gnu.org
>> From: Ash <ext0l@catgirl.ai>
>>
>> On 8/17/23 22:56, Eli Zaretskii wrote:
>>
>>   Can we close this bug, or is there anything left to do here?
>>
>> IMO the fact that a set-frame-size call can fail to have an effect is absolutely a bug.
> I disagree.  It is a consequence of the fact that the actual resizing
> is performed by the window manager, and that Emacs must wait for the
> window-system response event to perform the resize correctly.  Lisp
> programs that perform several such operations in a row must inject
> short wait periods to allow for the processing of the window-system
> events.  That's what Martin meant by saying that using sit-for solves
> the problems.
>
> So this isn't a bug, but a limitation caused by the way Emacs's
> interaction with the GUI systems is designed.  If by "bug" you mean
> that design, then it is pointless to keep such "bugs" open, since no
> one is working on redesigning that aspect of Emacs, nor intends to do
> so any time soon.
I think if making this specific case work would require a substantial 
change then it's fine closing this out. But then I think there should be 
documentation that this can happen somewhere (in the general emacs 
documentation on frames, maybe with a link from the set-frame-size docs).





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  6:37               ` Eli Zaretskii
  2023-08-18  7:23                 ` Ash
@ 2023-08-18  8:25                 ` martin rudalics
  2023-08-18 12:12                   ` Eli Zaretskii
  2023-08-18  8:34                 ` Gregory Heytings
  2 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2023-08-18  8:25 UTC (permalink / raw)
  To: Eli Zaretskii, Ash; +Cc: 65217

[-- Attachment #1: Type: text/plain, Size: 1586 bytes --]

 > So this isn't a bug, but a limitation caused by the way Emacs's
 > interaction with the GUI systems is designed.

The first thing xg_frame_set_char_size (the function responsible for
dispatching the 'set-frame-size' call to GTK) does is to call
gtk_window_get_size to get the "current size" of the window showing the
frame.  The doc of that function says that

  * Depending on the windowing system and the window manager constraints,
  * the size returned by this function may not match the size set using
  * gtk_window_resize(); additionally, since gtk_window_resize() may be
  * implemented as an asynchronous operation, GTK+ cannot guarantee in any
  * way that this code:
  *
  * |[<!-- language="C" -->
  *   // width and height are set elsewhere
  *   gtk_window_resize (window, width, height);
  *
  *   int new_width, new_height;
  *   gtk_window_get_size (window, &new_width, &new_height);
  * ]|
  *
  * will result in `new_width` and `new_height` matching `width` and
  * `height`, respectively.

where gtk_window_resize (window, width, height) corresponds to our
(set-frame-size my/frame 10 10) and the gwidth and gheight used in the
earlier mentioned

       if (outer_width != gwidth || outer_height != gheight)

check are the new_width and new_height values returned by
gtk_window_get_size.  So since we've been warned by the GTK people, the
attached patch which removes that conditional seems in order.

Note that all other uses of gwidth and gheight remain in place and may
cause the above mentioned problems so maybe we should warn about this in
PROBLEMS.

martin

[-- Attachment #2: my-twiddle.diff --]
[-- Type: text/x-patch, Size: 1957 bytes --]

diff --git a/src/gtkutil.c b/src/gtkutil.c
index f5e70305ead..f69ca5706d5 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -1251,48 +1251,45 @@ xg_frame_set_char_size (struct frame *f, int width, int height)
       hide_child_frame = false;
 #endif
 
-      if (outer_width != gwidth || outer_height != gheight)
+      if (hide_child_frame)
 	{
-          if (hide_child_frame)
-            {
-              block_input ();
+	  block_input ();
 #ifndef HAVE_PGTK
-              gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
+	  gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
 #else
-	      gtk_widget_hide (FRAME_WIDGET (f));
+	  gtk_widget_hide (FRAME_WIDGET (f));
 #endif
-              unblock_input ();
-            }
+	  unblock_input ();
+	}
 
 #ifndef HAVE_PGTK
+      gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+			 outer_width, outer_height);
+#else
+      if (FRAME_GTK_OUTER_WIDGET (f))
+	{
 	  gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
 			     outer_width, outer_height);
-#else
-	  if (FRAME_GTK_OUTER_WIDGET (f))
-	    {
-	      gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-				 outer_width, outer_height);
-	    }
-	  else
-	    {
-	      gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
-					   outer_width, outer_height);
-	    }
+	}
+      else
+	{
+	  gtk_widget_set_size_request (FRAME_GTK_WIDGET (f),
+				       outer_width, outer_height);
+	}
 #endif
 
-          if (hide_child_frame)
-            {
-              block_input ();
+      if (hide_child_frame)
+	{
+	  block_input ();
 #ifndef HAVE_PGTK
-              gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+	  gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
 #else
-	      gtk_widget_show_all (FRAME_WIDGET (f));
+	  gtk_widget_show_all (FRAME_WIDGET (f));
 #endif
-              unblock_input ();
-            }
-
-	  fullscreen = Qnil;
+	  unblock_input ();
 	}
+
+      fullscreen = Qnil;
     }
   else
     {

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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  6:37               ` Eli Zaretskii
  2023-08-18  7:23                 ` Ash
  2023-08-18  8:25                 ` martin rudalics
@ 2023-08-18  8:34                 ` Gregory Heytings
  2023-08-18 12:14                   ` Eli Zaretskii
  2023-08-19  8:04                   ` martin rudalics
  2 siblings, 2 replies; 26+ messages in thread
From: Gregory Heytings @ 2023-08-18  8:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Ash, 65217, rudalics


>
> I disagree.  It is a consequence of the fact that the actual resizing is 
> performed by the window manager, and that Emacs must wait for the 
> window-system response event to perform the resize correctly.  Lisp 
> programs that perform several such operations in a row must inject short 
> wait periods to allow for the processing of the window-system events. 
> That's what Martin meant by saying that using sit-for solves the 
> problems.
>

Instead of assuming that Elisp programmers understand these subtle points, 
can't we provide an optional argument to set-frame-size, say FORCE, that 
would do that sit-for?






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  8:25                 ` martin rudalics
@ 2023-08-18 12:12                   ` Eli Zaretskii
  0 siblings, 0 replies; 26+ messages in thread
From: Eli Zaretskii @ 2023-08-18 12:12 UTC (permalink / raw)
  To: martin rudalics; +Cc: ext0l, 65217

> Date: Fri, 18 Aug 2023 10:25:27 +0200
> Cc: 65217@debbugs.gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
> The first thing xg_frame_set_char_size (the function responsible for
> dispatching the 'set-frame-size' call to GTK) does is to call
> gtk_window_get_size to get the "current size" of the window showing the
> frame.  The doc of that function says that
> 
>   * Depending on the windowing system and the window manager constraints,
>   * the size returned by this function may not match the size set using
>   * gtk_window_resize(); additionally, since gtk_window_resize() may be
>   * implemented as an asynchronous operation, GTK+ cannot guarantee in any
>   * way that this code:
>   *
>   * |[<!-- language="C" -->
>   *   // width and height are set elsewhere
>   *   gtk_window_resize (window, width, height);
>   *
>   *   int new_width, new_height;
>   *   gtk_window_get_size (window, &new_width, &new_height);
>   * ]|
>   *
>   * will result in `new_width` and `new_height` matching `width` and
>   * `height`, respectively.
> 
> where gtk_window_resize (window, width, height) corresponds to our
> (set-frame-size my/frame 10 10) and the gwidth and gheight used in the
> earlier mentioned
> 
>        if (outer_width != gwidth || outer_height != gheight)
> 
> check are the new_width and new_height values returned by
> gtk_window_get_size.  So since we've been warned by the GTK people, the
> attached patch which removes that conditional seems in order.

Po Lu, do you agree with the patch?  If you do, I'll install it on
master.

> Note that all other uses of gwidth and gheight remain in place and may
> cause the above mentioned problems so maybe we should warn about this in
> PROBLEMS.

Please suggest the text for PROBLEMS, I think this is a good idea.

Thanks.





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  8:34                 ` Gregory Heytings
@ 2023-08-18 12:14                   ` Eli Zaretskii
  2023-08-18 12:26                     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2023-08-19  8:04                   ` martin rudalics
  1 sibling, 1 reply; 26+ messages in thread
From: Eli Zaretskii @ 2023-08-18 12:14 UTC (permalink / raw)
  To: Gregory Heytings, Po Lu; +Cc: ext0l, 65217, rudalics

> Date: Fri, 18 Aug 2023 08:34:15 +0000
> From: Gregory Heytings <gregory@heytings.org>
> cc: Ash <ext0l@catgirl.ai>, rudalics@gmx.at, 65217@debbugs.gnu.org
> 
> > I disagree.  It is a consequence of the fact that the actual resizing is 
> > performed by the window manager, and that Emacs must wait for the 
> > window-system response event to perform the resize correctly.  Lisp 
> > programs that perform several such operations in a row must inject short 
> > wait periods to allow for the processing of the window-system events. 
> > That's what Martin meant by saying that using sit-for solves the 
> > problems.
> >
> 
> Instead of assuming that Elisp programmers understand these subtle points, 
> can't we provide an optional argument to set-frame-size, say FORCE, that 
> would do that sit-for?

Fine with me, assuming that Martin and Po Lu agree.





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18 12:14                   ` Eli Zaretskii
@ 2023-08-18 12:26                     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 26+ messages in thread
From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-08-18 12:26 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: ext0l, Gregory Heytings, 65217, rudalics

Eli Zaretskii <eliz@gnu.org> writes:

> Fine with me, assuming that Martin and Po Lu agree.

I have no objection to this, provided that x-wait-for-event-timeout is
respected.  Also, bear in mind that a window manager is under no
obligation to send a ConfigureNotify event if it elects not to resize
the frame, so using such an argument is liable to result in timeouts
under tiling window managers and their ilk, as well as if the window
manager is unresponsive or crashes.





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-10 23:16   ` Ash
  2023-08-17  9:49     ` Eli Zaretskii
@ 2023-08-18 13:26     ` Gregory Heytings
  1 sibling, 0 replies; 26+ messages in thread
From: Gregory Heytings @ 2023-08-18 13:26 UTC (permalink / raw)
  To: Ash; +Cc: 65217


Ash, can you please try the following variant of your recipe?  Does it do 
what you want?

(setq my/frame
       (make-frame `((left . 500)
 		    (top . 5)
 		    (width . 20)
 		    (height . 20)
 		    (parent-frame . ,(selected-frame)))))

(defun my/twiddle (width height)
   (set-frame-size my/frame 10 10)
   (redisplay t)
   (set-frame-size my/frame width height)
   (redisplay t)
   (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-18  8:34                 ` Gregory Heytings
  2023-08-18 12:14                   ` Eli Zaretskii
@ 2023-08-19  8:04                   ` martin rudalics
  2023-08-19 10:18                     ` Gregory Heytings
  1 sibling, 1 reply; 26+ messages in thread
From: martin rudalics @ 2023-08-19  8:04 UTC (permalink / raw)
  To: Gregory Heytings, Eli Zaretskii; +Cc: Ash, 65217

 > Instead of assuming that Elisp programmers understand these subtle
 > points, can't we provide an optional argument to set-frame-size, say
 > FORCE, that would do that sit-for?

What would you pass to

   (modify-frame-parameters my/frame `((width . ,width) (height . ,height)))

in my/twiddle?

martin





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-19  8:04                   ` martin rudalics
@ 2023-08-19 10:18                     ` Gregory Heytings
  2023-08-20  6:32                       ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Gregory Heytings @ 2023-08-19 10:18 UTC (permalink / raw)
  To: martin rudalics; +Cc: Ash, Eli Zaretskii, 65217


>> Instead of assuming that Elisp programmers understand these subtle 
>> points, can't we provide an optional argument to set-frame-size, say 
>> FORCE, that would do that sit-for?
>
> What would you pass to
>
>  (modify-frame-parameters my/frame `((width . ,width) (height . ,height)))
>
> in my/twiddle?
>

I'm not sure yet, but after thinking a bit more about this, ATM my 
conclusion is that adding a sentence in the docstings of set-frame-* and 
modify-frame-parameters, suggesting to use (redisplay t) after these 
functions, would be enough.






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-19 10:18                     ` Gregory Heytings
@ 2023-08-20  6:32                       ` martin rudalics
  2023-08-20  7:55                         ` Gregory Heytings
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2023-08-20  6:32 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Ash, Eli Zaretskii, 65217

 > I'm not sure yet, but after thinking a bit more about this, ATM my
 > conclusion is that adding a sentence in the docstings of set-frame-*
 > and modify-frame-parameters, suggesting to use (redisplay t) after
 > these functions, would be enough.

Not really, I think.  With emacs -Q try

(let ((i 100))
   (while (> i 0)
     (scroll-bar-mode -1)
     (scroll-bar-mode 1)
     (sit-for 0.1)
     (setq i (1- i))))

martin






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-20  6:32                       ` martin rudalics
@ 2023-08-20  7:55                         ` Gregory Heytings
  2023-08-21  6:19                           ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Gregory Heytings @ 2023-08-20  7:55 UTC (permalink / raw)
  To: martin rudalics; +Cc: Ash, Eli Zaretskii, 65217


>
> Not really, I think.  With emacs -Q try
>
> (let ((i 100))
>  (while (> i 0)
>    (scroll-bar-mode -1)
>    (scroll-bar-mode 1)
>    (sit-for 0.1)
>    (setq i (1- i))))
>

I tried a small variant of this

(let ((i 100))
   (while (> i 0)
     (scroll-bar-mode -1)
     (sit-for 0.1)
     (scroll-bar-mode 1)
     (sit-for 0.1)
     (setq i (1- i))))

and it works, for both the GTK and Lucid toolkits.  The scroll bar is 
displayed and hidden repeatedly.

In any case, there will always be pathological cases in which the window 
manager (who has the last word) does not do what the Elisp code requested. 
But ISTM that telling Elisp programmers that such requests are "committed" 
asynchronously, and that they can "commit" them immediately by calling 
(redisplay t), should solve most similar problems.






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-20  7:55                         ` Gregory Heytings
@ 2023-08-21  6:19                           ` martin rudalics
  2023-08-21  8:30                             ` Gregory Heytings
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2023-08-21  6:19 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Ash, Eli Zaretskii, 65217

 > I tried a small variant of this
 >
 > (let ((i 100))
 >    (while (> i 0)
 >      (scroll-bar-mode -1)
 >      (sit-for 0.1)
 >      (scroll-bar-mode 1)
 >      (sit-for 0.1)
 >      (setq i (1- i))))
 >
 > and it works, for both the GTK and Lucid toolkits.  The scroll bar is displayed and hidden repeatedly.

The scroll bar is displayed and hidden repeatedly in either case- The
surprising thing is that with GTK3 the frame shrinks continuously.

 > In any case, there will always be pathological cases in which the
 > window manager (who has the last word) does not do what the Elisp code
 > requested.

It's not the window manager, its's the toolkit which has the first word
here.  GTK2, Motif or Lucid builds have no problems.

 > But ISTM that telling Elisp programmers that such requests
 > are "committed" asynchronously, and that they can "commit" them
 > immediately by calling (redisplay t), should solve most similar
 > problems.

People changing the tab bar or the default font may be hardly aware of
the fact that the toolkit stochastically resizes their frames behind
their backs.

martin






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-21  6:19                           ` martin rudalics
@ 2023-08-21  8:30                             ` Gregory Heytings
  2023-08-21 13:39                               ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Gregory Heytings @ 2023-08-21  8:30 UTC (permalink / raw)
  To: martin rudalics; +Cc: Ash, Eli Zaretskii, 65217


>
> The scroll bar is displayed and hidden repeatedly in either case- The 
> surprising thing is that with GTK3 the frame shrinks continuously.
>

It doesn't here.  Just in case, I tried a few different window managers 
(IceWM, Fluxbox, Window Maker, ...) and the result was the same: the 
scroll bar is displayed and hidden repeatedly, but the frame size doesn't 
change (except of course by the few pixels that are used to display the 
scroll bar).

>> But ISTM that telling Elisp programmers that such requests are 
>> "committed" asynchronously, and that they can "commit" them immediately 
>> by calling (redisplay t), should solve most similar problems.
>
> People changing the tab bar or the default font may be hardly aware of 
> the fact that the toolkit stochastically resizes their frames behind 
> their backs.
>

What would you suggest for this specific bug report?  The OP hasn't 
replied yet, so it's not yet know whether that advice solves their 
problem, but don't you agree that calling (redisplay t) after calling 
set-frame-size (and other similar functions) would in most cases help to 
have the frame "in sync" with the code?






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-21  8:30                             ` Gregory Heytings
@ 2023-08-21 13:39                               ` martin rudalics
  2023-08-21 14:12                                 ` Gregory Heytings
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2023-08-21 13:39 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Ash, Eli Zaretskii, 65217

 > It doesn't here.  Just in case, I tried a few different window
 > managers (IceWM, Fluxbox, Window Maker, ...) and the result was the
 > same: the scroll bar is displayed and hidden repeatedly, but the frame
 > size doesn't change (except of course by the few pixels that are used
 > to display the scroll bar).

Does that mean that my older recipe

(setq my/frame
       (make-frame `((left . 500)
                     (top . 5)
                     (width . 20)
                     (height . 20))))

(defun my/twiddle (width height)
   (set-frame-size my/frame 10 10)
   (set-frame-size my/frame width height)
   (sit-for 0)
   (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))

(my/twiddle 20 20)

works correctly with your setup?  In which case the GTK people might
have fixed this in the meantime (I'm still on GTK+ Version 3.24.5) and
the only problem is with child frames as in the OP.

 > What would you suggest for this specific bug report?  The OP hasn't
 > replied yet, so it's not yet know whether that advice solves their
 > problem, but don't you agree that calling (redisplay t) after calling
 > set-frame-size (and other similar functions) would in most cases help
 > to have the frame "in sync" with the code?

I'd agree if (1) the patch I posted earlier doesn't help and (2) the
problem above with normal top-level frames has not been fixed.

martin





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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-21 13:39                               ` martin rudalics
@ 2023-08-21 14:12                                 ` Gregory Heytings
  2023-08-21 17:31                                   ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Gregory Heytings @ 2023-08-21 14:12 UTC (permalink / raw)
  To: martin rudalics; +Cc: Ash, Eli Zaretskii, 65217


>
> Does that mean that my older recipe
>
> (setq my/frame
>      (make-frame `((left . 500)
>                    (top . 5)
>                    (width . 20)
>                    (height . 20))))
>
> (defun my/twiddle (width height)
>  (set-frame-size my/frame 10 10)
>  (set-frame-size my/frame width height)
>  (sit-for 0)
>  (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))
>
> (my/twiddle 20 20)
>
> works correctly with your setup?
>

I'm not sure what you mean by "works correctly".  That exact recipe (with 
emacs -Q -l file.el) produces either a 10x10 frame or a 20x20 frame, 
randomly but apparently equally distributed.  Adding a (sit-for 0) after 
the first call to set-frame-size does not help.  But adding a (redisplay 
t) after the first call to set-frame-size helps: the result is then always 
a 20x20 frame.

One problem remains, however: the message is still either "10 10" or "20 
20".

>
> In which case the GTK people might have fixed this in the meantime (I'm 
> still on GTK+ Version 3.24.5) and the only problem is with child frames 
> as in the OP.
>

I have version 3.24.37 here.

>> What would you suggest for this specific bug report?  The OP hasn't 
>> replied yet, so it's not yet know whether that advice solves their 
>> problem, but don't you agree that calling (redisplay t) after calling 
>> set-frame-size (and other similar functions) would in most cases help 
>> to have the frame "in sync" with the code?
>
> I'd agree if (1) the patch I posted earlier doesn't help and (2) the 
> problem above with normal top-level frames has not been fixed.
>

I just tried your "my-twiddle.diff" patch, and with your recipe above it 
doesn't help: it still produces either a 10x10 frame or a 20x20 frame. 
I'm don't know you mean by "the problem above with normal top-level 
frames".






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-21 14:12                                 ` Gregory Heytings
@ 2023-08-21 17:31                                   ` martin rudalics
  2023-08-21 18:26                                     ` Gregory Heytings
  0 siblings, 1 reply; 26+ messages in thread
From: martin rudalics @ 2023-08-21 17:31 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Ash, Eli Zaretskii, 65217

 > I'm not sure what you mean by "works correctly".  That exact recipe
 > (with emacs -Q -l file.el) produces either a 10x10 frame or a 20x20
 > frame, randomly but apparently equally distributed.  Adding a (sit-for
 > 0) after the first call to set-frame-size does not help.

Can you check whether input is pending before the 'sit-for' call?

 > But adding a
 > (redisplay t) after the first call to set-frame-size helps: the result
 > is then always a 20x20 frame.

Here it works with FORCE nil too.  'redisplay' with non-nil FORCE means
don't process pending input.  Maybe any such redisplay just takes long
enough so that in the meantime the 10x10 sizes get processed by GTK and
the second 'set-frame-size' is recognized by GTK as something that wants
to change the size.  (sleep-for 0.001) works here too.  I see problems
with (sleep-for 0.00000000000000000000000000000000000000000000000001).

 > One problem remains, however: the message is still either "10 10" or "20 20".

Always 10x10 wouldn't be that bad.  The "either" means that some race
condition persists.  Here I get always "20x20" with the redisplay call.

 > I just tried your "my-twiddle.diff" patch, and with your recipe above
 > it doesn't help: it still produces either a 10x10 frame or a 20x20
 > frame. I'm don't know you mean by "the problem above with normal
 > top-level frames".

My "recipe above" was for normal top-level frames. The patch was for
child frames exclusively.  To avoid confusions: The scenario for child
frames is

(setq my/frame
       (make-frame `((left . 500)
                     (top . 5)
                     (width . 20)
                     (height . 20)
                     (parent-frame . ,(selected-frame)))))

(defun my/twiddle (width height)
   (set-frame-size my/frame 10 10)
   (set-frame-size my/frame width height)
   (sit-for 0)
   (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))

(my/twiddle 20 20)

and my patch fixed that here.  The scenario for normal top-level frames
is

(setq my/frame
       (make-frame `((left . 500)
                     (top . 5)
                     (width . 20)
                     (height . 20))))

(defun my/twiddle (width height)
   (set-frame-size my/frame 10 10)
   (set-frame-size my/frame width height)
   (sit-for 0)
   (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))

(my/twiddle 20 20)

and my patch doesn't do anything about it.

martin






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-21 17:31                                   ` martin rudalics
@ 2023-08-21 18:26                                     ` Gregory Heytings
  2023-08-22  8:53                                       ` martin rudalics
  0 siblings, 1 reply; 26+ messages in thread
From: Gregory Heytings @ 2023-08-21 18:26 UTC (permalink / raw)
  To: martin rudalics; +Cc: Ash, Eli Zaretskii, 65217


>> I'm not sure what you mean by "works correctly".  That exact recipe 
>> (with emacs -Q -l file.el) produces either a 10x10 frame or a 20x20 
>> frame, randomly but apparently equally distributed.  Adding a (sit-for 
>> 0) after the first call to set-frame-size does not help.
>
> Can you check whether input is pending before the 'sit-for' call?
>

input-pending-p invariably returns t in that recipe.

>> But adding a (redisplay t) after the first call to set-frame-size 
>> helps: the result is then always a 20x20 frame.
>
> Here it works with FORCE nil too.
>

Indeed, here it works also with simply (redisplay), with the recipe for 
normal frames.  I guess (redisplay t) is a bit safer though.

>
> (sleep-for 0.001) works here too.  I see problems with (sleep-for 
> 0.00000000000000000000000000000000000000000000000001).
>

(sleep-for 0.001) between the two calls to set-frame-size, in the recipe 
for normal frames, doesn't work here, most often the child frame is 10x10, 
sometimes it is 20x20.  However, (sleep-for 0.001) before the two calls to 
set-frame-size does work, the child frame is always 20x20.

>> One problem remains, however: the message is still either "10 10" or 
>> "20 20".
>
> Always 10x10 wouldn't be that bad.  The "either" means that some race 
> condition persists.  Here I get always "20x20" with the redisplay call.
>

I just tried again to run the recipe for normal frames 20 times in a row: 
I get "10 10" ten times and "20 20" ten times.

>
> My "recipe above" was for normal top-level frames. The patch was for 
> child frames exclusively.  To avoid confusions: The scenario for child 
> frames is
>
> (setq my/frame
>      (make-frame `((left . 500)
>                    (top . 5)
>                    (width . 20)
>                    (height . 20)
>                    (parent-frame . ,(selected-frame)))))
>
> (defun my/twiddle (width height)
>  (set-frame-size my/frame 10 10)
>  (set-frame-size my/frame width height)
>  (sit-for 0)
>  (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))
>
> (my/twiddle 20 20)
>

The "(parent-frame . ,(selected-frame))" was not in the recipe you sent a 
few hours ago.  Amusingly (or not), with that additional frame parameter, 
the result is always a 10x10 child frame, and the message always "20 20". 
With a (redisplay) or (redisplay t) between the two calls to 
set-frame-size the result is always a 20x20 child frame, and the message 
always "20 20".  With a (sleep-for 0.001) before or between the two calls 
to set-frame-size the result is always a 10x10 child frame, and the 
message always "20 20".

>
> and my patch fixed that here.
>

It also fixes the above recipe, the one for child frames.

>
> The scenario for normal top-level frames is
>
> (setq my/frame
>      (make-frame `((left . 500)
>                    (top . 5)
>                    (width . 20)
>                    (height . 20))))
>
> (defun my/twiddle (width height)
>  (set-frame-size my/frame 10 10)
>  (set-frame-size my/frame width height)
>  (sit-for 0)
>  (message (format "%s %s" (frame-width my/frame) (frame-height my/frame))))
>
> (my/twiddle 20 20)
>
> and my patch doesn't do anything about it.
>

Correct, that's what I also see here.

To summarize:

- with the recipe for normal frames, (redisplay) or (redisplay t) between 
the two calls to set-frame-size, or (sleep-for 0.001) before the two calls 
to set-frame-size, fix the problem (but frame-width and frame-height 
return the actual frame width and height only with a 50% probability)

- with the recipe for child frames, your patch, and (redisplay) or 
(redisplay t) between the two calls to set-frame-size and without your 
patch, fix the problem






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

* bug#65217: 29.1; set-frame-size gets confused and drops calls
  2023-08-21 18:26                                     ` Gregory Heytings
@ 2023-08-22  8:53                                       ` martin rudalics
  0 siblings, 0 replies; 26+ messages in thread
From: martin rudalics @ 2023-08-22  8:53 UTC (permalink / raw)
  To: Gregory Heytings; +Cc: Ash, Eli Zaretskii, 65217

 >> Can you check whether input is pending before the 'sit-for' call?
 >>
 >
 > input-pending-p invariably returns t in that recipe.

This is with the default value of 'x-wait-for-event-timeout', so
apparently the WM has answered our request.  If I set
'x-wait-for-event-timeout' to zero, I reliably get a 10x10 frame for the
non-child-frame case.  Which IIUC means that GTK skips the second
request.  What do you get when you set 'x-wait-for-event-timeout' to
zero for a non-child-frame without any redisplay?

 > Indeed, here it works also with simply (redisplay), with the recipe
 > for normal frames.  I guess (redisplay t) is a bit safer though.

But why would we want to _not_ process the ConfigureNotify event for the
first 'set-frame-size' call?  All (redisplay t) can do is to confirm
that the frame has still its initial size of 20x20.  Or what am I
missing?

 > (sleep-for 0.001) between the two calls to set-frame-size, in the
 > recipe for normal frames, doesn't work here, most often the child
 > frame is 10x10,

We still did not completely remove our earlier misunderstanding.  In the
"recipe for normal frames" there is no "child frame".  That frame is a
plain top-level frame - let's call it the "second" frame.

 > sometimes it is 20x20.  However, (sleep-for 0.001)
 > before the two calls to set-frame-size does work, the child frame is
 > always 20x20.

This must be a red herring: sleeping or not sleeping before theses calls
cannot possibly affect what happens then, unless something like C-x C-e
interacts with the window manager.

 > I just tried again to run the recipe for normal frames 20 times in a
 > row: I get "10 10" ten times and "20 20" ten times.

The real visible sizes or the ones reported via the message?

 > The "(parent-frame . ,(selected-frame))" was not in the recipe you
 > sent a few hours ago.  Amusingly (or not), with that additional frame
 > parameter, the result is always a 10x10 child frame,

As mentioned above, in this case we _do_ create a child frame.  Without
the parent-frame parameter, the initial 'make-frame' call produces a
simple top-level frame and not a child frame.  Child frames and
top-level frames are treated differently by the window manager in a
number of regards - a child frames moves together with its parent and
its position is always calculated relative to that of its parent.

 > and the message
 > always "20 20". With a (redisplay) or (redisplay t) between the two
 > calls to set-frame-size the result is always a 20x20 child frame, and
 > the message always "20 20".  With a (sleep-for 0.001) before or
 > between

... the fact that there's no difference between "before or between"
stumbles me ...

 > the two calls to set-frame-size the result is always a 10x10
 > child frame, and the message always "20 20".

 > It also fixes the above recipe, the one for child frames.

... which again only hints at that GTK treats child frames differently
here.  It passes on the second request although the sizes are the same
as the initial ones.

 > To summarize:
 >
 > - with the recipe for normal frames, (redisplay) or (redisplay t)
 > between the two calls to set-frame-size, or (sleep-for 0.001) before
 > the two calls to set-frame-size, fix the problem (but frame-width and
 > frame-height return the actual frame width and height only with a 50%
 > probability)
 >
 > - with the recipe for child frames, your patch, and (redisplay) or
 > (redisplay t) between the two calls to set-frame-size and without your
 > patch, fix the problem

There's one additional experiment you could conduct:

After you finished loading eval

(setq frame-size-history '(100))

then do the

(my/twiddle 20 20)

and then eval

(frame--size-history my/frame)

and look at the *frame-size-history* buffer.  Without (redisplay t) this
gets me

Frame size history of #<frame *scratch* 0x2620610>
size (1), TS=180x360~>90x180, TC=20x20~>10x10, NS=212x360~>122x180, IS=212x360~>122x180, MS=90x90
xg_frame_set_char_size, invisible, PS=212x360, XS=122x180, DS=122x180
xg_frame_set_char_size (5), TS=180x360~>90x180, TC=20x20~>10x10, NS=212x360~>122x180, IS=212x360~>122x180, MS=18x36 IH IV
size (1), TS=90x180~>180x360, TC=10x10~>20x20, NS=122x180~>212x360, IS=122x180~>212x360, MS=90x90
xg_frame_set_char_size, invisible, PS=122x180, XS=212x360, DS=212x360
xg_frame_set_char_size (5), TS=90x180~>180x360, TC=10x10~>20x20, NS=122x180~>212x360, IS=122x180~>212x360, MS=18x36 IH IV
ConfigureNotify, PS=212x360, XS=122x180, DS=212x360
xg_frame_resized, changed, PS=212x360, XS=122x180
change_frame_size_1, delayed, PS=212x360, XS=122x180, DS=212x360
change_frame_size (5), TS=180x360~>90x180, TC=20x20~>10x10, NS=212x360~>122x180, IS=212x360~>122x180, MS=18x36 IH IV

With your (redisplay t) it gets me

Frame size history of #<frame *scratch* 0x29cf610>
size (1), TS=180x360~>90x180, TC=20x20~>10x10, NS=212x360~>122x180, IS=212x360~>122x180, MS=90x90
xg_frame_set_char_size, invisible, PS=212x360, XS=122x180, DS=122x180
xg_frame_set_char_size (5), TS=180x360~>90x180, TC=20x20~>10x10, NS=212x360~>122x180, IS=212x360~>122x180, MS=18x36 IH IV
ConfigureNotify, PS=122x180, XS=122x180, DS=122x180
xg_frame_resized, unchanged, PS=122x180, XS=122x180
size (1), TS=90x180~>180x360, TC=10x10~>20x20, NS=122x180~>212x360, IS=122x180~>212x360, MS=90x90
xg_frame_set_char_size, invisible, PS=122x180, XS=212x360, DS=212x360
xg_frame_set_char_size (5), TS=90x180~>180x360, TC=10x10~>20x20, NS=122x180~>212x360, IS=122x180~>212x360, MS=18x36 IH IV
ConfigureNotify, PS=212x360, XS=212x360, DS=212x360
xg_frame_resized, unchanged, PS=212x360, XS=212x360

so that redisplay call is apparently responsible for getting us a second
ConfigureNotify event where we both recognize them as _not_ causing any
change.  Without the redisplay call we get one event indicating a change
from 212x360 to 122x180 pixels.  I'm not yet sure what to make of these
and would like to see what you get first.

Thanks, martin





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

end of thread, other threads:[~2023-08-22  8:53 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-10 23:07 bug#65217: 29.1; set-frame-size gets confused and drops calls Ash
     [not found] ` <handler.65217.B.169170885617684.ack@debbugs.gnu.org>
2023-08-10 23:16   ` Ash
2023-08-17  9:49     ` Eli Zaretskii
2023-08-17 16:44       ` martin rudalics
2023-08-18  1:13         ` Ash
2023-08-18  5:56           ` Eli Zaretskii
2023-08-18  6:04             ` Ash
2023-08-18  6:37               ` Eli Zaretskii
2023-08-18  7:23                 ` Ash
2023-08-18  8:25                 ` martin rudalics
2023-08-18 12:12                   ` Eli Zaretskii
2023-08-18  8:34                 ` Gregory Heytings
2023-08-18 12:14                   ` Eli Zaretskii
2023-08-18 12:26                     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-08-19  8:04                   ` martin rudalics
2023-08-19 10:18                     ` Gregory Heytings
2023-08-20  6:32                       ` martin rudalics
2023-08-20  7:55                         ` Gregory Heytings
2023-08-21  6:19                           ` martin rudalics
2023-08-21  8:30                             ` Gregory Heytings
2023-08-21 13:39                               ` martin rudalics
2023-08-21 14:12                                 ` Gregory Heytings
2023-08-21 17:31                                   ` martin rudalics
2023-08-21 18:26                                     ` Gregory Heytings
2023-08-22  8:53                                       ` martin rudalics
2023-08-18 13:26     ` Gregory Heytings

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