|
| 1 | +# Python-MSS 10.2.0 |
| 2 | + |
| 3 | +This is **version 10.2.0 of Python-MSS**, the ultra-fast cross-platform multiple screenshots module. |
| 4 | + |
| 5 | +This release improves **performance, reliability, and multithreaded behavior**, and introduces several new features for working with multi-monitor systems. It also lays groundwork for upcoming improvements planned for **MSS 11.0**, while remaining fully backward-compatible. |
| 6 | + |
| 7 | +If your code works with previous versions of MSS, **it should continue to work unchanged in 10.2.0.** |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +# Highlights |
| 12 | + |
| 13 | +## Demo Applications |
| 14 | + |
| 15 | +The repository now includes several **full demo programs** under `demos/` showing common screenshot-processing workflows built on MSS. |
| 16 | + |
| 17 | +These examples are intended as **learning resources and reference implementations**. The demos include extensive comments explaining the pipeline architecture and performance considerations involved in real-world screenshot processing, as well as how to use MSS with several popular libraries. |
| 18 | + |
| 19 | +Included demos: |
| 20 | + |
| 21 | +### Video Recorder |
| 22 | +Records the screen to a video file using MSS frames. |
| 23 | + |
| 24 | +### TinyTV Streamer |
| 25 | +Streams the screen as **MJPEG** to a TinyTV device. |
| 26 | + |
| 27 | +### Cat Detector |
| 28 | +Demonstrates real-time computer vision by detecting cats appearing on the screen. |
| 29 | + |
| 30 | +While playful, these examples illustrate techniques for: |
| 31 | + |
| 32 | +- video capture |
| 33 | +- streaming |
| 34 | +- real-time analysis of screenshots |
| 35 | +- multithreaded pipelining |
| 36 | +- integration with PyAV, Pillow, and PyTorch |
| 37 | + |
| 38 | +## Richer Monitor Metadata |
| 39 | + |
| 40 | +**If you currently use `sct.monitors[1]` to select the primary display, you may prefer the new `sct.primary_monitor` property.** |
| 41 | + |
| 42 | +Monitor dictionaries now include additional metadata to help applications identify displays reliably: |
| 43 | + |
| 44 | +- `is_primary` — whether this monitor is the primary display |
| 45 | +- `name` — human-readable device name |
| 46 | +- `unique_id` — stable identifier for the display |
| 47 | + |
| 48 | +These values make it easier to: |
| 49 | + |
| 50 | +- detect the primary monitor |
| 51 | +- select a specific display across runs |
| 52 | +- handle dynamic multi-monitor configurations |
| 53 | + |
| 54 | +These new values are only present if they can be detected. In some cases (such as with a very old monitor), they may not be available. |
| 55 | + |
| 56 | +A new convenience property has also been added: |
| 57 | + |
| 58 | +```python |
| 59 | +sct.primary_monitor |
| 60 | +``` |
| 61 | + |
| 62 | +This returns the monitor dictionary corresponding to the system’s primary display. |
| 63 | + |
| 64 | +Currently available on: |
| 65 | + |
| 66 | +- **Windows** |
| 67 | +- **Linux** |
| 68 | + |
| 69 | +Support for macOS will be added in the future. |
| 70 | + |
| 71 | +## Multithreading Improvements |
| 72 | + |
| 73 | +Multithreaded usage of MSS has been improved and clarified. |
| 74 | + |
| 75 | +In 10.2.0: |
| 76 | + |
| 77 | +- **An `MSS` instance can safely be passed between threads** |
| 78 | +- **Calls to `grab()` on the same `MSS` instance remain serialized**, but are now guaranteed to be safe |
| 79 | +- **Multiple `MSS` instances can capture concurrently**, allowing parallel capture across threads |
| 80 | + |
| 81 | +Previously, some internal locking effectively serialized capture across all MSS usage. In 10.2.0, locking is now **per instance**, allowing independent MSS objects to perform captures simultaneously. |
| 82 | + |
| 83 | +The [documentation](https://python-mss.readthedocs.io/usage.html#multithreading) has also been expanded to describe MSS’s supported multithreading guarantees. |
| 84 | + |
| 85 | +On Linux, the new **XCB-based backend** further improves the reliability of multithreaded usage compared to the previous Xlib-based implementation. |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +## Improved Linux Capture Backend |
| 90 | + |
| 91 | +The Linux capture implementation has been significantly modernized to reduce capture overhead and improve multithreaded reliability. |
| 92 | + |
| 93 | +### New XCB Backend |
| 94 | + |
| 95 | +MSS now includes an **XCB-based backend stack**, replacing the previous Xlib-based implementation. XCB provides more predictable thread-safety and improves the reliability of multithreaded capture. |
| 96 | + |
| 97 | +The previous Xlib implementation remains available as a fallback for systems where the XCB backend cannot be used. See [the GNU/Linux usage documentation](https://python-mss.readthedocs.io/usage.html#gnu-linux) for configuration details. |
| 98 | + |
| 99 | +### Shared-Memory Capture (XShm) |
| 100 | + |
| 101 | +Linux now uses **`XShmGetImage`** by default, allowing MSS to capture screenshots using the X11 shared-memory extension when it is available. |
| 102 | + |
| 103 | +With this method, the X server writes pixel data directly into a shared memory buffer provided by the client, avoiding the extra copy required by the traditional `XGetImage` path. This reduces overhead during capture and dramatically improves performance for applications that take screenshots frequently. |
| 104 | + |
| 105 | +If shared memory is not available, MSS automatically falls back to `XGetImage`. |
| 106 | + |
| 107 | +### Capture Performance |
| 108 | + |
| 109 | +The new Linux backend can significantly reduce screenshot capture overhead. |
| 110 | + |
| 111 | +In local testing (local desktop system, Debian testing, X11, 4K display), a tight loop capturing the full screen (1000 iterations, best of three runs) improved from: |
| 112 | + |
| 113 | +``` |
| 114 | +10.1.0: 46.2 ms per screenshot |
| 115 | +10.2.0: 9.48 ms per screenshot |
| 116 | +``` |
| 117 | + |
| 118 | +This represents roughly a **5× reduction in capture time** in that environment. |
| 119 | + |
| 120 | +The improvement comes primarily from the new backend architecture and the use of the **X11 shared-memory extension (`XShmGetImage`)**, which avoids an additional memory copy when transferring pixel data from the X server. |
| 121 | + |
| 122 | +Actual performance improvements will vary depending on factors such as: |
| 123 | + |
| 124 | +- display resolution |
| 125 | +- X server configuration |
| 126 | +- hardware |
| 127 | +- whether the shared-memory capture path is available |
| 128 | + |
| 129 | +## Windows Capture Improvements |
| 130 | + |
| 131 | +The Windows screenshot implementation now uses **`CreateDIBSection`** instead of `GetDIBits`. |
| 132 | + |
| 133 | +This reduces memory overhead and improves reliability during long capture sessions. |
| 134 | + |
| 135 | +Additional improvements include: |
| 136 | + |
| 137 | +- improved Win32 error handling and diagnostics |
| 138 | +- fixes for capture failures during extended recordings |
| 139 | + |
| 140 | +## macOS Stability Fix |
| 141 | + |
| 142 | +A memory leak in the macOS backend has been fixed. |
| 143 | + |
| 144 | +--- |
| 145 | + |
| 146 | +# Deprecations and Upcoming Changes (Planned for 11.0) |
| 147 | + |
| 148 | +This release introduces deprecations that will take effect in **MSS 11.0**. |
| 149 | + |
| 150 | +These changes are intended to improve: |
| 151 | + |
| 152 | +- API clarity |
| 153 | +- type safety |
| 154 | +- future GPU capture support |
| 155 | +- internal performance |
| 156 | + |
| 157 | +Most users will **not need to change anything immediately**. |
| 158 | + |
| 159 | +If you are unsure whether you are affected, search your codebase for the names mentioned below. |
| 160 | + |
| 161 | +## Deprecated Attribute |
| 162 | + |
| 163 | +### `mss.ScreenShot.raw` |
| 164 | + |
| 165 | +**Status:** Deprecated |
| 166 | +**Removal:** 11.0 |
| 167 | + |
| 168 | +Use `bgra` instead. |
| 169 | + |
| 170 | +```python |
| 171 | +# Before |
| 172 | +data = screenshot.raw |
| 173 | + |
| 174 | +# After |
| 175 | +data = screenshot.bgra |
| 176 | +``` |
| 177 | + |
| 178 | +Important differences: |
| 179 | + |
| 180 | +- `raw` is **mutable** |
| 181 | +- `bgra` is **immutable** |
| 182 | + |
| 183 | +In 11.0, screenshot pixel buffers will no longer support in-place modification. |
| 184 | + |
| 185 | +If your application relies on modifying screenshot pixels directly, please [open an issue](https://github.com/BoboTiG/python-mss/issues/new) so we can discuss your use case. |
| 186 | + |
| 187 | +## Screenshot Class Changes |
| 188 | + |
| 189 | +To prepare for future GPU capture support, the screenshot class hierarchy will change in **11.0**. |
| 190 | + |
| 191 | +`ScreenShot` will become a base class with specialized implementations: |
| 192 | + |
| 193 | +``` |
| 194 | +ScreenShot |
| 195 | + └── ScreenShotCPU |
| 196 | +``` |
| 197 | + |
| 198 | +In preparation for this change, **10.2.0 introduces `ScreenShotCPU`** as a subclass of the current `ScreenShot` class. |
| 199 | + |
| 200 | +Users who rely on type annotations can begin migrating now: |
| 201 | + |
| 202 | +```python |
| 203 | +foo: mss.ScreenShotCPU = sct.grab() |
| 204 | +``` |
| 205 | + |
| 206 | +This annotation works in both **10.2.x** and **11.x**. |
| 207 | + |
| 208 | +If you do not use explicit type annotations, **no changes are required**. |
| 209 | + |
| 210 | +## Monitor Objects |
| 211 | + |
| 212 | +In 11.0, monitor dictionaries will become a dedicated **`Monitor` class**. |
| 213 | + |
| 214 | +To maintain compatibility: |
| 215 | + |
| 216 | +- dictionary-style access will continue to work |
| 217 | + |
| 218 | +```python |
| 219 | +monitor["left"] |
| 220 | +monitor["top"] |
| 221 | +``` |
| 222 | + |
| 223 | +- `grab()` will continue accepting dictionaries |
| 224 | + |
| 225 | +If you use type annotations, you can switch to the provided `Monitor` type: |
| 226 | + |
| 227 | +```python |
| 228 | +from mss.models import Monitor |
| 229 | +``` |
| 230 | + |
| 231 | +This works in both **10.2.x** and **11.x**. |
| 232 | + |
| 233 | +## `bgra` Return Type |
| 234 | + |
| 235 | +In 11.0, `ScreenShot.bgra` will return a **bytes-like object**, not necessarily a `bytes` instance. |
| 236 | + |
| 237 | +Code that treats the result as binary data will continue to work. |
| 238 | + |
| 239 | +If your code checks for an exact type, update it to accept bytes-like objects: |
| 240 | + |
| 241 | +```python |
| 242 | +isinstance(data, (bytes, bytearray, memoryview)) |
| 243 | +``` |
| 244 | + |
| 245 | +## `cls_image` Constructor Behavior |
| 246 | + |
| 247 | +The constructor signature used when providing a custom screenshot class via `cls_image` may change in 11.0. |
| 248 | + |
| 249 | +If you implement a custom class, ensure your constructor accepts flexible arguments: |
| 250 | + |
| 251 | +```python |
| 252 | +def __init__(self, *args, **kwargs): |
| 253 | +``` |
| 254 | + |
| 255 | +If you do not use `cls_image`, you are unaffected. |
| 256 | + |
| 257 | +## Internal Platform Attributes |
| 258 | + |
| 259 | +The following attributes were never intended as public API and will be removed in 11.0. |
| 260 | + |
| 261 | +If you need these system libraries, load them directly via `ctypes`. |
| 262 | + |
| 263 | +### Windows |
| 264 | +- `mss.windows.MSS.user32` |
| 265 | +- `mss.windows.MSS.gdi32` |
| 266 | + |
| 267 | +### macOS |
| 268 | +- `mss.darwin.MSS.max_displays` |
| 269 | + |
| 270 | +Most users are **not affected**. |
| 271 | + |
| 272 | +--- |
| 273 | + |
| 274 | +If you believe an upcoming change could impact your workflow, please [open an issue](https://github.com/BoboTiG/python-mss/issues/new) so we can discuss it before 11.0. |
0 commit comments