]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix focus stealing in the Emacs server for old window managers
authorPo Lu <luangruo@yahoo.com>
Mon, 24 Oct 2022 11:18:17 +0000 (19:18 +0800)
committerPo Lu <luangruo@yahoo.com>
Mon, 24 Oct 2022 11:18:49 +0000 (19:18 +0800)
* src/xterm.c (x_focus_frame): Apply focus stealing preference
to non-EWMH focus as well.  Otherwise frames get raised but not
focused.

src/xterm.c

index 06c84e2b53492e90ae931c2f4a9994481e6295a4..205c948c4617f2a0cf2aabc5f1bf12114fe1802c 100644 (file)
@@ -27348,6 +27348,7 @@ static void
 x_focus_frame (struct frame *f, bool noactivate)
 {
   struct x_display_info *dpyinfo;
+  Time time;
 
   dpyinfo = FRAME_DISPLAY_INFO (f);
 
@@ -27373,16 +27374,25 @@ x_focus_frame (struct frame *f, bool noactivate)
       /* Ignore any BadMatch error this request might result in.  */
       x_ignore_errors_for_next_request (dpyinfo);
       if (NILP (Vx_no_window_manager))
-       XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
-                       /* It is invalid to use CurrentTime according to
-                          the ICCCM:
-
-                          Clients that use a SetInputFocus request must
-                          set the time field to the timestamp of the
-                          event that caused them to make the
-                          attempt. [...] Note that clients must not use
-                          CurrentTime in the time field. */
-                       RevertToParent, dpyinfo->last_user_time);
+       {
+         /* Use the last user time.  It is invalid to use CurrentTime
+            according to the ICCCM:
+
+              Clients that use a SetInputFocus request must set the
+              time field to the timestamp of the event that caused
+              them to make the attempt. [...] Note that clients must
+              not use CurrentTime in the time field.  */
+         time = dpyinfo->last_user_time;
+
+         /* Unless the focus doesn't belong to Emacs anymore and
+            `x-allow-focus-stealing' is set to Qnewer_time.  */
+         if (EQ (Vx_allow_focus_stealing, Qnewer_time)
+             && !dpyinfo->x_focus_frame)
+           time = x_get_server_time (f);
+
+         XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+                         RevertToParent, time);
+       }
       else
        XSetInputFocus (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
                        /* But when no window manager is in use, we
@@ -31049,10 +31059,16 @@ connection setup.  */);
 
 Some window managers prevent `x-focus-frame' from activating the given
 frame when Emacs is in the background, which is especially prone to
-cause problems when the Emacs server wants to activate itself.  This
-variable specifies the strategy used to activate frames when that is
-the case, and has several valid values (any other value means to not
-bypass window manager focus stealing prevention):
+cause problems when the Emacs server wants to activate itself.
+
+In addition, when an old-fashioned (pre-EWMH) window manager is being
+run and `x-no-window-manager' is nil, the X server will not let Emacs
+focus itself if another program was focused after the last time Emacs
+obtained the input focus.
+
+This variable specifies the strategy used to activate frames when that
+is the case, and has several valid values (any other value means to
+not bypass window manager focus stealing prevention):
 
   - The symbol `imitate-pager', which means to pretend that Emacs is a
     pager.