Skip to content

Commit 7e9a697

Browse files
committed
Move the shm_fallback_reason to a more general performance_status property.
1 parent c6f31c3 commit 7e9a697

3 files changed

Lines changed: 26 additions & 35 deletions

File tree

docs/source/examples/linux_xshm_backend.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
screenshot = sct.grab(sct.monitors[1])
1111
print(f"Captured screenshot dimensions: {screenshot.size.width}x{screenshot.size.height}")
1212

13-
print(f"shm_status: {sct.shm_status.name}")
14-
if sct.shm_fallback_reason:
15-
print(f"Falling back to XGetImage because: {sct.shm_fallback_reason}")
16-
else:
17-
print("MIT-SHM capture active.")
13+
print("Did MIT-SHM work:")
14+
for message in sct.performance_status:
15+
print(message)

src/mss/base.py

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
if TYPE_CHECKING:
1818
from collections.abc import Callable, Iterator
1919

20-
from mss.linux.xshmgetimage import ShmStatus
2120
from mss.models import Monitor, Monitors, Size
2221

2322
# Prior to 3.11, Python didn't have the Self type. typing_extensions does, but we don't want to depend on it.
@@ -74,7 +73,7 @@ class MSSImplementation(ABC):
7473
MSS object will hold a lock during these calls.
7574
"""
7675

77-
__slots__ = ("with_cursor",)
76+
__slots__ = ("performance_status", "with_cursor")
7877

7978
with_cursor: bool
8079

@@ -87,6 +86,10 @@ def __init__(self, /, *, with_cursor: bool = False) -> None:
8786
# Xlib is legacy, and just complicates things.
8887
self.with_cursor = with_cursor
8988

89+
# Any notes the backend needs to give the user for debugging purposes, like why it had to fall back to a
90+
# slower implementation.
91+
self.performance_status: list[str] = []
92+
9093
@abstractmethod
9194
def cursor(self) -> ScreenShot | None:
9295
"""Retrieve all cursor data. Pixels have to be RGB."""
@@ -169,15 +172,17 @@ class MSS:
169172
170173
:param backend: Backend selector, for platforms with multiple backends.
171174
:param compression_level: PNG compression level.
172-
:param with_cursor: Include the mouse cursor in screenshots (GNU/Linux only)
175+
:param with_cursor: Include the mouse cursor in screenshots
176+
(GNU/Linux only)
173177
:type display: bool, optional (default False)
174178
:param display: X11 display name (GNU/Linux only).
175179
:type display: bytes | str, optional (default :envvar:`$DISPLAY`)
176180
:param max_displays: Maximum number of displays to enumerate (macOS only).
177181
:type max_displays: int, optional (default 32)
178182
179183
.. versionadded:: 8.0.0
180-
``compression_level``, ``display``, ``max_displays``, and ``with_cursor`` keyword arguments.
184+
``compression_level``, ``display``, ``max_displays``, and
185+
``with_cursor`` keyword arguments.
181186
182187
.. versionadded:: 10.2.0
183188
``backend`` keyword argument.
@@ -498,35 +503,23 @@ def _cfactory(
498503
# max_displays, should probably be removed in 11.0. with_cursor
499504
# should probably be moved to MSS instead of MSSImplementation (as
500505
# noted there).
501-
#
502-
# The shm_status is mostly a debugging field, and probably should
503-
# be replaced with something different. Ideas include a log
504-
# message, an exception if the user explicitly requested
505-
# xshmgetimage, or a platform-independent message attribute (for
506-
# instance, if Windows has to fall back to GDI).
507506

508507
@property
509-
def shm_status(self) -> ShmStatus:
510-
"""Whether we can use the MIT-SHM extensions for this connection.
508+
def performance_status(self) -> list[str]:
509+
"""Implementation-specific notes that might affect performance.
511510
512-
Availability: GNU/Linux, when using the default XShmGetImage backend.
511+
For instance, on GNU/Linux, when using the default XShmGetImage
512+
backend, this will include a note if the MIT-SHM extension is
513+
not usable.
513514
514-
This will not be ``AVAILABLE`` until at least one capture has succeeded.
515-
It may be set to ``UNAVAILABLE`` sooner.
516-
517-
.. versionadded:: 10.2.0
518-
"""
519-
return self._impl.shm_status # type: ignore[attr-defined]
520-
521-
@property
522-
def shm_fallback_reason(self) -> str | None:
523-
"""If MIT-SHM is unavailable, the reason why (for debugging purposes).
515+
This may not be ready until one screenshot has been taken.
524516
525-
Availability: GNU/Linux, when using the default XShmGetImage backend.
517+
This is meant only for debugging purposes; the contents are
518+
subject to change at any time.
526519
527520
.. versionadded:: 10.2.0
528521
"""
529-
return self._impl.shm_fallback_reason # type: ignore[attr-defined]
522+
return self._impl.performance_status
530523

531524
@property
532525
def max_displays(self) -> int:

src/mss/linux/xshmgetimage.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
This implementation prefers shared-memory captures for performance and will
77
fall back to XGetImage when the MIT-SHM extension is unavailable or fails at
8-
runtime. The fallback reason is exposed via ``shm_fallback_reason`` to aid
8+
runtime. The fallback reason is exposed via ``performance_status`` to aid
99
debugging.
1010
1111
.. versionadded:: 10.2.0
@@ -61,8 +61,6 @@ def __init__(self, *, display: str | bytes | None = None, with_cursor: bool = Fa
6161
#: This will not be ``AVAILABLE`` until at least one capture has succeeded.
6262
#: It may be set to ``UNAVAILABLE`` sooner.
6363
self.shm_status: ShmStatus = self._setup_shm()
64-
#: If MIT-SHM is unavailable, the reason why (for debugging purposes).
65-
self.shm_fallback_reason: str | None = None
6664

6765
def _shm_report_issue(self, msg: str, *args: Any) -> None:
6866
"""Debugging hook for troubleshooting MIT-SHM issues.
@@ -73,7 +71,7 @@ def _shm_report_issue(self, msg: str, *args: Any) -> None:
7371
full_msg = msg
7472
if args:
7573
full_msg += " | " + ", ".join(str(arg) for arg in args)
76-
self.shm_fallback_reason = full_msg
74+
self.performance_status.append(full_msg)
7775

7876
def _setup_shm(self) -> ShmStatus: # noqa: PLR0911
7977
assert self.conn is not None # noqa: S101
@@ -200,7 +198,9 @@ def grab(self, monitor: Monitor) -> bytearray:
200198
# The usual path is just the next few lines.
201199
try:
202200
rv = self._grab_xshmgetimage(monitor)
203-
self.shm_status = ShmStatus.AVAILABLE
201+
if self.shm_status != ShmStatus.AVAILABLE:
202+
self.shm_status = ShmStatus.AVAILABLE
203+
self.performance_status.append("MIT-SHM is working correctly.")
204204
except XProtoError as e:
205205
if self.shm_status != ShmStatus.UNKNOWN:
206206
# We know XShmGetImage works, because it worked earlier. Reraise the error.

0 commit comments

Comments
 (0)