GNU bug report logs - #11513
24.1.50; raise-frame never raise the foreground window on Windows

Previous Next

Package: emacs;

Reported by: Kazuhiro Ito <kzhr <at> d1.dion.ne.jp>

Date: Fri, 18 May 2012 21:08:02 UTC

Severity: normal

Found in version 24.1.50

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: help-debbugs <at> gnu.org (GNU bug Tracking System)
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: tracker <at> debbugs.gnu.org
Subject: bug#11513: closed (24.1.50; raise-frame never raise the
 foreground window on Windows)
Date: Mon, 28 May 2012 17:30:02 +0000
[Message part 1 (text/plain, inline)]
Your message dated Mon, 28 May 2012 20:28:13 +0300
with message-id <83fwak1ahe.fsf <at> gnu.org>
and subject line Re: bug#11513: 24.1.50; raise-frame never raise the foreground window on Windows
has caused the debbugs.gnu.org bug report #11513,
regarding 24.1.50; raise-frame never raise the foreground window on Windows
to be marked as done.

(If you believe you have received this mail in error, please contact
help-debbugs <at> gnu.org.)


-- 
11513: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11513
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: Kazuhiro Ito <kzhr <at> d1.dion.ne.jp>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.1.50; raise-frame never raise the foreground window on Windows
Date: Sat, 19 May 2012 06:06:09 +0900
When I start Emacs with -Q option nd evaluate the below code, I get
unexpected result.

(let ((frame (selected-frame)))
  (lower-frame frame)
  ;; If we change the foreground window while sleeping, raise-frame
  ;; correctly works.
  (sleep-for 5)
  (raise-frame frame))

Result: raise-frame never raise the frame if the selected frame is the
foreground window.  If other frame or application is the foreground
window, raise-frame works as expected.

I guess SetForegroundWindow function does not modify Z-order when the
window is already foreground.  Below patch or similar workaround would
be needed.

=== modified file 'src/w32fns.c'
--- src/w32fns.c	2012-05-11 06:39:26 +0000
+++ src/w32fns.c	2012-05-18 11:24:26 +0000
@@ -3681,6 +3760,8 @@
 
         retval = SetForegroundWindow ((HWND) wParam);
 
+	BringWindowToTop ((HWND) wParam);
+
         /* Detach from the previous foreground thread.  */
         if (foreground_thread)
           AttachThreadInput (GetCurrentThreadId (),

-- 
Kazuhiro Ito


[Message part 3 (message/rfc822, inline)]
From: Eli Zaretskii <eliz <at> gnu.org>
To: Kazuhiro Ito <kzhr <at> d1.dion.ne.jp>
Cc: rudalics <at> gmx.at, 11513-done <at> debbugs.gnu.org, drew.adams <at> oracle.com
Subject: Re: bug#11513: 24.1.50;
	raise-frame never raise the foreground window on Windows
Date: Mon, 28 May 2012 20:28:13 +0300
> Date: Thu, 24 May 2012 15:04:59 +0900
> From: Kazuhiro Ito <kzhr <at> d1.dion.ne.jp>
> Cc: rudalics <at> gmx.at, 11513 <at> debbugs.gnu.org, drew.adams <at> oracle.com
> 
> > > raise-frame always make the unexpected result when Emacs frame is
> > > the foreground window (I mean Emacs frame is colored as active window)
> > > and behind of other application window(s).  And, as I described
> > > previously, If Emacs frame is not the foreground window raise-frame
> > > correctly works.
> > 
> > But the default behavior on Windows is that a window that is lowered
> > loses its focus.  You need to click into it to get focus there.  So
> > how come a lowered window still has focus for you?
> 
> When I run lower-frame function in Emacs frame interactively, Emacs
> frame is brought behind of other application window(s) but has focus.
> Key inputs are passed to lowered frame.  I tested 4 Windows PC, and
> all PCs show the same behavior.

Sorry, I was confused.  You are right, the focus isn't lost.

Anyway, I don't think it is a good idea to modify the reaction to the
WM_EMACS_SETFOREGROUND message, because it is also used by
x-focus-frame, which is not supposed to raise the frame to the top of
the Z-order, unless it is strictly necessary.  And if the frame is
already a foreground frame, raising it isn't necessary.

So instead I introduced a new message, WM_EMACS_BRINGTOTOP, and used
that in raise-frame.  The diffs are below (installed as revision
108409 on the trunk).

Thanks.  I'm closing this bug report.


=== modified file 'src/ChangeLog'
--- src/ChangeLog	2012-05-28 07:13:45 +0000
+++ src/ChangeLog	2012-05-28 17:22:40 +0000
@@ -1,3 +1,17 @@
+2012-05-28  Eli Zaretskii  <eliz <at> gnu.org>
+
+	* w32term.c (my_bring_window_to_top): New function.
+	(x_raise_frame): Use handle returned by DeferWindowPos, which
+	could be different from the original one.  Call
+	my_bring_window_to_top instead of my_set_foreground_window.
+	(Bug#11513)
+
+	* w32fns.c (w32_wnd_proc): Accept and process WM_EMACS_BRINGTOTOP
+	by calling BringWindowToTop.
+
+	* w32term.h (WM_EMACS_BRINGTOTOP): New message.
+	(WM_EMACS_END): Increase by one.
+
 2012-05-28  Paul Eggert  <eggert <at> cs.ucla.edu>
 
 	* bidi.c (bidi_mirror_char): Put eassert before conversion to int.

=== modified file 'src/w32fns.c'
--- src/w32fns.c	2012-05-25 18:19:24 +0000
+++ src/w32fns.c	2012-05-28 17:22:40 +0000
@@ -3663,6 +3663,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARA
     case WM_EMACS_SHOWWINDOW:
       return ShowWindow ((HWND) wParam, (WPARAM) lParam);
 
+    case WM_EMACS_BRINGTOTOP:
     case WM_EMACS_SETFOREGROUND:
       {
         HWND foreground_window;
@@ -3680,6 +3681,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARA
           foreground_thread = 0;
 
         retval = SetForegroundWindow ((HWND) wParam);
+        if (msg == WM_EMACS_BRINGTOTOP)
+          retval = BringWindowToTop ((HWND) wParam);
 
         /* Detach from the previous foreground thread.  */
         if (foreground_thread)

=== modified file 'src/w32term.c'
--- src/w32term.c	2012-05-18 08:36:50 +0000
+++ src/w32term.c	2012-05-28 17:22:40 +0000
@@ -3492,6 +3492,12 @@ my_destroy_window (struct frame * f, HWN
 	       (WPARAM) hwnd, 0);
 }
 
+static void
+my_bring_window_to_top (HWND hwnd)
+{
+  SendMessage (hwnd, WM_EMACS_BRINGTOTOP, (WPARAM) hwnd, 0);
+}
+
 /* Create a scroll bar and return the scroll bar vector for it.  W is
    the Emacs window on which to create the scroll bar. TOP, LEFT,
    WIDTH and HEIGHT are the pixel coordinates and dimensions of the
@@ -5600,24 +5606,27 @@ x_raise_frame (struct frame *f)
       HDWP handle = BeginDeferWindowPos (2);
       if (handle)
 	{
-	  DeferWindowPos (handle,
-			  FRAME_W32_WINDOW (f),
-  			  HWND_TOP,
-  			  0, 0, 0, 0,
-  			  SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
-	  DeferWindowPos (handle,
-			  GetForegroundWindow (),
-			  FRAME_W32_WINDOW (f),
-			  0, 0, 0, 0,
-			  SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
-	  EndDeferWindowPos (handle);
+	  handle = DeferWindowPos (handle,
+				   FRAME_W32_WINDOW (f),
+				   HWND_TOP,
+				   0, 0, 0, 0,
+				   SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+	  if (handle)
+	    {
+	      handle = DeferWindowPos (handle,
+				       GetForegroundWindow (),
+				       FRAME_W32_WINDOW (f),
+				       0, 0, 0, 0,
+				       SWP_NOSIZE | SWP_NOMOVE |
+				       SWP_NOACTIVATE);
+	      if (handle)
+		EndDeferWindowPos (handle);
+	    }
 	}
     }
   else
     {
-      my_set_foreground_window (FRAME_W32_WINDOW (f));
+      my_bring_window_to_top (FRAME_W32_WINDOW (f));
     }
 
   UNBLOCK_INPUT;

=== modified file 'src/w32term.h'
--- src/w32term.h	2012-01-19 07:21:25 +0000
+++ src/w32term.h	2012-05-28 17:22:40 +0000
@@ -576,7 +576,8 @@ do { \
 #define WM_EMACS_HIDE_CARET            (WM_EMACS_START + 18)
 #define WM_EMACS_SETCURSOR             (WM_EMACS_START + 19)
 #define WM_EMACS_PAINT                 (WM_EMACS_START + 20)
-#define WM_EMACS_END                   (WM_EMACS_START + 21)
+#define WM_EMACS_BRINGTOTOP            (WM_EMACS_START + 21)
+#define WM_EMACS_END                   (WM_EMACS_START + 22)
 
 #define WND_FONTWIDTH_INDEX    (0)
 #define WND_LINEHEIGHT_INDEX   (4)



This bug report was last modified 13 years and 79 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.