def get_shape_rectangles(self, logit=False): #get the list of windows l = log if logit or envbool("XPRA_SHAPE_DEBUG", False): l = shapelog taskbar = FindWindowA("Shell_TrayWnd", None) l("taskbar window=%#x", taskbar) ourpid = os.getpid() l("our pid=%i", ourpid) rectangles = [] def enum_windows_cb(hwnd, lparam): if not IsWindowVisible(hwnd): l("skipped invisible window %#x", hwnd) return True pid = c_int() thread_id = GetWindowThreadProcessId(hwnd, byref(pid)) if pid == ourpid: l("skipped our own window %#x", hwnd) return True #skipping IsWindowEnabled check length = GetWindowTextLengthW(hwnd) buf = create_unicode_buffer(length + 1) if GetWindowTextW(hwnd, buf, length + 1) > 0: window_title = buf.value else: window_title = '' l( "get_shape_rectangles() found window '%s' with pid=%i and thread id=%i", window_title, pid, thread_id) rect = RECT() if GetWindowRect(hwnd, byref(rect)) == 0: l("GetWindowRect failure") return True left, top, right, bottom = rect.left, rect.top, rect.right, rect.bottom if right < 0 or bottom < 0: l("skipped offscreen window at %ix%i", right, bottom) return True if hwnd == taskbar: l("skipped taskbar") return True #dirty way: if window_title == 'Program Manager': return True #this should be the proper way using GetTitleBarInfo (but does not seem to work) #import ctypes #from ctypes.windll.user32 import GetTitleBarInfo #@UnresolvedImport #from ctypes.wintypes import (DWORD, RECT) #class TITLEBARINFO(ctypes.Structure): # pass #TITLEBARINFO._fields_ = [ # ('cbSize', DWORD), # ('rcTitleBar', RECT), # ('rgstate', DWORD * 6), #] #ti = TITLEBARINFO() #ti.cbSize = sizeof(ti) #GetTitleBarInfo(hwnd, byref(ti)) #if ti.rgstate[0] & win32con.STATE_SYSTEM_INVISIBLE: # log("skipped system invisible window") # return True w = right - left h = bottom - top l("shape(%s - %#x)=%s", window_title, hwnd, (left, top, w, h)) if w <= 0 and h <= 0: l("skipped invalid window size: %ix%i", w, h) return True if left == -32000 and top == -32000: #there must be a better way of skipping those - I haven't found it l("skipped special window") return True #now clip rectangle: if left < 0: left = 0 w = right if top < 0: top = 0 h = bottom rectangles.append((left, top, w, h)) return True EnumWindows(EnumWindowsProc(enum_windows_cb)) l("get_shape_rectangles()=%s", rectangles) return sorted(rectangles)
def makeDynamicWindowModels(self): assert self.window_matches ourpid = os.getpid() taskbar = FindWindowA("Shell_TrayWnd", None) windows = {} def enum_windows_cb(hwnd, lparam): if not IsWindowVisible(hwnd): log("window %#x is not visible", hwnd) return True pid = c_ulong() thread_id = GetWindowThreadProcessId(hwnd, byref(pid)) if pid==ourpid: log("skipped our own window %#x, thread id=%#x", hwnd, thread_id) return True rect = RECT() if GetWindowRect(hwnd, byref(rect))==0: log("GetWindowRect failure") return True if hwnd==taskbar: log("skipped taskbar") return True #skipping IsWindowEnabled check length = GetWindowTextLengthW(hwnd) buf = create_unicode_buffer(length+1) if GetWindowTextW(hwnd, buf, length+1)>0: window_title = buf.value else: window_title = '' left, top, right, bottom = rect.left, rect.top, rect.right, rect.bottom w = right-left h = bottom-top if left<=-32000 or top<=-32000: log("%r is not visible: %s", window_title, (left, top, w, h)) if w<=0 and h<=0: log("skipped invalid window size: %ix%i", w, h) return True windows[hwnd] = (window_title, (left, top, w, h)) return True EnumWindows(EnumWindowsProc(enum_windows_cb), 0) log("makeDynamicWindowModels() windows=%s", windows) models = [] def add_model(hwnd, title, geometry): model = Win32ShadowModel(self.root, self.capture, title=title, geometry=geometry) model.hwnd = hwnd models.append(model) for m in self.window_matches: window = None try: if m.startswith("0x"): hwnd = int(m, 16) else: hwnd = int(m) if hwnd: window = windows.pop(hwnd, None) if window: add_model(hwnd, *window) except ValueError: namere = re.compile(m, re.IGNORECASE) for hwnd, window in tuple(windows.items()): title, geometry = window if namere.match(title): add_model(hwnd, title, geometry) windows.pop(hwnd) log("makeDynamicWindowModels()=%s", models) return models