mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-05 23:51:29 +02:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
339dd9b412 | ||
|
|
3f272d102b | ||
|
|
29988c94fa | ||
|
|
35f2b3254a | ||
|
|
898a8075be | ||
|
|
f5d957e8ff | ||
|
|
2cc3cabd3f |
@@ -364,7 +364,7 @@ class Boss(Thread):
|
|||||||
|
|
||||||
@callback
|
@callback
|
||||||
def on_mouse_move(self, window, xpos, ypos):
|
def on_mouse_move(self, window, xpos, ypos):
|
||||||
mouse_cursor_pos[:2] = int(xpos * viewport_size.x_ratio), int(ypos * viewport_size.y_ratio)
|
mouse_cursor_pos[:2] = xpos, ypos = int(xpos * viewport_size.x_ratio), int(ypos * viewport_size.y_ratio)
|
||||||
self.show_mouse_cursor()
|
self.show_mouse_cursor()
|
||||||
w = self.window_for_pos(xpos, ypos)
|
w = self.window_for_pos(xpos, ypos)
|
||||||
if w is not None:
|
if w is not None:
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import signal
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from .constants import terminfo_dir
|
from .constants import terminfo_dir
|
||||||
|
import kitty.fast_data_types as fast_data_types
|
||||||
|
|
||||||
|
|
||||||
def remove_cloexec(fd):
|
def remove_cloexec(fd):
|
||||||
@@ -33,6 +34,7 @@ class Child:
|
|||||||
self.forked = True
|
self.forked = True
|
||||||
master, slave = os.openpty() # Note that master and slave are in blocking mode
|
master, slave = os.openpty() # Note that master and slave are in blocking mode
|
||||||
remove_cloexec(slave)
|
remove_cloexec(slave)
|
||||||
|
self.set_iutf8(fd=master)
|
||||||
stdin, self.stdin = self.stdin, None
|
stdin, self.stdin = self.stdin, None
|
||||||
if stdin is not None:
|
if stdin is not None:
|
||||||
stdin_read_fd, stdin_write_fd = os.pipe()
|
stdin_read_fd, stdin_write_fd = os.pipe()
|
||||||
@@ -79,6 +81,16 @@ class Child:
|
|||||||
if self.child_fd is not None:
|
if self.child_fd is not None:
|
||||||
fcntl.ioctl(self.child_fd, termios.TIOCSWINSZ, struct.pack('4H', h, w, ww, wh))
|
fcntl.ioctl(self.child_fd, termios.TIOCSWINSZ, struct.pack('4H', h, w, ww, wh))
|
||||||
|
|
||||||
|
def set_iutf8(self, on=True, fd=None):
|
||||||
|
fd = fd or self.child_fd
|
||||||
|
if fd is not None and hasattr(fast_data_types, 'IUTF8'):
|
||||||
|
attrs = termios.tcgetattr(fd)
|
||||||
|
if on:
|
||||||
|
attrs[0] |= fast_data_types.IUTF8
|
||||||
|
else:
|
||||||
|
attrs[0] &= ~fast_data_types.IUTF8
|
||||||
|
termios.tcsetattr(fd, termios.TCSANOW, attrs)
|
||||||
|
|
||||||
def hangup(self):
|
def hangup(self):
|
||||||
if self.pid is not None:
|
if self.pid is not None:
|
||||||
pid, self.pid = self.pid, None
|
pid, self.pid = self.pid, None
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from .fast_data_types import (
|
|||||||
GLFW_KEY_LEFT_SUPER, GLFW_KEY_RIGHT_SUPER)
|
GLFW_KEY_LEFT_SUPER, GLFW_KEY_RIGHT_SUPER)
|
||||||
|
|
||||||
appname = 'kitty'
|
appname = 'kitty'
|
||||||
version = (0, 2, 2)
|
version = (0, 2, 3)
|
||||||
str_version = '.'.join(map(str, version))
|
str_version = '.'.join(map(str, version))
|
||||||
_plat = sys.platform.lower()
|
_plat = sys.platform.lower()
|
||||||
isosx = 'darwin' in _plat
|
isosx = 'darwin' in _plat
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ static struct PyModuleDef module = {
|
|||||||
.m_methods = module_methods
|
.m_methods = module_methods
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
PyInit_fast_data_types(void) {
|
PyInit_fast_data_types(void) {
|
||||||
PyObject *m;
|
PyObject *m;
|
||||||
@@ -105,6 +107,9 @@ PyInit_fast_data_types(void) {
|
|||||||
PyModule_AddIntMacro(m, NORMAL_PROTOCOL);
|
PyModule_AddIntMacro(m, NORMAL_PROTOCOL);
|
||||||
PyModule_AddIntMacro(m, URXVT_PROTOCOL);
|
PyModule_AddIntMacro(m, URXVT_PROTOCOL);
|
||||||
PyModule_AddIntMacro(m, UTF8_PROTOCOL);
|
PyModule_AddIntMacro(m, UTF8_PROTOCOL);
|
||||||
|
#ifdef IUTF8
|
||||||
|
PyModule_AddIntMacro(m, IUTF8);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ PyTypeObject ScreenModes_Type;
|
|||||||
#define SAVEPOINTS_SZ 256
|
#define SAVEPOINTS_SZ 256
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t utf8_state, *g0_charset, *g1_charset, *g_charset;
|
uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset, *g_charset;
|
||||||
bool use_latin1;
|
bool use_latin1;
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
bool mDECOM, mDECAWM, mDECSCNM;
|
bool mDECOM, mDECAWM, mDECSCNM;
|
||||||
@@ -274,7 +274,7 @@ typedef struct {
|
|||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
unsigned int columns, lines, margin_top, margin_bottom, charset;
|
unsigned int columns, lines, margin_top, margin_bottom, charset;
|
||||||
uint32_t utf8_state, *g0_charset, *g1_charset, *g_charset;
|
uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset, *g_charset;
|
||||||
bool use_latin1;
|
bool use_latin1;
|
||||||
Cursor *cursor;
|
Cursor *cursor;
|
||||||
SavepointBuffer main_savepoints, alt_savepoints;
|
SavepointBuffer main_savepoints, alt_savepoints;
|
||||||
@@ -396,6 +396,7 @@ void screen_erase_characters(Screen *self, unsigned int count);
|
|||||||
void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom);
|
void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom);
|
||||||
void screen_change_charset(Screen *, uint32_t to);
|
void screen_change_charset(Screen *, uint32_t to);
|
||||||
void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
|
void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
|
||||||
|
void screen_use_latin1(Screen *, bool);
|
||||||
void set_title(Screen *self, PyObject*);
|
void set_title(Screen *self, PyObject*);
|
||||||
void set_icon(Screen *self, PyObject*);
|
void set_icon(Screen *self, PyObject*);
|
||||||
void set_dynamic_color(Screen *self, unsigned int code, PyObject*);
|
void set_dynamic_color(Screen *self, unsigned int code, PyObject*);
|
||||||
|
|||||||
@@ -225,10 +225,12 @@ handle_esc_mode_char(Screen *screen, uint32_t ch, PyObject DUMP_UNUSED *dump_cal
|
|||||||
switch(ch) {
|
switch(ch) {
|
||||||
case '@':
|
case '@':
|
||||||
REPORT_COMMAND(screen_use_latin1, 1);
|
REPORT_COMMAND(screen_use_latin1, 1);
|
||||||
screen->use_latin1 = true; screen->utf8_state = 0; break;
|
screen_use_latin1(screen, true);
|
||||||
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
REPORT_COMMAND(screen_use_latin1, 0);
|
REPORT_COMMAND(screen_use_latin1, 0);
|
||||||
screen->use_latin1 = false; screen->utf8_state = 0; break;
|
screen_use_latin1(screen, false);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
REPORT_ERROR("Unhandled Esc %% code: 0x%x", ch); break;
|
REPORT_ERROR("Unhandled Esc %% code: 0x%x", ch); break;
|
||||||
}
|
}
|
||||||
@@ -688,17 +690,17 @@ dispatch_unicode_char(Screen *screen, uint32_t codepoint, PyObject DUMP_UNUSED *
|
|||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_parse_bytes(Screen *screen, uint8_t *buf, Py_ssize_t len, PyObject DUMP_UNUSED *dump_callback) {
|
_parse_bytes(Screen *screen, uint8_t *buf, Py_ssize_t len, PyObject DUMP_UNUSED *dump_callback) {
|
||||||
uint32_t prev = screen->utf8_state, codepoint = 0;
|
uint32_t prev = screen->utf8_state;
|
||||||
for (unsigned int i = 0; i < len; i++) {
|
for (unsigned int i = 0; i < len; i++) {
|
||||||
if (screen->use_latin1) dispatch_unicode_char(screen, latin1_charset[buf[i]], dump_callback);
|
if (screen->use_latin1) dispatch_unicode_char(screen, latin1_charset[buf[i]], dump_callback);
|
||||||
else {
|
else {
|
||||||
switch (decode_utf8(&screen->utf8_state, &codepoint, buf[i])) {
|
switch (decode_utf8(&screen->utf8_state, &screen->utf8_codepoint, buf[i])) {
|
||||||
case UTF8_ACCEPT:
|
case UTF8_ACCEPT:
|
||||||
dispatch_unicode_char(screen, codepoint, dump_callback);
|
dispatch_unicode_char(screen, screen->utf8_codepoint, dump_callback);
|
||||||
break;
|
break;
|
||||||
case UTF8_REJECT:
|
case UTF8_REJECT:
|
||||||
screen->utf8_state = UTF8_ACCEPT;
|
screen->utf8_state = UTF8_ACCEPT;
|
||||||
if (prev != UTF8_ACCEPT) i--;
|
if (prev != UTF8_ACCEPT && i > 0) i--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prev = screen->utf8_state;
|
prev = screen->utf8_state;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ init_tabstops(bool *tabstops, index_type count) {
|
|||||||
self->g1_charset = self->g0_charset; \
|
self->g1_charset = self->g0_charset; \
|
||||||
self->g_charset = self->g0_charset; \
|
self->g_charset = self->g0_charset; \
|
||||||
self->utf8_state = 0; \
|
self->utf8_state = 0; \
|
||||||
|
self->utf8_codepoint = 0; \
|
||||||
self->use_latin1 = false;
|
self->use_latin1 = false;
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
@@ -638,6 +639,7 @@ savepoints_pop(SavepointBuffer *self) {
|
|||||||
|
|
||||||
#define COPY_CHARSETS(self, sp) \
|
#define COPY_CHARSETS(self, sp) \
|
||||||
sp->utf8_state = self->utf8_state; \
|
sp->utf8_state = self->utf8_state; \
|
||||||
|
sp->utf8_codepoint = self->utf8_codepoint; \
|
||||||
sp->g0_charset = self->g0_charset; \
|
sp->g0_charset = self->g0_charset; \
|
||||||
sp->g1_charset = self->g1_charset; \
|
sp->g1_charset = self->g1_charset; \
|
||||||
sp->g_charset = self->g_charset; \
|
sp->g_charset = self->g_charset; \
|
||||||
@@ -855,6 +857,14 @@ void screen_erase_characters(Screen *self, unsigned int count) {
|
|||||||
|
|
||||||
// Device control {{{
|
// Device control {{{
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_use_latin1(Screen *self, bool on) {
|
||||||
|
self->use_latin1 = on; self->utf8_state = 0; self->utf8_codepoint = 0;
|
||||||
|
PyObject_CallMethod(self->callbacks, "use_utf8", "O", on ? Py_False : Py_True);
|
||||||
|
if (PyErr_Occurred()) PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_bell(Screen UNUSED *self) {
|
screen_bell(Screen UNUSED *self) {
|
||||||
PyObject_CallMethod(self->callbacks, "bell", NULL);
|
PyObject_CallMethod(self->callbacks, "bell", NULL);
|
||||||
|
|||||||
@@ -120,6 +120,9 @@ class Window:
|
|||||||
self.start_visual_bell_at = monotonic()
|
self.start_visual_bell_at = monotonic()
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|
||||||
|
def use_utf8(self, on):
|
||||||
|
self.child.set_iutf8(on)
|
||||||
|
|
||||||
def update_screen(self):
|
def update_screen(self):
|
||||||
self.char_grid.update_cell_data()
|
self.char_grid.update_cell_data()
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|||||||
@@ -33,10 +33,14 @@ class Callbacks:
|
|||||||
def buf_toggled(self, is_alt):
|
def buf_toggled(self, is_alt):
|
||||||
self.is_alt = is_alt
|
self.is_alt = is_alt
|
||||||
|
|
||||||
|
def use_utf8(self, on):
|
||||||
|
self.iutf8 = on
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.wtcbuf = b''
|
self.wtcbuf = b''
|
||||||
self.iconbuf = self.titlebuf = self.colorbuf = self.qbuf = self.ctbuf = ''
|
self.iconbuf = self.titlebuf = self.colorbuf = self.qbuf = self.ctbuf = ''
|
||||||
self.is_alt = False
|
self.is_alt = False
|
||||||
|
self.iutf8 = True
|
||||||
|
|
||||||
|
|
||||||
def filled_line_buf(ynum=5, xnum=5, cursor=Cursor()):
|
def filled_line_buf(ynum=5, xnum=5, cursor=Cursor()):
|
||||||
|
|||||||
@@ -72,11 +72,17 @@ class TestParser(BaseTest):
|
|||||||
self.ae(str(s.line(0)), '123 ')
|
self.ae(str(s.line(0)), '123 ')
|
||||||
|
|
||||||
def test_charsets(self):
|
def test_charsets(self):
|
||||||
|
s = self.create_screen()
|
||||||
|
pb = partial(self.parse_bytes_dump, s)
|
||||||
|
pb(b'\xc3')
|
||||||
|
pb(b'\xa1', ('draw', b'\xc3\xa1'.decode('utf-8')))
|
||||||
s = self.create_screen()
|
s = self.create_screen()
|
||||||
pb = partial(self.parse_bytes_dump, s)
|
pb = partial(self.parse_bytes_dump, s)
|
||||||
pb('\033)0\x0e/_', ('screen_designate_charset', 1, ord('0')), ('screen_change_charset', 1), '/_')
|
pb('\033)0\x0e/_', ('screen_designate_charset', 1, ord('0')), ('screen_change_charset', 1), '/_')
|
||||||
self.ae(str(s.line(0)), '/\xa0 ')
|
self.ae(str(s.line(0)), '/\xa0 ')
|
||||||
pb('\033%G_', ('screen_use_latin1', 0), '_')
|
self.assertTrue(s.callbacks.iutf8)
|
||||||
|
pb('\033%@_', ('screen_use_latin1', 1), '_')
|
||||||
|
self.assertFalse(s.callbacks.iutf8)
|
||||||
s = self.create_screen()
|
s = self.create_screen()
|
||||||
pb = partial(self.parse_bytes_dump, s)
|
pb = partial(self.parse_bytes_dump, s)
|
||||||
pb('\033(0/_', ('screen_designate_charset', 0, ord('0')), '/_')
|
pb('\033(0/_', ('screen_designate_charset', 0, ord('0')), '/_')
|
||||||
|
|||||||
Reference in New Issue
Block a user