-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(screengrab): use protocols and similar logic as for capture
- Loading branch information
Showing
29 changed files
with
517 additions
and
454 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 13 additions & 1 deletion
14
normcap/screengrab/grim.py → normcap/screengrab/handlers/grim.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
normcap/screengrab/qt.py → normcap/screengrab/handlers/qt.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,94 @@ | ||
import logging | ||
import sys | ||
from typing import Protocol | ||
|
||
from PySide6 import QtGui | ||
|
||
from normcap.screengrab import utils | ||
from normcap.screengrab.handlers import dbus_portal, dbus_shell, grim, qt | ||
from normcap.screengrab.structures import Handler, HandlerProtocol | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class CaptureFunc(Protocol): | ||
def __call__(self) -> list[QtGui.QImage]: | ||
... # pragma: no cover | ||
_capture_handlers: dict[Handler, HandlerProtocol] = { | ||
Handler.QT: qt, | ||
Handler.DBUS_PORTAL: dbus_portal, | ||
Handler.DBUS_SHELL: dbus_shell, | ||
Handler.GRIM: grim, | ||
} | ||
|
||
|
||
def get_capture_func() -> CaptureFunc: | ||
# fmt: off | ||
if sys.platform != "linux" or not utils.is_wayland_display_manager(): | ||
logger.debug("Select capture method QT") | ||
from normcap.screengrab import qt | ||
return qt.capture | ||
def get_available_handlers() -> list[Handler]: | ||
compatible_handlers = [h for h in Handler if _capture_handlers[h].is_compatible()] | ||
logger.debug( | ||
"Compatible capture handlers: %s", [h.name for h in compatible_handlers] | ||
) | ||
|
||
if utils.has_grim_support(): | ||
logger.debug("Select capture method grim") | ||
from normcap.screengrab import grim | ||
return grim.capture | ||
available_handlers = [ | ||
n for n in compatible_handlers if _capture_handlers[n].is_installed() | ||
] | ||
logger.debug("Available capture handlers: %s", [h.name for h in available_handlers]) | ||
|
||
# TODO: implement gnome-screenshot method | ||
if not compatible_handlers: | ||
logger.error( | ||
"None of the implemented capture handlers is compatible with this system!" | ||
) | ||
return [] | ||
|
||
if utils.has_dbus_portal_support(): | ||
logger.debug("Select capture method DBUS portal") | ||
from normcap.screengrab import dbus_portal | ||
return dbus_portal.capture | ||
if not available_handlers: | ||
logger.error( | ||
"No working capture handler found for your system. " | ||
"The preferred handler on your system would be %s but can't be " | ||
"used due to missing dependencies. %s", | ||
compatible_handlers[0].name, | ||
_capture_handlers[compatible_handlers[0]].install_instructions, | ||
) | ||
return [] | ||
|
||
if compatible_handlers[0] != available_handlers[0]: | ||
logger.warning( | ||
"The preferred capture handler on your system would be %s but can't be " | ||
"used due to missing dependencies. %s", | ||
compatible_handlers[0].name, | ||
_capture_handlers[compatible_handlers[0]].install_instructions, | ||
) | ||
|
||
logger.debug("Select capture method DBUS shell") | ||
from normcap.screengrab import dbus_shell | ||
return dbus_shell.capture | ||
# fmt: on | ||
return available_handlers | ||
|
||
|
||
def _capture(handler: Handler) -> list[QtGui.QImage]: | ||
capture_handler = _capture_handlers[handler] | ||
if not capture_handler.is_compatible(): | ||
logger.warning("%s's capture() called on incompatible system!", handler.name) | ||
try: | ||
images = capture_handler.capture() | ||
except Exception: | ||
logger.exception("%s's capture() failed!", handler.name) | ||
return [] | ||
else: | ||
logger.info("Screen captured using %s", handler.name) | ||
return images | ||
|
||
|
||
def capture_with_handler(handler_name: str) -> list[QtGui.QImage]: | ||
"""Capture screen using a specific handler. | ||
Args: | ||
handler_name: Name of one of the supported capture methods. | ||
Returns: | ||
Single image for every screen. | ||
""" | ||
return _capture(handler=Handler[handler_name.upper()]) | ||
|
||
|
||
def capture() -> list[QtGui.QImage]: | ||
capture_func = get_capture_func() | ||
return capture_func() | ||
"""Capture screen using compatible handlers. | ||
Returns: | ||
Single image for every screen. | ||
""" | ||
for handler in get_available_handlers(): | ||
if images := _capture(handler=handler): | ||
return images | ||
|
||
logger.error("Unable to capture screen! (Increase log-level for details)") | ||
return [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.