OSC 52: Fix specifying both clipboard and primary in OSC 52 requests not supported

This commit is contained in:
Kovid Goyal
2025-03-18 08:07:05 +05:30
parent 1696524949
commit 5754fa2260
2 changed files with 22 additions and 12 deletions

View File

@@ -112,6 +112,8 @@ Detailed list of changes
- macOS: Fix a regression causing a crash when using :opt:`focus_follows_mouse` (:iss:`8437`) - macOS: Fix a regression causing a crash when using :opt:`focus_follows_mouse` (:iss:`8437`)
- OSC 52: Fix specifying both clipboard and primary in OSC 52 requests not supported
0.40.0 [2025-03-08] 0.40.0 [2025-03-08]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -76,11 +76,15 @@ TARGETS_MIME = '.'
class ClipboardType(IntEnum): class ClipboardType(IntEnum):
clipboard = GLFW_CLIPBOARD clipboard = GLFW_CLIPBOARD
primary_selection = GLFW_PRIMARY_SELECTION primary_selection = GLFW_PRIMARY_SELECTION
unknown = -311
@staticmethod @staticmethod
def from_osc52_where_field(where: str) -> 'ClipboardType': def from_osc52_where_field(where: str) -> 'ClipboardType':
where = where or 's0' if where in ('c', 's'):
return ClipboardType.clipboard if 'c' in where or 's' in where else ClipboardType.primary_selection return ClipboardType.clipboard
if where == 'p':
return ClipboardType.primary_selection
return ClipboardType.unknown
class Clipboard: class Clipboard:
@@ -394,18 +398,22 @@ class ClipboardRequestManager:
else: else:
where = str(data, "utf-8", 'replace') where = str(data, "utf-8", 'replace')
data = data[len(data):] data = data[len(data):]
destinations = {ClipboardType.from_osc52_where_field(where) for where in where}
destinations.discard(ClipboardType.unknown)
if len(data) == 1 and data.tobytes() == b'?': if len(data) == 1 and data.tobytes() == b'?':
rr = ReadRequest(is_primary_selection=ClipboardType.from_osc52_where_field(where) is ClipboardType.primary_selection) for d in destinations:
self.handle_read_request(rr) rr = ReadRequest(is_primary_selection=d is ClipboardType.primary_selection)
self.handle_read_request(rr)
else: else:
wr = self.in_flight_write_request for d in destinations:
if wr is None: wr = self.in_flight_write_request
wr = self.in_flight_write_request = WriteRequest(ClipboardType.from_osc52_where_field(where) is ClipboardType.primary_selection) if wr is None:
wr.add_base64_data(data) wr = self.in_flight_write_request = WriteRequest(d is ClipboardType.primary_selection)
if is_partial: wr.add_base64_data(data)
return if is_partial:
self.in_flight_write_request = None return
self.handle_write_request(wr) self.in_flight_write_request = None
self.handle_write_request(wr)
def handle_write_request(self, wr: WriteRequest) -> None: def handle_write_request(self, wr: WriteRequest) -> None:
wr.flush_base64_data() wr.flush_base64_data()