unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Q on frame focus with MS Windows
@ 2005-10-25 20:33 Drew Adams
  2005-10-25 21:45 ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Drew Adams @ 2005-10-25 20:33 UTC (permalink / raw)


This is driving me crazy. I've tried a zillion ways to try to work around
this problem, to no avail.

On MS Windows, whenever a new frame is created, it becomes
"selected"/"focussed". I use quote-marks here, because I think it might be
more than what Emacs calls frame selection & focus. I admit that it's
unclear to me just what's going on.

Symptoms of the newly "selected"/"focussed" frame:

1) It has the focus, in the Emacs sense of editing operations applying to
it.
2) The frame border (title bar etc.) are highlighted by the window manager.
3) The frame is raised, so it is in front of all other frames.

It is #1 that gets in my way - I'm looking for a way to get around it.

I use a standalone minibuffer frame and (setq pop-up-frames t). I have
focus-follows-mouse = nil, but I've also tried t.

Here's the problem:

1. I want to be able to open a new frame from a command that is bound in a
minibuffer map such as minibuffer-local-completion-map. The command does not
exit the minibuffer.

2. I do not want the new frame to grab the input focus. I want to be able to
continue using the minibuffer for input.

I know that Windows uses click-to-focus, and it automatically focusses a new
frame. But I'm thinking there must be some way to override this to some
extent.

I've tried every hack I can think of, from saving and restoring the selected
buffer/window/frame, to redirecting and un-redirecting the frame focus, to
playing with before-make-frame-hook and after-make-frame-functions. I cannot
get the new frame to become un-"selected"/"focussed" and let me continue to
use the minibuffer for input.

My impression is that this is not necessarily related to buffer/window/frame
selection in the Emacs sense. I say this, because I've tried to explicitly
reselect the original buffer/window/frame, and that doesn't seem to do the
trick.

It is only creating a new frame that presents this problem. For example, if
the command bound in the minibuffer map just calls display-buffer (which
doesn't select the buffer), I get the same problem: If the buffer is already
displayed in a frame, no problem; if a new frame is created, the "focus"
goes to it - I must click the minibuffer frame to get the focus back.
Otherwise, hitting a key uses the keymap (e.g. global) of the newly created
frame, rather than the minibuffer keymap.

I apologize for a rambling, not-too-clear description. If you are on
Windows, please do this, to see what I mean:

1. Put this in a file foo.el, then start emacs with runemacs.exe -q -l
"foo.el"

(setq pop-up-frames          t
      default-frame-alist    '((minibuffer))
      minibuffer-frame-alist '((minibuffer . only)))

(define-key minibuffer-local-completion-map [down] 'foo)

(defun foo () (interactive)
   (display-buffer (get-buffer-create "foo")))

2. Run `foo' during minibuffer completion. For example, `M-x [down]'.

As soon as buffer foo is created in a new frame, the focus is taken away
from the minibuffer. You can no longer type minibuffer input or hit keys
that are bound in a minibuffer map - all input goes to buffer foo.

What I'm looking for is:

1. To understand this better. Just what is the nature/cause of the problem?

2. A way (workaround) to deal with this problem - something that will keep
the input focus in the minibuffer for as long as the minibuffer is active.
(So, for instance, if done by redirect-frame-focus, I would want that undone
after the minibuffer is inactivated.)

3. If this is a bug in some sense, which could be fixed in Emacs, that would
be great. However, I also need this to work in other versions of Emacs, so I
would still want the workaround (#2).

Any help is appreciated.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q on frame focus with MS Windows
  2005-10-25 20:33 Q on frame focus with MS Windows Drew Adams
@ 2005-10-25 21:45 ` Lennart Borgman
  2005-10-25 21:57   ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2005-10-25 21:45 UTC (permalink / raw)
  Cc: Emacs-Devel

Drew Adams wrote:

>What I'm looking for is:
>
>1. To understand this better. Just what is the nature/cause of the problem?
>
>2. A way (workaround) to deal with this problem - something that will keep
>the input focus in the minibuffer for as long as the minibuffer is active.
>(So, for instance, if done by redirect-frame-focus, I would want that undone
>after the minibuffer is inactivated.)
>
>3. If this is a bug in some sense, which could be fixed in Emacs, that would
>be great. However, I also need this to work in other versions of Emacs, so I
>would still want the workaround (#2).
>
>Any help is appreciated.
>  
>
I am not sure here, but I dived into the C code to see what might be 
happening. If I understand this correct (which I am not sure about at 
all) this happens:

1) A frame is created through a call to x-create-frame.
2) This calls x_make_frame_visible
3) There is a call to my_show_window with a parameter that is 
SW_SHOWNORMAL which I guess is later given to the w32 API ShowWindow or 
something similar.

The documentation for SW_SHOWNORMAL says

    SW_SHOWNORMAL
    Activates and displays a window. If the window is minimized or
    maximized, the system restores it to its original size and position.
    An application should specify this flag when displaying the window
    for the first time.

I am not sure about what "activates" mean here but I believe it was that 
it will get the keyboard input focus. And I wonder if the documentation 
is correct when it sounds that you have to use SW_SHOWNORMAL.

***************
A workaround is maybe to use `after-make-frame-functions'?

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Q on frame focus with MS Windows
  2005-10-25 21:45 ` Lennart Borgman
@ 2005-10-25 21:57   ` Drew Adams
  2005-10-25 22:21     ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Drew Adams @ 2005-10-25 21:57 UTC (permalink / raw)


    1) A frame is created through a call to x-create-frame.
    2) This calls x_make_frame_visible
    3) There is a call to my_show_window with a parameter that is
    SW_SHOWNORMAL which I guess is later given to the w32 API ShowWindow or
    something similar.

    The documentation for SW_SHOWNORMAL says
        Activates and displays a window. If the window is minimized or
        maximized, the system restores it to its original size and position.
        An application should specify this flag when displaying the window
        for the first time.

    I am not sure about what "activates" mean here but I believe it
    was that it will get the keyboard input focus. And I wonder if
    the documentation is correct when it sounds that you have to use
    SW_SHOWNORMAL.

My understanding is that it is the MS Windows window-manager that
automatically selects/focusses the new frame, and that that cannot be
prevented from within Emacs. If there is a way to inhibit this behavior,
that would be even better than getting the focus back after it has been
given to the new frame.

But I don't understand what you are suggesting I do - at all.

       A workaround is maybe to use `after-make-frame-functions'?

I already mentioned that I tried that. What do you suggest I put in that
hook, concretely? I tried reselecting the original buffer/window/frame and
the minibuffer, none of which seemed to work.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q on frame focus with MS Windows
  2005-10-25 21:57   ` Drew Adams
@ 2005-10-25 22:21     ` Lennart Borgman
  2005-10-25 23:43       ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2005-10-25 22:21 UTC (permalink / raw)
  Cc: Emacs-Devel

Drew Adams wrote:

>My understanding is that it is the MS Windows window-manager that
>automatically selects/focusses the new frame, and that that cannot be
>prevented from within Emacs. If there is a way to inhibit this behavior,
>that would be even better than getting the focus back after it has been
>given to the new frame.
>  
>
I believe that the new w32 window can be created without getting the 
focus, but I am not sure. And it is a rather complex change that must be 
made.

>But I don't understand what you are suggesting I do - at all.
>
>       A workaround is maybe to use `after-make-frame-functions'?
>
>I already mentioned that I tried that. What do you suggest I put in that
>hook, concretely? I tried reselecting the original buffer/window/frame and
>the minibuffer, none of which seemed to work.
>  
>
Something like this (but it is a bit ugly):

(setq pop-up-frames          t
      default-frame-alist    '((minibuffer))
      minibuffer-frame-alist '((minibuffer . only)))

(define-key minibuffer-local-completion-map [down] 'foo)

(defvar this-frame nil)
(defun foo-focus-this(frame-dummy)
  (run-with-idle-timer 0.1
                       nil
                       'select-frame-set-input-focus
                       this-frame))

(defun foo () (interactive)
  (add-hook 'after-make-frame-functions 'foo-focus-this)
  (setq this-frame (selected-frame))
  (display-buffer (get-buffer-create "foo")))

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Q on frame focus with MS Windows
  2005-10-25 22:21     ` Lennart Borgman
@ 2005-10-25 23:43       ` Drew Adams
  2005-10-26  7:03         ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Drew Adams @ 2005-10-25 23:43 UTC (permalink / raw)
  Cc: Lennart Borgman

It turns out that this will do the trick for me:

    (defun foo () (interactive)
      (display-buffer (get-buffer-create "foo")
      (select-frame-set-input-focus (window-frame (minibuffer-window))))

It was select-frame-set-input-focus that I was missing - in particular,
w32-focus-frame. I thought I had already tried it, but I guess not.

BTW - It seems that the problem is not just with newly created frames (which
is why I do the select-frame-set-input-focus even when no new frame is
created).  In spite of the doc string for display-buffer, on MS Windows
display-buffer always sends the focus to the displayed buffer. Try the code
I sent originally, with buffer foo already displayed in some unselected
frame.  Buffer foo's frame will get the focus, so the
minibuffer-local-completion-map binding will not be used when you hit
[next] - instead, the global binding for [next] in buffer foo is used.

Thanks, Lennart.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q on frame focus with MS Windows
  2005-10-25 23:43       ` Drew Adams
@ 2005-10-26  7:03         ` Lennart Borgman
  2005-10-26 15:15           ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2005-10-26  7:03 UTC (permalink / raw)
  Cc: Emacs-Devel

Drew Adams wrote:

>It turns out that this will do the trick for me:
>
>    (defun foo () (interactive)
>      (display-buffer (get-buffer-create "foo")
>      (select-frame-set-input-focus (window-frame (minibuffer-window))))
>
>It was select-frame-set-input-focus that I was missing - in particular,
>w32-focus-frame. I thought I had already tried it, but I guess not.
>  
>

Or, it is just that it is a bit tricky. I think there might be a race 
condition here. It does not work for me without the 
`run-with-idle-timer' I suggested.

I believe some part of the frame creation is run asynchronously.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Q on frame focus with MS Windows
  2005-10-26  7:03         ` Lennart Borgman
@ 2005-10-26 15:15           ` Drew Adams
  2005-10-26 15:30             ` Lennart Borgman
  0 siblings, 1 reply; 9+ messages in thread
From: Drew Adams @ 2005-10-26 15:15 UTC (permalink / raw)


   >It was select-frame-set-input-focus that I was missing - in particular,
    >w32-focus-frame. I thought I had already tried it, but I guess not.

    Or, it is just that it is a bit tricky. I think there might be a race
    condition here. It does not work for me without the
    `run-with-idle-timer' I suggested.

    I believe some part of the frame creation is run asynchronously.

Are you using emacs -q?  I have no problem without the timer and no problem
with it - even using a delay of 0 sec.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q on frame focus with MS Windows
  2005-10-26 15:15           ` Drew Adams
@ 2005-10-26 15:30             ` Lennart Borgman
  2005-10-26 16:01               ` Drew Adams
  0 siblings, 1 reply; 9+ messages in thread
From: Lennart Borgman @ 2005-10-26 15:30 UTC (permalink / raw)
  Cc: Emacs-Devel

Drew Adams wrote:

>   >It was select-frame-set-input-focus that I was missing - in particular,
>    >w32-focus-frame. I thought I had already tried it, but I guess not.
>
>    Or, it is just that it is a bit tricky. I think there might be a race
>    condition here. It does not work for me without the
>    `run-with-idle-timer' I suggested.
>
>    I believe some part of the frame creation is run asynchronously.
>
>Are you using emacs -q?  I have no problem without the timer and no problem
>with it - even using a delay of 0 sec.
>  
>
I am using emacs -Q.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Q on frame focus with MS Windows
  2005-10-26 15:30             ` Lennart Borgman
@ 2005-10-26 16:01               ` Drew Adams
  0 siblings, 0 replies; 9+ messages in thread
From: Drew Adams @ 2005-10-26 16:01 UTC (permalink / raw)


    >    >w32-focus-frame.

    >    I think there might be a race condition here.
    >    It does not work for me without `run-with-idle-timer'
    >    I believe some part of the frame creation is run asynchronously.

    >Are you using emacs -q?  I have no problem without the timer
    >and no problem with it - even using a delay of 0 sec.

    I am using emacs -Q.

Sounds like a bug.

FWIW, I don't see a problem on Windows XP SP1, with GNU Emacs 22.0.50.1
(i386-mingw-nt5.1.2600) of 2005-06-26 on NONIQPC X server distributor
`Microsoft Corp.', version 5.1.2600 configured using `configure --with-gcc
(3.3) --cflags -I../../jpeg-6b-3/include -I../../libpng-1.2.8/include -I../.
./tiff-3.6.1-2/include -I../../xpm-nox-4.2.0/include -I../../zlib-1.2.2/incl
ude'

I load this file, test.el, with runemacs.exe -q --debug-init -l "test.el":

(setq pop-up-frames t
      default-frame-alist '((minibuffer))
      minibuffer-frame-alist '((minibuffer . only)))

(define-key minibuffer-local-completion-map [down] 'foo)

(defun foo () (interactive)
      (display-buffer (get-buffer-create "foo"))
      (select-frame-set-input-focus (window-frame (minibuffer-window))))

Regardless of whether foo is displayed prior to doing `M-x' and hitting
`[down]', it correctly displays "foo" and gives the standalone minibuffer
frame the focus (so subsequent uses of [next] continue to use the minibuffer
binding).

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2005-10-26 16:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-10-25 20:33 Q on frame focus with MS Windows Drew Adams
2005-10-25 21:45 ` Lennart Borgman
2005-10-25 21:57   ` Drew Adams
2005-10-25 22:21     ` Lennart Borgman
2005-10-25 23:43       ` Drew Adams
2005-10-26  7:03         ` Lennart Borgman
2005-10-26 15:15           ` Drew Adams
2005-10-26 15:30             ` Lennart Borgman
2005-10-26 16:01               ` Drew Adams

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).