Add support for the CSI t escape code to query window and cell sizes

This commit is contained in:
Kovid Goyal 2018-05-28 13:47:42 +05:30
parent 6570565e2d
commit dd20789249
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 52 additions and 0 deletions

View File

@ -56,6 +56,10 @@ print('number of columns: {}, number of rows: {}, screen width: {}, screen heigh
Note that some terminals return `0` for the width and height values. Such terminals should be modified to return the correct values.
Examples of terminals that return correct values: `kitty, xterm`
You can also use the *CSI t* escape code to get the screen size. Send `<ESC>[14t` to *stdout* and kitty will reply on *stdin* with
`<ESC>[4;<height>;<width>t` where *height* and *width* are the window size in pixels. This escape code is supported in many terminals,
not just kitty.
== The graphics escape code
All graphics escape codes are of the form:

View File

@ -694,6 +694,22 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
}
REPORT_ERROR("Unknown CSI s sequence with start and end modifiers: '%c' '%c' and %u parameters", start_modifier, end_modifier, num_params);
break;
case 't':
if (!start_modifier && !end_modifier && num_params == 1) {
switch(params[0]) {
case 14:
case 16:
case 18:
CALL_CSI_HANDLER1(screen_report_size, 0);
break;
default:
REPORT_ERROR("Unknown CSI t sequences with parameter: '%u'", params[0]);
break;
}
break;
}
REPORT_ERROR("Unknown CSI t sequence with start and end modifiers: '%c' '%c' and %u parameters", start_modifier, end_modifier, num_params);
break;
case 'u':
if (!start_modifier && !end_modifier && !num_params) {
REPORT_COMMAND(screen_restore_cursor);

View File

@ -1113,6 +1113,34 @@ report_device_attributes(Screen *self, unsigned int mode, char start_modifier) {
}
}
void
screen_report_size(Screen *self, unsigned int which) {
char buf[32] = {0};
unsigned int code = 0;
unsigned int width = 0, height = 0;
switch(which) {
case 14:
code = 4;
width = self->cell_size.width * self->columns;
height = self->cell_size.height * self->lines;
break;
case 16:
code = 6;
width = self->cell_size.width;
height = self->cell_size.height;
break;
case 18:
code = 8;
width = self->columns;
height = self->lines;
break;
}
if (code) {
snprintf(buf, sizeof(buf), "%u;%u;%ut", code, height, width);
write_escape_code_to_child(self, CSI, buf);
}
}
void
report_device_status(Screen *self, unsigned int which, bool private) {
// We dont implement the private device status codes, since I haven't come

View File

@ -172,6 +172,7 @@ void screen_handle_graphics_command(Screen *self, const GraphicsCommand *cmd, co
bool screen_open_url(Screen*);
void screen_dirty_sprite_positions(Screen *self);
void screen_rescale_images(Screen *self);
void screen_report_size(Screen *, unsigned int which);
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen);
DECLARE_CH_SCREEN_HANDLER(bell)
DECLARE_CH_SCREEN_HANDLER(backspace)

View File

@ -160,6 +160,9 @@ class TestParser(BaseTest):
pb('\033[?1$p', ('report_mode_status', 1, 1))
self.ae(c.wtcbuf, b'\033[?1;2$y')
pb('\033[2;4r', ('screen_set_margins', 2, 4))
c.clear()
pb('\033[14t', ('screen_report_size', 14))
self.ae(c.wtcbuf, b'\033[4;100;50t')
self.ae(s.margin_top, 1), self.ae(s.margin_bottom, 3)
pb('\033[r', ('screen_set_margins', 0, 0))
self.ae(s.margin_top, 0), self.ae(s.margin_bottom, 4)