Respond to OSC color query escape codes

This commit is contained in:
Kovid Goyal 2017-12-01 21:02:30 +05:30
parent 73b501c961
commit c12bce3d2f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 31 additions and 11 deletions

2
kitty/rgb.py generated
View File

@ -37,7 +37,7 @@ def to_color(raw, validate=False):
try: try:
if raw.startswith('#'): if raw.startswith('#'):
val = parse_sharp(raw[1:]) val = parse_sharp(raw[1:])
elif raw.startswith('rgb:'): elif raw[:4].lower() == 'rgb:':
val = parse_rgb(raw[4:]) val = parse_rgb(raw[4:])
except Exception: except Exception:
pass pass

View File

@ -109,7 +109,10 @@ def parse_color_set(raw):
try: try:
c = int(c) c = int(c)
if c < 0 or c > 255: if c < 0 or c > 255:
raise IndexError('Out of bounds') continue
if spec == '?':
yield c, None
else:
r, g, b = to_color(spec) r, g, b = to_color(spec)
yield c, r << 16 | g << 8 | b yield c, r << 16 | g << 8 | b
except Exception: except Exception:

View File

@ -206,6 +206,12 @@ class Window:
if dirtied: if dirtied:
self.screen.mark_as_dirty() self.screen.mark_as_dirty()
def report_color(self, osc, r, g, b):
r |= r << 8
g |= g << 8
b |= b << 8
self.write_to_child('\033]{};rgb:{:04x}/{:04x}/{:04x}\033\\'.format(osc, r, g, b))
def set_dynamic_color(self, code, value): def set_dynamic_color(self, code, value):
if isinstance(value, bytes): if isinstance(value, bytes):
value = value.decode('utf-8') value = value.decode('utf-8')
@ -213,18 +219,29 @@ class Window:
for val in value.split(';'): for val in value.split(';'):
w = DYNAMIC_COLOR_CODES.get(code) w = DYNAMIC_COLOR_CODES.get(code)
if w is not None: if w is not None:
if val == '?':
col = getattr(self.screen.color_profile, w.name)
self.report_color(str(code), col >> 16, (col >> 8) & 0xff, col & 0xff)
else:
if code >= 110: if code >= 110:
val = None val = None
color_changes[w] = val color_changes[w] = val
code += 1 code += 1
if color_changes:
self.change_colors(color_changes) self.change_colors(color_changes)
glfw_post_empty_event() glfw_post_empty_event()
def set_color_table_color(self, code, value): def set_color_table_color(self, code, value):
cp = self.screen.color_profile cp = self.screen.color_profile
if code == 4: if code == 4:
changed = False
for c, val in parse_color_set(value): for c, val in parse_color_set(value):
if val is None: # color query
self.report_color('4;{}'.format(c), *self.screen.color_profile.as_color((c << 8) | 1))
else:
changed = True
cp.set_color(c, val) cp.set_color(c, val)
if changed:
self.refresh() self.refresh()
elif code == 104: elif code == 104:
if not value.strip(): if not value.strip():