]> git.eshelyaron.com Git - emacs.git/commitdiff
Bring back the busy wait after x_make_frame_visible (Bug#25521)
authorNoam Postavsky <npostavs@gmail.com>
Thu, 31 Aug 2017 03:12:22 +0000 (23:12 -0400)
committerNoam Postavsky <npostavs@gmail.com>
Fri, 29 Sep 2017 22:40:06 +0000 (18:40 -0400)
But wait specfically for a MapNotify event, and only for a
configurable amount of time.
* src/xterm.c (syms_of_xterm) [x-wait-for-event-timeout]: New
variable.
(x_wait_for_event): Use it instead of hardcoding the wait to 0.1s.
(x_make_frame_visible): Call x_wait_for_event at the end.
* etc/NEWS: Announce x_wait_for_event.

etc/NEWS
src/xterm.c

index 922dfbdc2462438daddc6378c878db5d77b6b465..ab9a2a5f32d2fd5c00707c6c2c9dbba05173c53a 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -600,6 +600,11 @@ The two new variables, 'bidi-paragraph-start-re' and
 'bidi-paragraph-separate-re', allow customization of what exactly are
 paragraphs, for the purposes of bidirectional display.
 
+---
+** New variable 'x-wait-for-event-timeout'.
+This controls how long Emacs will wait for updates to the graphical
+state to take effect (making a frame visible, for example).
+
 \f
 * Changes in Specialized Modes and Packages in Emacs 26.1
 
index 0b321909c85dc515d2df3455c84a528fa932940a..90275763cbe0830ca69c8683bee3652c9757a78a 100644 (file)
@@ -11029,17 +11029,22 @@ x_sync_with_move (struct frame *f, int left, int top, bool fuzzy)
 void
 x_wait_for_event (struct frame *f, int eventtype)
 {
-  int level = interrupt_input_blocked;
+  if (!FLOATP (Vx_wait_for_event_timeout))
+    return;
 
+  int level = interrupt_input_blocked;
   fd_set fds;
   struct timespec tmo, tmo_at, time_now;
   int fd = ConnectionNumber (FRAME_X_DISPLAY (f));
 
   f->wait_event_type = eventtype;
 
-  /* Set timeout to 0.1 second.  Hopefully not noticeable.
-     Maybe it should be configurable.  */
-  tmo = make_timespec (0, 100 * 1000 * 1000);
+  /* Default timeout is 0.1 second.  Hopefully not noticeable.  */
+  double timeout = XFLOAT_DATA (Vx_wait_for_event_timeout);
+  time_t timeout_seconds = (time_t) timeout;
+  tmo = make_timespec
+    (timeout_seconds, (long int) ((timeout - timeout_seconds)
+                                  * 1000 * 1000 * 1000));
   tmo_at = timespec_add (current_timespec (), tmo);
 
   while (f->wait_event_type)
@@ -11365,8 +11370,13 @@ xembed_send_message (struct frame *f, Time t, enum xembed_message msg,
 \f
 /* Change of visibility.  */
 
-/* This function sends the request to make the frame visible, but may
-   return before it the frame's visibility is changed.  */
+/* This tries to wait until the frame is really visible, depending on
+   the value of Vx_wait_for_event_timeout.
+   However, if the window manager asks the user where to position
+   the frame, this will return before the user finishes doing that.
+   The frame will not actually be visible at that time,
+   but it will become visible later when the window manager
+   finishes with it.  */
 
 void
 x_make_frame_visible (struct frame *f)
@@ -11437,11 +11447,14 @@ x_make_frame_visible (struct frame *f)
      before we do anything else.  We do this loop with input not blocked
      so that incoming events are handled.  */
   {
+    Lisp_Object frame;
     /* This must be before UNBLOCK_INPUT
        since events that arrive in response to the actions above
        will set it when they are handled.  */
     bool previously_visible = f->output_data.x->has_been_visible;
 
+    XSETFRAME (frame, f);
+
     int original_left = f->left_pos;
     int original_top = f->top_pos;
 
@@ -11488,6 +11501,10 @@ x_make_frame_visible (struct frame *f)
 
        unblock_input ();
       }
+
+    /* Try to wait for a MapNotify event (that is what tells us when a
+       frame becomes visible).  */
+    x_wait_for_event (f, MapNotify);
   }
 }
 
@@ -13283,6 +13300,17 @@ This should be one of the symbols `ctrl', `alt', `hyper', `meta',
 keysyms.  The default is nil, which is the same as `super'.  */);
   Vx_super_keysym = Qnil;
 
+  DEFVAR_LISP ("x-wait-for-event-timeout", Vx_wait_for_event_timeout,
+    doc: /* How long to wait for X events.
+
+Emacs will wait up to this many seconds to receive X events after
+making changes which affect the state of the graphical interface.
+Under some window managers this can take an indefinite amount of time,
+so it is important to limit the wait.
+
+If set to a non-float value, there will be no wait at all.  */);
+  Vx_wait_for_event_timeout = make_float (0.1);
+
   DEFVAR_LISP ("x-keysym-table", Vx_keysym_table,
     doc: /* Hash table of character codes indexed by X keysym codes.  */);
   Vx_keysym_table = make_hash_table (hashtest_eql, 900,