Skip to content

Instantly share code, notes, and snippets.

@aont
Created December 2, 2023 04:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aont/104e18617fec495d76f009f0f104baa6 to your computer and use it in GitHub Desktop.
Save aont/104e18617fec495d76f009f0f104baa6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import sys
import os
import json
import ctypes
import pywintypes
import win32api
import win32gui
import win32process
import win32con
import winerror
ctypes.windll.user32.SetProcessDPIAware()
scaleFactor = ctypes.windll.shcore.GetScaleFactorForDevice(0) / 100
sys.stderr.write(f"info: {scaleFactor=}\n")
def get_wt_win_callback(hwnd, wt_win_list):
window_title = win32gui.GetWindowText(hwnd)
class_name = win32gui.GetClassName(hwnd)
thread_id, process_id = win32process.GetWindowThreadProcessId(hwnd)
process_handle = None
try:
process_handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, 0, process_id)
except pywintypes.error as e:
if e.winerror not in (winerror.ERROR_ACCESS_DENIED, ):
sys.stderr.write("[warn] pid %s: %s\n" % (process_id, e.strerror))
return True
process_name = None
if process_handle:
module_handle_tuple = win32process.EnumProcessModules(process_handle)
# module_handle_tuple = win32process.EnumProcessModulesEx(process_handle, win32process.LIST_MODULES_ALL)
if len(module_handle_tuple)>0:
module_handle = module_handle_tuple[0]
process_path = win32process.GetModuleFileNameEx(process_handle, module_handle)
process_name = os.path.basename(process_path)
if 'WindowsTerminal.exe' == process_name and class_name == 'CASCADIA_HOSTING_WINDOW_CLASS':
sys.stderr.write(f"info: {hwnd=} {process_name=} {window_title=} {class_name=} {process_path=}\n")
wt_win_list.append({"hwnd": hwnd, "process_name": process_name, "window_title": window_title, "class_name": class_name, "process_path": process_path})
# if 'WindowsTerminal.exe' == process_name and not class_name in ('MSCTFIME UI', 'IME', 'Windows.UI.Core.CoreWindow', 'CASCADIA_HOSTING_WINDOW_CLASS'):
# sys.stderr.write(f"warn: {hwnd=} {process_name=} {window_title=} {class_name=} {process_path=}\n")
return True
def load_json():
if os.path.exists("data.json"):
with open("data.json", "rt") as f:
try:
obj = json.loads(f.read())
return obj
except json.JSONDecodeError as e:
return {}
else:
return {}
def save_json(obj):
with open("data.json", "wt") as f:
f.write(json.dumps(obj))
if __name__ == "__main__":
if len(sys.argv)==2:
argv_method = sys.argv[1]
config = load_json()
wt_win_list = []
win32gui.EnumWindows(get_wt_win_callback, wt_win_list)
if argv_method=="save":
for wt_win in wt_win_list:
(left, top, right, bottom) = win32gui.GetWindowRect(wt_win["hwnd"])
width = right - left
height = bottom - top
sys.stderr.write(f"info: {wt_win['hwnd']} {wt_win['window_title']} {width=} {height=}\n")
config["width"] = width
config["height"] = height
save_json(config)
break
elif argv_method=="restore":
default_width = config["width"]
default_height = config["height"]
for wt_win in wt_win_list:
hwnd = wt_win["hwnd"]
(left, top, right, bottom) = win32gui.GetWindowRect(hwnd)
win32gui.SetWindowPos(hwnd, 0, left, top, default_width, default_height, 0)
sys.stderr.write(f"info: {wt_win['hwnd']} {wt_win['window_title']}\n")
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment