├── README.md ├── LICENSE └── qt_behind_blender.py /README.md: -------------------------------------------------------------------------------- 1 | # blender_snippets 2 | A collection of blender code snippets (not necessarily functional on their own) 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Frieder Erdmann 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /qt_behind_blender.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import os 3 | from ctypes import wintypes 4 | from collections import namedtuple 5 | from PySide2.QtWidgets import QApplication 6 | 7 | 8 | def get_process_hwnds(): 9 | # https://stackoverflow.com/questions/37501191/how-to-get-windows-window-names-with-ctypes-in-python 10 | user32 = ctypes.WinDLL('user32', use_last_error=True) 11 | 12 | def check_zero(result, func, args): 13 | if not result: 14 | err = ctypes.get_last_error() 15 | if err: 16 | raise ctypes.WinError(err) 17 | return args 18 | 19 | if not hasattr(wintypes, 'LPDWORD'): # PY2 20 | wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) 21 | 22 | WindowInfo = namedtuple('WindowInfo', 'title hwnd') 23 | 24 | WNDENUMPROC = ctypes.WINFUNCTYPE( 25 | wintypes.BOOL, 26 | wintypes.HWND, # _In_ hWnd 27 | wintypes.LPARAM,) # _In_ lParam 28 | 29 | user32.EnumWindows.errcheck = check_zero 30 | user32.EnumWindows.argtypes = ( 31 | WNDENUMPROC, # _In_ lpEnumFunc 32 | wintypes.LPARAM,) # _In_ lParam 33 | 34 | user32.IsWindowVisible.argtypes = ( 35 | wintypes.HWND,) # _In_ hWnd 36 | 37 | user32.GetWindowThreadProcessId.restype = wintypes.DWORD 38 | user32.GetWindowThreadProcessId.argtypes = ( 39 | wintypes.HWND, # _In_ hWnd 40 | wintypes.LPDWORD,) # _Out_opt_ lpdwProcessId 41 | 42 | user32.GetWindowTextLengthW.errcheck = check_zero 43 | user32.GetWindowTextLengthW.argtypes = ( 44 | wintypes.HWND,) # _In_ hWnd 45 | 46 | user32.GetWindowTextW.errcheck = check_zero 47 | user32.GetWindowTextW.argtypes = ( 48 | wintypes.HWND, # _In_ hWnd 49 | wintypes.LPWSTR, # _Out_ lpString 50 | ctypes.c_int,) # _In_ nMaxCount 51 | 52 | def list_windows(): 53 | '''Return a sorted list of visible windows.''' 54 | result = [] 55 | @WNDENUMPROC 56 | def enum_proc(hWnd, lParam): 57 | if user32.IsWindowVisible(hWnd): 58 | pid = wintypes.DWORD() 59 | tid = user32.GetWindowThreadProcessId( 60 | hWnd, ctypes.byref(pid)) 61 | length = user32.GetWindowTextLengthW(hWnd) + 1 62 | title = ctypes.create_unicode_buffer(length) 63 | user32.GetWindowTextW(hWnd, title, length) 64 | current_pid = os.getpid() 65 | if pid.value == current_pid: 66 | result.append(WindowInfo(title.value, hWnd)) 67 | return True 68 | user32.EnumWindows(enum_proc, 0) 69 | return sorted(result) 70 | 71 | return list_windows() 72 | 73 | def get_window_z_order(): 74 | '''Returns windows in z-order (top first)''' 75 | # https://stackoverflow.com/questions/6381198/get-window-z-order-with-python-windows-extensions 76 | user32 = ctypes.windll.user32 77 | lst = [] 78 | top = user32.GetTopWindow(None) 79 | if not top: 80 | return lst 81 | lst.append(top) 82 | while True: 83 | next = user32.GetWindow(lst[-1], 2) 84 | if not next: 85 | break 86 | lst.append(next) 87 | return lst 88 | 89 | ''' 90 | def get_qt_window_order(): 91 | window_order = get_window_z_order() 92 | app = QApplication.instance() 93 | qt_windows = app.topLevelWidgets() 94 | qt_window_ids = [window.winId() for window in qt_windows] 95 | return qt_window_ids 96 | # return order_window_list(qt_window_ids) 97 | 98 | 99 | def order_window_list(list_of_windows=[]): 100 | all_windows_ordered_list = get_window_z_order() 101 | ordered_list = [] 102 | for window in all_windows_ordered_list: 103 | if window in list_of_windows: 104 | ordered_list.append(window) 105 | return ordered_list 106 | ''' 107 | 108 | # qt_order = get_qt_window_order() 109 | all_windows = get_window_z_order() 110 | process_windows = get_process_hwnds() 111 | 112 | # blender_windows = [b_window.hwnd for b_window in process_windows if b_window.hwnd not in qt_order] 113 | window_dict = {wind.hwnd: wind.title for wind in process_windows} 114 | 115 | print("Sort order is:") 116 | i = 0 117 | for window in all_windows: 118 | if window in window_dict: 119 | print("\t", i, window_dict[window]) 120 | i += 1 121 | --------------------------------------------------------------------------------