From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Helmut Eller Newsgroups: gmane.emacs.bugs Subject: bug#745: pop-to-buffer, frames, and input focus Date: Tue, 26 Aug 2008 23:45:27 +0200 Message-ID: References: <48AC2F4A.1000507@gmx.at> <48AC851A.3020906@gmx.at> <48AD2FB5.3000204@gmx.at> <48ADD085.50505@gmx.at> <48AEEBB8.50201@gmx.at> <48AFFD26.3040204@gmx.at> <48B2B78C.9090407@gmx.at> Reply-To: Helmut Eller , 745@emacsbugs.donarmstrong.com NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1219788467 25836 80.91.229.12 (26 Aug 2008 22:07:47 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 26 Aug 2008 22:07:47 +0000 (UTC) Cc: 745@emacsbugs.donarmstrong.com To: martin rudalics Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Aug 27 00:08:40 2008 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1KY6iL-0004tr-GX for geb-bug-gnu-emacs@m.gmane.org; Wed, 27 Aug 2008 00:08:37 +0200 Original-Received: from localhost ([127.0.0.1]:40518 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KY6hN-0003x6-0a for geb-bug-gnu-emacs@m.gmane.org; Tue, 26 Aug 2008 18:07:37 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KY6hJ-0003wP-9F for bug-gnu-emacs@gnu.org; Tue, 26 Aug 2008 18:07:33 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KY6hH-0003vU-RI for bug-gnu-emacs@gnu.org; Tue, 26 Aug 2008 18:07:32 -0400 Original-Received: from [199.232.76.173] (port=43110 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KY6hH-0003vJ-GQ for bug-gnu-emacs@gnu.org; Tue, 26 Aug 2008 18:07:31 -0400 Original-Received: from rzlab.ucr.edu ([138.23.92.77]:50134) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KY6hG-0004Rr-KY for bug-gnu-emacs@gnu.org; Tue, 26 Aug 2008 18:07:31 -0400 Original-Received: from rzlab.ucr.edu (rzlab.ucr.edu [127.0.0.1]) by rzlab.ucr.edu (8.13.8/8.13.8/Debian-3) with ESMTP id m7QM7SrV027151; Tue, 26 Aug 2008 15:07:28 -0700 Original-Received: (from debbugs@localhost) by rzlab.ucr.edu (8.13.8/8.13.8/Submit) id m7QLo3Z3020391; Tue, 26 Aug 2008 14:50:03 -0700 X-Loop: don@donarmstrong.com Resent-From: Helmut Eller Resent-To: bug-submit-list@donarmstrong.com Resent-CC: Emacs Bugs Resent-Date: Tue, 26 Aug 2008 21:50:03 +0000 Resent-Message-ID: Resent-Sender: don@donarmstrong.com X-Emacs-PR-Message: report 745 X-Emacs-PR-Package: emacs X-Emacs-PR-Keywords: Original-Received: via spool by 745-submit@emacsbugs.donarmstrong.com id=B745.121978704318741 (code B ref 745); Tue, 26 Aug 2008 21:50:03 +0000 Original-Received: (at 745) by emacsbugs.donarmstrong.com; 26 Aug 2008 21:44:03 +0000 Original-Received: from rolmail.net (cgp1.rolmail.net [195.254.252.190]) by rzlab.ucr.edu (8.13.8/8.13.8/Debian-3) with ESMTP id m7QLhwWL018733 for <745@emacsbugs.donarmstrong.com>; Tue, 26 Aug 2008 14:44:00 -0700 Original-Received: from dummy.name; Tue, 26 Aug 2008 23:43:55 +0200 Original-Received: from dummy.name; Tue, 26 Aug 2008 23:45:27 +0200 In-Reply-To: <48B2B78C.9090407@gmx.at> (martin rudalics's message of "Mon, 25 Aug 2008 15:45:48 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) Resent-Date: Tue, 26 Aug 2008 18:07:32 -0400 X-BeenThere: bug-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:19738 Archived-At: * martin rudalics [2008-08-25 15:45+0200] writes: [...] > So when `display-buffer' has called `pop-up-frame-function' we always > anticipate that the new frame is mapped (visible), has got input focus, > and is raised. We cannot remove input focus from it or lower it because > we would risk some nasty race conditions with the window manager. The > only reasonable alternative would be to make the new frame Withdrawn and > let `pop-to-buffer' etc. activate it but this seems hardly manageable. > > We should document the current behavior to avoid going through these > torments again. At the risk of repeating what you said, the current implementation can't assume whether the frame created by display-buffer has got focus or not. It's the window manager who decides that. We only know definitely that a particular frame has got focus if we receive a FocusIn event. But display-buffer (which AFAICT ultimately calls x_make_frame_visible) only waits until the frame is mapped. [I found this entertaining comment in xterm.c:x_make_frame_visible: /* 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.. */ In other words, we don't even know that the frame is mapped!] However, even documenting that the input focus is unspecified would be of some use. >>>> (If the >>>> buffer is already visible in some frame, that frame is raised but the >>>> focus is not moved to that frame. This is IMO correct.) >>> I think so. But what happens in the `pop-to-buffer' case when a _new_ >>> frame gets displayed. Should we give it input-focus? >> >> Yes. I don't see why not. > > And raise it I presume. Yes. > IIUC we currently rely on the window-manager to > raise and focus the frame. Currently Emacs does both. Requesting the focus from the X server (XSetInputFocus) and telling the window manager to activate (x_ewmh_activate_frame [which for most WMs is focus+raise]) the frame. >>> I suppose so from >>> your situation B comments below. So in all cases where situation A has >>> Y (that is `display-buffer' fails TDTRT) `pop-to-buffer' DTRT? >> >> Yes, right. In this case pop-up-frames must be t when pop-to-buffer is >> called. > > Is `pop-to-buffer' free of complications when activating a just created > frame? From your understanding would this be a NOOP for most window > managers? Good question. I guess the usual sequence of events is this: 1. Emacs tries to map a frame and waits for notification 2. WM intercepts map request 3. WM maps the frame + gives focus to frame + raises frame 4. Emacs receives MapNotify If we add a fifth step: 5. Emacs requests focus and informs WM to activate the frame we probably do something twice, but activating the same frame twice shouldn't hurt. We have a problem if the WM decides to activate a different frame, but that seems unlikely. > Note that `x-focus-frame' uses XSetInputFocus together with > x_ewmh_activate_frame. This mixture seems slightly frightening. Yes, this looks like "programming by accident". >>> Note in this context >>> that `select-frame-set-input-focus' always raises the frame. >> >> Looks unnecessary. > > For Metacity, maybe, because of their "can't raise without focusing" > invariant read backwards. But would it harm? IIRC some window-managers > may also move frames between desktops/workspaces when raising them. The only harm, that I can think of right now, is the understandability of the implementation :-) >> Emacs also calls XSetInputFocus together with >> x_ewmh_activate_frame in Fx_focus_frame. One of those is probably >> unnecessary. x_ewmh_activate_frame tells the WM to try to focus the >> frame, but some WMs will also raise the window at the same time. >> >>>> ? N Metacity follow-mouse (mouse) >>>> ? N Metacity follow-mouse (sloppy) >>>> ? N Metacity click-to-focus (click) >>> Does Metacity respect `select-frame-set-input-focus' at all? >> >> Yes, this seems to work. [Though, it also moves the mouse pointer to >> the upper right corner of the new frame. Maybe some Metacity >> idiosyncrasy.] > > Does it do so even with `focus-follows-mouse' nil? select-frame-set-input-focus seems to work identical for focus-follows-mouse and click-to-focus mode. The frame receives the input focus, is raised, and the mouse pointer is moved to its upper right corner. > Anyway: I could imagine something like the (completely untested) snippet > below to handle situation B - modulo whatever we should change in > `select-frame-set-input-focus', `x-focus-frame', ... > > > (defcustom pop-up-frame-activate nil > "When non-nil try to explicitly activate popped up frames. > If this is nil leave it to Emacs how to activate the frame. If > this is t always try to activate a new frame. Anything else > means activate a frame if and only if it existed before the most > recent call to `display-buffer' ..." > :type '(choice (const :tag "System Dependent" nil) > (const :tag "Existing frames only" 'existing-only) > (const :tag "Always" t)) > :group 'frames) I'm not sure that this issue must be customizable at all. As a user of pop-to-buffer, I don't quite see the usefulness of the "System Dependent" and "Existing frames only" choices. An Emacs implementor could argue that "System Dependent" is simpler to implement, but if the more complicated variants are implemented too it's no longer "simpler". I propose this change instead: (defun pop-to-buffer (buffer-or-name &optional other-window norecord) "Select buffer BUFFER-OR-NAME in some window, preferably a different one. ... " (let ((buffer ;; FIXME: This behavior is carried over from the previous C version ;; of pop-to-buffer, but really we should use just ;; `get-buffer' here. (if (null buffer-or-name) (other-buffer (current-buffer)) (or (get-buffer buffer-or-name) (let ((buf (get-buffer-create buffer-or-name))) (set-buffer-major-mode buf) buf))))) (set-buffer buffer) (let ((old-frame (selected-frame))) (select-window (display-buffer buffer other-window) norecord) (unless (eq old-frame (selected-frame)) ;; select-window doesn't set the input focus. Set it explicitly. ;; FIXME: select-window should request focus (perhaps lazily). (select-frame-set-input-focus (select-frame)))) buffer)) Helmut.