Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ See Git commit messages for full history.

## v10.2.0.dev0
(2026-xx-xx)
- Introduce a new API, mss.MSS, that we can keep stable as we continue to improve MSS. The previous documented API is deprecated, but still available, in 10.2. Some parts of the existing API (such as certain type names and internal variables) may be removed in 11.0, but the most important parts will remain available for as long as can be reasonably supported. (#486, #494)
- Add `is_primary`, `name`, and `unique_id` keys to Monitor dicts for primary monitor detection, device names, and stable per-monitor identification (#153)
- Add `primary_monitor` property to MSS base class for easy access to the primary monitor (#153)
- Windows: add primary monitor detection using `GetMonitorInfoW` API (#153)
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 10.2.0 (2026-xx-xx)

### base.py
- (This affected almost every file in some respect, but base.py was the most affected.) Introduced a new API, mss.MSS. This class can be used instead of the previous various MSSBase subclasses, so that the user can work with a consistent class regardless of implementation details. The methods implemented by MSSBase subclasses were renamed, and moved to MSSImplementation subclasses. The mss.MSS class now holds an MSSImplementation instance as an instance variable. (#486, #494)
- Added `primary_monitor` property to return the primary monitor (or first monitor as fallback).

### models.py
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
> [![Patreon](https://img.shields.io/badge/Patreon-F96854?style=for-the-badge&logo=patreon&logoColor=white)](https://www.patreon.com/mschoentgen)
```python
from mss import mss
from mss import MSS

# The simplest use, save a screenshot of the 1st monitor
with mss() as sct:
with MSS() as sct:
sct.shot()
```

Expand Down
2 changes: 1 addition & 1 deletion demos/cat-detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def main() -> None:
model_labels = weights.meta["categories"]
cat_label = model_labels.index("cat")

with mss.mss() as sct:
with mss.MSS() as sct:
monitor = sct.monitors[1]

# Compute the minimum size, in square pixels, that we'll consider reliable.
Expand Down
2 changes: 1 addition & 1 deletion demos/tinytv-stream-simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def main() -> None:
# Note that we use the same MSS object the whole time. We don't try to keep creating a new MSS object each
# time we take a new screenshot. That's because the MSS object has a lot of stuff that it sets up and
# remembers, and creating a new MSS object each time would mean that it has to repeat that setup constantly.
with mss.mss() as sct:
with mss.MSS() as sct:
# It's time to get the monitor that we're going to capture. In this demo, we just capture the first
# monitor. (We could also use monitors[0] for all the monitors combined.)
monitor = sct.monitors[1]
Expand Down
2 changes: 1 addition & 1 deletion demos/tinytv-stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def capture_image(
'width', 'height'.
:yields: PIL Image objects from the captured monitor.
"""
with mss.mss() as sct:
with mss.MSS() as sct:
rect = capture_area if capture_area is not None else sct.monitors[monitor]
LOGGER.debug("Capture area: %i,%i, %ix%i", rect["left"], rect["top"], rect["width"], rect["height"])

Expand Down
2 changes: 1 addition & 1 deletion demos/video-capture-simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def main() -> None:
# If we don't enable PyAV's own logging, a lot of important error messages from libav won't be shown.
av.logging.set_level(av.logging.VERBOSE)

with mss.mss() as sct:
with mss.MSS() as sct:
monitor = sct.monitors[1]

# Because of how H.264 video stores color information, libx264 requires the video size to be a multiple of
Expand Down
4 changes: 2 additions & 2 deletions demos/video-capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@

def video_capture(
fps: int,
sct: mss.base.MSSBase,
sct: mss.MSS,
monitor: mss.models.Monitor,
shutdown_requested: Event,
) -> Generator[tuple[mss.screenshot.ScreenShot, float], None, None]:
Expand Down Expand Up @@ -434,7 +434,7 @@ def main() -> None:
duration_secs = args.duration_secs
region_crop_to_multiple_of_two = args.region_crop_to_multiple_of_two

with mss.mss() as sct:
with mss.MSS() as sct:
if args.region:
left, top, right, bottom = args.region
monitor = {
Expand Down
60 changes: 0 additions & 60 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,7 @@ Core Package

.. automodule:: mss

Screenshot Objects
==================

.. automodule:: mss.screenshot

Base Classes
============

.. automodule:: mss.base

Tools
=====

.. automodule:: mss.tools

Exceptions
==========

.. automodule:: mss.exception

Data Models
===========

.. automodule:: mss.models

Platform Backends
=================

macOS Backend
-------------

.. automodule:: mss.darwin

GNU/Linux Dispatcher
--------------------

.. automodule:: mss.linux

GNU/Linux Xlib Backend
----------------------

.. automodule:: mss.linux.xlib

GNU/Linux XCB Base
------------------

.. automodule:: mss.linux.base

GNU/Linux XCB XGetImage Backend
-------------------------------

.. automodule:: mss.linux.xgetimage

GNU/Linux XCB XShmGetImage Backend
----------------------------------

.. automodule:: mss.linux.xshmgetimage

Windows Backend
---------------

.. automodule:: mss.windows


5 changes: 3 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
import ctypes

# Monkey-patch PROT_READ into mmap if missing (Windows), so that we can
# import mss.linux.xshmgetimage while building the documentation.
# import the Linux shared-memory backend implementation while building the
# documentation.
import mmap

if not hasattr(mmap, "PROT_READ"):
mmap.PROT_READ = 1 # type:ignore[attr-defined]
mmap.PROT_READ = 1

import mss

Expand Down
4 changes: 2 additions & 2 deletions docs/source/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Get PNG bytes, no file output
You can get the bytes of the PNG image:
::

with mss.mss() as sct:
with mss.MSS() as sct:
# The monitor or screen part to capture
monitor = sct.monitors[1] # or a region

Expand Down Expand Up @@ -203,7 +203,7 @@ Different possibilities to convert raw BGRA values to RGB::
return Image.frombytes('RGB', im.size, im.bgra, 'raw', 'BGRX').tobytes()


with mss.mss() as sct:
with mss.MSS() as sct:
im = sct.grab(sct.monitors[1])
rgb = pil_frombytes(im)
...
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ def on_exists(fname: str) -> None:
file.rename(newfile)


with mss.mss() as sct:
with mss.MSS() as sct:
filename = sct.shot(output="mon-{mon}.png", callback=on_exists)
print(filename)
2 changes: 1 addition & 1 deletion docs/source/examples/custom_cls_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def __init__(self, data: bytearray, monitor: Monitor, **_: Any) -> None:
self.monitor = monitor


with mss.mss() as sct:
with mss.MSS() as sct:
sct.cls_image = SimpleScreenShot
image = sct.grab(sct.monitors[1])
# ...
2 changes: 1 addition & 1 deletion docs/source/examples/fps.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def screen_record_efficient() -> int:

title = "[MSS] FPS benchmark"
fps = 0
sct = mss.mss()
sct = mss.MSS()
last_time = time.time()

while time.time() - last_time < 1:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/fps_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
def grab(queue: Queue) -> None:
rect = {"top": 0, "left": 0, "width": 600, "height": 800}

with mss.mss() as sct:
with mss.MSS() as sct:
for _ in range(1_000):
queue.put(sct.grab(rect))

Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/from_pil_tuple.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import mss
import mss.tools

with mss.mss() as sct:
with mss.MSS() as sct:
# Use the 1st monitor
monitor = sct.monitors[1]

Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/linux_display_keyword.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

import mss

with mss.mss(display=":0.0") as sct:
with mss.MSS(display=":0.0") as sct:
for filename in sct.save():
print(filename)
4 changes: 2 additions & 2 deletions docs/source/examples/linux_xshm_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
Select the XShmGetImage backend explicitly and inspect its status.
"""

from mss.linux.xshmgetimage import MSS as mss
from mss import MSS

with mss() as sct:
with MSS(backend="xshmgetimage") as sct:
screenshot = sct.grab(sct.monitors[1])
print(f"Captured screenshot dimensions: {screenshot.size.width}x{screenshot.size.height}")

Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/opencv_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import mss

with mss.mss() as sct:
with mss.MSS() as sct:
# Part of the screen to capture
monitor = {"top": 40, "left": 0, "width": 800, "height": 640}

Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/part_of_screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import mss
import mss.tools

with mss.mss() as sct:
with mss.MSS() as sct:
# The screen part to capture
monitor = {"top": 160, "left": 160, "width": 160, "height": 135}
output = "sct-{top}x{left}_{width}x{height}.png".format(**monitor)
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/part_of_screen_monitor_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import mss
import mss.tools

with mss.mss() as sct:
with mss.MSS() as sct:
# Get information of monitor 2
monitor_number = 2
mon = sct.monitors[monitor_number]
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/pil.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import mss

with mss.mss() as sct:
with mss.MSS() as sct:
# Get rid of the first, as it represents the "All in One" monitor:
for num, monitor in enumerate(sct.monitors[1:], 1):
# Get raw pixels from the screen
Expand Down
2 changes: 1 addition & 1 deletion docs/source/examples/pil_pixels.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import mss

with mss.mss() as sct:
with mss.MSS() as sct:
# Get a screenshot of the 1st monitor
sct_img = sct.grab(sct.monitors[1])

Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ Welcome to Python MSS's documentation!

.. code-block:: python
from mss import mss
from mss import MSS
# The simplest use, save a screenshot of the 1st monitor
with mss() as sct:
with MSS() as sct:
sct.shot()
Expand Down
Loading