You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(linux): Implement an XShmGetImage-based backend (#431)
* Add XCB MIT-SHM support, and factor out the XCB setup
This only adds the support for the XCB MIT-SHM extension to mss's
internal xcb libraries. The actual usage of shared memory for
screenshots will be done in a future commit.
* Implement an XShmGetImage-based backend.
This is close to complete, but there's a few things that need to be
chased down: notably, the test_thread_safety test is failing, for some
reason. It also currently doesn't work correctly if the root window
size increases.
That said, this is quite promising: on my computer, the new backend
can take 4k screenshots at 30-34 fps, while the XGetImage backend
could only run at 11-14 fps.
* Expand the xcb-util-errors test to include xshmgetimage
* Track down the closed memfd.
Previously, I had been trying to close the memfd in _shutdown_shm, and
ignoring EBADF. It turns out that XCB will close the memfd when you
send it to the X server.
I think this was one potential cause of the issues I saw in
test_thread_safety: the two threads would be reallocated each others'
fds, leading to thread A closing an fd that thread B was using,
thinking that it was thread A's memfd.
Fix so that the memfd is only explicitly closed in an error situation.
* Ensure that an X11 connection is open during the test session.
Under X11, when the last client disconnects, the server resets. If
a new client tries to connect before the reset is complete, it may fail.
Since we often run the tests under Xvfb, they're frequently the only
clients. Since our tests run in rapid succession, this combination
can lead to intermittent failures.
To avoid this, we open a connection at the start of the test session
and keep it open until the end.
* Update the docs
Also, before marking XShmGetImage as unavailable if the first grab()
fails, also test to see if the fallback XGetImage also fails (such as
if the user gave an out-of-bounds rect). In that case, just reraise
the exception and try XShmGetImage again with the next grab().
* Changes that should have been in the previous commit
* Change the default backend on Linux to xshmgetimage
Also, fix a minor error in the docs formatting.
* Add a --backend argument to the CLI
Copy file name to clipboardExpand all lines: docs/source/usage.rst
+55-9Lines changed: 55 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@ Usage
5
5
Import
6
6
======
7
7
8
-
So MSS can be used as simply as::
8
+
MSS can be used as simply as::
9
9
10
10
from mss import mss
11
11
@@ -20,6 +20,11 @@ Or import the good one based on your operating system::
20
20
# Microsoft Windows
21
21
from mss.windows import MSS as mss
22
22
23
+
On GNU/Linux you can also import a specific backend (see :ref:`backends`)
24
+
directly when you need a particular implementation, for example::
25
+
26
+
from mss.linux.xshmgetimage import MSS as mss
27
+
23
28
24
29
Instance
25
30
========
@@ -49,18 +54,56 @@ This is a much better usage, memory efficient::
49
54
Also, it is a good thing to save the MSS instance inside an attribute of your class and calling it when needed.
50
55
51
56
57
+
.. _backends:
58
+
59
+
Backends
60
+
--------
61
+
62
+
Some platforms have multiple ways to take screenshots. In MSS, these are known as *backends*. The :py:func:`mss` functions will normally autodetect which one is appropriate for your situation, but you can override this if you want. For instance, you may know that your specific situation requires a particular backend.
63
+
64
+
If you want to choose a particular backend, you can use the :py::`backend` keyword to :py:func:`mss`::
65
+
66
+
with mss(backend="xgetimage") as sct:
67
+
...
68
+
69
+
Alternatively, you can also directly import the backend you want to use::
70
+
71
+
from mss.linux.xgetimage import MSS as mss
72
+
73
+
Currently, only the GNU/Linux implementation has multiple backends. These are described in their own section below.
74
+
75
+
52
76
GNU/Linux
53
77
---------
54
78
55
-
On GNU/Linux, you can specify which display to use (useful for distant screenshots via SSH)::
56
-
57
-
with mss(display=":0.0") as sct:
58
-
# ...
79
+
Display
80
+
^^^^^^^
59
81
60
-
A more specific example (only valid on GNU/Linux):
82
+
On GNU/Linux, the default display is taken from the :envvar:`DISPLAY` environment variable. You can instead specify which display to use (useful for distant screenshots via SSH) using the ``display`` keyword:
The GNU/Linux implementation has multiple backends (see :ref:`backends`), or ways it can take screenshots. The :py:func:`mss.mss` and :py:func:`mss.linux.mss` functions will normally autodetect which one is appropriate, but you can override this if you want.
92
+
93
+
There are three available backends.
94
+
95
+
:py:mod:`xshmgetimage` (default)
96
+
The fastest backend, based on :c:func:`xcb_shm_get_image`. It is roughly three times faster than :py:mod:`xgetimage`
97
+
and is used automatically. When the MIT-SHM extension is unavailable (for example on remote SSH displays), it
98
+
transparently falls back to :py:mod:`xgetimage` so you can always request it safely.
99
+
100
+
:py:mod:`xgetimage`
101
+
A highly-compatible, but slower, backend based on :c:func:`xcb_get_image`. Use this explicitly only when you know
102
+
that :py:mod:`xshmgetimage` cannot operate in your environment.
103
+
104
+
:py:mod:`xlib`
105
+
The legacy backend powered by :c:func:`XGetImage`. It is kept solely for systems where XCB libraries are
106
+
unavailable and no new features are being added to it.
64
107
65
108
66
109
Command Line
@@ -73,8 +116,8 @@ You can use ``mss`` via the CLI::
0 commit comments