diff --git a/CHANGES.txt b/CHANGES.txt index 8641ffc..88cabb5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,4 @@ +0.93, 2026/XX/XX -- ALL: Replaced bare `except:` clauses with `except Exception:`, preventing accidental suppression of system-exit signals (KeyboardInterrupt, SystemExit) during error handling. 0.8, 2023/10/11 -- ALL: Added saveSetup() and restoreSetup(). Fixed / Improved watchdog (especially in Linux). Fixed / improved setPosition() method LINUX: Added ewmhlib as separate module. Fixed watchdog (freezing randomly invoking screen_resources and get_output_info), fixed workarea crash (some apps/environments do not set it), improved to work almost fine in Manjaro/KDE, avoid crashing in Wayland for "fake" :1 display (though module won't likely work) WIN32: Fixed dev.StateFlags returning weird values for multi-monitor. Fixed GetAwarenessFromDpiAwarenessContext not supported on Windows Server diff --git a/src/pymonctl/_main.py b/src/pymonctl/_main.py index 908a315..1cd6dcd 100644 --- a/src/pymonctl/_main.py +++ b/src/pymonctl/_main.py @@ -229,7 +229,7 @@ def restoreSetup(setup: List[Tuple[Monitor, ScreenValue]]): if not monitor.isAttached: try: monitor.attach() - except: + except Exception: continue if monitor.isAttached: if monitor.isSuspended or not monitor.isOn: @@ -743,7 +743,7 @@ def getMonitors(self) -> list[Monitor]: for screen in self._screens.keys(): try: monitors.append(Monitor(self._screens[screen]["id"])) - except: + except Exception: pass return monitors @@ -826,7 +826,7 @@ def plugListenerUnregister(monitorCountChanged: Callable[[List[str], dict[str, S try: objIndex = _plugListeners.index(monitorCountChanged) _plugListeners.pop(objIndex) - except: + except Exception: pass global _changeListeners global _updateRequested @@ -866,7 +866,7 @@ def changeListenerUnregister(monitorPropsChanged: Callable[[List[str], dict[str, try: objIndex = _changeListeners.index(monitorPropsChanged) _changeListeners.pop(objIndex) - except: + except Exception: pass global _plugListeners global _updateRequested diff --git a/src/pymonctl/_pymonctl_linux.py b/src/pymonctl/_pymonctl_linux.py index a5a77aa..afc00fd 100644 --- a/src/pymonctl/_pymonctl_linux.py +++ b/src/pymonctl/_pymonctl_linux.py @@ -269,7 +269,7 @@ def setPosition(self, relativePos: Union[int, Position, Point, Tuple[int, int]], try: index = monKeys.index(self.name) monKeys.pop(index) - except: + except Exception: return arrangement[self.name] = {"relativePos": relativePos, "relativeTo": None} xOffset = monitor.width_in_pixels @@ -428,7 +428,7 @@ def brightness(self) -> Optional[int]: if ret: try: value = int(float(ret) * 100) - except: + except Exception: pass return value @@ -448,7 +448,7 @@ def contrast(self) -> Optional[int]: try: r, g, b = ret.split(":") value = int((((1 / (float(r) or 1)) + (1 / (float(g) or 1)) + (1 / (float(b) or 1))) / 3) * 100) - except: + except Exception: pass return value @@ -608,7 +608,7 @@ def detach(self, permanent: bool = False): try: # randr.set_crtc_config() fails in Cinnamon randr.set_crtc_config(self.display, crtc, Xlib.X.CurrentTime, crtcInfo.x, crtcInfo.y, 0, crtcInfo.rotation, []) - except: + except Exception: cmd = "xrandr --output %s --mode %sx%s" % (self.name, 0, 0) _, _ = _runProc(cmd) @@ -640,7 +640,7 @@ def _GNOME_isScalingGlobal() -> Optional[bool]: return bool("scale-monitor-framebuffer" not in proc.stdout) else: return bool("x11-randr-fractional-scaling" not in proc.stdout) - except: + except Exception: pass return None @@ -656,7 +656,7 @@ def _GNOME_setGlobalScaling(setGlobal=True): proc = subprocess.run("grep -sl mutter /proc/*/maps", text=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if "/maps" in proc.stdout: cmd = '''gsettings set org.gnome.mutter experimental-features "['scale-monitor-framebuffer']"''' - except: + except Exception: pass else: cmd = '''gsettings set org.gnome.mutter experimental-features "['x11-randr-fractional-scaling']"''' @@ -670,7 +670,7 @@ def _GNOME_getScalingFactor() -> Optional[int]: if "WindowScalingFactor" in ret: try: return int(ret.split("WindowScalingFactor': <")[1][0]) - except: + except Exception: pass return None @@ -696,7 +696,7 @@ def _GNOME_getScalingFactor() -> Optional[int]: # # try: # import dbus -# except: +# except Exception: # return {}, {}, {} # # namespace = "org.gnome.Mutter.DisplayConfig" @@ -742,7 +742,7 @@ def _GNOME_getScalingFactor() -> Optional[int]: # # try: # import dbus -# except: +# except Exception: # return # # namespace = "org.gnome.Mutter.DisplayConfig" @@ -794,7 +794,7 @@ def _scale(name: str) -> Optional[Tuple[float, float]]: h = int(b) r = float(lines[1].replace("+", "").replace("*", "")) value = DisplayMode(w, h, r) - except: + except Exception: pass if value: monitors = _XgetMonitors(name) @@ -817,7 +817,7 @@ def _runProc(cmd: str): # Some commands will take some time to be executed and return required value proc = subprocess.run(cmd, text=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) #, timeout=3) return proc.returncode, proc.stdout - except: + except Exception: pass return -1, "" @@ -845,7 +845,7 @@ def _getMonitorsData(handle: Optional[int] = None) -> ( display, screen, root = rootData try: mons = randr.get_monitors(root).monitors - except: + except Exception: # In Cinnamon randr extension has no get_monitors() method (?!?!?!?) mons = _RgetAllMonitors() stopSearching = True @@ -885,7 +885,7 @@ def _XgetAllMonitors(name: str = ""): display, screen, root = rootData try: mons = randr.get_monitors(root).monitors - except: + except Exception: # In Cinnamon randr extension has no get_monitors() method (?!?!?!?) mons = _RgetAllMonitors() stopSearching = True @@ -940,7 +940,7 @@ def _RgetMonitorsInfo(activeOnly: bool = True): y = parts[2] w, h = parts[0].split("x") monInfo.append((name, primary, int(x), int(y), int(w), int(h))) - except: + except Exception: pass return monInfo diff --git a/src/pymonctl/_pymonctl_macos.py b/src/pymonctl/_pymonctl_macos.py index 0ca3ffc..4b90719 100644 --- a/src/pymonctl/_pymonctl_macos.py +++ b/src/pymonctl/_pymonctl_macos.py @@ -38,7 +38,7 @@ def _getAllMonitorsDict() -> dict[str, ScreenValue]: try: name = screen.localizedName() - except: + except Exception: # In older macOS, screen doesn't have localizedName() method name = "Display" + "_" + str(displayId) is_primary = Quartz.CGDisplayIsMain(displayId) == 1 @@ -246,7 +246,7 @@ def setPosition(self, relativePos: Union[int, Position, Point, Tuple[int, int]], try: index = monKeys.index(self.name) monKeys.pop(index) - except: + except Exception: return arrangement[self.name] = {"relativePos": Position.PRIMARY, "relativeTo": None} xOffset = self.screen.frame().size.width @@ -379,7 +379,7 @@ def setOrientation(self, orientation: Optional[Union[int, Orientation]]): try: ret = self._iokit.IOServiceRequestProbe(self._ioservice, options) - except: + except Exception: ret = 1 if ret != 0: self._useIOOrientation = False @@ -408,7 +408,7 @@ def brightness(self) -> Optional[int]: value = ctypes.c_float() try: ret = self._ds.DisplayServicesGetBrightness(self.handle, ctypes.byref(value)) - except: + except Exception: ret = 1 if ret == 0: res = value.value @@ -423,7 +423,7 @@ def brightness(self) -> Optional[int]: value = ctypes.c_double() try: ret = self._cd.CoreDisplay_Display_GetUserBrightness(self.handle, ctypes.byref(value)) - except: + except Exception: ret = 1 if ret == 0: res = value.value @@ -439,7 +439,7 @@ def brightness(self) -> Optional[int]: value = ctypes.c_float() try: ret = self._iokit.IODisplayGetFloatParameter(self._ioservice, 0, kDisplayBrightnessKey, ctypes.byref(value)) - except: + except Exception: ret = 1 if ret == 0: res = value.value @@ -465,7 +465,7 @@ def setBrightness(self, brightness: Optional[int]): ret = 0 if self._ds.DisplayServicesCanChangeBrightness(self.handle): ret = self._ds.DisplayServicesSetBrightness(self.handle, value) - except: + except Exception: ret = 1 if ret != 0: self._useDS = False @@ -478,7 +478,7 @@ def setBrightness(self, brightness: Optional[int]): value = ctypes.c_double(brightness / 100) try: ret = self._cd.CoreDisplay_Display_SetUserBrightness(self.handle, value) - except: + except Exception: ret = 1 if ret != 0: self._useCD = False @@ -492,7 +492,7 @@ def setBrightness(self, brightness: Optional[int]): value = ctypes.c_float(brightness / 100) try: ret = self._iokit.IODisplaySetFloatParameter(self._ioservice, 0, kDisplayBrightnessKey, value) - except: + except Exception: ret = 1 if ret != 0: self._useIOBrightness = False @@ -508,7 +508,7 @@ def contrast(self) -> Optional[int]: CG.CGGetDisplayTransferByFormula(self.handle, None, None, None, None, None, None, None, None, None)) if ret == 0: contrast = int((float(redGamma) + float(greenGamma) + float(blueGamma)) / 3 * 100) - except: + except Exception: pass return contrast @@ -608,7 +608,7 @@ def turnOn(self): cmd = "caffeinate -u -t 2" try: _ = subprocess.run(cmd, text=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=1) - except: + except Exception: pass def turnOff(self): @@ -623,7 +623,7 @@ def suspend(self): cmd = "pmset displaysleepnow" try: _ = subprocess.run(cmd, text=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=1) - except: + except Exception: pass @property @@ -651,7 +651,7 @@ def _getName(displayId: int, screen: Optional[AppKit.NSScreen] = None): break try: scrName = cast(AppKit.NSScreen, screen).localizedName() + "_" + str(displayId) - except: + except Exception: # In older macOS, screen doesn't have localizedName() method scrName = "Display" + "_" + str(displayId) return scrName @@ -711,7 +711,7 @@ def _loadDisplayServices(): # Display Services Framework can be used in modern systems. It takes A LOT to load try: ds: ctypes.CDLL = ctypes.cdll.LoadLibrary('/System/Library/PrivateFrameworks/DisplayServices.framework/DisplayServices') - except: + except Exception: return None return ds @@ -725,7 +725,7 @@ def _loadCoreDisplay(): cd: ctypes.CDLL = ctypes.cdll.LoadLibrary(lib) cd.CoreDisplay_Display_SetUserBrightness.argtypes = [ctypes.c_int, ctypes.c_double] cd.CoreDisplay_Display_GetUserBrightness.argtypes = [ctypes.c_int, ctypes.c_void_p] - except: + except Exception: return None return cd @@ -762,7 +762,7 @@ class _CFString(ctypes.Structure): try: service: int = Quartz.CGDisplayIOServicePort(displayID) - except: + except Exception: service = 0 # Check if this works in an actual macOS (preferably in several versions) @@ -800,7 +800,7 @@ class _CFString(ctypes.Structure): if service: return iokit, CF, service - except: + except Exception: pass return None, None, None diff --git a/src/pymonctl/_pymonctl_win.py b/src/pymonctl/_pymonctl_win.py index 2237973..88f0713 100644 --- a/src/pymonctl/_pymonctl_win.py +++ b/src/pymonctl/_pymonctl_win.py @@ -46,7 +46,7 @@ def _getAllMonitors() -> list[Win32Monitor]: hMon = mon[0].handle try: monitors.append(Win32Monitor(hMon)) - except: + except Exception: pass return monitors @@ -70,10 +70,10 @@ def _getAllMonitorsDict() -> dict[str, ScreenValue]: ctypes.windll.shcore.GetDpiForMonitor(hMon, 0, ctypes.byref(dpiX), ctypes.byref(dpiY)) try: settings = win32api.EnumDisplaySettings(monName, win32con.ENUM_CURRENT_SETTINGS) - except: + except Exception: try: settings = win32api.EnumDisplaySettings(monName, win32con.ENUM_REGISTRY_SETTINGS) - except: + except Exception: continue rot = Orientation(settings.DisplayOrientation) @@ -106,7 +106,7 @@ def _findMonitor(x: int, y: int) -> List[Win32Monitor]: if hMon and hasattr(hMon, "handle"): try: return [Win32Monitor(hMon.handle)] - except: + except Exception: pass return [] @@ -220,7 +220,7 @@ def __init__(self, handle: Optional[int] = None): self._isWindows11 = False try: self._isWindows11 = bool(int(platform.win32_ver()[1].rsplit(".", 1)[1]) >= 22000) - except: + except Exception: self._isWindows11 = False @property @@ -263,7 +263,7 @@ def setPosition(self, relativePos: Union[int, Position, Point, Tuple[int, int]], try: index = monKeys.index(self.name) monKeys.pop(index) - except: + except Exception: return arrangement[self.name] = {"relativePos": Position.PRIMARY, "relativeTo": None} x, y, r, b = monitors[self.name]["monitor"]["Monitor"] @@ -394,7 +394,7 @@ def setScale(self, scale: Optional[Tuple[float, float]], applyGlobally: bool = T else: try: targetScale = _DPI_VALUES.index(scaleValue) - except: + except Exception: for i, value in enumerate(_DPI_VALUES): targetScale = i if value > scaleValue: @@ -421,10 +421,10 @@ def orientation(self) -> Optional[Union[int, Orientation]]: settings = None try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_CURRENT_SETTINGS) - except: + except Exception: try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_REGISTRY_SETTINGS) - except: + except Exception: pass if settings: return Orientation(settings.DisplayOrientation) @@ -435,10 +435,10 @@ def setOrientation(self, orientation: Optional[Union[int, Orientation]]): # In most cases an empty struct is required, but in this case we need to retrieve Display Settings first try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_CURRENT_SETTINGS) - except: + except Exception: try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_REGISTRY_SETTINGS) - except: + except Exception: return if (settings.DisplayOrientation + orientation) % 2 == 1: settings.PelsWidth, settings.PelsHeight = settings.PelsHeight, settings.PelsWidth @@ -453,10 +453,10 @@ def frequency(self) -> Optional[float]: settings = None try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_CURRENT_SETTINGS) - except: + except Exception: try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_REGISTRY_SETTINGS) - except: + except Exception: pass if settings: return settings.DisplayFrequency @@ -468,10 +468,10 @@ def colordepth(self) -> Optional[int]: settings = None try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_CURRENT_SETTINGS) - except: + except Exception: try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_REGISTRY_SETTINGS) - except: + except Exception: pass if settings: return settings.BitsPerPel @@ -542,10 +542,10 @@ def mode(self) -> Optional[DisplayMode]: settings = None try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_CURRENT_SETTINGS) - except: + except Exception: try: settings = win32api.EnumDisplaySettings(self.name, win32con.ENUM_REGISTRY_SETTINGS) - except: + except Exception: pass if settings: return DisplayMode(settings.PelsWidth, settings.PelsHeight, settings.DisplayFrequency) @@ -580,7 +580,7 @@ def allModes(self) -> list[DisplayMode]: try: winSettings = win32api.EnumDisplaySettings(self.name, i) modes.append(DisplayMode(winSettings.PelsWidth, winSettings.PelsHeight, winSettings.DisplayFrequency)) - except: + except Exception: break i += 1 return modes @@ -797,7 +797,7 @@ def _win32getAllMonitorsDict(): try: monitorInfo = win32api.GetMonitorInfo(hMon) monitors[monitorInfo["Device"]] = {"hMon": hMon, "monitor": monitorInfo} - except: + except Exception: pass return monitors @@ -820,7 +820,7 @@ def _findNewHandles(): if instance.name == monInfo.get("Device", ""): instance.handle = hMon break - except: + except Exception: stopSearching = False break if stopSearching: @@ -832,7 +832,7 @@ def _getMonitorInfo(handle: int): try: monitorInfo = win32api.GetMonitorInfo(handle) return monitorInfo - except: + except Exception: pass return None @@ -860,7 +860,7 @@ def _win32destroyPhysicalMonitors(hDevices): for hDevice in hDevices: try: ctypes.windll.dxva2.DestroyPhysicalMonitor(hDevice) - except: + except Exception: pass diff --git a/tests/test_pymonctl.py b/tests/test_pymonctl.py index b86b45a..43987fd 100644 --- a/tests/test_pymonctl.py +++ b/tests/test_pymonctl.py @@ -40,7 +40,7 @@ def changedCB(names: List[str], info: dict[str, pmc.ScreenValue]): try: initArrangement = pmc.saveSetup() print("INITIAL POSITIONS:", initArrangement) -except: +except Exception: for monitor in monitorsPlugged: initDict[monitor.name] = {"relativePos": cast(pmc.Point, monitor.position)} if monitor.isPrimary: