Search code examples
python-3.xcmdwindows-10setforegroundwindowalacritty

Win 10: Cmd can bring windows to foreground, but any other terminal can't(even if elevated). Why is this so?


I'm using pygetwindow to bring a window to the foreground, via it's title. And it works flawlessly if I run my python script from cmd(and PowerShell). But if I run it from any other terminal, say Alacritty, instead of coming to the foreground, the mentioned window just starts flashing in the taskbar.

Why would this be so? I've configured Alacritty to use cmd.

Following is the relevant part of my code:

import pygetwindow
try:
        window = pygetwindow.getWindowsWithTitle('foobar')[0]
        window.activate()
    except Exception as e:
        #raise e
        print("open foobar please")
        exit(1)

And following is the relevant part of my alacritty config

# Shell
# You can set `shell.program` to the path of your favorite shell, e.g. `/bin/fish`.
# Entries in `shell.args` are passed unmodified as arguments to the shell.
# Default:
#   - (macOS) /bin/bash --login
#   - (Linux/BSD) user login shell
#   - (Windows) powershell
  shell:
    program: cmd.exe
    args:
            - /s /k pushd C:\Users\interesting\bug\hunt\Repos

Thank You


Solution

  • Your program must comply with one of the following to be allowed to set the active window (which uses the API call SetForegroundWindow).

    You may find using SendKeys to send system keystrokes like Ctrl+Tab will work for you, but you need to be able to predict your z-order.

    The system restricts which processes can set the foreground window. A process can set the foreground window only if one of the following conditions is true:

    •The process is the foreground process.

    •The process was started by the foreground process.

    •The process received the last input event.

    •There is no foreground process.

    •The process is being debugged.

    •The foreground process is not a Modern Application or the Start Screen.

    •The foreground is not locked (see LockSetForegroundWindow).

    •The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).

    •No menus are active.

    https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow

    The purpose of these restrictions is solving a problem of programs stealing focus. So basically if the user clicks another window the user's choice wins.

    When starting programs the program has two seconds to show a window. If the user clicks a another window before the program shows its' window within the two seconds then that program will still become the active window. If the program takes longer than 2 seconds and the user clicks away the user's window will be the active window.

    Also see https://devblogs.microsoft.com/oldnewthing/20090220-00/?p=19083 for a discussion.