Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping the terminal in focus

I have a python script which uses selenium to automate web page, drawing focus away from the terminal where user input is required.

Is there anyway in python to switch focus back to the terminal, programmatically?

I will be running my program in the Windows Command Prompt on Windows 7, if it matters, but a cross platform answer would be most useful.


Attempts

Looking at the pywin32 package bindings for the win32 API I have the following:

import win32console
import win32gui
from selenium import webdriver as wd

d = wd.Firefox()
win32gui.SetFocus(win32console.GetConsoleWindow())
win32gui.FlashWindow(win32console.GetConsoleWindow(), False)
input('Should have focus: ')

SetFocus causes the error pywintypes.error: (5, 'SetFocus', 'Access is denied.') due to Microsoft removing the ability to take focus from another application.

FlashWindow appears to do nothing.

like image 209
thodic Avatar asked May 28 '15 16:05

thodic


1 Answers

Here is what I came up with that seems to be working.

class WindowManager:
    def __init__(self):
        self._handle = None

    def _window_enum_callback( self, hwnd, wildcard ):
        if re.match(wildcard, str(win32gui.GetWindowText(hwnd))) != None:
            self._handle = hwnd

    #CASE SENSITIVE
    def find_window_wildcard(self, wildcard):
        self._handle = None
        win32gui.EnumWindows(self._window_enum_callback, wildcard)

    def set_foreground(self):
        win32gui.ShowWindow(self._handle, win32con.SW_RESTORE)
        win32gui.SetWindowPos(self._handle,win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)  
        win32gui.SetWindowPos(self._handle,win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)  
        win32gui.SetWindowPos(self._handle,win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_SHOWWINDOW + win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
        shell = win32com.client.Dispatch("WScript.Shell")
        shell.SendKeys('%')
        win32gui.SetForegroundWindow(self._handle)

    def find_and_set(self, search):
        self.find_window_wildcard(search)
        self.set_foreground()

Then to find a window and make it active you can...

w = WindowManager()
w.find_and_set(".*cmd.exe*")

This is in python 2.7, also here are some links I found to explain why you have to go through so much trouble to switch active windows.

win32gui.SetActiveWindow() ERROR : The specified procedure could not be found

Windows 7: how to bring a window to the front no matter what other window has focus?

like image 131
SimKev2 Avatar answered Sep 22 '22 16:09

SimKev2