Compare commits

...

7 Commits

Author SHA1 Message Date
Kovid Goyal
339dd9b412 version 0.2.3 2017-04-28 09:48:27 +05:30
Kovid Goyal
3f272d102b Test for toggling IUTF8 2017-04-28 09:41:47 +05:30
Kovid Goyal
29988c94fa Fix #70 2017-04-28 09:21:40 +05:30
Kovid Goyal
35f2b3254a A spot of refactoring 2017-04-28 08:54:06 +05:30
Kovid Goyal
898a8075be Fix #69 2017-04-28 08:31:07 +05:30
Kovid Goyal
f5d957e8ff Merge branch 'binor-patch-1' of https://github.com/binor/kitty 2017-04-07 08:24:33 +05:30
binor
2cc3cabd3f Fix mouse coordinates off on macOS Retina display 2017-04-06 19:53:14 +02:00
10 changed files with 54 additions and 11 deletions

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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*);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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()

View File

@@ -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()):

View File

@@ -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')), '/_')