From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Noam Postavsky Newsgroups: gmane.emacs.bugs Subject: bug#25521: 26.0.50; After (make-frame '((name . "foo"))) (select-frame-by-name "foo") doesn't see the frame Date: Mon, 25 Sep 2017 22:54:14 -0400 Message-ID: <87zi9if9ux.fsf@users.sourceforge.net> References: <87a8agrwwx.fsf@gmail.com> <83lgtz3jdf.fsf@gnu.org> <87mvefk54q.fsf@gmail.com> <87inp2u2nn.fsf@users.sourceforge.net> <87r33qm4lh.fsf@gmail.com> <87a8adubtz.fsf@users.sourceforge.net> <877f5hq0tl.fsf@gmail.com> <87ziids1j2.fsf@users.sourceforge.net> <83vat10wdp.fsf@gnu.org> <87wp7ukw8x.fsf@users.sourceforge.net> <5955F510.5040101@gmx.at> <87efrr6rgx.fsf@users.sourceforge.net> <59A95A75.8040100@gmx.at> <87bmmu7czr.fsf@users.sourceforge.net> <59A980A5.9010705@gmx.at> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: blaine.gmane.org 1506394517 11335 195.159.176.226 (26 Sep 2017 02:55:17 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 26 Sep 2017 02:55:17 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.60 (gnu/linux) Cc: 25521@debbugs.gnu.org, qwxlea@gmail.com To: martin rudalics Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Sep 26 04:55:10 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dwg1d-0002GZ-UE for geb-bug-gnu-emacs@m.gmane.org; Tue, 26 Sep 2017 04:55:10 +0200 Original-Received: from localhost ([::1]:45308 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwg1i-0003TR-2A for geb-bug-gnu-emacs@m.gmane.org; Mon, 25 Sep 2017 22:55:14 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54485) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dwg1a-0003TH-NA for bug-gnu-emacs@gnu.org; Mon, 25 Sep 2017 22:55:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dwg1W-0005qd-Hn for bug-gnu-emacs@gnu.org; Mon, 25 Sep 2017 22:55:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:50677) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dwg1W-0005pw-BR for bug-gnu-emacs@gnu.org; Mon, 25 Sep 2017 22:55:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dwg1W-0005PK-0e for bug-gnu-emacs@gnu.org; Mon, 25 Sep 2017 22:55:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Noam Postavsky Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 26 Sep 2017 02:55:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 25521 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 25521-submit@debbugs.gnu.org id=B25521.150639446520740 (code B ref 25521); Tue, 26 Sep 2017 02:55:01 +0000 Original-Received: (at 25521) by debbugs.gnu.org; 26 Sep 2017 02:54:25 +0000 Original-Received: from localhost ([127.0.0.1]:59358 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dwg0u-0005OR-NY for submit@debbugs.gnu.org; Mon, 25 Sep 2017 22:54:25 -0400 Original-Received: from mail-io0-f177.google.com ([209.85.223.177]:50112) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dwg0s-0005OE-HH for 25521@debbugs.gnu.org; Mon, 25 Sep 2017 22:54:23 -0400 Original-Received: by mail-io0-f177.google.com with SMTP id 21so11550852iof.6 for <25521@debbugs.gnu.org>; Mon, 25 Sep 2017 19:54:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version; bh=q+p+EKUO12cuZsepyjE6O20MykUN1zDbT2TxELieQ7E=; b=hQobL7IYRIBTmZ9Kd9cihGckOpaoaCY8ugcBlG1WsON2hsqGZj92SGbozJR4S6rJok dq9fZqV8401+P6ctV9IO6GFE5g/qWRfAGMaTNLyptpstwPQTR7AoT2qfZzAWuBoEwR72 zVLqWDqB87DdLZFzwScwu87PRX7DFLD4SRis0/7A0WBG958VfbqXps2fk+J4LwL/H3Aq cBJcgnihb+7d79HGi3oO6YKs+/fYbCp8qFJxIqOiIp1uyAY8CS13ukzJ7A2hJuy+sbfS ELN/qol2UjHwawb+bhxseGT1N9F8NosB+9ppiPE3AYDvFe2Q66TSzZ7bdYCRmx+Qk0Lv 04HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:references:date :in-reply-to:message-id:user-agent:mime-version; bh=q+p+EKUO12cuZsepyjE6O20MykUN1zDbT2TxELieQ7E=; b=Z2Jpftm93IFc2Wz0vMv+zCgODzmlRHCRVaZDYMyYze7a+8hZ+Tz482rwyOiCJIhlE4 iTmwYVThugHobC8pU2zq94cSCUz4DMyfMj8fe1L6VcIzfBMjm4mSHk5l6DjPnJxq9X/c xK7fFGKhy1jKz5k/pgu9TGVWGGlsVmha9DW1OysVMWbmXgV9itqSpGY/CYh13xWhUVSV xjCEekSLna89+u4ivG0rKCI0cdlAQkfHa9SGzDCEsbhx0bjeCvRoJCMgQwwfZjzCTmFH Xp32l56s0SBLc4G9UU36Kir3CVSHSmGj2rc4VH7q5IdBWhCH5lX6qPNVRLvT0TBTk7W1 25wA== X-Gm-Message-State: AHPjjUjxhIpDQvygJ4Nx+7mYP57PH0B6OACRfGK5HO4qjqD8LREcsi2I etE9SyHk7qBgeE3DjfppEjs= X-Google-Smtp-Source: AOwi7QAsggJlnd3UH2iiWp4Vsbk/9nb2ouaFBwEhAGukSalwloprCcEQ6YSvs/Uf0uQ1oecba9vc+g== X-Received: by 10.107.200.71 with SMTP id y68mr13587144iof.238.1506394456857; Mon, 25 Sep 2017 19:54:16 -0700 (PDT) Original-Received: from zebian ([45.2.119.34]) by smtp.googlemail.com with ESMTPSA id c198sm3693509ioc.67.2017.09.25.19.54.14 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 25 Sep 2017 19:54:15 -0700 (PDT) In-Reply-To: <59A980A5.9010705@gmx.at> (martin rudalics's message of "Fri, 01 Sep 2017 17:45:41 +0200") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:137448 Archived-At: --=-=-= Content-Type: text/plain martin rudalics writes: >> Ah, so we could just do something like this? (untested) > > With a slightly amended doc-string, yes. If someone insists on having > two frames with the same name on different displays and relying on the > old behavior to choose the one on the same display, we could add such a > check to give preference to a frame with the given name on the same > display. I doubt that someone relies on this function to throw an error > when a frame with the given name exists only on another display. Right, here's an update: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Let-select-frame-by-name-choose-any-frame-when-calle.patch Content-Description: patch >From 846c5603a02544ef9b25f395c253b3621aea4984 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 1 Sep 2017 09:38:55 -0400 Subject: [PATCH 1/3] Let select-frame-by-name choose any frame when called from lisp (Bug#25521) * lisp/frame.el (select-frame-by-name): Choose from the whole list of frames in the non-interactive part, if not found on the current display. --- lisp/frame.el | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lisp/frame.el b/lisp/frame.el index 76c1842455..a710360cdb 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -892,7 +892,8 @@ make-frame-names-alist (defvar frame-name-history nil) (defun select-frame-by-name (name) - "Select the frame on the current terminal whose name is NAME and raise it. + "Select the frame whose name is NAME and raise it. +Frames on the current terminal are checked first. If there is no frame by that name, signal an error." (interactive (let* ((frame-names-alist (make-frame-names-alist)) @@ -903,11 +904,14 @@ select-frame-by-name (if (= (length input) 0) (list default) (list input)))) - (let* ((frame-names-alist (make-frame-names-alist)) - (frame (cdr (assoc name frame-names-alist)))) - (if frame - (select-frame-set-input-focus frame) - (error "There is no frame named `%s'" name)))) + (select-frame-set-input-focus + ;; Prefer frames on the current display. + (or (cdr (assoc name (make-frame-names-alist))) + (catch 'done + (dolist (frame (frame-list)) + (when (equal (frame-parameter frame 'name) name) + (throw 'done frame)))) + (error "There is no frame named `%s'" name)))) ;;;; Background mode. -- 2.11.0 --=-=-= Content-Type: text/plain > Note that I'm not opposed to a timeout solution. As far as w32term.c is > concerned, I think your solution is superior to the present one. But > IMHO we should try to orchestrate all these efforts using a timer to > synchronize Emacs with the window manager or window system in a uniform > way so that the user knows where and how her time is spent. > > For example, if we decided that x_wait_for_event is a good idea, then we > should implement it on Windows too and use it uniformly when waiting for > a move frame event or the visibility confirmation. Huh. I was not aware of those other functions. Here's a patch which makes the timeout in x_wait_for_event configurable, and uses it in x_make_frame_visible. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0002-Bring-back-the-busy-wait-after-x_make_frame_visible-.patch Content-Description: patch >From 9c6730723507505f2c9f46148addd56901cd0bcc Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 30 Aug 2017 23:12:22 -0400 Subject: [PATCH 2/3] Bring back the busy wait after x_make_frame_visible (Bug#25521) 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 | 5 +++++ src/xterm.c | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 1b5ae658f6..adcc879cb2 100644 --- 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). + * Changes in Specialized Modes and Packages in Emacs 26.1 diff --git a/src/xterm.c b/src/xterm.c index 0b321909c8..50d023f4d9 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -11029,17 +11029,19 @@ 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); + tmo = make_timespec (0, (long int) (timeout * 1000 * 1000 * 1000)); tmo_at = timespec_add (current_timespec (), tmo); while (f->wait_event_type) @@ -11365,8 +11367,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) @@ -11437,11 +11444,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 +11498,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 +13297,17 @@ syms_of_xterm (void) 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, -- 2.11.0 --=-=-= Content-Type: text/plain However, based on this comment in w32_read_socket, I think we can't use the x_wait_for_event approach for w32. /* Check which frames are still visible, if we have enqueued any user events or been notified of events that may affect visibility. We do this here because there doesn't seem to be any direct notification from Windows that the visibility of a window has changed (at least, not in all cases). */ The final patch uses the same timeout variable, not sure if that's much of an improvement. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0003-Wait-for-frame-visibility-with-timeout-in-w32term-to.patch Content-Description: patch >From e0f8d29834afe72b64a3b6f87490cd4e0e571490 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Mon, 25 Sep 2017 21:58:55 -0400 Subject: [PATCH 3/3] Wait for frame visibility with timeout in w32term too * src/w32term.c (syms_of_w32term) [x-wait-for-event-timeout]: New variable. (x_make_frame_visible): Wait for frame to become visible according to its value. (input_signal_count): Remove. --- src/w32term.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/w32term.c b/src/w32term.c index a7a510b9ec..59d1b950ae 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -163,10 +163,6 @@ BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); /* Keyboard code page - may be changed by language-change events. */ int w32_keyboard_codepage; -/* Incremented by w32_read_socket whenever it really tries to read - events. */ -static int volatile input_signal_count; - #ifdef CYGWIN int w32_message_fd = -1; #endif /* CYGWIN */ @@ -4658,9 +4654,6 @@ w32_read_socket (struct terminal *terminal, block_input (); - /* So people can tell when we have read the available input. */ - input_signal_count++; - /* Process any incoming thread messages. */ drain_message_queue (); @@ -6612,7 +6605,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, @@ -6671,12 +6665,16 @@ x_make_frame_visible (struct frame *f) : SW_SHOWNORMAL); } + if (!FLOATP (Vx_wait_for_event_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_wait_for_event_timeout); + double start_time = XFLOAT_DATA (Ffloat_time (Qnil)); /* This must come after we set COUNT. */ unblock_input (); @@ -6686,8 +6684,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? */ @@ -7319,6 +7317,17 @@ syms_of_w32term (void) DEFSYM (Qrenamed_from, "renamed-from"); DEFSYM (Qrenamed_to, "renamed-to"); + 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_INT ("w32-num-mouse-buttons", w32_num_mouse_buttons, doc: /* Number of physical mouse buttons. */); -- 2.11.0 --=-=-=--