* bug#745: pop-to-buffer, frames, and input focus @ 2008-08-20 7:35 ` Helmut Eller 2008-08-20 14:50 ` martin rudalics 2008-09-11 7:05 ` bug#745: marked as done (pop-to-buffer, frames, and input focus) Emacs bug Tracking System 0 siblings, 2 replies; 31+ messages in thread From: Helmut Eller @ 2008-08-20 7:35 UTC (permalink / raw) To: bug-gnu-emacs Hi, The behavior of pop-to-buffer in combination with multiple frames is rather unpredictable or at least not what I expected. For example: shell$ cat pop-to-buffer-test.el (let ((frame (selected-frame)) (pop-up-frames t)) (display-buffer (get-buffer-create "foo")) (select-frame-set-input-focus frame)) (let ((display-buffer-reuse-frames t)) (pop-to-buffer "foo")) shell$ emacs -Q -l pop-to-buffer-test.el Pops up two frames, one frame displays the "foo" buffer and the other the "*scratch*" buffer (so far so good). But the "foo" frame has not the input focus. Isn't pop-to-buffer supposed to switch input focus too? Also note that I had to save and restore the selected frame around display-buffer. If I try emacs -Q --eval '(let ((pop-up-frames t)) (display-buffer (get-buffer-create "foo")))' the "foo" buffer is selected, even though display-buffer should not switch the selected window. Not even save-window-excursion stops display-buffer from switching the frame: emacs -Q --eval '(save-window-excursion (let ((pop-up-frames t)) (display-buffer (get-buffer-create "foo"))))' This is with: GNU Emacs 23.0.60.4 (i686-pc-linux-gnu, GTK+ Version 2.8.20) of 2008-08-15 on xaital Windowing system distributor `The X.Org Foundation', version 11.0.70101000 configured using `configure '--without-sound' '--without-pop' '--without-gif' '--without-tiff'' My window manager is Sawfish 1.3. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-20 7:35 ` bug#745: pop-to-buffer, frames, and input focus Helmut Eller @ 2008-08-20 14:50 ` martin rudalics 2008-08-20 18:42 ` Helmut Eller 2008-09-11 7:05 ` bug#745: marked as done (pop-to-buffer, frames, and input focus) Emacs bug Tracking System 1 sibling, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-20 14:50 UTC (permalink / raw) To: Helmut Eller, 745 > (let ((frame (selected-frame)) > (pop-up-frames t)) > (display-buffer (get-buffer-create "foo")) > (select-frame-set-input-focus frame)) > > (let ((display-buffer-reuse-frames t)) > (pop-to-buffer "foo")) > > shell$ emacs -Q -l pop-to-buffer-test.el > > Pops up two frames, one frame displays the "foo" buffer and the other > the "*scratch*" buffer (so far so good). But the "foo" frame has not > the input focus. Isn't pop-to-buffer supposed to switch input focus > too? (select-frame-set-input-focus frame)) gives input focus to the previously selected frame. > Also note that I had to save and restore the selected frame > around display-buffer. If I try > > emacs -Q --eval '(let ((pop-up-frames t)) > (display-buffer (get-buffer-create "foo")))' > > the "foo" buffer is selected, even though display-buffer should not > switch the selected window. I'm not sure whether on some system there were problems when raising a frame and/or giving it input focus, and not selecting it. At least with Emacs 22 the frame was selected already. Since there's only one window on the new frame, that window must be selected as well. In any case you're right: either the window must not be selected or the documentation should tell when and why it selects the window. > Not even save-window-excursion stops display-buffer from switching the > frame: > > emacs -Q --eval '(save-window-excursion > (let ((pop-up-frames t)) > (display-buffer (get-buffer-create "foo"))))' `save-window-excursion' is of no use here: It permits you to change the contents of a frame in the body and restore the initial contents afterwards. You do that with the originally selected frame here. The new frame created by `display-buffer' is not affected by this. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-20 14:50 ` martin rudalics @ 2008-08-20 18:42 ` Helmut Eller 2008-08-20 20:42 ` David Reitter 2008-08-20 20:56 ` martin rudalics 0 siblings, 2 replies; 31+ messages in thread From: Helmut Eller @ 2008-08-20 18:42 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-20 16:50+0200] writes: >> Pops up two frames, one frame displays the "foo" buffer and the other >> the "*scratch*" buffer (so far so good). But the "foo" frame has not >> the input focus. Isn't pop-to-buffer supposed to switch input focus >> too? > > (select-frame-set-input-focus frame)) > > gives input focus to the previously selected frame. Are you saying, that pop-to-buffer can't be used to select the window, the frame, and input focus at the same time? If so, when should pop-to-buffer be used? Aren't that unusual situations when pop-to-buffer should not also select the input focus? If you have any hints or guidelines how be a good buffer/window/frame citizen in different scenarios, that would be much appreciated. I'm not using multiple frames myself, but I'm maintaining a package called SLIME[*] which is used by a number of people who use frames. I'm not excited at all about rewriting a dozen or so uses of pop-to-buffer just to support multiple frames. There are some variables like display-buffer-reuse-frames and special-display-buffer-names and I hoped that those variables were supposed to make it easy to support multiple frames without cluttering the source code. [*] http://www.common-lisp.net/project/slime/ > >> Also note that I had to save and restore the selected frame >> around display-buffer. If I try >> >> emacs -Q --eval '(let ((pop-up-frames t)) >> (display-buffer (get-buffer-create "foo")))' >> >> the "foo" buffer is selected, even though display-buffer should not >> switch the selected window. > > I'm not sure whether on some system there were problems when raising a > frame and/or giving it input focus, and not selecting it. At least with > Emacs 22 the frame was selected already. Since there's only one window > on the new frame, that window must be selected as well. > > In any case you're right: either the window must not be selected or the > documentation should tell when and why it selects the window. The docstring of display-buffer reads "Make buffer BUFFER-OR-NAME appear in some window but don't select it. ..." I think it be would less surprising if the input focus would not be switched to the new frame. >> Not even save-window-excursion stops display-buffer from switching the >> frame: >> >> emacs -Q --eval '(save-window-excursion >> (let ((pop-up-frames t)) >> (display-buffer (get-buffer-create "foo"))))' > > `save-window-excursion' is of no use here: It permits you to change the > contents of a frame in the body and restore the initial contents > afterwards. You do that with the originally selected frame here. The > new frame created by `display-buffer' is not affected by this. save-window-excursion is supposed to "... Also restore the choice of selected window. ..." If I do emacs -Q -nw --eval '(save-window-excursion (let ((pop-up-frames t)) (display-buffer (get-buffer-create "foo"))))' I end up in the "*scratch*" buffer not in "foo". It would be more consistent if the X11 version and the tty version would restore the input focus to the same frame. The tty version is the behavior that I would expect. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-20 18:42 ` Helmut Eller @ 2008-08-20 20:42 ` David Reitter 2008-08-20 20:56 ` martin rudalics 1 sibling, 0 replies; 31+ messages in thread From: David Reitter @ 2008-08-20 20:42 UTC (permalink / raw) To: Helmut Eller, 745 [-- Attachment #1: Type: text/plain, Size: 2056 bytes --] On 20 Aug 2008, at 14:42, Helmut Eller wrote: > Are you saying, that pop-to-buffer can't be used to select the > window, > the frame, and input focus at the same time? If so, when should > pop-to-buffer be used? Aren't that unusual situations when > pop-to-buffer should not also select the input focus? I have long used the patch below in Aquamacs to create consistency between multi-frame and multi-window operations. Most packages are designed to work with the multi-window setup, and it is my conviction that most Emacs developers work with the Emacs default (multi- window). Perhaps that is why some packages do not play ball when buffers are set to pop up in new frames... *** src/buffer.c 25 Feb 2006 23:33:57 +0000 1.501 --- src/buffer.c 07 May 2006 22:45:45 +0100 *************** *** 175,180 **** --- 175,182 ---- Lisp_Object Qinsert_in_front_hooks; Lisp_Object Qinsert_behind_hooks; + Lisp_Object Qselect_frame_set_input_focus; + static void alloc_buffer_text P_ ((struct buffer *, size_t)); static void free_buffer_text P_ ((struct buffer *b)); static struct Lisp_Overlay * copy_overlays P_ ((struct buffer *, struct Lisp_Overlay *)); *************** *** 1723,1729 **** } } Fset_buffer (buf); ! Fselect_window (Fdisplay_buffer (buf, other_window, Qnil), norecord); return buf; } --- 1725,1734 ---- } } Fset_buffer (buf); ! call1(Qselect_frame_set_input_focus, ! Fwindow_frame( Fselect_window (Fdisplay_buffer (buf, ! other_window, Qnil), ! norecord))); return buf; } *************** *** 5227,5232 **** --- 5232,5239 ---- Qafter_change_functions = intern ("after-change-functions"); staticpro (&Qafter_change_functions); staticpro (&Qucs_set_table_for_input); + Qselect_frame_set_input_focus = intern ("select-frame-set-input- focus"); + staticpro (&Qselect_frame_set_input_focus); Qkill_buffer_query_functions = intern ("kill-buffer-query- functions"); staticpro (&Qkill_buffer_query_functions); [-- Attachment #2: smime.p7s --] [-- Type: application/pkcs7-signature, Size: 2193 bytes --] ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-20 18:42 ` Helmut Eller 2008-08-20 20:42 ` David Reitter @ 2008-08-20 20:56 ` martin rudalics 2008-08-21 8:07 ` Helmut Eller 1 sibling, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-20 20:56 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 > Are you saying, that pop-to-buffer can't be used to select the window, > the frame, and input focus at the same time? If so, when should > pop-to-buffer be used? Aren't that unusual situations when > pop-to-buffer should not also select the input focus? With emacs -Q evaluating (let ((pop-up-frames t) (buffer (get-buffer-create "foo"))) (pop-to-buffer buffer)) here gets me a new frame on top of the previously selected one, the window displaying buffer `foo' is the selected window, and when I now start typing, characters get displayed in that window. What did you expect and what did you get? > If you have any hints or guidelines how be a good buffer/window/frame > citizen in different scenarios, that would be much appreciated. I'm slightly confused because in your earlier scenario you bemoaned the fact that the frame _was_ selected. All I wanted to say that raising a frame, giving it input focus, and _not_ selecting it might be difficult. > I'm not using multiple frames myself, but I'm maintaining a package > called SLIME[*] which is used by a number of people who use frames. I'm > not excited at all about rewriting a dozen or so uses of pop-to-buffer > just to support multiple frames. There are some variables like > display-buffer-reuse-frames and special-display-buffer-names and I hoped > that those variables were supposed to make it easy to support multiple > frames without cluttering the source code. > > [*] http://www.common-lisp.net/project/slime/ I moved `pop-to-buffer' to window.el so you can easier try to play around with it and propose a solution that fits your needs ;-) > The docstring of display-buffer reads > "Make buffer BUFFER-OR-NAME appear in some window but don't select it. ..." > I think it be would less surprising if the input focus would not be switched > to the new frame. You have a point here but it's not up to me to decide that. > If I do > > emacs -Q -nw --eval '(save-window-excursion > (let ((pop-up-frames t)) > (display-buffer (get-buffer-create "foo"))))' > > I end up in the "*scratch*" buffer not in "foo". It would be more > consistent if the X11 version and the tty version would restore the > input focus to the same frame. The tty version is the behavior that I > would expect. When I do (save-window-excursion (let ((pop-up-frames t)) (display-buffer (get-buffer-create "foo")))) in the *scratch* buffer I end up in `foo' - whether this is TRT I don't know. Doing a `save-window-excursion' on the command line is beyond my comprehension. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-20 20:56 ` martin rudalics @ 2008-08-21 8:07 ` Helmut Eller 2008-08-21 9:04 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-21 8:07 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-20 22:56+0200] writes: >> Are you saying, that pop-to-buffer can't be used to select the window, >> the frame, and input focus at the same time? If so, when should >> pop-to-buffer be used? Aren't that unusual situations when >> pop-to-buffer should not also select the input focus? > > With emacs -Q evaluating > > (let ((pop-up-frames t) > (buffer (get-buffer-create "foo"))) > (pop-to-buffer buffer)) > > here gets me a new frame on top of the previously selected one, the > window displaying buffer `foo' is the selected window, and when I now > start typing, characters get displayed in that window. What did you > expect and what did you get? Consider my original example: (progn (let ((frame (selected-frame)) (pop-up-frames t)) (display-buffer (get-buffer-create "foo")) (select-frame-set-input-focus frame)) (let ((display-buffer-reuse-frames t)) (pop-to-buffer "foo"))) First, display-buffer is just used to create two frames. This switches (surprisingly) focus to the "foo" buffer. select-frame-set-input-focus is used to force the focus back to the "*scratch*" buffer. Then we use pop-to-buffer, but the input focus remains (surprisingly) in the "*scratch*" buffer. I expect this: pop-to-buffer should switch the input focus display-buffer should not change the input focus >> If you have any hints or guidelines how be a good buffer/window/frame >> citizen in different scenarios, that would be much appreciated. > > I'm slightly confused because in your earlier scenario you bemoaned the > fact that the frame _was_ selected. All I wanted to say that raising a > frame, giving it input focus, and _not_ selecting it might be difficult. I see. But this is also not what I expect. >> I'm not using multiple frames myself, but I'm maintaining a package >> called SLIME[*] which is used by a number of people who use frames. I'm >> not excited at all about rewriting a dozen or so uses of pop-to-buffer >> just to support multiple frames. There are some variables like >> display-buffer-reuse-frames and special-display-buffer-names and I hoped >> that those variables were supposed to make it easy to support multiple >> frames without cluttering the source code. >> >> [*] http://www.common-lisp.net/project/slime/ > > I moved `pop-to-buffer' to window.el so you can easier try to play > around with it and propose a solution that fits your needs ;-) Thanks for the moving it :-) pop-to-buffer is more or less (select-window (display-buffer ...)). This looks very reasonable, but it doesn't transfer the input focus. (under X; in a tty everything works well.) On the other hand, display-buffer switches sometimes (when a new frame is created) the input focus, even when that was not asked for. Maybe pop-to-buffer could do something like (let ((window (display-buffer ...))) (select-window window) (select-frame-set-input-focus (window-frame window))) That would solve my immediate problem, but I suspect that select-window should be smarter. My naive interpretation of select-window's C source is that select-window tries to select the frame. But apparently forgets about the input focus. This may also be the reason why save-window-excursion doesn't restore the input focus. Selecting a window, without giving it the input focus is probably rarely needed. Perhaps select-window should transfer the input focus by default. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-21 8:07 ` Helmut Eller @ 2008-08-21 9:04 ` martin rudalics 2008-08-21 13:20 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-21 9:04 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 > Consider my original example: > > (progn > (let ((frame (selected-frame)) > (pop-up-frames t)) > (display-buffer (get-buffer-create "foo")) > (select-frame-set-input-focus frame)) > > (let ((display-buffer-reuse-frames t)) > (pop-to-buffer "foo"))) > > First, display-buffer is just used to create two frames. This switches > (surprisingly) focus to the "foo" buffer. select-frame-set-input-focus > is used to force the focus back to the "*scratch*" buffer. Then we use > pop-to-buffer, but the input focus remains (surprisingly) in the > "*scratch*" buffer. Ahhh, I can't reproduce that. Evaluating your `progn' moves focus to the `foo' buffer here (with emacs -Q). So it seems we have a platform (maybe window manager) specific problem. > I expect this: > > pop-to-buffer should switch the input focus > display-buffer should not change the input focus `pop-to-buffer' has the sole additional twist WRT `display-buffer': (select-window (display-buffer buffer other-window) norecord) That is, the window used by `display-buffer' should get definitively selected. So, if `display-buffer' has decided to use "another" frame, raising that frame, giving it input focus, and implicitly selecting that frame and the window used for displaying the buffer_must_ have been already handled by `display-buffer'. In this case, the `select-window' done by `pop-to-buffer' looks like a NOOP though I didn't verify that. >> All I wanted to say that raising a >> frame, giving it input focus, and _not_ selecting it might be difficult. > > I see. But this is also not what I expect. So `pop-to-buffer' raising a frame + giving it input focus + selecting it is always OK with you? > pop-to-buffer is more or less (select-window (display-buffer ...)). > This looks very reasonable, but it doesn't transfer the input focus. > (under X; in a tty everything works well.) > > On the other hand, display-buffer switches sometimes (when a new frame > is created) the input focus, even when that was not asked for. > > Maybe pop-to-buffer could do something like > > (let ((window (display-buffer ...))) > (select-window window) > (select-frame-set-input-focus (window-frame window))) > > That would solve my immediate problem, ... Does it solve all your problems in this context? I suppose it won't be of any help when you use `display-buffer' with `pop-up-frames' t :-( > ... but I suspect that select-window > should be smarter. My naive interpretation of select-window's C source > is that select-window tries to select the frame. But apparently forgets > about the input focus. This may also be the reason why > save-window-excursion doesn't restore the input focus. > > Selecting a window, without giving it the input focus is probably rarely > needed. Perhaps select-window should transfer the input focus by > default. I suppose we can't do that. `select-window' is frequently used to temporarily switch to another window (compare `save-selected-window'). Shifting input focus to another frame and possibly back to the initial frame might confuse the window manager. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-21 9:04 ` martin rudalics @ 2008-08-21 13:20 ` Helmut Eller 2008-08-21 20:31 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-21 13:20 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-21 11:04+0200] writes: >> Consider my original example: >> >> (progn >> (let ((frame (selected-frame)) >> (pop-up-frames t)) >> (display-buffer (get-buffer-create "foo")) >> (select-frame-set-input-focus frame)) >> >> (let ((display-buffer-reuse-frames t)) >> (pop-to-buffer "foo"))) >> >> First, display-buffer is just used to create two frames. This switches >> (surprisingly) focus to the "foo" buffer. select-frame-set-input-focus >> is used to force the focus back to the "*scratch*" buffer. Then we use >> pop-to-buffer, but the input focus remains (surprisingly) in the >> "*scratch*" buffer. > > Ahhh, I can't reproduce that. Evaluating your `progn' moves focus to > the `foo' buffer here (with emacs -Q). So it seems we have a platform > (maybe window manager) specific problem. I have tried a few window managers now. pop-to-buffer doesn't switch input focus with: Sawfish, kwin, metacity, fluxbox, twm. It does with icewm. display-buffer seems to switch focus with: Sawfish, kwin, fluxbox, icewm, twm. Metacity seems to make the decision based on the mouse pointer, but it's not clear how. The new buffer receives the input focus sometimes but not always. > >> I expect this: >> >> pop-to-buffer should switch the input focus >> display-buffer should not change the input focus > > `pop-to-buffer' has the sole additional twist WRT `display-buffer': > > (select-window (display-buffer buffer other-window) norecord) > > That is, the window used by `display-buffer' should get definitively > selected. So, if `display-buffer' has decided to use "another" frame, > raising that frame, giving it input focus, and implicitly selecting that > frame and the window used for displaying the buffer_must_ have been > already handled by `display-buffer'. In this case, the `select-window' > done by `pop-to-buffer' looks like a NOOP though I didn't verify that. I still think that display-buffer should neither select the other frame nor give it the input focus. (Whether the other frame should be raised or not should probably be customizable, but that's a minor issue.) If the problem only occurs for new frames it's not so serious, tough. Once created, frames will probably stay there for a while and not be continuously closed/created. It's probably also harder to stop window managers from doing stupid things with new frames. >>> All I wanted to say that raising a >>> frame, giving it input focus, and _not_ selecting it might be difficult. >> >> I see. But this is also not what I expect. > > So `pop-to-buffer' raising a frame + giving it input focus + selecting > it is always OK with you? Yes, I think so. > >> pop-to-buffer is more or less (select-window (display-buffer ...)). >> This looks very reasonable, but it doesn't transfer the input focus. >> (under X; in a tty everything works well.) >> >> On the other hand, display-buffer switches sometimes (when a new frame >> is created) the input focus, even when that was not asked for. >> >> Maybe pop-to-buffer could do something like >> >> (let ((window (display-buffer ...))) >> (select-window window) >> (select-frame-set-input-focus (window-frame window))) >> >> That would solve my immediate problem, ... > > Does it solve all your problems in this context? For now, yes :-) > I suppose it won't be > of any help when you use `display-buffer' with `pop-up-frames' t :-( Well, yeah this wouldn't fix display-buffer. >> ... but I suspect that select-window >> should be smarter. My naive interpretation of select-window's C source >> is that select-window tries to select the frame. But apparently forgets >> about the input focus. This may also be the reason why >> save-window-excursion doesn't restore the input focus. >> >> Selecting a window, without giving it the input focus is probably rarely >> needed. Perhaps select-window should transfer the input focus by >> default. > > I suppose we can't do that. `select-window' is frequently used to > temporarily switch to another window (compare `save-selected-window'). Hmm, I see. Yet, select-window calls Fselect_frame. The distinction between select-frame and select-frame-set-input-focus is certainly confusing. > Shifting input focus to another frame and possibly back to the initial > frame might confuse the window manager. That would be a stupid window manager :-) Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-21 13:20 ` Helmut Eller @ 2008-08-21 20:31 ` martin rudalics 2008-08-22 14:27 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-21 20:31 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 > pop-to-buffer doesn't switch input focus with: Sawfish, kwin, > metacity, fluxbox, twm. > It does with icewm. > > display-buffer seems to switch focus with: Sawfish, kwin, fluxbox, > icewm, twm. You probably mean display-buffer does _not_ switch focus with these. > I still think that display-buffer should neither select the other frame > nor give it the input focus. (Whether the other frame should be raised > or not should probably be customizable, but that's a minor issue.) I agree with you but I'm afraid there were issues with this. If you have some spare time please look at the threads starting with http://lists.gnu.org/archive/html/emacs-devel/2006-04/msg00922.html http://lists.gnu.org/archive/html/emacs-devel/2005-11/msg00107.html http://lists.gnu.org/archive/html/emacs-devel/2008-03/msg00946.html respectively. At the very least you will find out that you're not alone. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-21 20:31 ` martin rudalics @ 2008-08-22 14:27 ` Helmut Eller 2008-08-22 16:39 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-22 14:27 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-21 22:31+0200] writes: >> pop-to-buffer doesn't switch input focus with: Sawfish, kwin, >> metacity, fluxbox, twm. >> It does with icewm. >> >> display-buffer seems to switch focus with: Sawfish, kwin, fluxbox, >> icewm, twm. > > You probably mean display-buffer does _not_ switch focus with these. I meant to say: display-buffer _does_ switch focus when creating a new frame with those window managers: Sawfish, kwin, fluxbox, icewm, twm. >> I still think that display-buffer should neither select the other frame >> nor give it the input focus. (Whether the other frame should be raised >> or not should probably be customizable, but that's a minor issue.) > > I agree with you but I'm afraid there were issues with this. If you > have some spare time please look at the threads starting with > > http://lists.gnu.org/archive/html/emacs-devel/2006-04/msg00922.html > > http://lists.gnu.org/archive/html/emacs-devel/2005-11/msg00107.html > > http://lists.gnu.org/archive/html/emacs-devel/2008-03/msg00946.html > > respectively. At the very least you will find out that you're not > alone. Those messages are several years old. And it looks like nobody is going to fix the issue this time. Maybe we could move the input focus to the selected frame in a lazy fashion. E.g. when Emacs waits for new events, we could compare the currently focused frame with the selected frame, and if they differ we could switch the focus to the selected frame. This would make select-frame more useful. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-22 14:27 ` Helmut Eller @ 2008-08-22 16:39 ` martin rudalics 2008-08-23 8:55 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-22 16:39 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 >>> pop-to-buffer doesn't switch input focus with: Sawfish, kwin, >>> metacity, fluxbox, twm. >>> It does with icewm. >>> >>> display-buffer seems to switch focus with: Sawfish, kwin, fluxbox, >>> icewm, twm. >> You probably mean display-buffer does _not_ switch focus with these. > > I meant to say: display-buffer _does_ switch focus when creating a new > frame with those window managers: Sawfish, kwin, fluxbox, icewm, twm. I still don't understand. Simplistically spoken, `pop-to-buffer' is `display-buffer' + `select-window'. How can, using Sawfish say, `display-buffer' switch focus and `pop-to-buffer' not switch focus? >>> I still think that display-buffer should neither select the other frame >>> nor give it the input focus. (Whether the other frame should be raised >>> or not should probably be customizable, but that's a minor issue.) >> I agree with you but I'm afraid there were issues with this. If you >> have some spare time please look at the threads starting with >> >> http://lists.gnu.org/archive/html/emacs-devel/2006-04/msg00922.html >> >> http://lists.gnu.org/archive/html/emacs-devel/2005-11/msg00107.html >> >> http://lists.gnu.org/archive/html/emacs-devel/2008-03/msg00946.html >> >> respectively. At the very least you will find out that you're not >> alone. > > Those messages are several years old. And it looks like nobody is > going to fix the issue this time. We should fix it this time. Please try again two things with the window-managers you listed above and `pop-up-frames' non-nil: - tell whether `display-buffer' does switch focus. - tell whether `pop-to-buffer' does switch focus. - try both, if possible, with click-to-focus and a focus-follows-mouse settings (maybe you have to set the value of the Emacs variable `focus-follows-mouse' appropriately). Here on Windos XP with a focus-follows-mouse policy, `display-buffer' and `pop-to-buffer' both switch focus. IIRC, people reported troubles with the standard click-to-focus policy. Honestly, I'm a bit reluctant to try out click-to-focus here, maybe someone else can try? > Maybe we could move the input focus to the selected frame in a lazy > fashion. E.g. when Emacs waits for new events, we could compare the > currently focused frame with the selected frame, and if they differ we > could switch the focus to the selected frame. This would make > select-frame more useful. I suppose we should introduce a customizable variable which allows to call `select-frame-set-input-focus' (or something similar) at least in `pop-to-buffer' but maybe also in `display-buffer'. But we should also provide a doc-string recommending what setting this variable should have on which platform. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-22 16:39 ` martin rudalics @ 2008-08-23 8:55 ` Helmut Eller 2008-08-23 12:05 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-23 8:55 UTC (permalink / raw) To: martin rudalics; +Cc: 745 [-- Attachment #1: Type: text/plain, Size: 4821 bytes --] * martin rudalics [2008-08-22 18:39+0200] writes: >>>> pop-to-buffer doesn't switch input focus with: Sawfish, kwin, >>>> metacity, fluxbox, twm. >>>> It does with icewm. >>>> >>>> display-buffer seems to switch focus with: Sawfish, kwin, fluxbox, >>>> icewm, twm. >>> You probably mean display-buffer does _not_ switch focus with these. >> >> I meant to say: display-buffer _does_ switch focus when creating a new >> frame with those window managers: Sawfish, kwin, fluxbox, icewm, twm. > > I still don't understand. Simplistically spoken, `pop-to-buffer' is > `display-buffer' + `select-window'. How can, using Sawfish say, > `display-buffer' switch focus and `pop-to-buffer' not switch focus? Sorry, that was indeed confusing. The problematic cases are (let ((pop-up-frames t)) (display-buffer ...)) for display-buffer, if the buffer was not visible before. In this case a new frame appears, which (wrongly) has the input focus. (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.) For pop-to-buffer: (let ((display-buffer-reuse-frames t)) (pop-to-buffer ...)) if the buffer is already visible in a frame which has not the input focus. This should move input focus to that frame, but it currently doesn't. (If the frame has already the focus, pop-to-buffer works as it should.) Let's call the display-buffer case, situation A and the pop-to-buffer case, situation B. > > We should fix it this time. Please try again two things with the > window-managers you listed above and `pop-up-frames' non-nil: > > - tell whether `display-buffer' does switch focus. > > - tell whether `pop-to-buffer' does switch focus. > > - try both, if possible, with click-to-focus and a focus-follows-mouse > settings (maybe you have to set the value of the Emacs variable > `focus-follows-mouse' appropriately). OK, here is what I see: A B WM WM focus mode --------------------------------------- Y N Sawfish follow-mouse (enter-only + focus-window-when-mapped) N N Sawfish follow-mouse (enter-only + !focus-window-when-mapped) Y N Sawfish follow-mouse (enter-exit + focus-window-when-mapped) N N Sawfish follow-mouse (enter-exit + !focus-window-when-mapped) Y N Sawfish click-to-focus (click + focus-window-when-mapped) N N Sawfish click-to-focus (click + !focus-window-when-mapped) Y N Sawfish click-to-focus (click + focus-window-when-mapped + focus-click-through) N N Sawfish click-to-focus (click + !focus-window-when-mapped + focus-click-through) ? N Metacity follow-mouse (mouse) ? N Metacity follow-mouse (sloppy) ? N Metacity click-to-focus (click) Y N KWin follow-mouse Y N KWin click-to-focus Y M FluxBox follow-mouse (Sloppy Focus) Y M FluxBox follow-mouse (Auto Raise) Y N FluxBox click-to-focus Y Y IceWM click-to-focus Y N Twm follow-mouse (new frames need mouse click for placement) A and B are the scenarios described above. Y means: Yes, does switch focus. N means: No, doesn't switch focus. ? means: sometimes (probably depending on mouse and window positions) M means: No, doesn't switch focus, except when raising the frame also moves the mouse pointer into the frame. I set Emacs' focus-follows-mouse according to the WM focus mode (except when I forgot it :-) The Ys for Sawfish are apparently directly related to the focus-window-when-mapped option. So, it's probably not Emacs that switches the focus in the A scenario, but the window managers. > > Here on Windos XP with a focus-follows-mouse policy, `display-buffer' > and `pop-to-buffer' both switch focus. IIRC, people reported troubles > with the standard click-to-focus policy. Honestly, I'm a bit reluctant > to try out click-to-focus here, maybe someone else can try? > >> Maybe we could move the input focus to the selected frame in a lazy >> fashion. E.g. when Emacs waits for new events, we could compare the >> currently focused frame with the selected frame, and if they differ we >> could switch the focus to the selected frame. This would make >> select-frame more useful. > > I suppose we should introduce a customizable variable which allows to > call `select-frame-set-input-focus' (or something similar) at least in > `pop-to-buffer' but maybe also in `display-buffer'. But we should also > provide a doc-string recommending what setting this variable should have > on which platform. Yes, that would be good. The docstring for select-window could perhaps also state a bit more prominently that the "selected window" and the "input focus" are different things or at least refer to select-frame-set-input-focus. BTW, below is a proof of concept implementation for the update-focus-lazily idea. Helmut. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: lazy-focus.diff --] [-- Type: text/x-diff, Size: 836 bytes --] --- keyboard.c.~1.969.~ 2008-08-15 14:47:16.000000000 +0200 +++ keyboard.c 2008-08-23 10:23:12.000000000 +0200 @@ -1602,6 +1602,21 @@ (at your option) any later version. && !EQ (internal_last_event_frame, selected_frame)) Fselect_frame (internal_last_event_frame); #endif +#if 1 + { + if (!detect_input_pending() + && NILP(internal_last_event_frame)) { + Display *dpy = FRAME_X_DISPLAY (check_x_frame(selected_frame)); + Window focus; + int revert_to; + XGetInputFocus (dpy, &focus, &revert_to); + if (focus != None + && focus != FRAME_X_WINDOW (check_x_frame(selected_frame))) + Fx_focus_frame (selected_frame); + } + } +#endif + /* If it has changed current-menubar from previous value, really recompute the menubar from the value. */ if (! NILP (Vlucid_menu_bar_dirty_flag) ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-23 8:55 ` Helmut Eller @ 2008-08-23 12:05 ` martin rudalics 2008-08-24 13:14 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-23 12:05 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 > The problematic cases are > > (let ((pop-up-frames t)) (display-buffer ...)) > > for display-buffer, if the buffer was not visible before. In this case > a new frame appears, which (wrongly) has the input focus. Rather "which (wrongly) has the input focus for window managers able to handle mapping a new frame without giving input focus to it" because IIUC with certain settings (focus-follows-mouse) some window managers automatically do give focus to the new frame. I also suppose that the only means to take focus away from the new frame is by giving focus to the previously selected frame (though we can't even be sure that frame had focus or was risen). > (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? 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? > For pop-to-buffer: > > (let ((display-buffer-reuse-frames t)) (pop-to-buffer ...)) > > if the buffer is already visible in a frame which has not the input > focus. This should move input focus to that frame, but it currently > doesn't. (If the frame has already the focus, pop-to-buffer works as it > should.) Do we agree on the general rule that - `display-buffer' should never try to move input focus to another (new or existing) frame, while - `pop-to-buffer' should try to give input focus to the frame where BUFFER is displayed (this could be the selected frame as well). > Let's call the display-buffer case, situation A and the pop-to-buffer > case, situation B. [...] > OK, here is what I see: > > A B WM WM focus mode > --------------------------------------- > Y N Sawfish follow-mouse (enter-only + focus-window-when-mapped) > N N Sawfish follow-mouse (enter-only + !focus-window-when-mapped) > Y N Sawfish follow-mouse (enter-exit + focus-window-when-mapped) > N N Sawfish follow-mouse (enter-exit + !focus-window-when-mapped) > Y N Sawfish click-to-focus (click + focus-window-when-mapped) > N N Sawfish click-to-focus (click + !focus-window-when-mapped) > Y N Sawfish click-to-focus (click + focus-window-when-mapped + focus-click-through) > N N Sawfish click-to-focus (click + !focus-window-when-mapped + focus-click-through) I'm completely ignorant WRT to focus-window-when-mapped: Does this mean that a window that is not risen can get focus? Note in this context that `select-frame-set-input-focus' always raises the frame. > ? 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? > Y N KWin follow-mouse > Y N KWin click-to-focus > Y M FluxBox follow-mouse (Sloppy Focus) > Y M FluxBox follow-mouse (Auto Raise) For the M cases `raise-frame' could move the mouse pointer to that frame which seems to call for yet another option. > Y N FluxBox click-to-focus > Y Y IceWM click-to-focus So IceWM is the only window manager to handle situation B. IIUC it does so because do_switch-frame manages to get Fredirect_frame_focus through to redirect input to that frame. Or do you have another explanation? Could you try to GDB do_switch_frame for IceWM and one of the others to see they do differently? > Y N Twm follow-mouse (new frames need mouse click for placement) > > A and B are the scenarios described above. > Y means: Yes, does switch focus. > N means: No, doesn't switch focus. > ? means: sometimes (probably depending on mouse and window positions) > M means: No, doesn't switch focus, except when raising the frame > also moves the mouse pointer into the frame. > > I set Emacs' focus-follows-mouse according to the WM focus mode (except > when I forgot it :-) > > The Ys for Sawfish are apparently directly related to the > focus-window-when-mapped option. So, it's probably not Emacs that > switches the focus in the A scenario, but the window managers. Can we conclucde that the other window managers implicitly focus a frame when mapping it? > The docstring for select-window could perhaps > also state a bit more prominently that the "selected window" and the > "input focus" are different things ... if the implementation is bogus this will hardly help ... > or at least refer to > select-frame-set-input-focus. That function lumps together too many things. At least `raise-frame' should probably be optional there. > BTW, below is a proof of concept implementation for the > update-focus-lazily idea. Would this work with `redirect-frame-focus'? I haven't studied it in detail. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-23 12:05 ` martin rudalics @ 2008-08-24 13:14 ` Helmut Eller 2008-08-25 13:45 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-24 13:14 UTC (permalink / raw) To: martin rudalics; +Cc: 745 [-- Attachment #1: Type: text/plain, Size: 9288 bytes --] * martin rudalics [2008-08-23 14:05+0200] writes: >> The problematic cases are >> >> (let ((pop-up-frames t)) (display-buffer ...)) >> >> for display-buffer, if the buffer was not visible before. In this case >> a new frame appears, which (wrongly) has the input focus. > > Rather "which (wrongly) has the input focus for window managers able to > handle mapping a new frame without giving input focus to it" because > IIUC with certain settings (focus-follows-mouse) some window managers > automatically do give focus to the new frame. Yes, I agree. I didn't know before that Sawfish has a focus-window-when-mapped option. Situation A is probably a window manager issue. > I also suppose that the > only means to take focus away from the new frame is by giving focus to > the previously selected frame (though we can't even be sure that frame > had focus or was risen). I've read a little bit in the Xlib Manual[*] and here is what I learned: If we set the focus to the old frame by calling select-frame-set-input-focus in display-buffer we have something like a race condition. The window manager may decide at the same time that the new frame should have the focus and either Emacs or the WM will win the race. Emacs sets the "input-hint" flag in WM_HINTS when creating new frames. This can be seen with: shell$ xprop WM_HINTS WM_HINTS(WM_HINTS): Client accepts input or input focus: True Initial state is Normal State. bitmap id # to use for icon: 0xa00710 bitmap id # of mask for icon: 0xa00712 window id # of group leader: 0xa00001 If the input-hint flag is set, some window managers will assume that Emacs doesn't switch the input focus by itself and so the WM does it. In theory, Emacs could clear the input-hint flag (to stop the WM from switching focus) and instead listen to WM_TAKE_FOCUS events. The window manager sends WM_TAKE_FOCUS to Emacs, when the WM thinks that Emacs should now be focused. Emacs can then decide to set (or not) the focus to the appropriate frame. I don't know how well that would work in practice or if all window managers follow the conventions. But if the input-hint flag is set, Emacs has to fight with the window manager. OTOH, some people will prefer that the WM does all the focus switching. I guess it's not worth fixing situation A. People with decent window managers will be able to configure their preferred focus behavior anyway. [*] http://tronche.com/gui/x/icccm/sec-4.html >> (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. > 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. >> For pop-to-buffer: >> >> (let ((display-buffer-reuse-frames t)) (pop-to-buffer ...)) >> >> if the buffer is already visible in a frame which has not the input >> focus. This should move input focus to that frame, but it currently >> doesn't. (If the frame has already the focus, pop-to-buffer works as it >> should.) > > Do we agree on the general rule that > > - `display-buffer' should never try to move input focus to another (new > or existing) frame, while > > - `pop-to-buffer' should try to give input focus to the frame where > BUFFER is displayed Yes, we agree. > (this could be the selected frame as well). [I guess, it would be an optimization for a common case not to give input focus to the frame that is already focused. But despite efficiency, it wouldn't make a difference.] > >> Let's call the display-buffer case, situation A and the pop-to-buffer >> case, situation B. > [...] >> OK, here is what I see: >> >> A B WM WM focus mode >> --------------------------------------- >> Y N Sawfish follow-mouse (enter-only + focus-window-when-mapped) >> N N Sawfish follow-mouse (enter-only + !focus-window-when-mapped) >> Y N Sawfish follow-mouse (enter-exit + focus-window-when-mapped) >> N N Sawfish follow-mouse (enter-exit + !focus-window-when-mapped) >> Y N Sawfish click-to-focus (click + focus-window-when-mapped) >> N N Sawfish click-to-focus (click + !focus-window-when-mapped) >> Y N Sawfish click-to-focus (click + focus-window-when-mapped + focus-click-through) >> N N Sawfish click-to-focus (click + !focus-window-when-mapped + focus-click-through) > > I'm completely ignorant WRT to focus-window-when-mapped: Does this mean > that a window that is not risen can get focus? [Note, this "window" is X jargon. Emacs would call this a frame.] AFAIK, it's possible to give the focus to a window without raising it. I guess though, that the window must be mapped (displayed). > Note in this context > that `select-frame-set-input-focus' always raises the frame. Looks unnecessary. 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.] >> Y N KWin follow-mouse >> Y N KWin click-to-focus >> Y M FluxBox follow-mouse (Sloppy Focus) >> Y M FluxBox follow-mouse (Auto Raise) > > For the M cases `raise-frame' could move the mouse pointer to that frame > which seems to call for yet another option. > >> Y N FluxBox click-to-focus >> Y Y IceWM click-to-focus > > So IceWM is the only window manager to handle situation B. IIUC it does > so because do_switch-frame manages to get Fredirect_frame_focus through > to redirect input to that frame. Or do you have another explanation? It could be, that IceWM gives focus to the other frame because Emacs called raise-frame (in window--display-buffer-1). I'm just speculating, though. I don't know what Fredirect_frame_focus is used for; but it looks like something exotic. > Could you try to GDB do_switch_frame for IceWM and one of the others to > see they do differently? I didn't know what to look for. Below I attach two event traces for emacs -Q --eval '(progn (let ((pop-up-frames t)) (select-frame-set-input-focus (window-frame (display-buffer (get-buffer-create "foo"))))) (let ((display-buffer-reuse-frames t)) (pop-to-buffer "foo")) (sleep-for 1) (kill-emacs))' 2> wm-log One for Sawfish (with focus-window-when-mapped) and one for IceWM. I traced the events in xterm.c:handle_one_xevent and calls to x_raise_frame. Maybe you can make some sense out of it. >> Y N Twm follow-mouse (new frames need mouse click for placement) >> >> A and B are the scenarios described above. >> Y means: Yes, does switch focus. >> N means: No, doesn't switch focus. >> ? means: sometimes (probably depending on mouse and window positions) >> M means: No, doesn't switch focus, except when raising the frame >> also moves the mouse pointer into the frame. >> >> I set Emacs' focus-follows-mouse according to the WM focus mode (except >> when I forgot it :-) >> >> The Ys for Sawfish are apparently directly related to the >> focus-window-when-mapped option. So, it's probably not Emacs that >> switches the focus in the A scenario, but the window managers. > > Can we conclucde that the other window managers implicitly focus a frame > when mapping it? The probability is at least not zero :-) I guess though, that if the input-hint flag is true, the WM may switch focus to whatever and whenever it thinks is appropriate (see Metacity). >> The docstring for select-window could perhaps >> also state a bit more prominently that the "selected window" and the >> "input focus" are different things > > ... if the implementation is bogus this will hardly help ... > >> or at least refer to >> select-frame-set-input-focus. > > That function lumps together too many things. At least `raise-frame' > should probably be optional there. > >> BTW, below is a proof of concept implementation for the >> update-focus-lazily idea. > > Would this work with `redirect-frame-focus'? I haven't studied it in > detail. I don't know. It's hard for me to guess for what or when redirect-frame-focus is used, just by staring at the code. Helmut. Lines like the following in the logs means: xevent: FocusOut serial: 2176 send: 0 win: c00184 mode: NotifyNormal detail: NotifyNonlinear FocusOut is the event type serial: is the number of last request processed by server send: true if this came from a SendEvent request (i.e. by WM) win: the window id of the event target and "x_raise_frame: win: c00183 ... done." is a call to x_raise_frame with argument c00183. [-- Attachment #2: Sawfish log --] [-- Type: text/plain, Size: 3018 bytes --] xevent: ConfigureNotify serial: 1157 send: 0 win: c0009a xevent: MapNotify serial: 1161 send: 0 win: c0009a xevent: ConfigureNotify serial: 1168 send: 0 win: c00011 xevent: ConfigureNotify serial: 1168 send: 0 win: c00011 xevent: ReparentNotify serial: 1168 send: 0 win: c00011 xevent: ConfigureNotify serial: 1168 send: 0 win: c00011 xevent: ConfigureNotify serial: 1168 send: 1 win: c00011 xevent: ConfigureNotify serial: 1168 send: 1 win: c00011 xevent: MapNotify serial: 1168 send: 0 win: c00011 xevent: VisibilityNotify serial: 1168 send: 0 win: c0009a xevent: Expose serial: 1168 send: 0 win: c0009a xevent: EnterNotify serial: 1168 send: 0 win: c00011 xevent: EnterNotify serial: 1168 send: 0 win: c0009a xevent: ConfigureNotify serial: 1168 send: 1 win: c00011 xevent: ClientMessage serial: 1168 send: 1 win: c00011 TAKE_FOCUS timestamp: f47403ea xevent: FocusIn serial: 1168 send: 0 win: c00011 mode: NotifyNormal detail: NotifyNonlinear xevent: FocusIn serial: 1168 send: 0 win: c0009a mode: NotifyNormal detail: NotifyPointer xevent: FocusOut serial: 1246 send: 0 win: c0009a mode: NotifyNormal detail: NotifyPointer xevent: FocusOut serial: 1246 send: 0 win: c00011 mode: NotifyNormal detail: NotifyInferior xevent: FocusIn serial: 1246 send: 0 win: c00012 mode: NotifyNormal detail: NotifyAncestor xevent: ConfigureNotify serial: 2031 send: 0 win: c00186 xevent: MapNotify serial: 2035 send: 0 win: c00186 xevent: ConfigureNotify serial: 2042 send: 0 win: c00183 xevent: ConfigureNotify serial: 2042 send: 0 win: c00183 xevent: ReparentNotify serial: 2042 send: 0 win: c00183 xevent: ConfigureNotify serial: 2042 send: 0 win: c00183 xevent: ConfigureNotify serial: 2042 send: 1 win: c00183 xevent: ConfigureNotify serial: 2042 send: 1 win: c00183 xevent: MapNotify serial: 2042 send: 0 win: c00183 xevent: VisibilityNotify serial: 2042 send: 0 win: c00186 xevent: Expose serial: 2042 send: 0 win: c00186 xevent: ConfigureNotify serial: 2042 send: 1 win: c00183 xevent: ClientMessage serial: 2042 send: 1 win: c00183 TAKE_FOCUS timestamp: f4740496 xevent: FocusOut serial: 2042 send: 0 win: c00012 mode: NotifyNormal detail: NotifyNonlinear xevent: FocusOut serial: 2042 send: 0 win: c00011 mode: NotifyNormal detail: NotifyNonlinearVirtual xevent: FocusIn serial: 2042 send: 0 win: c00183 mode: NotifyNormal detail: NotifyNonlinear xevent: FocusOut serial: 2119 send: 0 win: c00183 mode: NotifyNormal detail: NotifyInferior xevent: FocusIn serial: 2119 send: 0 win: c00184 mode: NotifyNormal detail: NotifyAncestor x_raise_frame: win: c00183 ... done. x_raise_frame: win: c00183 ... done. xevent: ConfigureNotify serial: 2174 send: 1 win: c00183 xevent: ConfigureNotify serial: 2174 send: 1 win: c00183 xevent: FocusOut serial: 2176 send: 0 win: c00184 mode: NotifyNormal detail: NotifyNonlinear xevent: FocusIn serial: 2176 send: 0 win: c00186 mode: NotifyNormal detail: NotifyNonlinear xevent: ClientMessage serial: 2190 send: 1 win: c00183 TAKE_FOCUS timestamp: f47404b5 [-- Attachment #3: IceWM log --] [-- Type: text/plain, Size: 3621 bytes --] xevent: ConfigureNotify serial: 1788 send: 0 win: 6000f0 xevent: MapNotify serial: 1792 send: 0 win: 6000f0 xevent: ConfigureNotify serial: 1800 send: 0 win: 600011 xevent: ReparentNotify serial: 1800 send: 0 win: 600011 xevent: ConfigureNotify serial: 1800 send: 1 win: 600011 xevent: MapNotify serial: 1800 send: 0 win: 600011 xevent: VisibilityNotify serial: 1800 send: 0 win: 6000f0 xevent: Expose serial: 1800 send: 0 win: 6000f0 xevent: EnterNotify serial: 1800 send: 0 win: 600011 xevent: EnterNotify serial: 1800 send: 0 win: 6000f0 xevent: FocusIn serial: 1800 send: 0 win: 600011 mode: NotifyNormal detail: NotifyNonlinear xevent: FocusIn serial: 1800 send: 0 win: 6000f0 mode: NotifyNormal detail: NotifyPointer xevent: ClientMessage serial: 1800 send: 1 win: 600011 TAKE_FOCUS timestamp: 2bbbe xevent: ClientMessage serial: 1800 send: 1 win: 600011 TAKE_FOCUS timestamp: 2bbbe xevent: ConfigureNotify serial: 1800 send: 1 win: 600011 xevent: ClientMessage serial: 1800 send: 1 win: 600011 TAKE_FOCUS timestamp: 2bbbe xevent: FocusOut serial: 1851 send: 0 win: 6000f0 mode: NotifyNormal detail: NotifyPointer xevent: FocusOut serial: 1851 send: 0 win: 600011 mode: NotifyNormal detail: NotifyInferior xevent: FocusIn serial: 1851 send: 0 win: 600012 mode: NotifyNormal detail: NotifyAncestor xevent: ConfigureNotify serial: 3079 send: 0 win: 600290 xevent: MapNotify serial: 3083 send: 0 win: 600290 xevent: ConfigureNotify serial: 3091 send: 0 win: 60028d xevent: ReparentNotify serial: 3091 send: 0 win: 60028d xevent: ConfigureNotify serial: 3091 send: 1 win: 60028d xevent: MapNotify serial: 3091 send: 0 win: 60028d xevent: VisibilityNotify serial: 3091 send: 0 win: 600290 xevent: VisibilityNotify serial: 3091 send: 0 win: 6000f0 xevent: Expose serial: 3091 send: 0 win: 600290 xevent: LeaveNotify serial: 3091 send: 0 win: 6000f0 xevent: LeaveNotify serial: 3091 send: 0 win: 600011 xevent: FocusOut serial: 3091 send: 0 win: 600012 mode: NotifyNormal detail: NotifyNonlinear xevent: FocusOut serial: 3091 send: 0 win: 600011 mode: NotifyNormal detail: NotifyNonlinearVirtual xevent: FocusIn serial: 3091 send: 0 win: 60028d mode: NotifyNormal detail: NotifyNonlinear xevent: ClientMessage serial: 3091 send: 1 win: 60028d TAKE_FOCUS timestamp: 2ffeb xevent: ClientMessage serial: 3091 send: 1 win: 60028d TAKE_FOCUS timestamp: 2ffeb xevent: ConfigureNotify serial: 3091 send: 1 win: 60028d xevent: ClientMessage serial: 3091 send: 1 win: 60028d TAKE_FOCUS timestamp: 2ffeb xevent: FocusOut serial: 3145 send: 0 win: 60028d mode: NotifyNormal detail: NotifyInferior xevent: FocusIn serial: 3145 send: 0 win: 60028e mode: NotifyNormal detail: NotifyAncestor x_raise_frame: win: 60028d ... done. x_raise_frame: win: 60028d ... done. xevent: FocusOut serial: 3220 send: 0 win: 60028e mode: NotifyNormal detail: NotifyAncestor xevent: FocusIn serial: 3220 send: 0 win: 60028d mode: NotifyNormal detail: NotifyInferior xevent: ClientMessage serial: 3220 send: 1 win: 60028d TAKE_FOCUS timestamp: 30059 xevent: ConfigureNotify serial: 3220 send: 1 win: 60028d xevent: ClientMessage serial: 3220 send: 1 win: 60028d TAKE_FOCUS timestamp: 30059 xevent: ConfigureNotify serial: 3220 send: 1 win: 60028d xevent: FocusOut serial: 3221 send: 0 win: 60028d mode: NotifyNormal detail: NotifyInferior xevent: FocusIn serial: 3221 send: 0 win: 600290 mode: NotifyNormal detail: NotifyAncestor xevent: ClientMessage serial: 3236 send: 1 win: 60028d TAKE_FOCUS timestamp: 30062 xevent: EnterNotify serial: 3283 send: 0 win: 60028d xevent: EnterNotify serial: 3283 send: 0 win: 600290 ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-24 13:14 ` Helmut Eller @ 2008-08-25 13:45 ` martin rudalics 2008-08-26 21:45 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-25 13:45 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 > I've read a little bit in the Xlib Manual[*] and here is what I learned: I've tried to read that but for the time being I simply believe what you say here. > If we set the focus to the old frame by calling > select-frame-set-input-focus in display-buffer we have something like a > race condition. The window manager may decide at the same time that the > new frame should have the focus and either Emacs or the WM will win the > race. > > Emacs sets the "input-hint" flag in WM_HINTS when creating new frames. > This can be seen with: > > shell$ xprop WM_HINTS > WM_HINTS(WM_HINTS): > Client accepts input or input focus: True > Initial state is Normal State. > bitmap id # to use for icon: 0xa00710 > bitmap id # of mask for icon: 0xa00712 > window id # of group leader: 0xa00001 > > If the input-hint flag is set, some window managers will assume that > Emacs doesn't switch the input focus by itself and so the WM does it. > > In theory, Emacs could clear the input-hint flag (to stop the WM from > switching focus) and instead listen to WM_TAKE_FOCUS events. The window > manager sends WM_TAKE_FOCUS to Emacs, when the WM thinks that Emacs > should now be focused. Emacs can then decide to set (or not) the focus > to the appropriate frame. > > I don't know how well that would work in practice or if all window > managers follow the conventions. But if the input-hint flag is set, > Emacs has to fight with the window manager. OTOH, some people will > prefer that the WM does all the focus switching. I guess it's not worth > fixing situation A. People with decent window managers will be able to > configure their preferred focus behavior anyway. 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. >>> (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. IIUC we currently rely on the window-manager to raise and focus 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? Note that `x-focus-frame' uses XSetInputFocus together with x_ewmh_activate_frame. This mixture seems slightly frightening. >> 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. > 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? > I didn't know what to look for. Below I attach two event traces for [...] > One for Sawfish (with focus-window-when-mapped) and one for IceWM. I > traced the events in xterm.c:handle_one_xevent and calls to > x_raise_frame. Maybe you can make some sense out of it. So far I can't :-( 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) (defvar display-buffer-made-new-frame nil "When non-nil `display-buffer' created a new frame.") (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)))) display-buffer-made-new-frame) (set-buffer buffer) (select-window (display-buffer buffer other-window) norecord) (when (and pop-up-frame-activate (or (not display-buffer-made-new-frame) (eq pop-up-frame-activate t))) (select-frame-set-input-focus (window-frame (selected-window)))) buffer)) ;;; In `display-buffer' replace the lines ((or pop-up-frames (not frame-to-use)) ;; We want or need a new frame. (window--display-buffer-2 buffer (frame-selected-window (funcall pop-up-frame-function)))) ;;; by the lines ((or pop-up-frames (not frame-to-use)) ;; We want or need a new frame. (window--display-buffer-2 buffer (frame-selected-window (funcall pop-up-frame-function))) (setq display-buffer-made-new-frame t)) ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-25 13:45 ` martin rudalics @ 2008-08-26 21:45 ` Helmut Eller 2008-08-27 8:12 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-26 21:45 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * 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. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-26 21:45 ` Helmut Eller @ 2008-08-27 8:12 ` martin rudalics 2008-08-27 12:54 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-27 8:12 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 >> 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. [...] > 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. Yes. Nevertheless, the idea that we "anticipate" the window manager to do all these things is valid I presume - even it we don't "know" whether the frame is visible in the first place. >> 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 we do both just because up to Emacs 22 we used XSetInputFocus exclusively and maybe some window managers won't handle EWMHs yet (or won't handle them in the sense of Emacs). Should we, in your opinion make this customizable? That is, an option `frame-activate-method' which if nil does both (as now), if 'explicit does XSetInputFocus only, and if 'implicit does x_ewmh_activate_frame only?. > 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 .... without waiting for a FocusIn event? > 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. IIRC window managers relying on EWMHs do not like explicit focus and raise frame requests. They might do something with such requests but this something could be quite unpredictable. I also STR that people reported some flickering with two subsequent raise or focus requests. Hence, once again: Should we try - with the help of an option - do this either the old-style way without calling window-manager hints or do it new-style with such hints and possibly waiting for a FocusIn event? >> 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". ... rather "better safe than sorry". >> 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. Ahhh no, this time I meant the Emacs option `focus-follows-mouse'. `select-frame-set-input-focus' moves the mouse iff that is non-nil. >> (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". The "System Dependent" choice is necessary to let the current (maybe faulty for some or many of us) behavior carry over for those who like it as it is. The question is whether we want to distinguish the other two. > I propose this change instead: [...] > (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)) I suppose you mean (select-frame-set-input-focus (selected-frame)))) here. This has the drawback that we unconditionally do `select-frame-set-input-focus' for new frames. If we decide that this won't harm ... My experience is that once in a while some window manager won't get along with whatever we decide here. Hence I'd like to put in one or two options so users can try an alternative without immediately affecting the behavior of this on other systems. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-27 8:12 ` martin rudalics @ 2008-08-27 12:54 ` Helmut Eller 2008-08-28 11:46 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-27 12:54 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-27 10:12+0200] writes: >> 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 we do both just because up to Emacs 22 we used XSetInputFocus > exclusively and maybe some window managers won't handle EWMHs yet (or > won't handle them in the sense of Emacs). Should we, in your opinion > make this customizable? That is, an option `frame-activate-method' > which if nil does both (as now), if 'explicit does XSetInputFocus only, > and if 'implicit does x_ewmh_activate_frame only?. A way to call one of XSetInputFocus or x_ewmh_activate_frame without calling the other would be useful for experimentation. But I think that few people will use/need that. So, no, it shouldn't be customizable. It think it would be nice (but not worth to implement) if Emacs could be customized with two "focus models": 1. Let the window manager do all the focus handling. This is similar to what Emacs does currently. In this model Emacs should use x_ewmh_activate_frame without XSetInputFocus [I think that this would avoid some race conditions]. pop-to-buffer could still "activate" the frame, but it would be merely a hint and no guarantee. Creating frames which aren't focused initially is probably hard(er) in this model. 2. Emacs does its own focus management. In this model, Emacs should clear the input flag in WM_HINTS, handle WM_TAKE_FOCUS events, and explicitly call XSetInputFocus. A reasonable window manager will handle FocusIn events to decorate the focused frame appropriately. Since the input flag is cleared, the WM shouldn't focus new frames. [This model may be incompatible with toolkits, like GTK.] >> 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 > > .... without waiting for a FocusIn event? Yes, without waiting. If we call (select-frame-set-input-focus (window-frame (display-buffer ...))) we don't wait for FocusIn. >> 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. > > IIRC window managers relying on EWMHs do not like explicit focus and > raise frame requests. They might do something with such requests but > this something could be quite unpredictable. I also STR that people > reported some flickering with two subsequent raise or focus requests. > Hence, once again: Should we try - with the help of an option - do this > either the old-style way without calling window-manager hints or do it > new-style with such hints and possibly waiting for a FocusIn event? Since we don't have a window manager which causes trouble, we can't even test whether the change makes any difference. Let's wait until somebody reports actual problems :-) >>> 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. > > Ahhh no, this time I meant the Emacs option `focus-follows-mouse'. > `select-frame-set-input-focus' moves the mouse iff that is non-nil. I read to fast :-) No with focus-follows-mouse=nil the mouse pointer doesn't move but the other frame receives the input focus. >>> (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". > > The "System Dependent" choice is necessary to let the current (maybe > faulty for some or many of us) behavior carry over for those who like it > as it is. The question is whether we want to distinguish the other two. I think that, if "System Dependent" stays the default, then few people will profit from the other choices, simply because few people take the time to customize it. Despite that, I think that very few people prefer the current behavior. >> I propose this change instead: > [...] >> (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)) > > I suppose you mean > > (select-frame-set-input-focus (selected-frame)))) > > here. Yes, you are right. > This has the drawback that we unconditionally do > `select-frame-set-input-focus' for new frames. If we decide that this > won't harm ... Most of the time it will work flawlessly on new frames. What's the worst that could happen? Some flickering. I think that we can live with that imperfection. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-27 12:54 ` Helmut Eller @ 2008-08-28 11:46 ` martin rudalics 2008-08-28 16:47 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-28 11:46 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 > A way to call one of XSetInputFocus or x_ewmh_activate_frame without > calling the other would be useful for experimentation. But I think that > few people will use/need that. So, no, it shouldn't be customizable. I'm afraid that we fix this just for the platforms we use. If someone reports a breakage of this on another platform before the release we might be able to fix it there as well. Otherwise this will go the way of most "fixes" in this department. > It think it would be nice (but not worth to implement) if Emacs could be > customized with two "focus models": > > 1. Let the window manager do all the focus handling. This is similar > to what Emacs does currently. In this model Emacs should use > x_ewmh_activate_frame without XSetInputFocus [I think that this would > avoid some race conditions]. pop-to-buffer could > still "activate" the frame, but it would be merely a hint and no > guarantee. Creating frames which aren't focused initially is > probably hard(er) in this model. We agreed that the latter isn't realistic anyway. > 2. Emacs does its own focus management. In this model, Emacs should > clear the input flag in WM_HINTS, handle WM_TAKE_FOCUS events, and > explicitly call XSetInputFocus. A reasonable window manager will > handle FocusIn events to decorate the focused frame appropriately. > Since the input flag is cleared, the WM shouldn't focus new frames. > [This model may be incompatible with toolkits, like GTK.] And why do you think this not worth implementing? > Yes, without waiting. If we call > > (select-frame-set-input-focus (window-frame (display-buffer ...))) > > we don't wait for FocusIn. Is there a place where Emacs _should_ wait for a FocusIn? > Since we don't have a window manager which causes trouble, we can't even > test whether the change makes any difference. Let's wait until somebody > reports actual problems :-) You've read some of the earlier threads - and there's a lot more of these (some of them related to frame resizing). We do have to anticipate such problems now: People usually don't go through the troubles testing this with any window-manager but their own. > I think that, if "System Dependent" stays the default, then few people > will profit from the other choices, simply because few people take the > time to customize it. But if they complain we can give them an option to test. > Despite that, I think that very few people prefer > the current behavior. It's not a question of preference. It might simply work for them. So let's not cause unwanted breakage. >> This has the drawback that we unconditionally do >> `select-frame-set-input-focus' for new frames. If we decide that this >> won't harm ... > > Most of the time it will work flawlessly on new frames. What's the > worst that could happen? Some flickering. I think that we can live > with that imperfection. Maybe there's more than just some imperfection. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-28 11:46 ` martin rudalics @ 2008-08-28 16:47 ` Helmut Eller 2008-08-28 21:26 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-28 16:47 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-28 13:46+0200] writes: >> 2. Emacs does its own focus management. In this model, Emacs should >> clear the input flag in WM_HINTS, handle WM_TAKE_FOCUS events, and >> explicitly call XSetInputFocus. A reasonable window manager will >> handle FocusIn events to decorate the focused frame appropriately. >> Since the input flag is cleared, the WM shouldn't focus new frames. >> [This model may be incompatible with toolkits, like GTK.] > > And why do you think this not worth implementing? This takes more than a few hours of hacking. At least a few days, more likely a few weeks. That's to much time for such a minor nicety. Improving select-window so that it request input focus (somewhat efficiently) would be more worthwhile. >> Yes, without waiting. If we call >> >> (select-frame-set-input-focus (window-frame (display-buffer ...))) >> >> we don't wait for FocusIn. > > Is there a place where Emacs _should_ wait for a FocusIn? No. select-frame-set-input-focus seems to be the only focus related function (despite x-focus-frame which is presumably internal). If we interpret select-frame-set-input-focus as "request input focus" and not as "request input focus and wait until we know that we actually have the focus" then we don't need to wait. IMO, the former interpretation is consistent with the usual assumption that Emacs updates the display "later" or at least not in lock step with Lisp code. >> Since we don't have a window manager which causes trouble, we can't even >> test whether the change makes any difference. Let's wait until somebody >> reports actual problems :-) > > You've read some of the earlier threads - and there's a lot more of > these (some of them related to frame resizing). We do have to > anticipate such problems now: People usually don't go through the > troubles testing this with any window-manager but their own. I know about the following problems: 1. pop-to-buffer doesn't switch input focus 2. select-window doesn't switch input focus 3. x-create-frame does switch input focus (with most WMs) Is there something else? We agreed that we wont fix 3. 1 would be fixed by calling select-frame-set-input-focus in pop-to-buffer (either customizable or not). Do we need to test something? Fixing 2 isn't so clear. This was shortly discussed on the mailing list but RMS said, at that time, that more important things should be done. >> I think that, if "System Dependent" stays the default, then few >> people will profit from the other choices, simply because few people >> take the time to customize it. > > But if they complain we can give them an option to test. It would be reasonable to minimize the number of people who need to change the defaults. >> Despite that, I think that very few people prefer the current >> behavior. > > It's not a question of preference. It might simply work for them. So > let's not cause unwanted breakage. Some people, like me, who do actually care, also like to keep the code readable, simple, and predictable. New customization options cost a lot in terms of readability. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-28 16:47 ` Helmut Eller @ 2008-08-28 21:26 ` martin rudalics 2008-08-29 7:39 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-28 21:26 UTC (permalink / raw) To: Helmut Eller; +Cc: 745, Chong Yidong, Stefan Monnier > I know about the following problems: > > 1. pop-to-buffer doesn't switch input focus > 2. select-window doesn't switch input focus > 3. x-create-frame does switch input focus (with most WMs) > > Is there something else? The XSetInputFocus vs x_ewmh_activate_frame dichotomy in `x-focus-frame'. > We agreed that we wont fix 3. Yes. > 1 would be fixed by calling select-frame-set-input-focus in > pop-to-buffer (either customizable or not). Do we need to test > something? Let's try without an option. Stefan, Chong, any objections? *** window.el.~1.146.~ 2008-08-23 09:41:38.156250000 +0200 --- window.el 2008-08-28 19:32:50.765625000 +0200 *************** *** 1061,1066 **** --- 1061,1067 ---- buf))))) (set-buffer buffer) (select-window (display-buffer buffer other-window) norecord) + (select-frame-set-input-focus (selected-frame)) buffer)) ;; I think this should be the default; I think people will prefer it--rms. > Fixing 2 isn't so clear. This was shortly discussed on the mailing list > but RMS said, at that time, that more important things should be done. You mean we could solve this with your update-focus-lazily approach? martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-28 21:26 ` martin rudalics @ 2008-08-29 7:39 ` Helmut Eller 2008-08-29 9:26 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-29 7:39 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-28 23:26+0200] writes: >> I know about the following problems: >> >> 1. pop-to-buffer doesn't switch input focus >> 2. select-window doesn't switch input focus >> 3. x-create-frame does switch input focus (with most WMs) >> >> Is there something else? > > The XSetInputFocus vs x_ewmh_activate_frame dichotomy in > `x-focus-frame'. Emacs could first test whether the window manager is EWMH compliant and depending on the outcome only call one of those functions. x_ewmh_activate_frame seems to test whether the WM supports "_NET_ACTIVE_WINDOW". I guess, we could just move that over to x-focus-frame. >> We agreed that we wont fix 3. > > Yes. Over night I had a little idea that could be useful. I'm just writing it down here so that it's not lost: We could avoid the focus-when-mapped problem, if we clear the input flag in WM_HINTS (the GTK equivalent seems to be gtk_window_set_accept_focus) when we create the frame. But when we receive the MapNotify event, we enable the flag. This should prevent the window manager from focusing the frame initially but afterwards it should be treated as usual. I also found the gtk_window_set_focus_on_map function. This seems to rely on the _NET_WM_USER_TIME EWMH. Sawfish ignores _NET_WM_USER_TIME, but it could be useful for other window managers. >> Fixing 2 isn't so clear. This was shortly discussed on the mailing list >> but RMS said, at that time, that more important things should be done. > > You mean we could solve this with your update-focus-lazily approach? I think it's feasible, yes. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-29 7:39 ` Helmut Eller @ 2008-08-29 9:26 ` martin rudalics 2008-08-29 15:02 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-29 9:26 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 > Emacs could first test whether the window manager is EWMH compliant How? Emacs can't even test whether the window manager is click to focus or focus follows mouse. > and > depending on the outcome only call one of those functions. > x_ewmh_activate_frame seems to test whether the WM supports > "_NET_ACTIVE_WINDOW". I guess, we could just move that over to > x-focus-frame. > >>> We agreed that we wont fix 3. >> Yes. > > Over night I had a little idea that could be useful. I'm just writing > it down here so that it's not lost: We could avoid the focus-when-mapped > problem, if we clear the input flag in WM_HINTS (the GTK equivalent > seems to be gtk_window_set_accept_focus) when we create the frame. Again this would work iff we knew that the window manager is EWMH compliant. > But > when we receive the MapNotify event, we enable the flag. This should > prevent the window manager from focusing the frame initially but > afterwards it should be treated as usual. > > I also found the gtk_window_set_focus_on_map function. This seems to > rely on the _NET_WM_USER_TIME EWMH. Sawfish ignores _NET_WM_USER_TIME, > but it could be useful for other window managers. And this would have to be supplied by the user separately. Or is there some way to get such basic information from window-managers? martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-29 9:26 ` martin rudalics @ 2008-08-29 15:02 ` Helmut Eller 2008-08-30 8:15 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-29 15:02 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-29 11:26+0200] writes: >> Emacs could first test whether the window manager is EWMH compliant > > How? Emacs can't even test whether the window manager is click to focus > or focus follows mouse. xterm.c:wm_supports implements the test already. By inspecting the _NET_SUPPORTED property on the root window. A compliant window manager must enumerate the supported features there. See http://standards.freedesktop.org/wm-spec/1.4/ar01s03.html#id2523263. E.g. for Sawfish I get shell$ xprop _NET_SUPPORTED _NET_SUPPORTED(ATOM) = _NET_ACTIVE_WINDOW, _NET_CLIENT_LIST, _NET_CLIENT_LIST_STACKING, _NET_CLOSE_WINDOW, _NET_CURRENT_DESKTOP, _NET_DESKTOP_GEOMETRY, _NET_DESKTOP_NAMES, _NET_DESKTOP_VIEWPORT, _NET_NUMBER_OF_DESKTOPS, _NET_PROTOCOLS, _NET_SHOWING_DESKTOP, _NET_SUPPORTED, _NET_SUPPORTING_WM_CHECK, _NET_WORKAREA, _NET_WM_DESKTOP, _NET_WM_ICON_GEOMETRY, _NET_WM_MOVERESIZE, _NET_WM_MOVERESIZE_MOVE, _NET_WM_MOVERESIZE_SIZE_BOTTOM, _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_LEFT, _NET_WM_MOVERESIZE_SIZE_RIGHT, _NET_WM_MOVERESIZE_SIZE_TOP, _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_KEYBOARD, _NET_WM_MOVERESIZE_MOVE_KEYBOARD, _NET_WM_PING, _NET_WM_STATE, _NET_WM_STATE_ABOVE, _NET_WM_STATE_ADD, _NET_WM_STATE_BELOW, _NET_WM_STATE_FULLSCREEN, _NET_WM_STATE_MAXIMIZED, _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_REMOVE, _NET_WM_STATE_SHADED, _NET_WM_STATE_SKIP_PAGER, _NET_WM_STATE_SKIP_TASKBAR, _NET_WM_STATE_STICKY, _NET_WM_STATE_TOGGLE, _NET_WM_STRUT, _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DESKTOP, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_WINDOW_TYPE_DOCK, _NET_WM_WINDOW_TYPE_TOOLBAR, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_UTILITY, _NET_WM_WINDOW_TYPE_SPLASH >> I also found the gtk_window_set_focus_on_map function. This seems to >> rely on the _NET_WM_USER_TIME EWMH. Sawfish ignores _NET_WM_USER_TIME, >> but it could be useful for other window managers. > > And this would have to be supplied by the user separately. Or is there > some way to get such basic information from window-managers? For a window manager which supports it, _NET_SUPPORTED will contain _NET_WM_USER_TIME. But it wouldn't hurt to set _NET_WM_USER_TIME to 0, because that should be interpreted as "disable focus-on-map". At least gtk_window_set_focus_on_map sets the property unconditionally. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-29 15:02 ` Helmut Eller @ 2008-08-30 8:15 ` martin rudalics 2008-08-30 11:06 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-30 8:15 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 >>> I also found the gtk_window_set_focus_on_map function. This seems to >>> rely on the _NET_WM_USER_TIME EWMH. Sawfish ignores _NET_WM_USER_TIME, >>> but it could be useful for other window managers. How do you find out that Sawfish ignores that? > For a window manager which supports it, _NET_SUPPORTED will contain > _NET_WM_USER_TIME. But it wouldn't hurt to set _NET_WM_USER_TIME to 0, > because that should be interpreted as "disable focus-on-map". At least > gtk_window_set_focus_on_map sets the property unconditionally. Do you have one window-manager setting where you can get Emacs (1) do a `display-buffer' making a new frame without that frame getting raised and/or input focus, and (2) give input focus to/raise a frame that hasn't input focus/is not raised. entirely using _NET_WM_USER_TIME? I faintly recall a discussion about a misinterpretation of timestamps sent to the window-manager (Metacity?) by Emacs. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-30 8:15 ` martin rudalics @ 2008-08-30 11:06 ` Helmut Eller 2008-08-30 13:42 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-30 11:06 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-30 10:15+0200] writes: >>>> I also found the gtk_window_set_focus_on_map function. This seems to >>>> rely on the _NET_WM_USER_TIME EWMH. Sawfish ignores _NET_WM_USER_TIME, >>>> but it could be useful for other window managers. > > How do you find out that Sawfish ignores that? a) by looking at the _NET_SUPPORTS property on the root window. I posted the content of that in my last email. It doesn't contain _NET_WM_USER_TIME. b) by grepping through Sawfish's source code. >> For a window manager which supports it, _NET_SUPPORTED will contain >> _NET_WM_USER_TIME. But it wouldn't hurt to set _NET_WM_USER_TIME to 0, >> because that should be interpreted as "disable focus-on-map". At least >> gtk_window_set_focus_on_map sets the property unconditionally. > > Do you have one window-manager setting where you can get Emacs > > (1) do a `display-buffer' making a new frame without that frame getting > raised and/or input focus, and If I call gtk_window_set_focus_on_map (GTK_WINDOW (wtop), FALSE) in gtkutil.c:xg_create_frame_widgets, then Metacity dosn't give the focus to new frames. The initial Emacs frame is also not focused. gtk_window_set_focus_on_map sets _NET_WM_USER_TIME to 0. I know that because I read the GTK source. It can be verified by calling xprop on the resulting Emacs frame. > (2) give input focus to/raise a frame that hasn't input focus/is not > raised. > > entirely using _NET_WM_USER_TIME? I don't know how to that with _NET_WM_USER_TIME. But the EWMH-spec says this: _NET_ACTIVE_WINDOW, WINDOW/32 The window ID of the currently active window or None if no window has the focus. This is a read-only property set by the Window Manager. If a Client wants to activate another window, it MUST send a _NET_ACTIVE_WINDOW client message to the root window: _NET_ACTIVE_WINDOW window = window to activate message_type = _NET_ACTIVE_WINDOW format = 32 data.l[0] = source indication data.l[1] = timestamp data.l[2] = requestor's currently active window, 0 if none other data.l[] elements = 0 Source indication should be 1 when the request comes from an application, and 2 when it comes from a pager. Clients using older version of this spec use 0 as source indication, see the section called "Source indication in request" for details. The timestamp is Client's last user activity timestamp (see _NET_WM_USER_TIME) at the time of the request, and the currently active window is the Client's active toplevel window, if any (the Window Manager may be e.g. more likely to obey the request if it will mean transferring focus from one active window to another). Depending on the information provided with the message, the Window Manager may decide to refuse the request (either completely ignore it, or e.g. use _NET_WM_STATE_DEMANDS_ATTENTION). The current implementation of x_ewmh_activate_frame seems to work fine. > I faintly recall a discussion about a > misinterpretation of timestamps sent to the window-manager (Metacity?) > by Emacs. I've seen Metacity spit out warnings along the lines that XSetInputFocus was called with a wrong timestamp. But I can't reproduce that right now. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-30 11:06 ` Helmut Eller @ 2008-08-30 13:42 ` martin rudalics 2008-08-31 8:55 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-08-30 13:42 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 >> (1) do a `display-buffer' making a new frame without that frame getting >> raised and/or input focus, and > > If I call gtk_window_set_focus_on_map (GTK_WINDOW (wtop), FALSE) in > gtkutil.c:xg_create_frame_widgets, then Metacity dosn't give the focus > to new frames. The initial Emacs frame is also not focused. > gtk_window_set_focus_on_map sets _NET_WM_USER_TIME to 0. I know that > because I read the GTK source. It can be verified by calling xprop on > the resulting Emacs frame. In this case we'd have to make `pop-to-buffer' give focus to the frame, look out for applications that ("wrongly") expect `display-buffer' to focus the frame, focus the initial frame, and decide what to do about `select-window/frame'. After the release we could implement this for all ewmh-compliant window-managers. >> (2) give input focus to/raise a frame that hasn't input focus/is not >> raised. >> >> entirely using _NET_WM_USER_TIME? > > I don't know how to that with _NET_WM_USER_TIME. For _NET_WM_USER_TIME I read This property allows a Window Manager to alter the focus, stacking, and/or placement behavior of windows when they are mapped depending on whether the new window was created by a user action or is a "pop-up" window activated by a timer or some other event. but I fail to understand what "new window" means here. > But the EWMH-spec says this: > > _NET_ACTIVE_WINDOW, WINDOW/32 > > The window ID of the currently active window or None if no window has > the focus. This is a read-only property set by the Window Manager. If > a Client wants to activate another window, it MUST send a > _NET_ACTIVE_WINDOW client message to the root window: > > _NET_ACTIVE_WINDOW > window = window to activate > message_type = _NET_ACTIVE_WINDOW > format = 32 > data.l[0] = source indication > data.l[1] = timestamp > data.l[2] = requestor's currently active window, 0 if none > other data.l[] elements = 0 > > Source indication should be 1 when the request comes from an > application, and 2 when it comes from a pager. Clients using older > version of this spec use 0 as source indication, see the section called > "Source indication in request" for details. The timestamp is Client's > last user activity timestamp (see _NET_WM_USER_TIME) at the time of the > request, and the currently active window is the Client's active toplevel > window, if any (the Window Manager may be e.g. more likely to obey the > request if it will mean transferring focus from one active window to > another). > > Depending on the information provided with the message, the Window > Manager may decide to refuse the request (either completely ignore it, > or e.g. use _NET_WM_STATE_DEMANDS_ATTENTION). > > The current implementation of x_ewmh_activate_frame seems to work fine. OK. >> I faintly recall a discussion about a >> misinterpretation of timestamps sent to the window-manager (Metacity?) >> by Emacs. > > I've seen Metacity spit out warnings along the lines that XSetInputFocus > was called with a wrong timestamp. But I can't reproduce that right now. Ahh, I recall that discussion. Yet another reason why XSetInputFocus should be avoided for ewmh-compliant window managers. We should avoid calling XSetInputFocus for these in the present release. So I think we can distinguish three types of window managers according to our needs and what _NET_SUPPORTS tells us: - _NET_WM_USER_TIME capable ones, where we can have `display-buffer' not set the input focus for new frames (and thus not implicitly select the new window thus contradicting the doc-string of `display-buffer'). I suppose Metacity falls into this group. - _NET_ACTIVE_WINDOW capable ones, where `display-buffer' will behave as now but x_ewmh_activate_frame works. Sawfish seems to belong here. - Non-ewmh-compliant ones where we have to use XSetInputFocus. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-30 13:42 ` martin rudalics @ 2008-08-31 8:55 ` Helmut Eller 2008-09-06 11:56 ` martin rudalics 0 siblings, 1 reply; 31+ messages in thread From: Helmut Eller @ 2008-08-31 8:55 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-08-30 15:42+0200] writes: >>> (1) do a `display-buffer' making a new frame without that frame getting >>> raised and/or input focus, and >> >> If I call gtk_window_set_focus_on_map (GTK_WINDOW (wtop), FALSE) in >> gtkutil.c:xg_create_frame_widgets, then Metacity dosn't give the focus >> to new frames. The initial Emacs frame is also not focused. >> gtk_window_set_focus_on_map sets _NET_WM_USER_TIME to 0. I know that >> because I read the GTK source. It can be verified by calling xprop on >> the resulting Emacs frame. > > In this case we'd have to make `pop-to-buffer' give focus to the frame, > look out for applications that ("wrongly") expect `display-buffer' to > focus the frame, focus the initial frame, and decide what to do about > `select-window/frame'. After the release we could implement this for > all ewmh-compliant window-managers. Sounds good. >>> (2) give input focus to/raise a frame that hasn't input focus/is not >>> raised. >>> >>> entirely using _NET_WM_USER_TIME? >> >> I don't know how to that with _NET_WM_USER_TIME. > > For _NET_WM_USER_TIME I read > > This property allows a Window Manager to alter the focus, stacking, > and/or placement behavior of windows when they are mapped depending > on whether the new window was created by a user action or is a > "pop-up" window activated by a timer or some other event. > > but I fail to understand what "new window" means here. Perhaps it means "newly mapped window". I guess some window manager could give the focus to a newly mapped window only if its timestamp is newer than the timestamp of the currently focused window. I would be surprised though, if some application would rely on this behavior :-) Continuously updating this timestamp, e.g. on every keypress, sounds rather excessive just to give the WM this possibility. >>> I faintly recall a discussion about a >>> misinterpretation of timestamps sent to the window-manager (Metacity?) >>> by Emacs. >> >> I've seen Metacity spit out warnings along the lines that XSetInputFocus >> was called with a wrong timestamp. But I can't reproduce that right now. > > Ahh, I recall that discussion. Yet another reason why XSetInputFocus > should be avoided for ewmh-compliant window managers. We should avoid > calling XSetInputFocus for these in the present release. > > So I think we can distinguish three types of window managers according > to our needs and what _NET_SUPPORTS tells us: > > - _NET_WM_USER_TIME capable ones, where we can have `display-buffer' not > set the input focus for new frames (and thus not implicitly select the > new window thus contradicting the doc-string of `display-buffer'). I > suppose Metacity falls into this group. > > - _NET_ACTIVE_WINDOW capable ones, where `display-buffer' will behave as > now but x_ewmh_activate_frame works. Sawfish seems to belong here. > > - Non-ewmh-compliant ones where we have to use XSetInputFocus. Yes, I think the same. Helmut. > LocalWords: timestamp keypress ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-08-31 8:55 ` Helmut Eller @ 2008-09-06 11:56 ` martin rudalics 2008-09-09 6:24 ` Helmut Eller 0 siblings, 1 reply; 31+ messages in thread From: martin rudalics @ 2008-09-06 11:56 UTC (permalink / raw) To: Helmut Eller; +Cc: 745 I'm currently using (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)))) (old-window (selected-window)) (old-frame (selected-frame)) new-window new-frame) (set-buffer buffer) (setq new-window (display-buffer buffer other-window) norecord) (unless (eq new-window old-window) ;; `display-buffer' has chosen another window. (setq new-frame (window-frame new-window)) (unless (eq new-frame old-frame) ;; `display-buffer' has chosen another frame, make sure it gets ;; input focus and is risen. (select-frame-set-input-focus new-frame)) ;; Make sure the window chosen by `display-buffer' gets selected. (select-window new-window)) buffer)) so `select-frame-set-input-focus' gets called iff `display-buffer' did choose another frame. I noticed that I cannot use `select-frame-set-input-focus' unconditionally for the following reason: On my Emacs `focus-follows-mouse' is t so the final check in `select-frame-set-input-focus' (when focus-follows-mouse (set-mouse-position (selected-frame) (1- (frame-width)) 0))) _always_ succeeds and sends my mouse cursor to the upper right corner of the corresponding frame. This is annoying whenever I click, for example, on a button in a help buffer to follow a link, causing the window returned by `display-buffer' show up on the already _selected_ frame. Since I additionally have `mouse-autoselect-window' non-nil, an unrelated window on top of the selected frame may get selected too. One annyoing aspect of the rigid use of `set-mouse-position' in `select-frame-set-input-focus' obviously remains, namely that with `mouse-autoselect-window' non-nil `other-frame' (and related functions) may change the selected window on the other frame :-( This has to be fixed independently. Please check whether `pop-to-buffer' as defined above fits your needs. If so, and no one else protests, I'll install this next week. martin ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: pop-to-buffer, frames, and input focus 2008-09-06 11:56 ` martin rudalics @ 2008-09-09 6:24 ` Helmut Eller 0 siblings, 0 replies; 31+ messages in thread From: Helmut Eller @ 2008-09-09 6:24 UTC (permalink / raw) To: martin rudalics; +Cc: 745 * martin rudalics [2008-09-06 13:56+0200] writes: > Please check whether `pop-to-buffer' as defined above fits your needs. Yes, this does what I need. Thanks you for fixing it. Helmut. ^ permalink raw reply [flat|nested] 31+ messages in thread
* bug#745: marked as done (pop-to-buffer, frames, and input focus) 2008-08-20 7:35 ` bug#745: pop-to-buffer, frames, and input focus Helmut Eller 2008-08-20 14:50 ` martin rudalics @ 2008-09-11 7:05 ` Emacs bug Tracking System 1 sibling, 0 replies; 31+ messages in thread From: Emacs bug Tracking System @ 2008-09-11 7:05 UTC (permalink / raw) To: martin rudalics [-- Attachment #1: Type: text/plain, Size: 839 bytes --] Your message dated Thu, 11 Sep 2008 08:52:54 +0200 with message-id <48C8C046.50203@gmx.at> and subject line Re: bug#745: pop-to-buffer, frames, and input focus has caused the Emacs bug report #745, regarding pop-to-buffer, frames, and input focus to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact don@donarmstrong.com immediately.) -- 745: http://emacsbugs.donarmstrong.com/cgi-bin/bugreport.cgi?bug=745 Emacs Bug Tracking System Contact don@donarmstrong.com with problems [-- Attachment #2: Type: message/rfc822, Size: 3647 bytes --] From: Helmut Eller <eller.helmut@gmail.com> To: bug-gnu-emacs@gnu.org Subject: pop-to-buffer, frames, and input focus Date: Wed, 20 Aug 2008 09:35:31 +0200 Message-ID: <m2tzdgdtq4.fsf@gmail.com> Hi, The behavior of pop-to-buffer in combination with multiple frames is rather unpredictable or at least not what I expected. For example: shell$ cat pop-to-buffer-test.el (let ((frame (selected-frame)) (pop-up-frames t)) (display-buffer (get-buffer-create "foo")) (select-frame-set-input-focus frame)) (let ((display-buffer-reuse-frames t)) (pop-to-buffer "foo")) shell$ emacs -Q -l pop-to-buffer-test.el Pops up two frames, one frame displays the "foo" buffer and the other the "*scratch*" buffer (so far so good). But the "foo" frame has not the input focus. Isn't pop-to-buffer supposed to switch input focus too? Also note that I had to save and restore the selected frame around display-buffer. If I try emacs -Q --eval '(let ((pop-up-frames t)) (display-buffer (get-buffer-create "foo")))' the "foo" buffer is selected, even though display-buffer should not switch the selected window. Not even save-window-excursion stops display-buffer from switching the frame: emacs -Q --eval '(save-window-excursion (let ((pop-up-frames t)) (display-buffer (get-buffer-create "foo"))))' This is with: GNU Emacs 23.0.60.4 (i686-pc-linux-gnu, GTK+ Version 2.8.20) of 2008-08-15 on xaital Windowing system distributor `The X.Org Foundation', version 11.0.70101000 configured using `configure '--without-sound' '--without-pop' '--without-gif' '--without-tiff'' My window manager is Sawfish 1.3. Helmut. [-- Attachment #3: Type: message/rfc822, Size: 2164 bytes --] From: martin rudalics <rudalics@gmx.at> To: 745-done@emacsbugs.donarmstrong.com Cc: Helmut Eller <eller.helmut@gmail.com> Subject: Re: bug#745: pop-to-buffer, frames, and input focus Date: Thu, 11 Sep 2008 08:52:54 +0200 Message-ID: <48C8C046.50203@gmx.at> Fixed as 2008-09-11 Martin Rudalics <rudalics@gmx.at> * window.el (pop-to-buffer): If the window for buffer-or-name is not on the selected frame, raise that window's frame and give it input focus. (Bug#745) ^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2008-09-11 7:05 UTC | newest] Thread overview: 31+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <48C8C046.50203@gmx.at> 2008-08-20 7:35 ` bug#745: pop-to-buffer, frames, and input focus Helmut Eller 2008-08-20 14:50 ` martin rudalics 2008-08-20 18:42 ` Helmut Eller 2008-08-20 20:42 ` David Reitter 2008-08-20 20:56 ` martin rudalics 2008-08-21 8:07 ` Helmut Eller 2008-08-21 9:04 ` martin rudalics 2008-08-21 13:20 ` Helmut Eller 2008-08-21 20:31 ` martin rudalics 2008-08-22 14:27 ` Helmut Eller 2008-08-22 16:39 ` martin rudalics 2008-08-23 8:55 ` Helmut Eller 2008-08-23 12:05 ` martin rudalics 2008-08-24 13:14 ` Helmut Eller 2008-08-25 13:45 ` martin rudalics 2008-08-26 21:45 ` Helmut Eller 2008-08-27 8:12 ` martin rudalics 2008-08-27 12:54 ` Helmut Eller 2008-08-28 11:46 ` martin rudalics 2008-08-28 16:47 ` Helmut Eller 2008-08-28 21:26 ` martin rudalics 2008-08-29 7:39 ` Helmut Eller 2008-08-29 9:26 ` martin rudalics 2008-08-29 15:02 ` Helmut Eller 2008-08-30 8:15 ` martin rudalics 2008-08-30 11:06 ` Helmut Eller 2008-08-30 13:42 ` martin rudalics 2008-08-31 8:55 ` Helmut Eller 2008-09-06 11:56 ` martin rudalics 2008-09-09 6:24 ` Helmut Eller 2008-09-11 7:05 ` bug#745: marked as done (pop-to-buffer, frames, and input focus) Emacs bug Tracking System
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).