wslg icon indicating copy to clipboard operation
wslg copied to clipboard

`other-frame` does not work in Emacs

Open LemonBreezes opened this issue 2 years ago • 3 comments

Windows build number:

10.0.19045.2604

Your Distribution version:

2.13

Your WSL versions:

WSL version: 1.1.3.0 Kernel version: 5.15.90.1 WSLg version: 1.0.49 MSRDC version: 1.2.3770 Direct3D version: 1.608.2-61064218 DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp Windows version: 10.0.19045.2604

Steps to reproduce:

  1. Install Emacs (I am using Emacs30 from Git)
  2. Open a vanilla Emacs session with emacs -Q
  3. Open a second Emacs frame with C-x 5 2
  4. Attempt to switch between the two frames with C-x 5 o

WSL logs:

No response

WSL dumps:

No response

Expected behavior:

The other-frame command on C-x 5 o should switch between the two Emacs frames.

Actual behavior:

The other frame is not focused. It looks to me like the current frame goes out of focus but input focus is not redirected and the other frame is not raised.

LemonBreezes avatar Mar 26 '23 21:03 LemonBreezes

I have this issue. In fact, more generally, the focus is a bit weird with Emacs; when on full screen, if I hover with the mouse around the Emacs window it seems to get raised automatically. This means I need to un-maximise Emacs to be able to use the regular windows applications.

mcraveiro avatar Apr 17 '24 16:04 mcraveiro

I found a workaround using AutoHotkey, which might be useful for others. Whenever emacs tries to use (x-focus-frame) within WSL, it calls an AHK script to focus the desired frame. It's not the most performant; there is a half-second delay on switching frames, but at least I can use Winum now to switch to buffers across frames:

Contents of AHK script, save it somewhere on the Windows host

; Set title matching mode to partial match
SetTitleMatchMode, 2  ; 1 = exact match, 2 = partial match, 3 = RegEx match

; Get the window name from the command line argument
if A_Args.Length() > 0
{
    windowName := A_Args[1]  ; Get the first argument
}
else
{
    MsgBox, No window name provided as an argument.
    ExitApp
}

; Activate the window that contains the partial window name
IfWinExist, %windowName%
{
    WinActivate
}
else
{
    MsgBox, Window not found: %windowName%
}

Elisp in user config, change path according to where you placed the AKH script

(when (string-match-p "Microsoft" (shell-command-to-string "uname -a"))
    (defun my-raise-frame-via-windows-command (frame)
      "Raise the Emacs frame FRAME by calling an AutoHotkey script via PowerShell."
      (let* ((frame-name (frame-parameter frame 'name))
             (script-path "C:/Users/micro/documents/AutoHotkey/raise_window.ahk")  ;; Ensure this path is correct
             (command (format "powershell.exe -Command \"& {Start-Process '%s' -ArgumentList '%s' -Wait} \"" script-path frame-name)))  ;; Use PowerShell to execute the command
        ;; (message "Execute shell command to focus window: %s" command)  ;; Print the command to the minibuffer
        (shell-command command)
        ))
  ;; Add the advice to x-focus-frame
  (advice-add 'x-focus-frame :after #'my-raise-frame-via-windows-command))

hexaeder avatar Oct 18 '24 09:10 hexaeder