Get query terminal working again

Also return current OS Window's font size
This commit is contained in:
Kovid Goyal
2024-05-07 19:02:59 +05:30
parent 8844ae3a10
commit d826265fd7
7 changed files with 55 additions and 34 deletions

View File

@@ -50,7 +50,7 @@ class Query:
return self.ans return self.ans
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
raise NotImplementedError() raise NotImplementedError()
@@ -69,7 +69,7 @@ class TerminalName(Query):
help_text: str = f'Terminal name (e.g. :code:`{names[0]}`)' help_text: str = f'Terminal name (e.g. :code:`{names[0]}`)'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
return appname return appname
@@ -79,7 +79,7 @@ class TerminalVersion(Query):
help_text: str = f'Terminal version (e.g. :code:`{str_version}`)' help_text: str = f'Terminal version (e.g. :code:`{str_version}`)'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
return str_version return str_version
@@ -89,7 +89,7 @@ class AllowHyperlinks(Query):
help_text: str = 'The config option :opt:`allow_hyperlinks` in :file:`kitty.conf` for allowing hyperlinks can be :code:`yes`, :code:`no` or :code:`ask`' help_text: str = 'The config option :opt:`allow_hyperlinks` in :file:`kitty.conf` for allowing hyperlinks can be :code:`yes`, :code:`no` or :code:`ask`'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
return 'ask' if opts.allow_hyperlinks == 0b11 else ('yes' if opts.allow_hyperlinks else 'no') return 'ask' if opts.allow_hyperlinks == 0b11 else ('yes' if opts.allow_hyperlinks else 'no')
@@ -99,10 +99,10 @@ class FontFamily(Query):
help_text: str = 'The current font\'s PostScript name' help_text: str = 'The current font\'s PostScript name'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
from kitty.fast_data_types import current_fonts from kitty.fast_data_types import current_fonts
cf = current_fonts() cf = current_fonts(os_window_id)
return str(cf['medium'].display_name()) return cf['medium'].postscript_name()
@query @query
@@ -111,10 +111,10 @@ class BoldFont(Query):
help_text: str = 'The current bold font\'s PostScript name' help_text: str = 'The current bold font\'s PostScript name'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
from kitty.fast_data_types import current_fonts from kitty.fast_data_types import current_fonts
cf = current_fonts() cf = current_fonts(os_window_id)
return str(cf['bold'].display_name()) return cf['bold'].postscript_name()
@query @query
@@ -123,10 +123,10 @@ class ItalicFont(Query):
help_text: str = 'The current italic font\'s PostScript name' help_text: str = 'The current italic font\'s PostScript name'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
from kitty.fast_data_types import current_fonts from kitty.fast_data_types import current_fonts
cf = current_fonts() cf = current_fonts(os_window_id)
return str(cf['italic'].display_name()) return cf['italic'].postscript_name()
@query @query
@@ -135,20 +135,22 @@ class BiFont(Query):
help_text: str = 'The current bold-italic font\'s PostScript name' help_text: str = 'The current bold-italic font\'s PostScript name'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
from kitty.fast_data_types import current_fonts from kitty.fast_data_types import current_fonts
cf = current_fonts() cf = current_fonts(os_window_id)
return str(cf['bi'].display_name()) return cf['bi'].postscript_name()
@query @query
class FontSize(Query): class FontSize(Query):
name: str = 'font_size' name: str = 'font_size'
help_text: str = 'The current overall font size (individual windows can have different per window font sizes)' help_text: str = 'The current font size in pts'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
return f'{opts.font_size:g}' from kitty.fast_data_types import current_fonts
cf = current_fonts(os_window_id)
return f'{cf['font_sz_in_pts']:g}'
@query @query
@@ -157,16 +159,16 @@ class ClipboardControl(Query):
help_text: str = 'The config option :opt:`clipboard_control` in :file:`kitty.conf` for allowing reads/writes to/from the clipboard' help_text: str = 'The config option :opt:`clipboard_control` in :file:`kitty.conf` for allowing reads/writes to/from the clipboard'
@staticmethod @staticmethod
def get_result(opts: Options) -> str: def get_result(opts: Options, window_id: int, os_window_id: int) -> str:
return ' '.join(opts.clipboard_control) return ' '.join(opts.clipboard_control)
def get_result(name: str) -> Optional[str]: def get_result(name: str, window_id: int, os_window_id: int) -> Optional[str]:
from kitty.fast_data_types import get_options from kitty.fast_data_types import get_options
q = all_queries.get(name) q = all_queries.get(name)
if q is None: if q is None:
return None return None
return q.get_result(get_options()) return q.get_result(get_options(), window_id, os_window_id)
def do_queries(queries: Iterable[str], cli_opts: QueryTerminalCLIOptions) -> Dict[str, str]: def do_queries(queries: Iterable[str], cli_opts: QueryTerminalCLIOptions) -> Dict[str, str]:

View File

@@ -849,8 +849,15 @@ display_name(CTFace *self) {
return convert_cfstring(dn, true); return convert_cfstring(dn, true);
} }
static PyObject*
postscript_name(CTFace *self) {
return self->postscript_name ? Py_BuildValue("O", self->postscript_name) : PyUnicode_FromString("");
}
static PyMethodDef methods[] = { static PyMethodDef methods[] = {
METHODB(display_name, METH_NOARGS), METHODB(display_name, METH_NOARGS),
METHODB(postscript_name, METH_NOARGS),
METHODB(get_variable_data, METH_NOARGS), METHODB(get_variable_data, METH_NOARGS),
METHODB(identify_for_debug, METH_NOARGS), METHODB(identify_for_debug, METH_NOARGS),
METHODB(get_best_name, METH_O), METHODB(get_best_name, METH_O),
@@ -894,7 +901,6 @@ static PyMemberDef members[] = {
MEM(family_name, T_OBJECT), MEM(family_name, T_OBJECT),
MEM(path, T_OBJECT), MEM(path, T_OBJECT),
MEM(full_name, T_OBJECT), MEM(full_name, T_OBJECT),
MEM(postscript_name, T_OBJECT),
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };

View File

@@ -425,7 +425,7 @@ class Face:
def __init__(self, descriptor: Optional[FontConfigPattern] = None, path: str = '', index: int = 0): ... def __init__(self, descriptor: Optional[FontConfigPattern] = None, path: str = '', index: int = 0): ...
def get_variable_data(self) -> VariableData: ... def get_variable_data(self) -> VariableData: ...
def identify_for_debug(self) -> str: ... def identify_for_debug(self) -> str: ...
def display_name(self) -> str: ... def postscript_name(self) -> str: ...
class CoreTextFont(TypedDict): class CoreTextFont(TypedDict):
@@ -456,7 +456,7 @@ class CTFace:
def __init__(self, descriptor: Optional[CoreTextFont] = None, path: str = ''): ... def __init__(self, descriptor: Optional[CoreTextFont] = None, path: str = ''): ...
def get_variable_data(self) -> VariableData: ... def get_variable_data(self) -> VariableData: ...
def identify_for_debug(self) -> str: ... def identify_for_debug(self) -> str: ...
def display_name(self) -> str: ... def postscript_name(self) -> str: ...
def coretext_all_fonts(monospaced_only: bool) -> Tuple[CoreTextFont, ...]: def coretext_all_fonts(monospaced_only: bool) -> Tuple[CoreTextFont, ...]:
@@ -922,9 +922,12 @@ class CurrentFonts(TypedDict):
bi: FontFace bi: FontFace
symbol: Tuple[FontFace, ...] symbol: Tuple[FontFace, ...]
fallback: Tuple[FontFace, ...] fallback: Tuple[FontFace, ...]
font_sz_in_pts: float
logical_dpi_x: float
logical_dpi_y: float
def current_fonts() -> CurrentFonts: ... def current_fonts(os_window_id: int = 0) -> CurrentFonts: ...
def remove_window(os_window_id: int, tab_id: int, window_id: int) -> None: def remove_window(os_window_id: int, tab_id: int, window_id: int) -> None:

View File

@@ -1633,11 +1633,18 @@ concat_cells(PyObject UNUSED *self, PyObject *args) {
} }
static PyObject* static PyObject*
current_fonts(PYNOARG) { current_fonts(PyObject *self UNUSED, PyObject *args) {
unsigned long long os_window_id = 0;
if (!PyArg_ParseTuple(args, "|K", &os_window_id)) return NULL;
if (!num_font_groups) { PyErr_SetString(PyExc_RuntimeError, "must create font group first"); return NULL; } if (!num_font_groups) { PyErr_SetString(PyExc_RuntimeError, "must create font group first"); return NULL; }
FontGroup *fg = font_groups;
if (os_window_id) {
OSWindow *os_window = os_window_for_id(os_window_id);
if (!os_window) { PyErr_SetString(PyExc_KeyError, "no oswindow with the specified id exists"); return NULL; }
fg = (FontGroup*)os_window->fonts_data;
}
RAII_PyObject(ans, PyDict_New()); RAII_PyObject(ans, PyDict_New());
if (!ans) return NULL; if (!ans) return NULL;
FontGroup *fg = font_groups;
#define SET(key, val) {if (PyDict_SetItemString(ans, #key, fg->fonts[val].face) != 0) { return NULL; }} #define SET(key, val) {if (PyDict_SetItemString(ans, #key, fg->fonts[val].face) != 0) { return NULL; }}
SET(medium, fg->medium_font_idx); SET(medium, fg->medium_font_idx);
if (fg->bold_font_idx > 0) SET(bold, fg->bold_font_idx); if (fg->bold_font_idx > 0) SET(bold, fg->bold_font_idx);
@@ -1658,6 +1665,9 @@ current_fonts(PYNOARG) {
PyTuple_SET_ITEM(ff, i, fg->fonts[fg->first_fallback_font_idx + i].face); PyTuple_SET_ITEM(ff, i, fg->fonts[fg->first_fallback_font_idx + i].face);
} }
if (PyDict_SetItemString(ans, "fallback", ff) != 0) return NULL; if (PyDict_SetItemString(ans, "fallback", ff) != 0) return NULL;
#define p(x) { RAII_PyObject(t, PyFloat_FromDouble(fg->x)); if (!t) return NULL; if (PyDict_SetItemString(ans, #x, t) != 0) return NULL; }
p(font_sz_in_pts); p(logical_dpi_x); p(logical_dpi_y);
#undef p
Py_INCREF(ans); Py_INCREF(ans);
return ans; return ans;
#undef SET #undef SET
@@ -1725,7 +1735,7 @@ static PyMethodDef module_methods[] = {
METHODB(concat_cells, METH_VARARGS), METHODB(concat_cells, METH_VARARGS),
METHODB(set_send_sprite_to_gpu, METH_O), METHODB(set_send_sprite_to_gpu, METH_O),
METHODB(test_shape, METH_VARARGS), METHODB(test_shape, METH_VARARGS),
METHODB(current_fonts, METH_NOARGS), METHODB(current_fonts, METH_VARARGS),
METHODB(test_render_line, METH_VARARGS), METHODB(test_render_line, METH_VARARGS),
METHODB(get_fallback_font, METH_VARARGS), METHODB(get_fallback_font, METH_VARARGS),
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */

View File

@@ -497,8 +497,8 @@ def test_render_string(
cell_width, cell_height, cells = render_string(text, family, size, dpi) cell_width, cell_height, cells = render_string(text, family, size, dpi)
rgb_data = concat_cells(cell_width, cell_height, True, tuple(cells)) rgb_data = concat_cells(cell_width, cell_height, True, tuple(cells))
cf = current_fonts() cf = current_fonts()
fonts = [cf['medium'].display_name()] fonts = [cf['medium'].postscript_name()]
fonts.extend(f.display_name() for f in cf['fallback']) fonts.extend(f.postscript_name() for f in cf['fallback'])
msg = 'Rendered string {} below, with fonts: {}\n'.format(text, ', '.join(fonts)) msg = 'Rendered string {} below, with fonts: {}\n'.format(text, ', '.join(fonts))
try: try:
print(msg) print(msg)

View File

@@ -517,7 +517,7 @@ def key_as_bytes(name: str) -> bytes:
return ans.encode('ascii') return ans.encode('ascii')
def get_capabilities(query_string: str, opts: 'Options') -> Generator[str, None, None]: def get_capabilities(query_string: str, opts: 'Options', window_id: int, os_window_id: int) -> Generator[str, None, None]:
from .fast_data_types import ERROR_PREFIX from .fast_data_types import ERROR_PREFIX
def result(encoded_query_name: str, x: Optional[str] = None) -> str: def result(encoded_query_name: str, x: Optional[str] = None) -> str:
@@ -533,7 +533,7 @@ def get_capabilities(query_string: str, opts: 'Options') -> Generator[str, None,
elif name.startswith('kitty-query-'): elif name.startswith('kitty-query-'):
from kittens.query_terminal.main import get_result from kittens.query_terminal.main import get_result
name = name[len('kitty-query-'):] name = name[len('kitty-query-'):]
rval = get_result(name) rval = get_result(name, window_id, os_window_id)
if rval is None: if rval is None:
from .utils import log_error from .utils import log_error
log_error('Unknown kitty terminfo query:', name) log_error('Unknown kitty terminfo query:', name)

View File

@@ -1273,7 +1273,7 @@ class Window:
self.refresh() self.refresh()
def request_capabilities(self, q: str) -> None: def request_capabilities(self, q: str) -> None:
for result in get_capabilities(q, get_options()): for result in get_capabilities(q, get_options(), self.id, self.os_window_id):
self.screen.send_escape_code_to_child(ESC_DCS, result) self.screen.send_escape_code_to_child(ESC_DCS, result)
def handle_remote_cmd(self, cmd: memoryview) -> None: def handle_remote_cmd(self, cmd: memoryview) -> None: