added clipcascade
This commit is contained in:
+149
@@ -0,0 +1,149 @@
|
||||
from io import BytesIO
|
||||
import logging
|
||||
import threading
|
||||
import time
|
||||
import pasteboard
|
||||
|
||||
_clipboard_thread = None
|
||||
_callback_update = None
|
||||
_run = False
|
||||
_first_run = False
|
||||
_block_image_once = False
|
||||
_pasteboard_lock = threading.Lock()
|
||||
_pb_writer = None
|
||||
|
||||
|
||||
def write_to_pasteboard(data, pb_type):
|
||||
global _pb_writer
|
||||
with _pasteboard_lock:
|
||||
if _pb_writer is None:
|
||||
_pb_writer = pasteboard.Pasteboard()
|
||||
_pb_writer.set_contents(data, pb_type)
|
||||
|
||||
|
||||
def _runner(enable_image_monitoring=False, enable_file_monitoring=False):
|
||||
global _first_run, _block_image_once
|
||||
try:
|
||||
pb_text = pasteboard.Pasteboard()
|
||||
if enable_image_monitoring:
|
||||
pb_image_png = pasteboard.Pasteboard()
|
||||
pb_image_tiff = pasteboard.Pasteboard()
|
||||
if enable_file_monitoring:
|
||||
pb_files = pasteboard.Pasteboard()
|
||||
image_processed = False
|
||||
files_processed = False
|
||||
while _run:
|
||||
# don't change the execution order (files,text,image or files,image,text)
|
||||
|
||||
if enable_file_monitoring:
|
||||
# Files
|
||||
with _pasteboard_lock:
|
||||
clipboard_files = pb_files.get_file_urls(diff=True)
|
||||
if (
|
||||
clipboard_files is not None
|
||||
and type(clipboard_files) is tuple
|
||||
and len(clipboard_files) > 0
|
||||
):
|
||||
if _callback_update and not _first_run:
|
||||
files_processed = True
|
||||
_callback_update("files", clipboard_files)
|
||||
|
||||
# Text
|
||||
with _pasteboard_lock:
|
||||
clipboard_text = pb_text.get_contents(
|
||||
type=pasteboard.String, diff=True
|
||||
) # If True, retrieves and returns the content only if it has changed since the last call.
|
||||
# This approach is efficient even in cases of frequent polling.
|
||||
if (
|
||||
clipboard_text is not None
|
||||
and type(clipboard_text) is str
|
||||
and len(clipboard_text) > 0
|
||||
):
|
||||
if _callback_update and not _first_run and not files_processed:
|
||||
_callback_update("text", clipboard_text)
|
||||
|
||||
if enable_image_monitoring:
|
||||
# Image (PNG)
|
||||
with _pasteboard_lock:
|
||||
clipboard_image_png = pb_image_png.get_contents(
|
||||
type=pasteboard.PNG, diff=True
|
||||
)
|
||||
if (
|
||||
clipboard_image_png is not None
|
||||
and type(clipboard_image_png) is bytes
|
||||
):
|
||||
if _callback_update and not _first_run and not image_processed:
|
||||
image_processed = True
|
||||
if _block_image_once:
|
||||
_block_image_once = False
|
||||
else:
|
||||
if not files_processed:
|
||||
_callback_update("image", clipboard_image_png)
|
||||
|
||||
# Image (TIFF)
|
||||
with _pasteboard_lock:
|
||||
clipboard_image_tiff = pb_image_tiff.get_contents(
|
||||
type=pasteboard.TIFF, diff=True
|
||||
)
|
||||
if (
|
||||
clipboard_image_tiff is not None
|
||||
and type(clipboard_image_tiff) is bytes
|
||||
):
|
||||
if _callback_update and not _first_run and not image_processed:
|
||||
image_processed = True
|
||||
if _block_image_once:
|
||||
_block_image_once = False
|
||||
else:
|
||||
if not files_processed:
|
||||
_callback_update("image", clipboard_image_tiff)
|
||||
|
||||
files_processed = False
|
||||
image_processed = False
|
||||
_first_run = False
|
||||
time.sleep(0.3) # seconds
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error processing clipboard update: {e}")
|
||||
|
||||
|
||||
def _start(enable_image_monitoring=False, enable_file_monitoring=False):
|
||||
global _clipboard_thread, _run, _first_run
|
||||
if not _clipboard_thread:
|
||||
_run = True
|
||||
_first_run = True
|
||||
_clipboard_thread = threading.Thread(
|
||||
target=_runner,
|
||||
args=(enable_image_monitoring, enable_file_monitoring),
|
||||
daemon=True,
|
||||
)
|
||||
_clipboard_thread.start()
|
||||
|
||||
|
||||
def stop():
|
||||
global _clipboard_thread, _callback_update, _run, _first_run, _block_image_once, _pb_writer
|
||||
if _clipboard_thread:
|
||||
_run = False
|
||||
_clipboard_thread.join() # Wait for the thread to finish
|
||||
_first_run = False
|
||||
_clipboard_thread = None
|
||||
_callback_update = None
|
||||
_block_image_once = False
|
||||
_pb_writer = None
|
||||
logging.info("Clipboard monitor stopped")
|
||||
|
||||
|
||||
def wait():
|
||||
global _clipboard_thread
|
||||
if _clipboard_thread:
|
||||
_clipboard_thread.join()
|
||||
|
||||
|
||||
def enable_block_image_once():
|
||||
global _block_image_once
|
||||
_block_image_once = True
|
||||
|
||||
|
||||
def on_update(callback, enable_image_monitoring=False, enable_file_monitoring=False):
|
||||
global _callback_update
|
||||
_callback_update = callback
|
||||
_start(enable_image_monitoring, enable_file_monitoring)
|
||||
Reference in New Issue
Block a user