[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#25521: 26.0.50; After (make-frame '((name . "foo"))) (select-frame-b
From: |
npostavs |
Subject: |
bug#25521: 26.0.50; After (make-frame '((name . "foo"))) (select-frame-by-name "foo") doesn't see the frame |
Date: |
Thu, 31 Aug 2017 23:13:50 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.2.50 (gnu/linux) |
tags 25521 + patch
quit
martin rudalics <rudalics@gmx.at> writes:
>> How about removing the delay from w32 as well, and implementing it in
> ...
>> +(add-hook 'after-make-frame-functions #'wait-until-frame-is-visible)
>
> Note that currently the w32 port waits only for frames that are meant to
> become visible and also waits every time a frame becomes visible and not
> only after it was created.
Hmm, I thought I could get away with using an existing hook. But
looking at all the places where x_make_frame_visible is called, I'm
feeling reluctant to introduce lisp evaluation into them. I think we
should go with Eli's idea, bring back the busy wait but add a timeout.
>From 3b8e60de58ae2b2f9fafd806e9f888e716a0f22b Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Wed, 30 Aug 2017 23:12:22 -0400
Subject: [PATCH v1] Bring back the busy wait after x_make_frame_visible
(Bug#25521)
But limit the wait to a configurable timeout. This mostly reverts
"Don't wait for frame to become visible".
* src/xterm.c (syms_of_xterm) [x-visible-frame-timeout]: New variable.
* src/xterm.c (x_make_frame_visible):
* src/w32term.c (x_make_frame_visible): Wait for frame to become
visible according to its value.
---
src/w32term.c | 13 ++++++++----
src/xterm.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/src/w32term.c b/src/w32term.c
index 2785ae2b52..8b129ae029 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -6609,7 +6609,8 @@ w32_frame_raise_lower (struct frame *f, bool raise_flag)
/* Change of visibility. */
-/* This tries to wait until the frame is really visible.
+/* This tries to wait until the frame is really visible, depending on
+ the value of Vx_visible_frame_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,
@@ -6668,12 +6669,16 @@ x_make_frame_visible (struct frame *f)
: SW_SHOWNORMAL);
}
+ if (!FLOATP (Vx_visible_frame_timeout))
+ return;
+
/* Synchronize to ensure Emacs knows the frame is visible
before we do anything else. We do this loop with input not blocked
so that incoming events are handled. */
{
Lisp_Object frame;
- int count;
+ double timeout = XFLOAT_DATA (Vx_visible_frame_timeout);
+ double start_time = XFLOAT_DATA (Ffloat_time (Qnil));
/* This must come after we set COUNT. */
unblock_input ();
@@ -6683,8 +6688,8 @@ x_make_frame_visible (struct frame *f)
/* Wait until the frame is visible. Process X events until a
MapNotify event has been seen, or until we think we won't get a
MapNotify at all.. */
- for (count = input_signal_count + 10;
- input_signal_count < count && !FRAME_VISIBLE_P (f);)
+ while (timeout > (XFLOAT_DATA (Ffloat_time (Qnil)) - start_time) &&
+ !FRAME_VISIBLE_P (f))
{
/* Force processing of queued events. */
/* TODO: x_sync equivalent? */
diff --git a/src/xterm.c b/src/xterm.c
index a7a52064a1..3ade688f1b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -11373,8 +11373,13 @@ xembed_send_message (struct frame *f, Time t, enum
xembed_message msg,
/* 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_visible_frame_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)
@@ -11445,11 +11450,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;
@@ -11496,6 +11504,48 @@ x_make_frame_visible (struct frame *f)
unblock_input ();
}
+
+
+ if (!FLOATP (Vx_visible_frame_timeout))
+ return;
+
+ double timeout = XFLOAT_DATA (Vx_visible_frame_timeout);
+ double start_time = XFLOAT_DATA (Ffloat_time (Qnil));
+
+ /* Process X events until a MapNotify event has been seen. */
+ while (timeout > (XFLOAT_DATA (Ffloat_time (Qnil)) - start_time) &&
+ !FRAME_VISIBLE_P (f))
+ {
+ /* Force processing of queued events. */
+ x_sync (f);
+
+ /* This hack is still in use at least for Cygwin. See
+ http://lists.gnu.org/archive/html/emacs-devel/2013-12/msg00351.html.
+
+ Machines that do polling rather than SIGIO have been
+ observed to go into a busy-wait here. So we'll fake an
+ alarm signal to let the handler know that there's something
+ to be read. We used to raise a real alarm, but it seems
+ that the handler isn't always enabled here. This is
+ probably a bug. */
+ if (input_polling_used ())
+ {
+ /* It could be confusing if a real alarm arrives while
+ processing the fake one. Turn it off and let the
+ handler reset it. */
+ int old_poll_suppress_count = poll_suppress_count;
+ poll_suppress_count = 1;
+ poll_for_input_1 ();
+ poll_suppress_count = old_poll_suppress_count;
+ }
+
+ if (XPending (FRAME_X_DISPLAY (f)))
+ {
+ XEvent xev;
+ XNextEvent (FRAME_X_DISPLAY (f), &xev);
+ x_dispatch_event (&xev, FRAME_X_DISPLAY (f));
+ }
+ }
}
}
@@ -13291,6 +13341,19 @@ syms_of_xterm (void)
keysyms. The default is nil, which is the same as `super'. */);
Vx_super_keysym = Qnil;
+ DEFVAR_LISP ("x-visible-frame-timeout", Vx_visible_frame_timeout,
+ doc: /* How long to wait for a frame to become visible.
+Emacs will wait up to this many seconds after `make-frame-visible' is
+called until receiving notification from the windowing system that the
+frame has become visible. 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. This
+should be fine unless your config contains some code that assumes
+frames will become visible immediately (e.g., calling
+`select-frame-by-name' directly after creating a named frame). */);
+ Vx_visible_frame_timeout = make_float (0.5);
+
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,
--
2.14.1
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- bug#25521: 26.0.50; After (make-frame '((name . "foo"))) (select-frame-by-name "foo") doesn't see the frame,
npostavs <=