Problem Description:
I am developing a program that tracks the user’s language and displays a corresponding flag near the cursor based on the detected language. The flag should only be displayed when the text cursor (I-beam) is active, not when the standard mouse arrow is displayed.
Issue:
the flag stops updating when the text cursor changes to the mouse arrow again, after that the flags do not change anymore
Steps to Reproduce:
-
The program should display a flag near the cursor according to the detected language.
-
When the cursor changes to an I-beam 2-nd time (text cursor), the flag is no longer updated
Expected Behavior:
The flag should update and be displayed correctly near the cursor regardless of whether it is an I-beam or standard arrow cursor.
import pyautogui
import win32api
import win32con
import win32gui
import ctypes
from PIL import Image, ImageTk
import tkinter as tk
import os
# Configuration
PNG_FLAGS_DIR = r'D:workpyProjMovaicons'
CURSOR_WIDTH = 20
CURSOR_HEIGHT = 16
current_language = None
# Get system language based on keyboard layout
def get_system_language():
lang_id = ctypes.windll.user32.GetKeyboardLayout(0)
lang_id = lang_id & 0xFFFF
language_map = {
0x0409: 'en',
0x0809: 'uk',
0x0422: 'ukr',
0x0415: 'pl',
}
lang = language_map.get(lang_id, 'en')
global current_language
if current_language != lang:
current_language = lang
return current_language
# Update the flag image on the canvas based on the system language
def update_flag_image():
lang = get_system_language()
file_names = {
'en': 'united-states-flag-icon.webp',
'uk': 'united-kingdom-flag-icon.webp',
'ukr': 'ukraine-flag-icon.webp',
'pl': 'poland-flag-icon.webp',
}
png_file = file_names.get(lang, 'united-states-flag-icon.webp')
flag_path = os.path.join(PNG_FLAGS_DIR, png_file)
if os.path.exists(flag_path):
try:
flag_img = Image.open(flag_path).resize((CURSOR_WIDTH, CURSOR_HEIGHT))
flag_img_tk = ImageTk.PhotoImage(flag_img)
canvas.delete("all") # Clear existing images
canvas.create_image(0, 0, anchor='nw', image=flag_img_tk)
canvas.image = flag_img_tk
except Exception as e:
print(f"Error updating flag: {e}")
else:
print(f"File not found: {flag_path}")
# Check if the cursor is a caret
def is_caret_cursor():
x, y = win32api.GetCursorPos()
hwnd = win32gui.WindowFromPoint((x, y))
cursor_info = win32gui.GetCursorInfo()
cursor_handle = cursor_info[1]
return cursor_handle == win32gui.LoadCursor(None, win32con.IDC_IBEAM)
# Update the flag position and visibility based on the cursor type
def update_position():
x, y = pyautogui.position()
flag_width, flag_height = CURSOR_WIDTH, CURSOR_HEIGHT
if is_caret_cursor():
root.geometry(f'{flag_width}x{flag_height}+{int(x) + 10}+{int(y) + 10}')
if not root.winfo_viewable():
root.deiconify()
update_flag_image() # Update flag when caret is visible
else:
if root.winfo_viewable():
root.withdraw()
update_flag_image() # Update flag even when caret is not visible
root.after(100, update_position)
# Periodically check and update the language flag
def periodic_language_check():
update_flag_image()
root.after(1000, periodic_language_check)
# Tkinter setup
root = tk.Tk()
root.title("Mova")
root.geometry(f"{CURSOR_WIDTH}x{CURSOR_HEIGHT}+0+0")
root.attributes('-topmost', True)
root.attributes('-transparentcolor', 'white')
root.overrideredirect(True)
canvas = tk.Canvas(root, width=CURSOR_WIDTH, height=CURSOR_HEIGHT, bg='white', highlightthickness=0)
canvas.pack()
# Start the main loop
root.withdraw()
update_position() # Update position and visibility
periodic_language_check() # Update flag based on language change
root.mainloop()
Sergei Didenko is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.