Bouncy mouse, bouncy windows, initial code
This commit is contained in:
		
							
								
								
									
										2
									
								
								bounce_c/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								bounce_c/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | |||||||
|  | *.exe | ||||||
|  | *.pdb | ||||||
							
								
								
									
										161
									
								
								bounce_c/bounce.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										161
									
								
								bounce_c/bounce.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,161 @@ | |||||||
|  | #include <math.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <windows.h> | ||||||
|  | #include <time.h> | ||||||
|  |  | ||||||
|  | #define MAX_WINDOWS 1024 | ||||||
|  |  | ||||||
|  | // resolution | ||||||
|  | uint32_t res_y; | ||||||
|  | void globals_init() { | ||||||
|  |     res_y = GetSystemMetrics(SM_CYSCREEN); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // bodies | ||||||
|  | typedef struct body_t { | ||||||
|  |     int32_t last_x; | ||||||
|  |     int32_t last_y; | ||||||
|  |     float offset_x; | ||||||
|  |     float offset_y; | ||||||
|  |     float velocity; | ||||||
|  | } body_t; | ||||||
|  |  | ||||||
|  | void body_init(body_t* body) { | ||||||
|  |     body->last_x = -1; | ||||||
|  |     body->last_y = -1; | ||||||
|  |     body->offset_x = 0.5; | ||||||
|  |     body->offset_y = 0.5; | ||||||
|  |     body->velocity = 0.0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void body_update(body_t* body, int32_t x, int32_t y, int32_t* x_new, int32_t* y_new) { | ||||||
|  |     if (body->last_x != -1 && body->last_y != -1) { | ||||||
|  |         int32_t dx = x - body->last_x; | ||||||
|  |         int32_t dy = y - body->last_y; | ||||||
|  |         double dist = sqrt((double) dx * dx + dy * dy); | ||||||
|  |         body->velocity *= 1.0 - min(dist / 128, 1.0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     float float_x = x + body->offset_x; | ||||||
|  |     float float_y = y + body->offset_y; | ||||||
|  |     for (uint8_t step = 0; step < 100; step += 1) { | ||||||
|  |         body->velocity += 0.0002; | ||||||
|  |  | ||||||
|  |         float_y += body->velocity; | ||||||
|  |         if (float_y > res_y && body->velocity > 0) { | ||||||
|  |             body->velocity = -body->velocity * 0.75; | ||||||
|  |             if (-body->velocity < 0.05) { | ||||||
|  |                 body->velocity = 0; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     *x_new = (int) float_x; | ||||||
|  |     *y_new = (int) float_y; | ||||||
|  |     body->last_x = *x_new; | ||||||
|  |     body->last_y = *y_new; | ||||||
|  |     body->offset_x = float_x - *x_new; | ||||||
|  |     body->offset_y = float_y - *y_new; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // == mouse == | ||||||
|  | typedef struct mouse_body_t { | ||||||
|  |     body_t body; | ||||||
|  | } mouse_body_t; | ||||||
|  |  | ||||||
|  | mouse_body_t mouse_body; | ||||||
|  |  | ||||||
|  | void mouse_init() { | ||||||
|  |     body_init(&mouse_body.body); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void mouse_update() { | ||||||
|  |     POINT xy; | ||||||
|  |     GetCursorPos(&xy); | ||||||
|  |     int32_t new_x, new_y; | ||||||
|  |     body_update(&mouse_body.body, xy.x, xy.y, &new_x, &new_y); | ||||||
|  |     SetCursorPos(new_x, new_y); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // == window == | ||||||
|  | typedef struct window_body_t { | ||||||
|  |     HWND window; | ||||||
|  |     body_t body; | ||||||
|  | } window_body_t; | ||||||
|  |  | ||||||
|  | size_t n_windows; | ||||||
|  | window_body_t* windows; | ||||||
|  | size_t _n_new_windows; | ||||||
|  | window_body_t* _new_windows; | ||||||
|  |  | ||||||
|  | void window_init() { | ||||||
|  |     n_windows = 0; | ||||||
|  |     windows = calloc(sizeof(window_body_t), MAX_WINDOWS); | ||||||
|  |     _n_new_windows = 0; | ||||||
|  |     _new_windows = calloc(sizeof(window_body_t), MAX_WINDOWS); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | BOOL CALLBACK window_handle_enum(HWND window, LPARAM _) { | ||||||
|  |     if (_n_new_windows >= MAX_WINDOWS) { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |     if (!IsWindowVisible(window)) { | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     window_body_t new; | ||||||
|  |     new.window = window; | ||||||
|  |     body_init(&new.body); | ||||||
|  |     for (size_t i = 0; i < n_windows; i++) { | ||||||
|  |         if (windows[i].window == new.window) { | ||||||
|  |             new.body = windows[i].body; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     _new_windows[_n_new_windows++] = new; | ||||||
|  |     return 1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void window_enumerate() { | ||||||
|  |     EnumWindows(window_handle_enum, 0); | ||||||
|  |  | ||||||
|  |     // do the swap | ||||||
|  |     window_body_t* tmp_windows = windows; | ||||||
|  |  | ||||||
|  |     n_windows = _n_new_windows; | ||||||
|  |     windows = _new_windows; | ||||||
|  |  | ||||||
|  |     _n_new_windows = 0; | ||||||
|  |     _new_windows = tmp_windows; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void window_update() { | ||||||
|  |     window_enumerate(); | ||||||
|  |  | ||||||
|  |     for (size_t i = 0; i < n_windows; i++) { | ||||||
|  |         RECT rect; | ||||||
|  |         GetWindowRect(windows[i].window, &rect); | ||||||
|  |         int32_t x = rect.left; | ||||||
|  |         int32_t y = rect.bottom; | ||||||
|  |  | ||||||
|  |         body_update(&windows[i].body, x, y, &x, &y); | ||||||
|  |  | ||||||
|  |         int32_t height = rect.bottom - rect.top; | ||||||
|  |         uint32_t flags = SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_ASYNCWINDOWPOS; | ||||||
|  |         SetWindowPos(windows[i].window, 0, x, y - height, -1, -1, flags); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main() { | ||||||
|  |     globals_init(); | ||||||
|  |  | ||||||
|  |     mouse_init(); | ||||||
|  |     window_init(); | ||||||
|  |  | ||||||
|  |     while (1) { | ||||||
|  |         // mouse_update(); | ||||||
|  |         window_update(); | ||||||
|  |  | ||||||
|  |         Sleep(1000/120); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										3
									
								
								bounce_c/run.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								bounce_c/run.bat
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | del bounce.exe | ||||||
|  | zig cc bounce.c -o bounce.exe -Wall -Ofast | ||||||
|  | bounce.exe | ||||||
							
								
								
									
										72
									
								
								bounce_v1.py.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								bounce_v1.py.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | from ctypes import POINTER, WINFUNCTYPE, byref, windll | ||||||
|  | from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, POINT | ||||||
|  | import time | ||||||
|  | import math | ||||||
|  |  | ||||||
|  | user32 = windll.user32 | ||||||
|  | gdi32 = windll.gdi32 | ||||||
|  |  | ||||||
|  | user32.GetSystemMetrics.argtypes = [INT] | ||||||
|  |  | ||||||
|  | user32.GetCursorPos.argtypes = [LPPOINT] | ||||||
|  | user32.SetCursorPos.argtypes = [INT, INT] | ||||||
|  |  | ||||||
|  | CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) | ||||||
|  |  | ||||||
|  | def get_mouse() -> tuple[int, int]: | ||||||
|  |     point = POINT() | ||||||
|  |     user32.GetCursorPos(byref(point)) | ||||||
|  |     x, y = point.x, point.y | ||||||
|  |     return x, y | ||||||
|  |  | ||||||
|  | def get_resolution() -> tuple[int, int]: | ||||||
|  |     SM_CXSCREEN = 0 | ||||||
|  |     SM_CYSCREEN = 1 | ||||||
|  |  | ||||||
|  |     return ( | ||||||
|  |         user32.GetSystemMetrics(SM_CXSCREEN), | ||||||
|  |         user32.GetSystemMetrics(SM_CYSCREEN) | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  | def set_mouse(x: int, y: int): | ||||||
|  |     user32.SetCursorPos(x, y) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class MouseBody(object): | ||||||
|  |     def __init__(self): | ||||||
|  |         self._last_mouse = None | ||||||
|  |         self.velocity = 0.0 | ||||||
|  |      | ||||||
|  |     def update(self): | ||||||
|  |         mouse_x, mouse_y = get_mouse() | ||||||
|  |         if self._last_mouse: | ||||||
|  |             last_x, last_y = self._last_mouse | ||||||
|  |             dx = mouse_x - last_x | ||||||
|  |             dy = mouse_y - last_y | ||||||
|  |             dist = math.sqrt(dx * dx + dy * dy) | ||||||
|  |  | ||||||
|  |             # if they move the mouse they can fight it | ||||||
|  |             # (but they have to move it a lot) | ||||||
|  |             self.velocity *= 1.0 - min(dist / 64, 1.0) | ||||||
|  |  | ||||||
|  |         _, res_y = get_resolution() | ||||||
|  |         self.velocity += 1 | ||||||
|  |  | ||||||
|  |         new_y = int(mouse_y + self.velocity) | ||||||
|  |  | ||||||
|  |         if new_y > res_y: | ||||||
|  |             # simulate an inelastic collision | ||||||
|  |             self.velocity = -self.velocity * 0.75 | ||||||
|  |             new_y = int(new_y + self.velocity) | ||||||
|  |  | ||||||
|  |         set_mouse(mouse_x, new_y) | ||||||
|  |         self._last_mouse = (mouse_x, new_y) | ||||||
|  |  | ||||||
|  | def main(): | ||||||
|  |     body = MouseBody() | ||||||
|  |     while True: | ||||||
|  |         time.sleep(1/120.0) | ||||||
|  |         body.update() | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
							
								
								
									
										153
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | |||||||
|  | from abc import ABC, abstractmethod | ||||||
|  | from ctypes import WINFUNCTYPE, byref, windll | ||||||
|  | from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPPOINT, LPRECT, POINT, RECT | ||||||
|  | import time | ||||||
|  | import math | ||||||
|  |  | ||||||
|  | user32 = windll.user32 | ||||||
|  | gdi32 = windll.gdi32 | ||||||
|  |  | ||||||
|  | user32.GetSystemMetrics.argtypes = [INT] | ||||||
|  |  | ||||||
|  | user32.GetCursorPos.argtypes = [LPPOINT] | ||||||
|  | user32.SetCursorPos.argtypes = [INT, INT] | ||||||
|  |  | ||||||
|  | CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) | ||||||
|  |  | ||||||
|  | user32.EnumWindows.argtypes = [CB_ENUM_WINDOWS, LPARAM] | ||||||
|  |  | ||||||
|  | user32.GetWindowRect.argtypes = [HWND, LPRECT] | ||||||
|  | user32.SetWindowPos.argtypes = [HWND, INT, INT, INT, INT, INT, INT] | ||||||
|  | user32.IsWindowVisible.argtypes = [HWND] | ||||||
|  |  | ||||||
|  | class BouncyObject(ABC): | ||||||
|  |     @abstractmethod | ||||||
|  |     def get_position(self) -> tuple[int, int]: | ||||||
|  |         raise NotImplementedError | ||||||
|  |  | ||||||
|  |     @abstractmethod | ||||||
|  |     def set_position(self, xy: tuple[int, int]): | ||||||
|  |         raise NotImplementedError | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Mouse(BouncyObject): | ||||||
|  |     def get_position(self) -> tuple[int, int]: | ||||||
|  |         point = POINT() | ||||||
|  |         user32.GetCursorPos(byref(point)) | ||||||
|  |         return point.x, point.y  | ||||||
|  |  | ||||||
|  |     def set_position(self, xy: tuple[int, int]): | ||||||
|  |         x, y = xy | ||||||
|  |         user32.SetCursorPos(x, y) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Window(BouncyObject): | ||||||
|  |     def __init__(self, handle: int): | ||||||
|  |         self._handle = handle | ||||||
|  |      | ||||||
|  |     def get_position(self) -> tuple[int, int]: | ||||||
|  |         rect = RECT() | ||||||
|  |         user32.GetWindowRect(self._handle, byref(rect)) | ||||||
|  |         return (rect.left, rect.bottom) | ||||||
|  |      | ||||||
|  |     def set_position(self, xy: tuple[int, int]): | ||||||
|  |         rect = RECT() | ||||||
|  |         user32.GetWindowRect(self._handle, byref(rect)) | ||||||
|  |         width = rect.right - rect.left | ||||||
|  |         height = rect.bottom - rect.top | ||||||
|  |         x, y = xy | ||||||
|  |         user32.SetWindowPos( | ||||||
|  |             self._handle, 0, x, y - height, -1, -1,  | ||||||
|  |             0x0010 |  # SWP_NOACTIVATE | ||||||
|  |             0x0001 |  # SWP_NOSIZE | ||||||
|  |             0x0004 |  # SWP_NOZORDER | ||||||
|  |             0x4000  # SWP_ASYNCWINDOWPOS | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def enumerate_windows() -> list[int]: | ||||||
|  |     windows: list[int] = [] | ||||||
|  |  | ||||||
|  |     @CB_ENUM_WINDOWS | ||||||
|  |     def _handle_window(hwnd, lparam): | ||||||
|  |         if user32.IsWindowVisible(hwnd): | ||||||
|  |             windows.append(hwnd) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  |     user32.EnumWindows(_handle_window, 0) | ||||||
|  |     return windows | ||||||
|  |          | ||||||
|  |  | ||||||
|  | def get_resolution_y() -> int: | ||||||
|  |     SM_CYSCREEN = 1 | ||||||
|  |     return user32.GetSystemMetrics(SM_CYSCREEN) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Body(object): | ||||||
|  |     def __init__(self, controlled_object: BouncyObject): | ||||||
|  |         self._last_xy: tuple[int, int] | None =None | ||||||
|  |         self._last_offset: tuple[float, float] = (0.5, 0.5) | ||||||
|  |         self._velocity = 0.0 | ||||||
|  |         self._controlled_object = controlled_object | ||||||
|  |      | ||||||
|  |     def update(self, res_y): | ||||||
|  |         x, y = self._controlled_object.get_position() | ||||||
|  |         ox, oy = self._last_offset | ||||||
|  |         x += ox | ||||||
|  |         y += oy | ||||||
|  |  | ||||||
|  |         if self._last_xy: | ||||||
|  |             last_x, last_y = self._last_xy | ||||||
|  |             dx = x - last_x | ||||||
|  |             dy = y - last_y | ||||||
|  |             dist = math.sqrt(dx * dx + dy * dy) | ||||||
|  |  | ||||||
|  |             # if they move the mouse they can fight it | ||||||
|  |             # (but they have to move it a lot) | ||||||
|  |             self._velocity *= 1.0 - min(dist / 128, 1.0) | ||||||
|  |  | ||||||
|  |         for _ in range(100): | ||||||
|  |             self._velocity += 0.0002 | ||||||
|  |  | ||||||
|  |             y += self._velocity | ||||||
|  |             if y > res_y and self._velocity > 0: | ||||||
|  |                 self._velocity = -self._velocity * 0.75 | ||||||
|  |                 if abs(self._velocity) < 0.05: | ||||||
|  |                     self._velocity = 0 | ||||||
|  |  | ||||||
|  |         self._controlled_object.set_position((int(x), int(y))) | ||||||
|  |         self._last_xy = (int(x), int(y)) | ||||||
|  |         self._last_offset = (x % 1, y % 1) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class Bodies(object): | ||||||
|  |     def __init__(self): | ||||||
|  |         self._mouse = Body(Mouse()) | ||||||
|  |         self._windows = {} | ||||||
|  |      | ||||||
|  |     def update_list(self): | ||||||
|  |         windows2 = {} | ||||||
|  |         for i in enumerate_windows(): | ||||||
|  |             if existing := self._windows.get(i): | ||||||
|  |                 windows2[i] = existing | ||||||
|  |             else: | ||||||
|  |                 windows2[i] = Body(Window(i)) | ||||||
|  |         self._windows = windows2 | ||||||
|  |  | ||||||
|  |     def get(self) -> list[Body]: | ||||||
|  |         return [self._mouse, *self._windows.values()] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def main(): | ||||||
|  |     bodies = Bodies() | ||||||
|  |  | ||||||
|  |     while True: | ||||||
|  |         res_y = get_resolution_y() | ||||||
|  |         bodies.update_list() | ||||||
|  |         print(len(bodies.get())); | ||||||
|  |         for b in bodies.get(): | ||||||
|  |             b.update(res_y) | ||||||
|  |         time.sleep(1/120.0) | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
							
								
								
									
										88
									
								
								main.py.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								main.py.old
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | from ctypes import POINTER, WINFUNCTYPE, WinError, create_unicode_buffer, get_last_error, windll | ||||||
|  | from ctypes.wintypes import BOOL, DWORD, HBRUSH, HDC, HINSTANCE, HMENU, HWND, LPARAM, LPCWSTR, LPVOID, LPWSTR, INT, RECT | ||||||
|  | import time | ||||||
|  |  | ||||||
|  | user32 = windll.user32 | ||||||
|  | gdi32 = windll.gdi32 | ||||||
|  |  | ||||||
|  | CB_ENUM_WINDOWS = WINFUNCTYPE(BOOL, HWND, LPARAM) | ||||||
|  |  | ||||||
|  | # thanks: https://stackoverflow.com/questions/37501191/how-to-get-windows-window-names-with-ctypes-in-python | ||||||
|  | def check_zero(result, func, args): | ||||||
|  |     if not result: | ||||||
|  |         err = get_last_error() | ||||||
|  |         if err: | ||||||
|  |             raise WinError(err) | ||||||
|  |     return args | ||||||
|  |  | ||||||
|  | user32.CreateWindowExW.argtypes = [ | ||||||
|  |     DWORD, LPCWSTR, LPCWSTR, DWORD, | ||||||
|  |     INT, INT, INT, INT,  | ||||||
|  |     HWND, HMENU, HINSTANCE, LPVOID | ||||||
|  | ] | ||||||
|  | user32.CreateWindowExW.errcheck = check_zero | ||||||
|  |  | ||||||
|  | user32.FillRect.argtypes = [HDC, POINTER(RECT), HBRUSH] | ||||||
|  |  | ||||||
|  | user32.GetWindowDC.argtypes = [HWND] | ||||||
|  | user32.GetWindowDC.errcheck = check_zero | ||||||
|  |  | ||||||
|  | user32.GetWindowTextLengthW.argtypes = [HWND] | ||||||
|  | user32.GetWindowTextLengthW.errcheck = check_zero | ||||||
|  |  | ||||||
|  | user32.GetWindowTextW.argtypes = [HWND, LPWSTR, INT] | ||||||
|  | user32.GetWindowTextW.errcheck = check_zero | ||||||
|  |  | ||||||
|  | def find_all_windows(): | ||||||
|  |     windows = [] | ||||||
|  |  | ||||||
|  |     @CB_ENUM_WINDOWS | ||||||
|  |     def _handle_window(hwnd, lparam): | ||||||
|  |         # +1: make room for the null  | ||||||
|  |         length = user32.GetWindowTextLengthW(hwnd) + 1 | ||||||
|  |         buffer = create_unicode_buffer(length) | ||||||
|  |         user32.GetWindowTextW(hwnd, buffer, length) | ||||||
|  |         windows.append((hwnd, buffer.value)) | ||||||
|  |         return True | ||||||
|  |  | ||||||
|  |     user32.EnumWindows(_handle_window, 0) | ||||||
|  |     return windows | ||||||
|  |  | ||||||
|  | def fix_window(window): | ||||||
|  |     """ | ||||||
|  |     hdc = user32.GetWindowDC(window) | ||||||
|  |     rect = RECT(0, 0, 10000, 10000) | ||||||
|  |     brush = gdi32.CreateSolidBrush(0x00FF0000) | ||||||
|  |     user32.FillRect(hdc, rect, brush) | ||||||
|  |     gdi32.DeleteObject(brush) | ||||||
|  |     print(window) | ||||||
|  |     """ | ||||||
|  |     classname = create_unicode_buffer("overlapper\x00") | ||||||
|  |     windowname = create_unicode_buffer("overlapper\x00") | ||||||
|  |     window = user32.CreateWindowExW( | ||||||
|  |         0x08000000 |  # WS_EX_NOACTIVATE | ||||||
|  |         0x8 |  # WS_EX_TOPMOST | ||||||
|  |         0x0, # 0x20,  # WS_EX_TRANSPARENT | ||||||
|  |         classname, | ||||||
|  |         windowname, | ||||||
|  |         0x10000000,  # WS_VISIBLE | ||||||
|  |         0, 0, 128, 128,  # x y w h | ||||||
|  |         None, None, | ||||||
|  |         None, None | ||||||
|  |     ) | ||||||
|  |     user32.ShowWindow(window, 5)  # SW_SHOW | ||||||
|  |  | ||||||
|  | def fix_step(): | ||||||
|  |     windows = find_all_windows() | ||||||
|  |     for window_id, window_name in windows: | ||||||
|  |         if window_name.endswith("Visual Studio Code"): | ||||||
|  |             fix_window(window_id) | ||||||
|  |  | ||||||
|  | def main(): | ||||||
|  |     fix_step() | ||||||
|  |  | ||||||
|  |     while True: | ||||||
|  |         time.sleep(1) | ||||||
|  |  | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
		Reference in New Issue
	
	Block a user