summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/core/fm.py4
-rw-r--r--ranger/ext/img_display.py45
2 files changed, 48 insertions, 1 deletions
diff --git a/ranger/core/fm.py b/ranger/core/fm.py
index 61b3cb11..46336e92 100644
--- a/ranger/core/fm.py
+++ b/ranger/core/fm.py
@@ -25,7 +25,7 @@ from ranger.core.runner import Runner
 from ranger.ext.img_display import (W3MImageDisplayer, ITerm2ImageDisplayer,
                                     TerminologyImageDisplayer,
                                     URXVTImageDisplayer, URXVTImageFSDisplayer,
-                                    KittyImageDisplayer,
+                                    KittyImageDisplayer, UeberzugImageDisplayer,
                                     ImageDisplayer)
 from ranger.core.metadata import MetadataManager
 from ranger.ext.rifle import Rifle
@@ -238,6 +238,8 @@ class FM(Actions,  # pylint: disable=too-many-instance-attributes
             return URXVTImageFSDisplayer()
         elif self.settings.preview_images_method == "kitty":
             return KittyImageDisplayer()
+        elif self.settings.preview_images_method == "ueberzug":
+            return UeberzugImageDisplayer()
         return ImageDisplayer()
 
     def _get_thisfile(self):
diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py
index f78e170b..4da745a5 100644
--- a/ranger/ext/img_display.py
+++ b/ranger/ext/img_display.py
@@ -20,6 +20,7 @@ import os
 import struct
 import sys
 import warnings
+import json
 from subprocess import Popen, PIPE
 
 import termios
@@ -664,3 +665,47 @@ class KittyImageDisplayer(ImageDisplayer):
         #         os.remove(self.temp_paths[k])
         #     except (OSError, IOError):
         #         continue
+
+
+class UeberzugImageDisplayer(ImageDisplayer):
+    """Implementation of ImageDisplayer using ueberzug.
+    Ueberzug can display images in a Xorg session.
+    Does not work over ssh.
+    """
+    IMAGE_ID = 'preview'
+    is_initialized = False
+
+    def __init__(self):
+        self.process = None
+
+    def initialize(self):
+        """start ueberzug"""
+        if self.is_initialized and self.process.poll() is None:
+            return
+
+        self.process = Popen(['python3', '-m', 'ueberzug', 'layer'],
+                             stdin=PIPE, universal_newlines=True)
+        self.is_initialized = True
+
+    def _execute(self, **kwargs):
+        self.initialize()
+        self.process.stdin.write(json.dumps(kwargs) + '\n')
+        self.process.stdin.flush()
+
+    def draw(self, path, start_x, start_y, width, height):
+        self._execute(
+            action='add',
+            identifier=self.IMAGE_ID,
+            x=start_x,
+            y=start_y,
+            max_width=width - 1,
+            max_height=height - 1,
+            path=path
+        )
+
+    def clear(self, start_x, start_y, width, height):
+        self._execute(action='remove', identifier=self.IMAGE_ID)
+
+    def quit(self):
+        # ueberzug will terminate itself if stdin was closed
+        pass