Set primary selection when dragging with mouse

This commit is contained in:
Kovid Goyal 2016-11-29 11:29:39 +05:30
parent 11182b3682
commit 5ef2c404ce
3 changed files with 58 additions and 9 deletions

View File

@ -8,7 +8,7 @@ from threading import Lock
from .config import build_ansi_color_table from .config import build_ansi_color_table
from .constants import tab_manager, viewport_size, cell_size, ScreenGeometry, GLuint from .constants import tab_manager, viewport_size, cell_size, ScreenGeometry, GLuint
from .utils import get_logical_dpi, to_color from .utils import get_logical_dpi, to_color, set_primary_selection
from .fast_data_types import ( from .fast_data_types import (
glUniform2ui, glUniform4f, glUniform1i, glUniform2f, glDrawArraysInstanced, glUniform2ui, glUniform4f, glUniform1i, glUniform2f, glDrawArraysInstanced,
GL_TRIANGLE_FAN, glEnable, glDisable, GL_BLEND, glDrawArrays, ColorProfile, GL_TRIANGLE_FAN, glEnable, glDisable, GL_BLEND, glDrawArrays, ColorProfile,
@ -277,6 +277,38 @@ class CharGrid:
self.current_selection.end_scrolled_by = self.scrolled_by self.current_selection.end_scrolled_by = self.scrolled_by
if is_press is False: if is_press is False:
self.current_selection.in_progress = False self.current_selection.in_progress = False
text = self.text_for_selection()
if text and text.strip():
set_primary_selection(text)
def screen_line(self, y):
' Return the Line object corresponding to the yth line on the rendered screen '
if y >= 0 and y < self.screen.lines:
if self.scrolled_by:
if y < self.scrolled_by:
return self.screen.historybuf.line(self.scrolled_by - y)
return self.screen.line(y - self.scrolled_by)
else:
return self.screen.line(y)
def text_for_selection(self, sel=None):
start, end = (sel or self.current_selection).limits(self.scrolled_by)
lines = []
if start != end:
for y in range(start[1], end[1] + 1):
line = self.screen_line(y)
if line is not None:
buf = []
startx, endx = 0, self.screen.columns - 1
if y == start[1]:
startx = max(0, min(start[0], endx))
if y == end[1]:
endx = max(0, min(end[0], endx))
for x in range(startx, endx + 1):
buf.append(line[x])
line = ''.join(buf).rstrip(' ')
lines.append(line)
return '\n'.join(lines)
def prepare_for_render(self, sprites): def prepare_for_render(self, sprites):
with self.buffer_lock: with self.buffer_lock:

View File

@ -260,3 +260,17 @@ def handle_unix_signals():
signal.siginterrupt(sig, False) signal.siginterrupt(sig, False)
signal.set_wakeup_fd(write_fd) signal.set_wakeup_fd(write_fd)
return read_fd return read_fd
def get_primary_selection():
# glfw has no way to get the primary selection
# https://github.com/glfw/glfw/issues/894
return subprocess.check_output(['xsel', '-p']).decode('utf-8')
def set_primary_selection(text):
if isinstance(text, str):
text = text.encode('utf-8')
p = subprocess.Popen(['xsel', '-i', '-p'], stdin=subprocess.PIPE)
p.stdin.write(text), p.stdin.close()
p.wait()

View File

@ -4,7 +4,6 @@
import os import os
import weakref import weakref
import subprocess
from functools import partial from functools import partial
import glfw import glfw
@ -15,7 +14,7 @@ from .fast_data_types import (
BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, read_bytes_dump, read_bytes BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, read_bytes_dump, read_bytes
) )
from .terminfo import get_capabilities from .terminfo import get_capabilities
from .utils import sanitize_title from .utils import sanitize_title, get_primary_selection
class Window: class Window:
@ -143,18 +142,22 @@ class Window:
def paste(self, text): def paste(self, text):
if text: if text:
if isinstance(text, str):
text = text.encode('utf-8')
if self.screen.in_bracketed_paste_mode(): if self.screen.in_bracketed_paste_mode():
text = BRACKETED_PASTE_START.encode('ascii') + text + BRACKETED_PASTE_END.encode('ascii') text = BRACKETED_PASTE_START.encode('ascii') + text + BRACKETED_PASTE_END.encode('ascii')
self.write_to_child(text) self.write_to_child(text)
def paste_from_clipboard(self): def paste_from_clipboard(self):
text = glfw.glfwGetClipboardString(self.window) text = glfw.glfwGetClipboardString(tab_manager().glfw_window)
self.paste(text) if text:
self.paste(text.decode('utf-8'))
def paste_from_selection(self): def paste_from_selection(self):
# glfw has no way to get the primary selection text = get_primary_selection()
# https://github.com/glfw/glfw/issues/894 if text:
text = subprocess.check_output(['xsel']) if isinstance(text, bytes):
text = text.decode('utf-8')
self.paste(text) self.paste(text)
def scroll_line_up(self): def scroll_line_up(self):