New Upstream Snapshot - screeninfo

Ready changes

Summary

Merged new upstream version: 0.8.1 (was: 0.6.7).

Resulting package

Built on 2022-10-21T07:48 (took 3m3s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots python3-screeninfo

Lintian Result

Diff

diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 5ebe98c..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-build/
-dist/
-*.egg-info/
-MANIFEST
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..96ac14f
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,97 @@
+Metadata-Version: 2.1
+Name: screeninfo
+Version: 0.8.1
+Summary: Fetch location and size of physical screens.
+Home-page: https://github.com/rr-/screeninfo
+License: MIT
+Author: Marcin Kurczewski
+Author-email: rr-@sakuya.pl
+Requires-Python: >=3.6.2,<4.0.0
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Natural Language :: English
+Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX :: Linux
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Topic :: Desktop Environment
+Classifier: Topic :: System :: Operating System
+Classifier: Typing :: Typed
+Requires-Dist: Cython; sys_platform == "darwin"
+Requires-Dist: dataclasses; python_version < "3.7"
+Requires-Dist: pyobjc-framework-Cocoa; sys_platform == "darwin"
+Project-URL: Repository, https://github.com/rr-/screeninfo
+Description-Content-Type: text/markdown
+
+screeninfo
+----------
+
+[![Build](https://github.com/rr-/screeninfo/actions/workflows/build.yml/badge.svg)](https://github.com/rr-/screeninfo/actions/workflows/build.yml)
+
+Fetch location and size of physical screens.
+
+### Supported environments
+
+- MS Windows
+- MS Windows: Cygwin
+- GNU/Linux: X11 (through Xinerama)
+- GNU/Linux: DRM (experimental)
+- OSX: (through AppKit)
+
+I don't plan on testing OSX or other environments myself. For this reason,
+I strongly encourage pull requests.
+
+### Installation
+
+```
+pip install screeninfo
+```
+
+### Usage
+
+```python
+from screeninfo import get_monitors
+for m in get_monitors():
+    print(str(m))
+```
+
+**Output**:
+
+```python console
+Monitor(x=3840, y=0, width=3840, height=2160, width_mm=1420, height_mm=800, name='HDMI-0', is_primary=False)
+Monitor(x=0, y=0, width=3840, height=2160, width_mm=708, height_mm=399, name='DP-0', is_primary=True)
+```
+
+### Forcing environment
+
+In some cases (emulating X server on Cygwin etc.) you might want to specify the
+driver directly. You can do so by passing extra parameter to `get_monitors()`
+like this:
+
+```python
+from screeninfo import get_monitors, Enumerator
+for m in get_monitors(Enumerator.OSX):
+    print(str(m))
+```
+
+Available drivers: `windows`, `cygwin`, `x11`, `osx`.
+
+# Contributing
+
+
+```sh
+git clone https://github.com/rr-/screeninfo.git # clone this repo
+cd screeninfo
+poetry install # to install the local venv
+poetry run pre-commit install # to setup pre-commit hooks
+poetry shell # to enter the venv
+```
+
+This project uses [poetry](https://python-poetry.org/) for packaging,
+install instructions at [poetry#installation](https://python-poetry.org/docs/#installation)
+
diff --git a/README.md b/README.md
index 71a4f62..771ec81 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 screeninfo
 ----------
 
+[![Build](https://github.com/rr-/screeninfo/actions/workflows/build.yml/badge.svg)](https://github.com/rr-/screeninfo/actions/workflows/build.yml)
+
 Fetch location and size of physical screens.
 
 ### Supported environments
@@ -9,7 +11,7 @@ Fetch location and size of physical screens.
 - MS Windows: Cygwin
 - GNU/Linux: X11 (through Xinerama)
 - GNU/Linux: DRM (experimental)
-- OSX: (through PyOBJus)
+- OSX: (through AppKit)
 
 I don't plan on testing OSX or other environments myself. For this reason,
 I strongly encourage pull requests.
@@ -20,12 +22,6 @@ I strongly encourage pull requests.
 pip install screeninfo
 ```
 
-If you install it from sources:
-
-```
-python3 setup.py install
-```
-
 ### Usage
 
 ```python
@@ -36,8 +32,10 @@ for m in get_monitors():
 
 **Output**:
 
->Monitor(x=1920, y=0, width=1920, height=1080, name=None)  
->Monitor(x=0, y=0, width=1920, height=1080, name=None)
+```python console
+Monitor(x=3840, y=0, width=3840, height=2160, width_mm=1420, height_mm=800, name='HDMI-0', is_primary=False)
+Monitor(x=0, y=0, width=3840, height=2160, width_mm=708, height_mm=399, name='DP-0', is_primary=True)
+```
 
 ### Forcing environment
 
@@ -52,3 +50,17 @@ for m in get_monitors(Enumerator.OSX):
 ```
 
 Available drivers: `windows`, `cygwin`, `x11`, `osx`.
+
+# Contributing
+
+
+```sh
+git clone https://github.com/rr-/screeninfo.git # clone this repo
+cd screeninfo
+poetry install # to install the local venv
+poetry run pre-commit install # to setup pre-commit hooks
+poetry shell # to enter the venv
+```
+
+This project uses [poetry](https://python-poetry.org/) for packaging,
+install instructions at [poetry#installation](https://python-poetry.org/docs/#installation)
diff --git a/debian/changelog b/debian/changelog
index f0ee0e5..4fa8c3b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+screeninfo (0.8.1-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Fri, 21 Oct 2022 07:47:17 -0000
+
 screeninfo (0.6.7-1) unstable; urgency=medium
 
   [ Debian Janitor ]
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..9dc0fa3
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,50 @@
+[tool.poetry]
+name = "screeninfo"
+version = "0.8.1"
+description = "Fetch location and size of physical screens."
+authors = ["Marcin Kurczewski <rr-@sakuya.pl>"]
+license = "MIT"
+readme = "README.md"
+repository = "https://github.com/rr-/screeninfo"
+classifiers = [
+    "Development Status :: 4 - Beta",
+    "Intended Audience :: Developers",
+    "License :: OSI Approved :: MIT License",
+    "Natural Language :: English",
+    "Operating System :: MacOS :: MacOS X",
+    "Operating System :: Microsoft :: Windows",
+    "Operating System :: POSIX :: Linux",
+    "Programming Language :: Python :: 3.7",
+    "Programming Language :: Python :: 3.8",
+    "Programming Language :: Python :: 3.9",
+    "Programming Language :: Python :: 3.10",
+    "Topic :: Desktop Environment",
+    "Topic :: System :: Operating System",
+    "Typing :: Typed",
+]
+packages = [{ include = "screeninfo" }]
+
+[tool.poetry.dependencies]
+python = "^3.6.2"
+dataclasses = { version = "*", python = "<3.7" }
+Cython = { version = "*", platform = "darwin" }
+pyobjc-framework-Cocoa = { version = "*", platform = "darwin" }
+
+[tool.poetry.dev-dependencies]
+pytest = "^6.2.5"
+black = "^21.11b1"
+pre-commit = "^2.16.0"
+isort = "^5.10.1"
+
+[build-system]
+requires = ["poetry-core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.black]
+line-length = 79
+py36 = true
+
+[tool.isort]
+known_third_party = "docstring_parser"
+multi_line_output = 3
+include_trailing_comma = true
diff --git a/screeninfo/__init__.py b/screeninfo/__init__.py
index ad1968a..2163dd4 100644
--- a/screeninfo/__init__.py
+++ b/screeninfo/__init__.py
@@ -1,2 +1,9 @@
 from .common import Enumerator, Monitor
-from .screeninfo import get_monitors
+from .screeninfo import ScreenInfoError, get_monitors
+
+__all__ = [
+    "Enumerator",
+    "Monitor",
+    "ScreenInfoError",
+    "get_monitors",
+]
diff --git a/screeninfo/common.py b/screeninfo/common.py
index 67c5fbe..dfc55e6 100644
--- a/screeninfo/common.py
+++ b/screeninfo/common.py
@@ -14,6 +14,7 @@ class Monitor:
     width_mm: T.Optional[int] = None
     height_mm: T.Optional[int] = None
     name: T.Optional[str] = None
+    is_primary: T.Optional[bool] = None
 
     def __repr__(self) -> str:
         return (
@@ -21,7 +22,8 @@ class Monitor:
             f"x={self.x}, y={self.y}, "
             f"width={self.width}, height={self.height}, "
             f"width_mm={self.width_mm}, height_mm={self.height_mm}, "
-            f"name={self.name!r}"
+            f"name={self.name!r}, "
+            f"is_primary={self.is_primary}"
             f")"
         )
 
diff --git a/screeninfo/enumerators/__init__.py b/screeninfo/enumerators/__init__.py
index 85e02c5..fce0eeb 100644
--- a/screeninfo/enumerators/__init__.py
+++ b/screeninfo/enumerators/__init__.py
@@ -1,6 +1,6 @@
 import screeninfo.enumerators.cygwin
+import screeninfo.enumerators.drm
 import screeninfo.enumerators.osx
 import screeninfo.enumerators.windows
 import screeninfo.enumerators.xinerama
 import screeninfo.enumerators.xrandr
-import screeninfo.enumerators.drm
diff --git a/screeninfo/enumerators/cygwin.py b/screeninfo/enumerators/cygwin.py
index 9734a5f..6b64e4e 100644
--- a/screeninfo/enumerators/cygwin.py
+++ b/screeninfo/enumerators/cygwin.py
@@ -44,6 +44,9 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
 
     monitors = []
 
+    def check_primary(rct: T.Any) -> bool:
+        return rct.left == 0 and rct.top == 0
+
     def callback(monitor: T.Any, dc: T.Any, rect: T.Any, data: T.Any) -> int:
         rct = rect.contents
         monitors.append(
@@ -52,6 +55,7 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
                 y=rct.top,
                 width=rct.right - rct.left,
                 height=rct.bottom - rct.top,
+                is_primary=check_primary(rct),
             )
         )
         return 1
diff --git a/screeninfo/enumerators/drm.py b/screeninfo/enumerators/drm.py
index 18fe0fb..d529618 100644
--- a/screeninfo/enumerators/drm.py
+++ b/screeninfo/enumerators/drm.py
@@ -7,6 +7,7 @@ from screeninfo.common import Monitor, ScreenInfoError
 def enumerate_monitors() -> T.Iterable[Monitor]:
     import ctypes
     import ctypes.util
+
     from screeninfo.util import load_library
 
     libdrm = load_library("drm")
diff --git a/screeninfo/enumerators/osx.py b/screeninfo/enumerators/osx.py
index 7d00fa5..6bde210 100644
--- a/screeninfo/enumerators/osx.py
+++ b/screeninfo/enumerators/osx.py
@@ -3,6 +3,12 @@ import typing as T
 from screeninfo.common import Monitor
 
 
+# https://developer.apple.com/documentation/appkit/nsscreen/1388371-main
+# first entry in array is always the primary screen
+def check_primary(screens: T.Any, screen: T.Any) -> bool:
+    return screen == screens[0]
+
+
 def enumerate_monitors() -> T.Iterable[Monitor]:
     from AppKit import NSScreen
 
@@ -18,4 +24,5 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
             y=int(f.origin.y),
             width=int(f.size.width),
             height=int(f.size.height),
+            is_primary=check_primary(screens, screen),
         )
diff --git a/screeninfo/enumerators/py.typed b/screeninfo/enumerators/py.typed
new file mode 100644
index 0000000..e69de29
diff --git a/screeninfo/enumerators/windows.py b/screeninfo/enumerators/windows.py
index 53685ba..904ce71 100644
--- a/screeninfo/enumerators/windows.py
+++ b/screeninfo/enumerators/windows.py
@@ -31,6 +31,9 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
 
     monitors = []
 
+    def check_primary(rct: T.Any) -> bool:
+        return rct.left == 0 and rct.top == 0
+
     def callback(monitor: T.Any, dc: T.Any, rect: T.Any, data: T.Any) -> int:
         info = MONITORINFOEXW()
         info.cbSize = ctypes.sizeof(MONITORINFOEXW)
@@ -52,6 +55,7 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
                 width_mm=h_size,
                 height_mm=v_size,
                 name=name,
+                is_primary=check_primary(rct),
             )
         )
         return 1
diff --git a/screeninfo/enumerators/xrandr.py b/screeninfo/enumerators/xrandr.py
index c9f34b4..b3dd018 100644
--- a/screeninfo/enumerators/xrandr.py
+++ b/screeninfo/enumerators/xrandr.py
@@ -59,6 +59,9 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
             ("modes", ctypes.POINTER(ctypes.c_ulong)),
         ]
 
+    def check_primary(display_id: int, crtc: XRRCrtcInfo) -> bool:
+        return display_id == crtc.contents.outputs.contents.value
+
     xlib = load_library("X11")
     xlib.XOpenDisplay.argtypes = [ctypes.c_char_p]
     xlib.XOpenDisplay.restype = ctypes.POINTER(ctypes.c_void_p)
@@ -98,6 +101,8 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
                     output_info.contents.crtc,
                 )
 
+                primary_id = xrandr.XRRGetOutputPrimary(display, root_window)
+
                 try:
                     yield Monitor(
                         x=crtc_info.contents.x,
@@ -109,6 +114,7 @@ def enumerate_monitors() -> T.Iterable[Monitor]:
                         name=output_info.contents.name.decode(
                             sys.getfilesystemencoding()
                         ),
+                        is_primary=check_primary(primary_id, crtc_info),
                     )
 
                 finally:
diff --git a/screeninfo/py.typed b/screeninfo/py.typed
new file mode 100644
index 0000000..e69de29
diff --git a/screeninfo/screeninfo.py b/screeninfo/screeninfo.py
index 6c50361..e10bb39 100644
--- a/screeninfo/screeninfo.py
+++ b/screeninfo/screeninfo.py
@@ -1,6 +1,4 @@
-import importlib
 import typing as T
-from pathlib import Path
 
 from screeninfo import enumerators
 from screeninfo.common import Enumerator, Monitor, ScreenInfoError
@@ -15,23 +13,20 @@ ENUMERATOR_MAP = {
 }
 
 
-def _get_monitors(enumerator: Enumerator) -> T.List[Monitor]:
-    return list(ENUMERATOR_MAP[enumerator].enumerate_monitors())
-
-
 def get_monitors(
     name: T.Union[Enumerator, str, None] = None
 ) -> T.List[Monitor]:
     """Returns a list of :class:`Monitor` objects based on active monitors."""
-    enumerator = Enumerator(name) if name is not None else None
+    if name is not None:
+        return list(ENUMERATOR_MAP[Enumerator(name)].enumerate_monitors())
 
-    if enumerator is not None:
-        return _get_monitors(enumerator)
-
-    for enumerator in Enumerator:
+    for enumerator in ENUMERATOR_MAP.keys():
         try:
-            return _get_monitors(enumerator)
-        except Exception:
-            pass
+            monitors = get_monitors(enumerator)
+        except Exception as ex:
+            monitors = []
+
+        if monitors:
+            return monitors
 
     raise ScreenInfoError("No enumerators available")
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index b88034e..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[metadata]
-description-file = README.md
diff --git a/setup.py b/setup.py
index 3c60745..7193f59 100644
--- a/setup.py
+++ b/setup.py
@@ -1,28 +1,31 @@
+# -*- coding: utf-8 -*-
 from setuptools import setup
 
-# Collect the Current README docs for PyPI
-with open("README.md", "r") as fh:
-    long_description = fh.read()
+packages = \
+['screeninfo', 'screeninfo.enumerators']
 
-setup(
-    name="screeninfo",
-    packages=["screeninfo", "screeninfo.enumerators"],
-    version="0.6.7",
-    description="Fetch location and size of physical screens.",
-    long_description=long_description,
-    long_description_content_type="text/markdown",
-    author="rr-",
-    author_email="rr-@sakuya.pl",
-    url="https://github.com/rr-/screeninfo",
-    keywords=["screen", "monitor", "desktop"],
-    classifiers=[
-        'Operating System :: MacOS :: MacOS X',
-        'Operating System :: Microsoft :: Windows',
-        'Operating System :: POSIX :: Linux',
-    ],
-    install_requires=[
-        "dataclasses ; python_version<'3.7'",
-        'Cython ; sys_platform=="darwin"',
-        'pyobjc-framework-Cocoa ; sys_platform=="darwin"',
-    ],
-)
+package_data = \
+{'': ['*']}
+
+extras_require = \
+{':python_version < "3.7"': ['dataclasses'],
+ ':sys_platform == "darwin"': ['Cython', 'pyobjc-framework-Cocoa']}
+
+setup_kwargs = {
+    'name': 'screeninfo',
+    'version': '0.8.1',
+    'description': 'Fetch location and size of physical screens.',
+    'long_description': "screeninfo\n----------\n\n[![Build](https://github.com/rr-/screeninfo/actions/workflows/build.yml/badge.svg)](https://github.com/rr-/screeninfo/actions/workflows/build.yml)\n\nFetch location and size of physical screens.\n\n### Supported environments\n\n- MS Windows\n- MS Windows: Cygwin\n- GNU/Linux: X11 (through Xinerama)\n- GNU/Linux: DRM (experimental)\n- OSX: (through AppKit)\n\nI don't plan on testing OSX or other environments myself. For this reason,\nI strongly encourage pull requests.\n\n### Installation\n\n```\npip install screeninfo\n```\n\n### Usage\n\n```python\nfrom screeninfo import get_monitors\nfor m in get_monitors():\n    print(str(m))\n```\n\n**Output**:\n\n```python console\nMonitor(x=3840, y=0, width=3840, height=2160, width_mm=1420, height_mm=800, name='HDMI-0', is_primary=False)\nMonitor(x=0, y=0, width=3840, height=2160, width_mm=708, height_mm=399, name='DP-0', is_primary=True)\n```\n\n### Forcing environment\n\nIn some cases (emulating X server on Cygwin etc.) you might want to specify the\ndriver directly. You can do so by passing extra parameter to `get_monitors()`\nlike this:\n\n```python\nfrom screeninfo import get_monitors, Enumerator\nfor m in get_monitors(Enumerator.OSX):\n    print(str(m))\n```\n\nAvailable drivers: `windows`, `cygwin`, `x11`, `osx`.\n\n# Contributing\n\n\n```sh\ngit clone https://github.com/rr-/screeninfo.git # clone this repo\ncd screeninfo\npoetry install # to install the local venv\npoetry run pre-commit install # to setup pre-commit hooks\npoetry shell # to enter the venv\n```\n\nThis project uses [poetry](https://python-poetry.org/) for packaging,\ninstall instructions at [poetry#installation](https://python-poetry.org/docs/#installation)\n",
+    'author': 'Marcin Kurczewski',
+    'author_email': 'rr-@sakuya.pl',
+    'maintainer': None,
+    'maintainer_email': None,
+    'url': 'https://github.com/rr-/screeninfo',
+    'packages': packages,
+    'package_data': package_data,
+    'extras_require': extras_require,
+    'python_requires': '>=3.6.2,<4.0.0',
+}
+
+
+setup(**setup_kwargs)

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.8.1.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.8.1.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.8.1.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.8.1.egg-info/top_level.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo/enumerators/py.typed
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo/py.typed

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.6.7.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.6.7.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.6.7.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/screeninfo-0.6.7.egg-info/top_level.txt

No differences were encountered in the control files

More details

Full run details