Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save aont/220f5e173f42bc0cb581387e91512261 to your computer and use it in GitHub Desktop.

Select an option

Save aont/220f5e173f42bc0cb581387e91512261 to your computer and use it in GitHub Desktop.

Programmatically Removing the “Always on Top” Window State from Chrome on Windows

  • Enumerates all visible top-level windows using the Windows API (via ctypes) and collects window metadata such as title, process ID, executable path, and extended window styles.
  • Identifies windows belonging to a specific target executable (chrome.exe) and checks whether they are marked with the WS_EX_TOPMOST (always-on-top) extended style.
  • Safely removes the topmost attribute from matching windows using SetWindowPos, logging successful modifications and failures for traceability.
import ctypes
from ctypes import wintypes
import os
import sys
# Ensure UTF-8 output
try:
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
except Exception:
pass
user32 = ctypes.WinDLL("user32", use_last_error=True)
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
EnumWindowsProc = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
# --- GWL / style constants ---
GWL_STYLE = -16
GWL_EXSTYLE = -20
WS_EX_TOPMOST = 0x00000008
# --- SetWindowPos constants ---
HWND_NOTOPMOST = wintypes.HWND(-2)
SWP_NOSIZE = 0x0001
SWP_NOMOVE = 0x0002
SWP_NOACTIVATE = 0x0010
SWP_FRAMECHANGED = 0x0020
# --- function prototypes ---
user32.EnumWindows.argtypes = [EnumWindowsProc, wintypes.LPARAM]
user32.EnumWindows.restype = wintypes.BOOL
user32.IsWindowVisible.argtypes = [wintypes.HWND]
user32.IsWindowVisible.restype = wintypes.BOOL
user32.GetWindowTextLengthW.argtypes = [wintypes.HWND]
user32.GetWindowTextLengthW.restype = ctypes.c_int
user32.GetWindowTextW.argtypes = [wintypes.HWND, wintypes.LPWSTR, ctypes.c_int]
user32.GetWindowTextW.restype = ctypes.c_int
user32.GetWindowThreadProcessId.argtypes = [wintypes.HWND, ctypes.POINTER(wintypes.DWORD)]
user32.GetWindowThreadProcessId.restype = wintypes.DWORD
kernel32.OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD]
kernel32.OpenProcess.restype = wintypes.HANDLE
kernel32.CloseHandle.argtypes = [wintypes.HANDLE]
kernel32.CloseHandle.restype = wintypes.BOOL
kernel32.QueryFullProcessImageNameW.argtypes = [
wintypes.HANDLE, wintypes.DWORD, wintypes.LPWSTR, ctypes.POINTER(wintypes.DWORD)
]
kernel32.QueryFullProcessImageNameW.restype = wintypes.BOOL
user32.SetWindowPos.argtypes = [
wintypes.HWND, wintypes.HWND,
ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int,
wintypes.UINT
]
user32.SetWindowPos.restype = wintypes.BOOL
# --- GetWindowLongPtrW (32/64-bit safe) ---
if ctypes.sizeof(ctypes.c_void_p) == 8:
user32.GetWindowLongPtrW.argtypes = [wintypes.HWND, ctypes.c_int]
user32.GetWindowLongPtrW.restype = ctypes.c_longlong
def get_window_long_ptr(hwnd, index) -> int:
return int(user32.GetWindowLongPtrW(hwnd, index))
else:
user32.GetWindowLongW.argtypes = [wintypes.HWND, ctypes.c_int]
user32.GetWindowLongW.restype = ctypes.c_long
def get_window_long_ptr(hwnd, index) -> int:
return int(user32.GetWindowLongW(hwnd, index))
def get_window_title(hwnd: int) -> str:
length = user32.GetWindowTextLengthW(hwnd)
if length <= 0:
return ""
buffer = ctypes.create_unicode_buffer(length + 1)
user32.GetWindowTextW(hwnd, buffer, length + 1)
return buffer.value
def get_process_id(hwnd: int) -> int:
pid = wintypes.DWORD(0)
user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
return int(pid.value)
def get_process_image_path(pid: int) -> str:
process = kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, pid)
if not process:
return ""
try:
size = wintypes.DWORD(4096)
buffer = ctypes.create_unicode_buffer(size.value)
if kernel32.QueryFullProcessImageNameW(process, 0, buffer, ctypes.byref(size)):
return buffer.value
return ""
finally:
kernel32.CloseHandle(process)
def get_extended_style(hwnd: int) -> int:
return get_window_long_ptr(hwnd, GWL_EXSTYLE)
def has_flag(value: int, flag: int) -> bool:
return (value & flag) == flag
def is_target_executable(image_path: str, target_exe: str = "chrome.exe") -> bool:
if not image_path:
return False
return os.path.basename(image_path).lower() == target_exe.lower()
def remove_topmost(hwnd: int) -> None:
flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_FRAMECHANGED
if not user32.SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, flags):
raise ctypes.WinError(ctypes.get_last_error())
def enumerate_windows():
windows = []
@EnumWindowsProc
def callback(hwnd, lparam):
if not user32.IsWindowVisible(hwnd):
return True
title = get_window_title(hwnd)
if not title:
return True
pid = get_process_id(hwnd)
image = get_process_image_path(pid)
exstyle = get_extended_style(hwnd)
windows.append((hwnd, pid, title, image, exstyle))
return True
if not user32.EnumWindows(callback, 0):
raise ctypes.WinError(ctypes.get_last_error())
return windows
if __name__ == "__main__":
TARGET_EXE = "chrome.exe"
modified_count = 0
for hwnd, pid, title, image, exstyle in enumerate_windows():
if not is_target_executable(image, TARGET_EXE):
continue
if has_flag(exstyle, WS_EX_TOPMOST):
try:
remove_topmost(hwnd)
modified_count += 1
print(f"[OK] TOPMOST removed HWND=0x{hwnd:08X} PID={pid} TITLE={title} EXE={image}")
except OSError as e:
print(f"[FAIL] Could not modify HWND=0x{hwnd:08X} PID={pid} TITLE={title} EXE={image} ERROR={e}")
print(f"Done: TOPMOST removed from {modified_count} window(s) (target EXE = {TARGET_EXE})")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment