How would I tell if my user has focus on the terminal?

465 Views Asked by At

I am creating a chat room application using a CLI over a GUI, and I am on windows so I just use the default terminal in command prompt to run my code. My program detects individual key presses and then adds them to a list in my data class, which, when joined, creates the user's message. The only problem I'm having here is that the program records keypresses even when it is not in focus. Is there any way I can detect if the terminal is in focus or not so I can handle keypresses appropriately? What I have here at the moment is essentially an accidental keylogger of sorts.

My code (although not useful to the question I feel I should add it just in case):

import json, keyboard, os, socket, termcolor, threading



def addKey(key):
    data.line.append(key)
    data.lineLength += 1



def cls():
    os.system("cls")



def display_chatLog():

    return "\n".join(data.chatLog)



def display_lineLength():

    return f"Characters: {data.lineLength}/{data.maxLineLength}\n\n"



def display_userInput():

    return f"\n{data.start} {''.join(data.line)}{data.end}\n"



def enterPressed():
    joinLine = " ".join(data.line)

    if data.server:

        if data.lineLength <= data.maxLineLength:
            data.server.send(bytes(f"{data.username}: {joinLine}", "utf-8"))
            data.line = []

        else:
            data.warning = "Your message is too long"

    else:

        if data.line[0] == "host":
            port = data.line[1]

        else:
            IP = data.line[1]
            port = data.line[2]



def getKeys():
    specialKeys = ("backspace", "ctrl", "enter", "esc", "shift", "right shift", "space")

    while True:
        key = keyboard.read_event()
        keyType = key.event_type
        keyName = key.name

        if keyType == "down":

            if keyName not in specialKeys:
                addKey(keyName)

            elif keyName == "backspace":

                if len(data.line) > 0:

                    del data.line[len(data.line) - 1]

                    data.lineLength -= 1

            elif keyName == "enter":
                enterPressed()

            elif keyName == "shift":

                if keyboard.is_pressed(f"shift+{keyName}") and keyName not in specialKeys:
                    addKey(keyName.upper)

            elif keyName == "space":
                addKey(" ")



class data:
    chatLog = []
    end = "_"
    line = []
    lineLength = 0
    maxLineLength = 512
    server = None
    start = ">>>"
    warning = "Make sure to either host a server using 'host (port)' or join one by using 'join (IP adress) (port)'"



getKeys_thread = threading.Thread(target = getKeys)
getKeys_thread.start()



while True:
    cls()
    print(display_chatLog(), display_userInput(), display_lineLength(), "\n", termcolor.colored(data.warning, "red", "on_white"))
1

There are 1 best solutions below

0
On BEST ANSWER
import ctypes

def getWindow():
    hwnd = ctypes.windll.user32.GetForegroundWindow()
    length = ctypes.windll.user32.GetWindowTextLengthW(hwnd)
    buff = ctypes.create_unicode_buffer(length + 1)
    ctypes.windll.user32.GetWindowTextW(hwnd, buff, length + 1)
    return (buff.value, hwnd) # buff.value is the title of the window, hwnd is the window handle

This code which I got from here and edited slightly allows me to capture the name and window handle of the currently focused window.