Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed windows fragment offset to read from the description #12

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions klembord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
"""

import sys
from collections import OrderedDict, Mapping, ByteString, Sequence
from collections import OrderedDict
from collections.abc import Mapping, Sequence
if sys.platform.startswith('win32'):
from .winclipboard import WinClipboard
from .winclipboard import parse_description
WINDOWS = True
LINUX = False
else:
Expand Down Expand Up @@ -199,7 +201,7 @@ def set_with_rich_text(self, text, html):
else:
raise TypeError('text or html is not str')

def get_with_rich_text(self):
def get_with_rich_text(self, include_win_description=False):
"""Get the contents of the selection in plaintext and HTML formats.

Returns:
Expand All @@ -209,11 +211,13 @@ def get_with_rich_text(self):
"""

if WINDOWS:
description = OrderedDict()
content = self.get((W_HTML, W_UNICODE))
html = content[W_HTML]
if html:
# Strip HTML Format additions and return just the fragment.
html = html.decode(UTF8)[131:-38]
description = parse_description(html.decode(UTF8))
html = html[ description['StartFragment']: description['EndFragment']].decode(UTF8) # Must decode after slicing
text = content[W_UNICODE]
if text:
text = text.decode(UTF16)
Expand All @@ -235,7 +239,11 @@ def get_with_rich_text(self):
html = html.decode(UTF16)
except UnicodeDecodeError:
html = html.decode(UTF8, 'ignore')
return (text, html)

if WINDOWS and include_win_description:
return (text, html, description)
else:
return (text, html)

def clear(self):
"""Empty selection.
Expand Down Expand Up @@ -365,7 +373,7 @@ def set_with_rich_text(text, html):
SELECTION.set_with_rich_text(text, html)


def get_with_rich_text():
def get_with_rich_text(include_win_description=False):
"""Get the contents of the selection in plaintext and HTML formats.

Returns:
Expand All @@ -377,7 +385,7 @@ def get_with_rich_text():
global SELECTION
if SELECTION is None:
SELECTION = Selection()
return SELECTION.get_with_rich_text()
return SELECTION.get_with_rich_text(include_win_description)


def clear():
Expand Down
32 changes: 31 additions & 1 deletion klembord/winclipboard.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#!/usr/bin/env python3

from collections import OrderedDict, ByteString
from collections import OrderedDict
from collections.abc import ByteString
from ctypes import windll, create_unicode_buffer, memmove, c_uint, c_wchar
from ctypes import c_void_p, c_bool, c_int, c_byte
import re


UNSUPPORTED = {
Expand Down Expand Up @@ -230,3 +232,31 @@ def wrap_html(self, fragment_str):


return wrapped


start_html_RE = re.compile(r'(StartHTML):(-?\d+)')
start_fragment_RE = re.compile(r'(StartFragment):(\d+)')
end_fragment_RE = re.compile(r'(EndFragment):(\d+)')

def parse_description(text):
''' Returns a dictionary of the description info.
Only StartFragment and EndFragment are guaranteed to exist and be integers.
'''
start_html = start_html_RE.search(text)
start_fragment = start_fragment_RE.search(text)
end_fragment = end_fragment_RE.search(text)

description = OrderedDict()

if start_html:
start_index = int(start_html.group(2))

if start_index > 0:
description_blob = text[:start_index]

description = OrderedDict( line.split(':', 1) for line in description_blob.splitlines() )

description[ start_fragment.group(1) ] = int(start_fragment.group(2))
description[ end_fragment.group(1) ] = int(end_fragment.group(2))

return description
2 changes: 1 addition & 1 deletion klembord/xclipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys
from threading import Thread
from queue import Queue, Empty
from collections import ByteString
from collections.abc import ByteString
from traceback import print_exception
from Xlib import X, display, Xatom
from Xlib.protocol import event
Expand Down