Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b0724530e | ||
|
|
e5681a93f9 | ||
|
|
fb838a694e | ||
|
|
8c6f188767 | ||
|
|
55e15dc79e | ||
|
|
514073cb75 | ||
|
|
f6ece6522e | ||
|
|
817f0997cf | ||
|
|
1d651270d3 | ||
|
|
6ea58fac1a | ||
|
|
c7eb63d4ff | ||
|
|
4062365b19 | ||
|
|
7f48a927de | ||
|
|
4a740cc556 | ||
|
|
628b92f20b | ||
|
|
8f9616c230 | ||
|
|
df475dfde5 | ||
|
|
a835b56a51 | ||
|
|
5555a66638 | ||
|
|
dad355b932 | ||
|
|
90a097d45c | ||
|
|
dba01bc014 | ||
|
|
1d0a3ce998 | ||
|
|
076ad850bb | ||
|
|
868546abe4 | ||
|
|
6b421fabd1 | ||
|
|
ab3c9658bd | ||
|
|
8c7886d429 | ||
|
|
110a3e7e0f | ||
|
|
ee0b70f51b | ||
|
|
df48061a8f | ||
|
|
b1387d50f0 | ||
|
|
73dd218a95 | ||
|
|
ee4cedcc81 | ||
|
|
d1b2f9c6a9 | ||
|
|
40dee44978 | ||
|
|
db04c70d4a | ||
|
|
7401c6ac97 | ||
|
|
f7a1222cc3 | ||
|
|
069f09c43c | ||
|
|
35f821f6a1 | ||
|
|
67f60847ee | ||
|
|
65f6b142a5 |
@@ -7,6 +7,7 @@ import re
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
from contextlib import suppress
|
||||||
|
|
||||||
from bypy.constants import (
|
from bypy.constants import (
|
||||||
LIBDIR, PREFIX, PYTHON, SRC as KITTY_DIR, ismacos, worker_env
|
LIBDIR, PREFIX, PYTHON, SRC as KITTY_DIR, ismacos, worker_env
|
||||||
@@ -47,6 +48,16 @@ def build_c_extensions(ext_dir, args):
|
|||||||
shutil.copytree(
|
shutil.copytree(
|
||||||
KITTY_DIR, writeable_src_dir, symlinks=True,
|
KITTY_DIR, writeable_src_dir, symlinks=True,
|
||||||
ignore=shutil.ignore_patterns('b', 'build', 'dist', '*_commands.json', '*.o'))
|
ignore=shutil.ignore_patterns('b', 'build', 'dist', '*_commands.json', '*.o'))
|
||||||
|
|
||||||
|
# Build the launcher as it is needed for the spawn test
|
||||||
|
with suppress(FileNotFoundError):
|
||||||
|
os.remove(os.path.join(writeable_src_dir, 'kitty', 'launcher', 'kitty'))
|
||||||
|
if run(PYTHON, 'setup.py', 'build-launcher', cwd=writeable_src_dir) != 0:
|
||||||
|
print('Building of kitty launcher failed', file=sys.stderr)
|
||||||
|
os.chdir(KITTY_DIR)
|
||||||
|
run_shell()
|
||||||
|
raise SystemExit('Building of kitty launcher failed')
|
||||||
|
|
||||||
cmd = [PYTHON, 'setup.py']
|
cmd = [PYTHON, 'setup.py']
|
||||||
bundle = 'macos-freeze' if ismacos else 'linux-freeze'
|
bundle = 'macos-freeze' if ismacos else 'linux-freeze'
|
||||||
cmd.append(bundle)
|
cmd.append(bundle)
|
||||||
|
|||||||
@@ -4,6 +4,27 @@ Changelog
|
|||||||
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
||||||
To update |kitty|, :doc:`follow the instructions <binary>`.
|
To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||||
|
|
||||||
|
0.18.3 [2020-08-11]
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- hints kitten: Allow customizing hint colors (:pull:`2894`)
|
||||||
|
|
||||||
|
- Wayland: Fix a typo in the previous release that broke reading mouse cursor size (:iss:`2895`)
|
||||||
|
|
||||||
|
- Fix a regression in the previous release that could cause an exception during
|
||||||
|
startup in rare circumstances (:iss:`2896`)
|
||||||
|
|
||||||
|
- Fix image leaving behind a black rectangle when switch away and back to
|
||||||
|
alternate screen (:iss:`2901`)
|
||||||
|
|
||||||
|
- Fix one pixel mis-alignment of rounded corners when either the cell
|
||||||
|
dimensions or the thickness of the line is an odd number of pixels
|
||||||
|
(:iss:`2907`)
|
||||||
|
|
||||||
|
- Fix a regression that broke specifying OS window size in the session file
|
||||||
|
(:iss:`2908`)
|
||||||
|
|
||||||
|
|
||||||
0.18.2 [2020-07-28]
|
0.18.2 [2020-07-28]
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
@@ -25,7 +46,7 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
- When a character from the Unicode Dingbat block is followed by a space, use
|
- When a character from the Unicode Dingbat block is followed by a space, use
|
||||||
the extra space to render a larger version of the character (:iss:`2850`)
|
the extra space to render a larger version of the character (:iss:`2850`)
|
||||||
|
|
||||||
- macOS: Fix the LC_TYPE env var being set to UTF-8 on systems in which the
|
- macOS: Fix the LC_CTYPE env var being set to UTF-8 on systems in which the
|
||||||
language and country code do not form a valid locale (:iss:`1233`)
|
language and country code do not form a valid locale (:iss:`1233`)
|
||||||
|
|
||||||
- macOS: Fix :kbd:`cmd+plus` not changing font size (:iss:`2839`)
|
- macOS: Fix :kbd:`cmd+plus` not changing font size (:iss:`2839`)
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ images and other types of documents directly in your terminal, even over SSH.
|
|||||||
`nnn <https://github.com/jarun/nnn/>`_
|
`nnn <https://github.com/jarun/nnn/>`_
|
||||||
another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||||
|
|
||||||
|
`hunter <https://github.com/rabite0/hunter>`_
|
||||||
|
another terminal file manager, with previews of file contents powered by kitty's graphics protocol.
|
||||||
|
|
||||||
`koneko <https://github.com/twenty5151/koneko>`_
|
`koneko <https://github.com/twenty5151/koneko>`_
|
||||||
browse images from the pixiv artist community directly in kitty
|
browse images from the pixiv artist community directly in kitty
|
||||||
|
|
||||||
@@ -109,3 +112,7 @@ Miscellaneous
|
|||||||
|
|
||||||
`kitti3 <https://github.com/LandingEllipse/kitti3>`_
|
`kitti3 <https://github.com/LandingEllipse/kitti3>`_
|
||||||
allow using kitty as a drop-down terminal under the i3 window manager
|
allow using kitty as a drop-down terminal under the i3 window manager
|
||||||
|
|
||||||
|
`weechat-hints <https://github.com/GermainZ/kitty-weechat-hints>`_
|
||||||
|
URL hints kitten for WeeChat that works without having to use WeeChat's
|
||||||
|
raw-mode.
|
||||||
|
|||||||
@@ -196,3 +196,7 @@ Kittens created by kitty users
|
|||||||
`insert password <https://github.com/kovidgoyal/kitty/issues/1222>`_
|
`insert password <https://github.com/kovidgoyal/kitty/issues/1222>`_
|
||||||
Insert a password from a CLI password manager, taking care to only do it at
|
Insert a password from a CLI password manager, taking care to only do it at
|
||||||
a password prompt.
|
a password prompt.
|
||||||
|
|
||||||
|
`weechat-hints <https://github.com/GermainZ/kitty-weechat-hints>`_
|
||||||
|
URL hints kitten for WeeChat that works without having to use WeeChat's
|
||||||
|
raw-mode.
|
||||||
|
|||||||
@@ -10,18 +10,18 @@ form::
|
|||||||
Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form::
|
Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form::
|
||||||
|
|
||||||
{
|
{
|
||||||
'cmd': "command name",
|
"cmd": "command name",
|
||||||
'version': "kitty version",
|
"version": <kitty version>,
|
||||||
'no_response': Optional Boolean,
|
"no_response": Optional Boolean,
|
||||||
'payload': <Optional JSON object>,
|
"payload": <Optional JSON object>,
|
||||||
}
|
}
|
||||||
|
|
||||||
The ``version`` above is a string of the form :code:`0.14.2`. If you are developing a
|
The ``version`` above is an array of the form :code:`[0, 14, 2]`. If you are developing a
|
||||||
standalone client, use the kitty version that you are developing against. Using
|
standalone client, use the kitty version that you are developing against. Using
|
||||||
a version greater than the version of the kitty instance you are talking to,
|
a version greater than the version of the kitty instance you are talking to,
|
||||||
will cause a failure.
|
will cause a failure.
|
||||||
|
|
||||||
Set ``no_response`` to True if you don't want a response from kitty.
|
Set ``no_response`` to ``true`` if you don't want a response from kitty.
|
||||||
|
|
||||||
The optional payload is a JSON object that is specific to the actual command being sent.
|
The optional payload is a JSON object that is specific to the actual command being sent.
|
||||||
The fields in the object for every command are documented below.
|
The fields in the object for every command are documented below.
|
||||||
|
|||||||
@@ -274,7 +274,9 @@ def category_test(
|
|||||||
comment: str,
|
comment: str,
|
||||||
use_static: bool = False,
|
use_static: bool = False,
|
||||||
extra_chars: Union[FrozenSet[int], Set[int]] = frozenset(),
|
extra_chars: Union[FrozenSet[int], Set[int]] = frozenset(),
|
||||||
exclude: Union[Set[int], FrozenSet[int]] = frozenset()
|
exclude: Union[Set[int], FrozenSet[int]] = frozenset(),
|
||||||
|
least_check_return: Optional[str] = None,
|
||||||
|
ascii_range: Optional[str] = None
|
||||||
) -> None:
|
) -> None:
|
||||||
static = 'static inline ' if use_static else ''
|
static = 'static inline ' if use_static else ''
|
||||||
chars: Set[int] = set()
|
chars: Set[int] = set()
|
||||||
@@ -284,6 +286,11 @@ def category_test(
|
|||||||
chars -= exclude
|
chars -= exclude
|
||||||
p(f'{static}bool\n{name}(char_type code) {{')
|
p(f'{static}bool\n{name}(char_type code) {{')
|
||||||
p(f'\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
|
p(f'\t// {comment} ({len(chars)} codepoints)' + ' {{' '{')
|
||||||
|
if least_check_return is not None:
|
||||||
|
least = min(chars)
|
||||||
|
p(f'\tif (LIKELY(code < {least})) return {least_check_return};')
|
||||||
|
if ascii_range is not None:
|
||||||
|
p(f'\tif (LIKELY(0x20 <= code && code <= 0x7e)) return {ascii_range};')
|
||||||
p('\tswitch(code) {')
|
p('\tswitch(code) {')
|
||||||
for spec in get_ranges(list(chars)):
|
for spec in get_ranges(list(chars)):
|
||||||
write_case(spec, p)
|
write_case(spec, p)
|
||||||
@@ -337,11 +344,15 @@ def gen_ucd() -> None:
|
|||||||
{c for c in class_maps if c.startswith('M')},
|
{c for c in class_maps if c.startswith('M')},
|
||||||
'M category (marks)',
|
'M category (marks)',
|
||||||
# See https://github.com/harfbuzz/harfbuzz/issues/169
|
# See https://github.com/harfbuzz/harfbuzz/issues/169
|
||||||
extra_chars=emoji_skin_tone_modifiers | {zwj}
|
extra_chars=emoji_skin_tone_modifiers | {zwj},
|
||||||
|
least_check_return='false'
|
||||||
)
|
)
|
||||||
category_test(
|
category_test(
|
||||||
'is_ignored_char', p, 'Cc Cf Cs'.split(),
|
'is_ignored_char', p, 'Cc Cf Cs'.split(),
|
||||||
'Control characters and non-characters', extra_chars=non_characters, exclude={zwj})
|
'Control characters and non-characters',
|
||||||
|
extra_chars=non_characters, exclude={zwj},
|
||||||
|
ascii_range='false'
|
||||||
|
)
|
||||||
category_test('is_word_char', p, {c for c in class_maps if c[0] in 'LN'}, 'L and N categories')
|
category_test('is_word_char', p, {c for c in class_maps if c[0] in 'LN'}, 'L and N categories')
|
||||||
category_test('is_CZ_category', p, cz, 'C and Z categories')
|
category_test('is_CZ_category', p, cz, 'C and Z categories')
|
||||||
category_test('is_P_category', p, {c for c in class_maps if c[0] == 'P'}, 'P category (punctuation)')
|
category_test('is_P_category', p, {c for c in class_maps if c[0] == 'P'}, 'P category (punctuation)')
|
||||||
@@ -421,7 +432,7 @@ def gen_names() -> None:
|
|||||||
p('}; // }}}\n')
|
p('}; // }}}\n')
|
||||||
|
|
||||||
# The trie
|
# The trie
|
||||||
p('typedef struct {{ uint32_t children_offset; uint32_t match_offset; }} word_trie;\n')
|
p('typedef struct { uint32_t children_offset; uint32_t match_offset; } word_trie;\n')
|
||||||
all_trie_nodes: List['TrieNode'] = [] # noqa
|
all_trie_nodes: List['TrieNode'] = [] # noqa
|
||||||
|
|
||||||
class TrieNode:
|
class TrieNode:
|
||||||
@@ -482,6 +493,7 @@ def gen_wcwidth() -> None:
|
|||||||
|
|
||||||
with create_header('kitty/wcwidth-std.h') as p:
|
with create_header('kitty/wcwidth-std.h') as p:
|
||||||
p('static int\nwcwidth_std(int32_t code) {')
|
p('static int\nwcwidth_std(int32_t code) {')
|
||||||
|
p('\tif (LIKELY(0x20 <= code && code <= 0x7e)) return 1;')
|
||||||
p('\tswitch(code) {')
|
p('\tswitch(code) {')
|
||||||
|
|
||||||
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
|
non_printing = class_maps['Cc'] | class_maps['Cf'] | class_maps['Cs']
|
||||||
|
|||||||
2
glfw/ibus_glfw.c
vendored
2
glfw/ibus_glfw.c
vendored
@@ -269,7 +269,7 @@ setup_connection(_GLFWIBUSData *ibus) {
|
|||||||
ibus->conn = NULL;
|
ibus->conn = NULL;
|
||||||
}
|
}
|
||||||
debug("Connecting to IBUS daemon @ %s for IME input management\n", ibus->address);
|
debug("Connecting to IBUS daemon @ %s for IME input management\n", ibus->address);
|
||||||
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", false);
|
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", true);
|
||||||
if (!ibus->conn) return false;
|
if (!ibus->conn) return false;
|
||||||
free((void*)ibus->input_ctx_path); ibus->input_ctx_path = NULL;
|
free((void*)ibus->input_ctx_path); ibus->input_ctx_path = NULL;
|
||||||
if (!glfw_dbus_call_method_with_reply(
|
if (!glfw_dbus_call_method_with_reply(
|
||||||
|
|||||||
2
glfw/null_joystick.c
vendored
2
glfw/null_joystick.c
vendored
@@ -33,7 +33,7 @@
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int _glfwPlatformInitJoysticks(void)
|
bool _glfwPlatformInitJoysticks(void)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
2
glfw/wl_cursors.c
vendored
2
glfw/wl_cursors.c
vendored
@@ -16,7 +16,7 @@ pixels_from_scale(int scale) {
|
|||||||
const char *env = getenv("XCURSOR_SIZE");
|
const char *env = getenv("XCURSOR_SIZE");
|
||||||
if (env) {
|
if (env) {
|
||||||
const int retval = atoi(env);
|
const int retval = atoi(env);
|
||||||
if (retval > 0 && retval < 2048) factor = 32;
|
if (retval > 0 && retval < 2048) factor = retval;
|
||||||
}
|
}
|
||||||
queried_env = true;
|
queried_env = true;
|
||||||
}
|
}
|
||||||
|
|||||||
2
glfw/wl_init.c
vendored
2
glfw/wl_init.c
vendored
@@ -802,6 +802,7 @@ void _glfwPlatformTerminate(void)
|
|||||||
glfw_xkb_release(&_glfw.wl.xkb);
|
glfw_xkb_release(&_glfw.wl.xkb);
|
||||||
glfw_dbus_terminate(&_glfw.wl.dbus);
|
glfw_dbus_terminate(&_glfw.wl.dbus);
|
||||||
|
|
||||||
|
glfw_wlc_destroy();
|
||||||
if (_glfw.wl.cursor.handle)
|
if (_glfw.wl.cursor.handle)
|
||||||
{
|
{
|
||||||
_glfw_dlclose(_glfw.wl.cursor.handle);
|
_glfw_dlclose(_glfw.wl.cursor.handle);
|
||||||
@@ -810,7 +811,6 @@ void _glfwPlatformTerminate(void)
|
|||||||
|
|
||||||
if (_glfw.wl.cursorSurface)
|
if (_glfw.wl.cursorSurface)
|
||||||
wl_surface_destroy(_glfw.wl.cursorSurface);
|
wl_surface_destroy(_glfw.wl.cursorSurface);
|
||||||
glfw_wlc_destroy();
|
|
||||||
if (_glfw.wl.subcompositor)
|
if (_glfw.wl.subcompositor)
|
||||||
wl_subcompositor_destroy(_glfw.wl.subcompositor);
|
wl_subcompositor_destroy(_glfw.wl.subcompositor);
|
||||||
if (_glfw.wl.compositor)
|
if (_glfw.wl.compositor)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ def decode_hint(x: str, alphabet: str = DEFAULT_HINT_ALPHABET) -> int:
|
|||||||
return i
|
return i
|
||||||
|
|
||||||
|
|
||||||
def highlight_mark(m: Mark, text: str, current_input: str, alphabet: str) -> str:
|
def highlight_mark(m: Mark, text: str, current_input: str, alphabet: str, colors: Dict[str, str]) -> str:
|
||||||
hint = encode_hint(m.index, alphabet)
|
hint = encode_hint(m.index, alphabet)
|
||||||
if current_input and not hint.startswith(current_input):
|
if current_input and not hint.startswith(current_input):
|
||||||
return faint(text)
|
return faint(text)
|
||||||
@@ -80,19 +80,19 @@ def highlight_mark(m: Mark, text: str, current_input: str, alphabet: str) -> str
|
|||||||
text = text[len(hint):]
|
text = text[len(hint):]
|
||||||
return styled(
|
return styled(
|
||||||
hint,
|
hint,
|
||||||
fg='black',
|
fg=colors['foreground'],
|
||||||
bg='green',
|
bg=colors['background'],
|
||||||
bold=True
|
bold=True
|
||||||
) + styled(
|
) + styled(
|
||||||
text, fg='gray', fg_intense=True, bold=True
|
text, fg=colors['text'], fg_intense=True, bold=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def render(text: str, current_input: str, all_marks: Sequence[Mark], ignore_mark_indices: Set[int], alphabet: str) -> str:
|
def render(text: str, current_input: str, all_marks: Sequence[Mark], ignore_mark_indices: Set[int], alphabet: str, colors: Dict[str, str]) -> str:
|
||||||
for mark in reversed(all_marks):
|
for mark in reversed(all_marks):
|
||||||
if mark.index in ignore_mark_indices:
|
if mark.index in ignore_mark_indices:
|
||||||
continue
|
continue
|
||||||
mtext = highlight_mark(mark, text[mark.start:mark.end], current_input, alphabet)
|
mtext = highlight_mark(mark, text[mark.start:mark.end], current_input, alphabet, colors)
|
||||||
text = text[:mark.start] + mtext + text[mark.end:]
|
text = text[:mark.start] + mtext + text[mark.end:]
|
||||||
|
|
||||||
text = text.replace('\0', '')
|
text = text.replace('\0', '')
|
||||||
@@ -105,6 +105,9 @@ class Hints(Handler):
|
|||||||
def __init__(self, text: str, all_marks: Sequence[Mark], index_map: Dict[int, Mark], args: HintsCLIOptions):
|
def __init__(self, text: str, all_marks: Sequence[Mark], index_map: Dict[int, Mark], args: HintsCLIOptions):
|
||||||
self.text, self.index_map = text, index_map
|
self.text, self.index_map = text, index_map
|
||||||
self.alphabet = args.alphabet or DEFAULT_HINT_ALPHABET
|
self.alphabet = args.alphabet or DEFAULT_HINT_ALPHABET
|
||||||
|
self.colors = {'foreground': args.hints_foreground_color,
|
||||||
|
'background': args.hints_background_color,
|
||||||
|
'text': args.hints_text_color}
|
||||||
self.all_marks = all_marks
|
self.all_marks = all_marks
|
||||||
self.ignore_mark_indices: Set[int] = set()
|
self.ignore_mark_indices: Set[int] = set()
|
||||||
self.args = args
|
self.args = args
|
||||||
@@ -198,7 +201,7 @@ class Hints(Handler):
|
|||||||
|
|
||||||
def draw_screen(self) -> None:
|
def draw_screen(self) -> None:
|
||||||
if self.current_text is None:
|
if self.current_text is None:
|
||||||
self.current_text = render(self.text, self.current_input, self.all_marks, self.ignore_mark_indices, self.alphabet)
|
self.current_text = render(self.text, self.current_input, self.all_marks, self.ignore_mark_indices, self.alphabet, self.colors)
|
||||||
self.cmd.clear_screen()
|
self.cmd.clear_screen()
|
||||||
self.write(self.current_text)
|
self.write(self.current_text)
|
||||||
|
|
||||||
@@ -513,6 +516,24 @@ type=bool-set
|
|||||||
Have the hints increase from top to bottom instead of decreasing from top to bottom.
|
Have the hints increase from top to bottom instead of decreasing from top to bottom.
|
||||||
|
|
||||||
|
|
||||||
|
--hints-foreground-color
|
||||||
|
default=black
|
||||||
|
type=str
|
||||||
|
The foreground color for hints
|
||||||
|
|
||||||
|
|
||||||
|
--hints-background-color
|
||||||
|
default=green
|
||||||
|
type=str
|
||||||
|
The background color for hints
|
||||||
|
|
||||||
|
|
||||||
|
--hints-text-color
|
||||||
|
default=gray
|
||||||
|
type=str
|
||||||
|
The foreground color for text pointed to by the hints
|
||||||
|
|
||||||
|
|
||||||
--customize-processing
|
--customize-processing
|
||||||
Name of a python file in the kitty config directory which will be imported to provide
|
Name of a python file in the kitty config directory which will be imported to provide
|
||||||
custom implementations for pattern finding and performing actions
|
custom implementations for pattern finding and performing actions
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ from typing import Callable, Dict, List, Tuple
|
|||||||
|
|
||||||
from kitty.cli import parse_args
|
from kitty.cli import parse_args
|
||||||
from kitty.cli_stub import PanelCLIOptions
|
from kitty.cli_stub import PanelCLIOptions
|
||||||
from kitty.options_stub import Options
|
|
||||||
from kitty.constants import is_macos
|
from kitty.constants import is_macos
|
||||||
|
from kitty.os_window_size import WindowSizeData
|
||||||
|
|
||||||
OPTIONS = r'''
|
OPTIONS = r'''
|
||||||
--lines
|
--lines
|
||||||
@@ -108,7 +108,7 @@ def setup_x11_window(win_id: int) -> None:
|
|||||||
func(win_id, window_width, window_height)
|
func(win_id, window_width, window_height)
|
||||||
|
|
||||||
|
|
||||||
def initial_window_size_func(opts: Options, cached_values: Dict) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]:
|
def initial_window_size_func(opts: WindowSizeData, cached_values: Dict) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]:
|
||||||
from kitty.fast_data_types import glfw_primary_monitor_size, set_smallest_allowed_resize
|
from kitty.fast_data_types import glfw_primary_monitor_size, set_smallest_allowed_resize
|
||||||
|
|
||||||
def initial_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> Tuple[int, int]:
|
def initial_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> Tuple[int, int]:
|
||||||
|
|||||||
2
kittens/unicode_input/names.h
generated
2
kittens/unicode_input/names.h
generated
@@ -1,4 +1,4 @@
|
|||||||
// unicode data, built from the unicode standard on: 2020-04-06
|
// unicode data, built from the unicode standard on: 2020-08-06
|
||||||
// see gen-wcwidth.py
|
// see gen-wcwidth.py
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ from .cli import create_opts, parse_args
|
|||||||
from .cli_stub import CLIOptions
|
from .cli_stub import CLIOptions
|
||||||
from .conf.utils import BadLine, to_cmdline
|
from .conf.utils import BadLine, to_cmdline
|
||||||
from .config import (
|
from .config import (
|
||||||
KeyAction, SubSequenceMap, common_opts_as_dict, initial_window_size_func,
|
KeyAction, SubSequenceMap, common_opts_as_dict,
|
||||||
prepare_config_file_for_editing
|
prepare_config_file_for_editing
|
||||||
)
|
)
|
||||||
from .config_data import MINIMUM_FONT_SIZE
|
from .config_data import MINIMUM_FONT_SIZE
|
||||||
@@ -40,8 +40,9 @@ from .fast_data_types import (
|
|||||||
from .keys import get_shortcut, shortcut_matches
|
from .keys import get_shortcut, shortcut_matches
|
||||||
from .layout.base import set_layout_options
|
from .layout.base import set_layout_options
|
||||||
from .options_stub import Options
|
from .options_stub import Options
|
||||||
|
from .os_window_size import initial_window_size_func
|
||||||
from .rgb import Color, color_from_int
|
from .rgb import Color, color_from_int
|
||||||
from .session import Session, create_sessions
|
from .session import Session, create_sessions, get_os_window_sizing_data
|
||||||
from .tabs import (
|
from .tabs import (
|
||||||
SpecialWindow, SpecialWindowInstance, Tab, TabDict, TabManager
|
SpecialWindow, SpecialWindowInstance, Tab, TabDict, TabManager
|
||||||
)
|
)
|
||||||
@@ -195,11 +196,11 @@ class Boss:
|
|||||||
startup_id: Optional[str] = None
|
startup_id: Optional[str] = None
|
||||||
) -> int:
|
) -> int:
|
||||||
if os_window_id is None:
|
if os_window_id is None:
|
||||||
opts_for_size = opts_for_size or getattr(startup_session, 'os_window_size', None) or self.opts
|
size_data = get_os_window_sizing_data(opts_for_size or self.opts, startup_session)
|
||||||
wclass = wclass or getattr(startup_session, 'os_window_class', None) or self.args.cls or appname
|
wclass = wclass or getattr(startup_session, 'os_window_class', None) or self.args.cls or appname
|
||||||
with startup_notification_handler(do_notify=startup_id is not None, startup_id=startup_id) as pre_show_callback:
|
with startup_notification_handler(do_notify=startup_id is not None, startup_id=startup_id) as pre_show_callback:
|
||||||
os_window_id = create_os_window(
|
os_window_id = create_os_window(
|
||||||
initial_window_size_func(opts_for_size, self.cached_values),
|
initial_window_size_func(size_data, self.cached_values),
|
||||||
pre_show_callback,
|
pre_show_callback,
|
||||||
self.args.title or appname, wname or self.args.name or wclass, wclass)
|
self.args.title or appname, wname or self.args.name or wclass, wclass)
|
||||||
tm = TabManager(os_window_id, self.opts, self.args, startup_session)
|
tm = TabManager(os_window_id, self.opts, self.args, startup_session)
|
||||||
|
|||||||
@@ -537,6 +537,11 @@ cocoa_hide_titlebar(void *w)
|
|||||||
} // autoreleasepool
|
} // autoreleasepool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cocoa_system_beep(void) {
|
||||||
|
NSBeep();
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
{"cocoa_get_lang", (PyCFunction)cocoa_get_lang, METH_NOARGS, ""},
|
{"cocoa_get_lang", (PyCFunction)cocoa_get_lang, METH_NOARGS, ""},
|
||||||
{"cocoa_set_new_window_trigger", (PyCFunction)cocoa_set_new_window_trigger, METH_VARARGS, ""},
|
{"cocoa_set_new_window_trigger", (PyCFunction)cocoa_set_new_window_trigger, METH_VARARGS, ""},
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ from .config_data import all_options, parse_mods, type_convert
|
|||||||
from .constants import cache_dir, defconf, is_macos
|
from .constants import cache_dir, defconf, is_macos
|
||||||
from .key_names import get_key_name_lookup, key_name_aliases
|
from .key_names import get_key_name_lookup, key_name_aliases
|
||||||
from .options_stub import Options as OptionsStub
|
from .options_stub import Options as OptionsStub
|
||||||
from .typing import EdgeLiteral, TypedDict
|
from .typing import TypedDict
|
||||||
from .utils import expandvars, log_error
|
from .utils import expandvars, log_error
|
||||||
|
|
||||||
KeySpec = Tuple[int, bool, int]
|
KeySpec = Tuple[int, bool, int]
|
||||||
@@ -718,51 +718,6 @@ def cached_values_for(name: str) -> Generator[Dict, None, None]:
|
|||||||
err))
|
err))
|
||||||
|
|
||||||
|
|
||||||
def initial_window_size_func(opts: OptionsStub, cached_values: Dict) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]:
|
|
||||||
|
|
||||||
if 'window-size' in cached_values and opts.remember_window_size:
|
|
||||||
ws = cached_values['window-size']
|
|
||||||
try:
|
|
||||||
w, h = map(int, ws)
|
|
||||||
|
|
||||||
def initial_window_size(*a: Any) -> Tuple[int, int]:
|
|
||||||
return w, h
|
|
||||||
return initial_window_size
|
|
||||||
except Exception:
|
|
||||||
log_error('Invalid cached window size, ignoring')
|
|
||||||
|
|
||||||
w, w_unit = opts.initial_window_width
|
|
||||||
h, h_unit = opts.initial_window_height
|
|
||||||
|
|
||||||
def get_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> Tuple[int, int]:
|
|
||||||
if not is_macos:
|
|
||||||
# scaling is not needed on Wayland, but is needed on macOS. Not
|
|
||||||
# sure about X11.
|
|
||||||
xscale = yscale = 1
|
|
||||||
|
|
||||||
def effective_margin(which: EdgeLiteral) -> float:
|
|
||||||
ans: float = getattr(opts.single_window_margin_width, which)
|
|
||||||
if ans < 0:
|
|
||||||
ans = getattr(opts.window_margin_width, which)
|
|
||||||
return ans
|
|
||||||
|
|
||||||
if w_unit == 'cells':
|
|
||||||
spacing = effective_margin('left') + effective_margin('right')
|
|
||||||
spacing += opts.window_padding_width.left + opts.window_padding_width.right
|
|
||||||
width = cell_width * w / xscale + (dpi_x / 72) * spacing + 1
|
|
||||||
else:
|
|
||||||
width = w
|
|
||||||
if h_unit == 'cells':
|
|
||||||
spacing = effective_margin('top') + effective_margin('bottom')
|
|
||||||
spacing += opts.window_padding_width.top + opts.window_padding_width.bottom
|
|
||||||
height = cell_height * h / yscale + (dpi_y / 72) * spacing + 1
|
|
||||||
else:
|
|
||||||
height = h
|
|
||||||
return int(width), int(height)
|
|
||||||
|
|
||||||
return get_window_size
|
|
||||||
|
|
||||||
|
|
||||||
def commented_out_default_config() -> str:
|
def commented_out_default_config() -> str:
|
||||||
ans = []
|
ans = []
|
||||||
for line in as_conf_file(all_options.values()):
|
for line in as_conf_file(all_options.values()):
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Version(NamedTuple):
|
|||||||
|
|
||||||
|
|
||||||
appname: str = 'kitty'
|
appname: str = 'kitty'
|
||||||
version: Version = Version(0, 18, 2)
|
version: Version = Version(0, 18, 3)
|
||||||
str_version: str = '.'.join(map(str, version))
|
str_version: str = '.'.join(map(str, version))
|
||||||
_plat = sys.platform.lower()
|
_plat = sys.platform.lower()
|
||||||
is_macos: bool = 'darwin' in _plat
|
is_macos: bool = 'darwin' in _plat
|
||||||
@@ -64,16 +64,16 @@ class WindowGeometry(NamedTuple):
|
|||||||
def kitty_exe() -> str:
|
def kitty_exe() -> str:
|
||||||
rpath = sys._xoptions.get('bundle_exe_dir')
|
rpath = sys._xoptions.get('bundle_exe_dir')
|
||||||
if not rpath:
|
if not rpath:
|
||||||
items = filter(None, os.environ.get('PATH', '').split(os.pathsep))
|
items = os.environ.get('PATH', '').split(os.pathsep) + [os.path.join(base, 'launcher')]
|
||||||
seen: Set[str] = set()
|
seen: Set[str] = set()
|
||||||
for candidate in items:
|
for candidate in filter(None, items):
|
||||||
if candidate not in seen:
|
if candidate not in seen:
|
||||||
seen.add(candidate)
|
seen.add(candidate)
|
||||||
if os.access(os.path.join(candidate, 'kitty'), os.X_OK):
|
if os.access(os.path.join(candidate, 'kitty'), os.X_OK):
|
||||||
rpath = candidate
|
rpath = candidate
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
rpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'launcher')
|
raise RuntimeError('kitty binary not found')
|
||||||
return os.path.join(rpath, 'kitty')
|
return os.path.join(rpath, 'kitty')
|
||||||
|
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ def wakeup() -> None:
|
|||||||
b.child_monitor.wakeup()
|
b.child_monitor.wakeup()
|
||||||
|
|
||||||
|
|
||||||
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
base_dir = os.path.dirname(base)
|
||||||
terminfo_dir = os.path.join(base_dir, 'terminfo')
|
terminfo_dir = os.path.join(base_dir, 'terminfo')
|
||||||
logo_data_file = os.path.join(base_dir, 'logo', 'kitty.rgba')
|
logo_data_file = os.path.join(base_dir, 'logo', 'kitty.rgba')
|
||||||
logo_png_file = os.path.join(base_dir, 'logo', 'kitty.png')
|
logo_png_file = os.path.join(base_dir, 'logo', 'kitty.png')
|
||||||
|
|||||||
2
kitty/emoji.h
generated
2
kitty/emoji.h
generated
@@ -1,4 +1,4 @@
|
|||||||
// unicode data, built from the unicode standard on: 2020-04-06
|
// unicode data, built from the unicode standard on: 2020-08-06
|
||||||
// see gen-wcwidth.py
|
// see gen-wcwidth.py
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
|
|||||||
@@ -364,20 +364,19 @@ def D(buf: BufType, width: int, height: int, left: bool = True) -> None:
|
|||||||
buf[offset + dest_x] = mbuf[offset + src_x]
|
buf[offset + dest_x] = mbuf[offset + src_x]
|
||||||
|
|
||||||
|
|
||||||
def draw_parametrized_curve(buf: BufType, width: int, height: int, thickness_in_pixels: int, xfunc: BezierFunc, yfunc: BezierFunc) -> None:
|
def draw_parametrized_curve(buf: BufType, width: int, height: int, delta: int, extra: int, xfunc: BezierFunc, yfunc: BezierFunc) -> None:
|
||||||
num_samples = height*4
|
num_samples = height*4
|
||||||
seen = set()
|
seen = set()
|
||||||
delta, extra = divmod(thickness_in_pixels, 2)
|
|
||||||
for i in range(num_samples + 1):
|
for i in range(num_samples + 1):
|
||||||
t = (i / num_samples)
|
t = (i / num_samples)
|
||||||
p = x_p, y_p = int(xfunc(t)), int(yfunc(t))
|
p = x_p, y_p = int(xfunc(t)), int(yfunc(t))
|
||||||
if p in seen:
|
if p in seen:
|
||||||
continue
|
continue
|
||||||
seen.add(p)
|
seen.add(p)
|
||||||
for y in range(int(y_p) - delta, int(y_p) + delta + extra):
|
for y in range(y_p - delta, y_p + delta + extra):
|
||||||
if 0 <= y < height:
|
if 0 <= y < height:
|
||||||
offset = y * width
|
offset = y * width
|
||||||
for x in range(int(x_p) - delta, int(x_p) + delta + extra):
|
for x in range(x_p - delta, x_p + delta + extra):
|
||||||
if 0 <= x < width:
|
if 0 <= x < width:
|
||||||
pos = offset + x
|
pos = offset + x
|
||||||
buf[pos] = min(255, buf[pos] + 255)
|
buf[pos] = min(255, buf[pos] + 255)
|
||||||
@@ -386,29 +385,31 @@ def draw_parametrized_curve(buf: BufType, width: int, height: int, thickness_in_
|
|||||||
@supersampled()
|
@supersampled()
|
||||||
def rounded_corner(buf: BufType, width: int, height: int, level: int = 1, which: str = '╭') -> None:
|
def rounded_corner(buf: BufType, width: int, height: int, level: int = 1, which: str = '╭') -> None:
|
||||||
supersample_factor = getattr(buf, 'supersample_factor')
|
supersample_factor = getattr(buf, 'supersample_factor')
|
||||||
thickness_in_pixels = thickness(level) * supersample_factor
|
delta, extra = divmod(thickness(level), 2)
|
||||||
|
hw = ((width / supersample_factor) // 2) * supersample_factor
|
||||||
|
hh = ((height / supersample_factor) // 2) * supersample_factor
|
||||||
if which == '╭':
|
if which == '╭':
|
||||||
start = width // 2, height - 1
|
start = hw, height - 1
|
||||||
end = width - 1, height // 2
|
end = width - 1, hh
|
||||||
c1 = width // 2, int(0.75 * height)
|
c1 = hw, int(0.75 * height)
|
||||||
c2 = width // 2, height // 2 + 1
|
c2 = hw, hh + 1
|
||||||
elif which == '╮':
|
elif which == '╮':
|
||||||
start = 0, height // 2
|
start = 0, hh
|
||||||
end = width // 2, height - 1
|
end = hw, height - 1
|
||||||
c1 = width // 2, height // 2 + 1
|
c1 = hw, hh + 1
|
||||||
c2 = width // 2, int(0.75 * height)
|
c2 = hw, int(0.75 * height)
|
||||||
elif which == '╰':
|
elif which == '╰':
|
||||||
start = width // 2, 0
|
start = width // 2, 0
|
||||||
end = width - 1, height // 2
|
end = width - 1, hh
|
||||||
c1 = width // 2, int(0.25 * height)
|
c1 = hw, int(0.25 * height)
|
||||||
c2 = width // 2 - 1, height // 2 - 1
|
c2 = hw, hh - 1
|
||||||
elif which == '╯':
|
elif which == '╯':
|
||||||
start = 0, height // 2
|
start = 0, hh
|
||||||
end = width // 2, 0
|
end = hw, 0
|
||||||
c1 = width // 2 - 1, height // 2 - 1
|
c1 = hw, hh - 1
|
||||||
c2 = width // 2, int(0.25 * height)
|
c2 = hw, int(0.25 * height)
|
||||||
xfunc, yfunc = cubic_bezier(start, end, c1, c2)
|
xfunc, yfunc = cubic_bezier(start, end, c1, c2)
|
||||||
draw_parametrized_curve(buf, width, height, thickness_in_pixels, xfunc, yfunc)
|
draw_parametrized_curve(buf, width, height, delta * supersample_factor, extra * supersample_factor, xfunc, yfunc)
|
||||||
|
|
||||||
|
|
||||||
def half_dhline(buf: BufType, width: int, height: int, level: int = 1, which: str = 'left', only: Optional[str] = None) -> Tuple[int, int]:
|
def half_dhline(buf: BufType, width: int, height: int, level: int = 1, which: str = 'left', only: Optional[str] = None) -> Tuple[int, int]:
|
||||||
@@ -686,7 +687,7 @@ t, f = 1, 3
|
|||||||
for start in '┌┐└┘':
|
for start in '┌┐└┘':
|
||||||
for i, (hlevel, vlevel) in enumerate(((t, t), (f, t), (t, f), (f, f))):
|
for i, (hlevel, vlevel) in enumerate(((t, t), (f, t), (t, f), (f, f))):
|
||||||
box_chars[chr(ord(start) + i)] = [p(corner, which=start, hlevel=hlevel, vlevel=vlevel)]
|
box_chars[chr(ord(start) + i)] = [p(corner, which=start, hlevel=hlevel, vlevel=vlevel)]
|
||||||
for ch in '╭╮╯╰':
|
for ch in '╭╮╰╯':
|
||||||
box_chars[ch] = [p(rounded_corner, which=ch)]
|
box_chars[ch] = [p(rounded_corner, which=ch)]
|
||||||
|
|
||||||
for i, (a_, b_, c_, d_) in enumerate((
|
for i, (a_, b_, c_, d_) in enumerate((
|
||||||
|
|||||||
16
kitty/glfw.c
16
kitty/glfw.c
@@ -15,6 +15,7 @@ extern long cocoa_window_number(void *w);
|
|||||||
extern void cocoa_create_global_menu(void);
|
extern void cocoa_create_global_menu(void);
|
||||||
extern void cocoa_hide_window_title(void *w);
|
extern void cocoa_hide_window_title(void *w);
|
||||||
extern void cocoa_hide_titlebar(void *w);
|
extern void cocoa_hide_titlebar(void *w);
|
||||||
|
extern void cocoa_system_beep(void);
|
||||||
extern void cocoa_set_activation_policy(bool);
|
extern void cocoa_set_activation_policy(bool);
|
||||||
extern void cocoa_set_titlebar_color(void *w, color_type color);
|
extern void cocoa_set_titlebar_color(void *w, color_type color);
|
||||||
extern bool cocoa_alt_option_key_pressed(unsigned long);
|
extern bool cocoa_alt_option_key_pressed(unsigned long);
|
||||||
@@ -888,16 +889,14 @@ get_clipboard_string(PYNOARG) {
|
|||||||
return Py_BuildValue("s", "");
|
return Py_BuildValue("s", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
ring_audio_bell(OSWindow *w UNUSED) {
|
ring_audio_bell(void) {
|
||||||
static monotonic_t last_bell_at = -1;
|
static monotonic_t last_bell_at = -1;
|
||||||
monotonic_t now = monotonic();
|
monotonic_t now = monotonic();
|
||||||
if (now - last_bell_at <= ms_to_monotonic_t(100ll)) return;
|
if (last_bell_at >= 0 && now - last_bell_at <= ms_to_monotonic_t(100ll)) return;
|
||||||
last_bell_at = now;
|
last_bell_at = now;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (w->handle) {
|
cocoa_system_beep();
|
||||||
glfwWindowBell(w->handle);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
play_canberra_sound("bell", "kitty bell");
|
play_canberra_sound("bell", "kitty bell");
|
||||||
#endif
|
#endif
|
||||||
@@ -905,8 +904,7 @@ ring_audio_bell(OSWindow *w UNUSED) {
|
|||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
ring_bell(PYNOARG) {
|
ring_bell(PYNOARG) {
|
||||||
OSWindow *w = current_os_window();
|
ring_audio_bell();
|
||||||
ring_audio_bell(w);
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,7 +958,7 @@ void
|
|||||||
request_window_attention(id_type kitty_window_id, bool audio_bell) {
|
request_window_attention(id_type kitty_window_id, bool audio_bell) {
|
||||||
OSWindow *w = os_window_for_kitty_window(kitty_window_id);
|
OSWindow *w = os_window_for_kitty_window(kitty_window_id);
|
||||||
if (w) {
|
if (w) {
|
||||||
if (audio_bell) ring_audio_bell(w);
|
if (audio_bell) ring_audio_bell();
|
||||||
if (OPT(window_alert_on_bell)) glfwRequestWindowAttention(w->handle);
|
if (OPT(window_alert_on_bell)) glfwRequestWindowAttention(w->handle);
|
||||||
glfwPostEmptyEvent();
|
glfwPostEmptyEvent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -645,20 +645,32 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree
|
|||||||
// Image lifetime/scrolling {{{
|
// Image lifetime/scrolling {{{
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
filter_refs(GraphicsManager *self, const void* data, bool free_images, bool (*filter_func)(ImageRef*, Image*, const void*, CellPixelSize), CellPixelSize cell) {
|
filter_refs(GraphicsManager *self, const void* data, bool free_images, bool (*filter_func)(const ImageRef*, Image*, const void*, CellPixelSize), CellPixelSize cell) {
|
||||||
self->layers_dirty = self->image_count > 0;
|
|
||||||
for (size_t i = self->image_count; i-- > 0;) {
|
for (size_t i = self->image_count; i-- > 0;) {
|
||||||
Image *img = self->images + i;
|
Image *img = self->images + i;
|
||||||
for (size_t j = img->refcnt; j-- > 0;) {
|
for (size_t j = img->refcnt; j-- > 0;) {
|
||||||
ImageRef *ref = img->refs + j;
|
ImageRef *ref = img->refs + j;
|
||||||
if (filter_func(ref, img, data, cell)) {
|
if (filter_func(ref, img, data, cell)) {
|
||||||
remove_i_from_array(img->refs, j, img->refcnt);
|
remove_i_from_array(img->refs, j, img->refcnt);
|
||||||
|
self->layers_dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (img->refcnt == 0 && (free_images || img->client_id == 0)) remove_image(self, i);
|
if (img->refcnt == 0 && (free_images || img->client_id == 0)) remove_image(self, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
modify_refs(GraphicsManager *self, const void* data, bool free_images, bool (*filter_func)(ImageRef*, Image*, const void*, CellPixelSize), CellPixelSize cell) {
|
||||||
|
for (size_t i = self->image_count; i-- > 0;) {
|
||||||
|
Image *img = self->images + i;
|
||||||
|
for (size_t j = img->refcnt; j-- > 0;) {
|
||||||
|
if (filter_func(img->refs + j, img, data, cell)) remove_i_from_array(img->refs, j, img->refcnt);
|
||||||
|
}
|
||||||
|
if (img->refcnt == 0 && (free_images || img->client_id == 0)) remove_image(self, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
scroll_filter_func(ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
scroll_filter_func(ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
||||||
ScrollData *d = (ScrollData*)data;
|
ScrollData *d = (ScrollData*)data;
|
||||||
@@ -667,12 +679,12 @@ scroll_filter_func(ImageRef *ref, Image UNUSED *img, const void *data, CellPixel
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
ref_within_region(ImageRef *ref, index_type margin_top, index_type margin_bottom) {
|
ref_within_region(const ImageRef *ref, index_type margin_top, index_type margin_bottom) {
|
||||||
return ref->start_row >= (int32_t)margin_top && ref->start_row + ref->effective_num_rows <= margin_bottom;
|
return ref->start_row >= (int32_t)margin_top && ref->start_row + ref->effective_num_rows <= margin_bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
ref_outside_region(ImageRef *ref, index_type margin_top, index_type margin_bottom) {
|
ref_outside_region(const ImageRef *ref, index_type margin_top, index_type margin_bottom) {
|
||||||
return ref->start_row + ref->effective_num_rows <= margin_top || ref->start_row > (int32_t)margin_bottom;
|
return ref->start_row + ref->effective_num_rows <= margin_top || ref->start_row > (int32_t)margin_bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,16 +721,19 @@ scroll_filter_margins_func(ImageRef* ref, Image* img, const void* data, CellPixe
|
|||||||
|
|
||||||
void
|
void
|
||||||
grman_scroll_images(GraphicsManager *self, const ScrollData *data, CellPixelSize cell) {
|
grman_scroll_images(GraphicsManager *self, const ScrollData *data, CellPixelSize cell) {
|
||||||
filter_refs(self, data, true, data->has_margins ? scroll_filter_margins_func : scroll_filter_func, cell);
|
if (self->image_count) {
|
||||||
|
self->layers_dirty = true;
|
||||||
|
modify_refs(self, data, true, data->has_margins ? scroll_filter_margins_func : scroll_filter_func, cell);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
clear_filter_func(ImageRef *ref, Image UNUSED *img, const void UNUSED *data, CellPixelSize cell UNUSED) {
|
clear_filter_func(const ImageRef *ref, Image UNUSED *img, const void UNUSED *data, CellPixelSize cell UNUSED) {
|
||||||
return ref->start_row + (int32_t)ref->effective_num_rows > 0;
|
return ref->start_row + (int32_t)ref->effective_num_rows > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
clear_all_filter_func(ImageRef *ref UNUSED, Image UNUSED *img, const void UNUSED *data, CellPixelSize cell UNUSED) {
|
clear_all_filter_func(const ImageRef *ref UNUSED, Image UNUSED *img, const void UNUSED *data, CellPixelSize cell UNUSED) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,37 +743,37 @@ grman_clear(GraphicsManager *self, bool all, CellPixelSize cell) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
id_filter_func(ImageRef UNUSED *ref, Image *img, const void *data, CellPixelSize cell UNUSED) {
|
id_filter_func(const ImageRef UNUSED *ref, Image *img, const void *data, CellPixelSize cell UNUSED) {
|
||||||
uint32_t iid = *(uint32_t*)data;
|
uint32_t iid = *(uint32_t*)data;
|
||||||
return img->client_id == iid;
|
return img->client_id == iid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
x_filter_func(ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
x_filter_func(const ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
||||||
const GraphicsCommand *g = data;
|
const GraphicsCommand *g = data;
|
||||||
return ref->start_column <= (int32_t)g->x_offset - 1 && ((int32_t)g->x_offset - 1) < ((int32_t)(ref->start_column + ref->effective_num_cols));
|
return ref->start_column <= (int32_t)g->x_offset - 1 && ((int32_t)g->x_offset - 1) < ((int32_t)(ref->start_column + ref->effective_num_cols));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
y_filter_func(ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
y_filter_func(const ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
||||||
const GraphicsCommand *g = data;
|
const GraphicsCommand *g = data;
|
||||||
return ref->start_row <= (int32_t)g->y_offset - 1 && ((int32_t)(g->y_offset - 1 < ref->start_row + ref->effective_num_rows));
|
return ref->start_row <= (int32_t)g->y_offset - 1 && ((int32_t)(g->y_offset - 1 < ref->start_row + ref->effective_num_rows));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
z_filter_func(ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
z_filter_func(const ImageRef *ref, Image UNUSED *img, const void *data, CellPixelSize cell UNUSED) {
|
||||||
const GraphicsCommand *g = data;
|
const GraphicsCommand *g = data;
|
||||||
return ref->z_index == g->z_index;
|
return ref->z_index == g->z_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
point_filter_func(ImageRef *ref, Image *img, const void *data, CellPixelSize cell) {
|
point_filter_func(const ImageRef *ref, Image *img, const void *data, CellPixelSize cell) {
|
||||||
return x_filter_func(ref, img, data, cell) && y_filter_func(ref, img, data, cell);
|
return x_filter_func(ref, img, data, cell) && y_filter_func(ref, img, data, cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
point3d_filter_func(ImageRef *ref, Image *img, const void *data, CellPixelSize cell) {
|
point3d_filter_func(const ImageRef *ref, Image *img, const void *data, CellPixelSize cell) {
|
||||||
return z_filter_func(ref, img, data, cell) && point_filter_func(ref, img, data, cell);
|
return z_filter_func(ref, img, data, cell) && point_filter_func(ref, img, data, cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
kitty/line.c
11
kitty/line.c
@@ -559,13 +559,14 @@ line_get_char(Line *self, index_type at) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Cursor *cursor, bool UNUSED is_second) {
|
line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Cursor *cursor, bool UNUSED is_second) {
|
||||||
|
GPUCell *g = self->gpu_cells + at;
|
||||||
if (cursor == NULL) {
|
if (cursor == NULL) {
|
||||||
self->gpu_cells[at].attrs = (self->gpu_cells[at].attrs & ATTRS_MASK_WITHOUT_WIDTH) | width;
|
g->attrs = (self->gpu_cells[at].attrs & ATTRS_MASK_WITHOUT_WIDTH) | width;
|
||||||
} else {
|
} else {
|
||||||
self->gpu_cells[at].attrs = CURSOR_TO_ATTRS(cursor, width & WIDTH_MASK);
|
g->attrs = CURSOR_TO_ATTRS(cursor, width & WIDTH_MASK);
|
||||||
self->gpu_cells[at].fg = (cursor->fg & COL_MASK);
|
g->fg = cursor->fg & COL_MASK;
|
||||||
self->gpu_cells[at].bg = (cursor->bg & COL_MASK);
|
g->bg = cursor->bg & COL_MASK;
|
||||||
self->gpu_cells[at].decoration_fg = cursor->decoration_fg & COL_MASK;
|
g->decoration_fg = cursor->decoration_fg & COL_MASK;
|
||||||
}
|
}
|
||||||
self->cpu_cells[at].ch = ch;
|
self->cpu_cells[at].ch = ch;
|
||||||
memset(self->cpu_cells[at].cc_idx, 0, sizeof(self->cpu_cells[at].cc_idx));
|
memset(self->cpu_cells[at].cc_idx, 0, sizeof(self->cpu_cells[at].cc_idx));
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from .child import set_default_env
|
|||||||
from .cli import create_opts, parse_args
|
from .cli import create_opts, parse_args
|
||||||
from .cli_stub import CLIOptions
|
from .cli_stub import CLIOptions
|
||||||
from .conf.utils import BadLine
|
from .conf.utils import BadLine
|
||||||
from .config import cached_values_for, initial_window_size_func
|
from .config import cached_values_for
|
||||||
from .constants import (
|
from .constants import (
|
||||||
appname, beam_cursor_data_file, config_dir, glfw_path, is_macos,
|
appname, beam_cursor_data_file, config_dir, glfw_path, is_macos,
|
||||||
is_wayland, kitty_exe, logo_data_file, running_in_kitty
|
is_wayland, kitty_exe, logo_data_file, running_in_kitty
|
||||||
@@ -28,6 +28,8 @@ from .fast_data_types import (
|
|||||||
from .fonts.box_drawing import set_scale
|
from .fonts.box_drawing import set_scale
|
||||||
from .fonts.render import set_font_family
|
from .fonts.render import set_font_family
|
||||||
from .options_stub import Options as OptionsStub
|
from .options_stub import Options as OptionsStub
|
||||||
|
from .os_window_size import initial_window_size_func
|
||||||
|
from .session import get_os_window_sizing_data
|
||||||
from .utils import (
|
from .utils import (
|
||||||
detach, expandvars, log_error, read_shell_environment, single_instance,
|
detach, expandvars, log_error, read_shell_environment, single_instance,
|
||||||
startup_notification_handler, unix_socket_paths
|
startup_notification_handler, unix_socket_paths
|
||||||
@@ -129,7 +131,7 @@ def _run_app(opts: OptionsStub, args: CLIOptions, bad_lines: Sequence[BadLine] =
|
|||||||
with cached_values_for(run_app.cached_values_name) as cached_values:
|
with cached_values_for(run_app.cached_values_name) as cached_values:
|
||||||
with startup_notification_handler(extra_callback=run_app.first_window_callback) as pre_show_callback:
|
with startup_notification_handler(extra_callback=run_app.first_window_callback) as pre_show_callback:
|
||||||
window_id = create_os_window(
|
window_id = create_os_window(
|
||||||
run_app.initial_window_size_func(opts, cached_values),
|
run_app.initial_window_size_func(get_os_window_sizing_data(opts), cached_values),
|
||||||
pre_show_callback,
|
pre_show_callback,
|
||||||
args.title or appname, args.name or args.cls or appname,
|
args.title or appname, args.name or args.cls or appname,
|
||||||
args.cls or appname, load_all_shaders)
|
args.cls or appname, load_all_shaders)
|
||||||
|
|||||||
74
kitty/os_window_size.py
Normal file
74
kitty/os_window_size.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
from typing import Any, Callable, Dict, NamedTuple, Tuple
|
||||||
|
|
||||||
|
from .constants import FloatEdges, is_macos
|
||||||
|
from .typing import EdgeLiteral
|
||||||
|
from .utils import log_error
|
||||||
|
|
||||||
|
|
||||||
|
class WindowSize(NamedTuple):
|
||||||
|
|
||||||
|
size: int
|
||||||
|
unit: str
|
||||||
|
|
||||||
|
|
||||||
|
class WindowSizes(NamedTuple):
|
||||||
|
|
||||||
|
width: WindowSize
|
||||||
|
height: WindowSize
|
||||||
|
|
||||||
|
|
||||||
|
class WindowSizeData(NamedTuple):
|
||||||
|
initial_window_sizes: WindowSizes
|
||||||
|
remember_window_size: bool
|
||||||
|
single_window_margin_width: FloatEdges
|
||||||
|
window_margin_width: FloatEdges
|
||||||
|
window_padding_width: FloatEdges
|
||||||
|
|
||||||
|
|
||||||
|
def initial_window_size_func(opts: WindowSizeData, cached_values: Dict) -> Callable[[int, int, float, float, float, float], Tuple[int, int]]:
|
||||||
|
|
||||||
|
if 'window-size' in cached_values and opts.remember_window_size:
|
||||||
|
ws = cached_values['window-size']
|
||||||
|
try:
|
||||||
|
w, h = map(int, ws)
|
||||||
|
|
||||||
|
def initial_window_size(*a: Any) -> Tuple[int, int]:
|
||||||
|
return w, h
|
||||||
|
return initial_window_size
|
||||||
|
except Exception:
|
||||||
|
log_error('Invalid cached window size, ignoring')
|
||||||
|
|
||||||
|
w, w_unit = opts.initial_window_sizes.width
|
||||||
|
h, h_unit = opts.initial_window_sizes.height
|
||||||
|
|
||||||
|
def get_window_size(cell_width: int, cell_height: int, dpi_x: float, dpi_y: float, xscale: float, yscale: float) -> Tuple[int, int]:
|
||||||
|
if not is_macos:
|
||||||
|
# scaling is not needed on Wayland, but is needed on macOS. Not
|
||||||
|
# sure about X11.
|
||||||
|
xscale = yscale = 1
|
||||||
|
|
||||||
|
def effective_margin(which: EdgeLiteral) -> float:
|
||||||
|
ans: float = getattr(opts.single_window_margin_width, which)
|
||||||
|
if ans < 0:
|
||||||
|
ans = getattr(opts.window_margin_width, which)
|
||||||
|
return ans
|
||||||
|
|
||||||
|
if w_unit == 'cells':
|
||||||
|
spacing = effective_margin('left') + effective_margin('right')
|
||||||
|
spacing += opts.window_padding_width.left + opts.window_padding_width.right
|
||||||
|
width = cell_width * w / xscale + (dpi_x / 72) * spacing + 1
|
||||||
|
else:
|
||||||
|
width = w
|
||||||
|
if h_unit == 'cells':
|
||||||
|
spacing = effective_margin('top') + effective_margin('bottom')
|
||||||
|
spacing += opts.window_padding_width.top + opts.window_padding_width.bottom
|
||||||
|
height = cell_height * h / yscale + (dpi_y / 72) * spacing + 1
|
||||||
|
else:
|
||||||
|
height = h
|
||||||
|
return int(width), int(height)
|
||||||
|
|
||||||
|
return get_window_size
|
||||||
@@ -4,24 +4,24 @@
|
|||||||
|
|
||||||
import shlex
|
import shlex
|
||||||
import sys
|
import sys
|
||||||
from typing import Generator, List, NamedTuple, Optional, Tuple, Union
|
from typing import Generator, List, Optional, Union
|
||||||
|
|
||||||
from .cli_stub import CLIOptions
|
from .cli_stub import CLIOptions
|
||||||
from .config_data import to_layout_names
|
from .config_data import to_layout_names
|
||||||
from .constants import FloatEdges, kitty_exe
|
from .constants import kitty_exe
|
||||||
from .layout.interface import all_layouts
|
from .layout.interface import all_layouts
|
||||||
from .options_stub import Options
|
from .options_stub import Options
|
||||||
|
from .os_window_size import WindowSize, WindowSizeData, WindowSizes
|
||||||
from .typing import SpecialWindowInstance
|
from .typing import SpecialWindowInstance
|
||||||
from .utils import log_error, resolved_shell
|
from .utils import log_error, resolved_shell
|
||||||
|
|
||||||
|
|
||||||
class WindowSizeOpts(NamedTuple):
|
def get_os_window_sizing_data(opts: Options, session: Optional['Session'] = None) -> WindowSizeData:
|
||||||
|
if session is None or session.os_window_size is None:
|
||||||
initial_window_width: Tuple[int, str]
|
sizes = WindowSizes(WindowSize(*opts.initial_window_width), WindowSize(*opts.initial_window_height))
|
||||||
initial_window_height: Tuple[int, str]
|
else:
|
||||||
window_margin_width: FloatEdges
|
sizes = session.os_window_size
|
||||||
window_padding_width: FloatEdges
|
return WindowSizeData(sizes, opts.remember_window_size, opts.single_window_margin_width, opts.window_margin_width, opts.window_padding_width)
|
||||||
remember_window_size: bool
|
|
||||||
|
|
||||||
|
|
||||||
class Tab:
|
class Tab:
|
||||||
@@ -42,7 +42,7 @@ class Session:
|
|||||||
self.tabs: List[Tab] = []
|
self.tabs: List[Tab] = []
|
||||||
self.active_tab_idx = 0
|
self.active_tab_idx = 0
|
||||||
self.default_title = default_title
|
self.default_title = default_title
|
||||||
self.os_window_size: Optional[WindowSizeOpts] = None
|
self.os_window_size: Optional[WindowSizes] = None
|
||||||
self.os_window_class: Optional[str] = None
|
self.os_window_class: Optional[str] = None
|
||||||
|
|
||||||
def add_tab(self, opts: Options, name: str = '') -> None:
|
def add_tab(self, opts: Options, name: str = '') -> None:
|
||||||
@@ -124,7 +124,7 @@ def parse_session(raw: str, opts: Options, default_title: Optional[str] = None)
|
|||||||
elif cmd == 'os_window_size':
|
elif cmd == 'os_window_size':
|
||||||
from kitty.config_data import window_size
|
from kitty.config_data import window_size
|
||||||
w, h = map(window_size, rest.split(maxsplit=1))
|
w, h = map(window_size, rest.split(maxsplit=1))
|
||||||
ans.os_window_size = WindowSizeOpts(w, h, opts.window_margin_width, opts.window_padding_width, False)
|
ans.os_window_size = WindowSizes(WindowSize(*w), WindowSize(*h))
|
||||||
elif cmd == 'os_window_class':
|
elif cmd == 'os_window_class':
|
||||||
ans.os_window_class = rest
|
ans.os_window_class = rest
|
||||||
else:
|
else:
|
||||||
|
|||||||
4
kitty/unicode-data.c
generated
4
kitty/unicode-data.c
generated
@@ -1,4 +1,4 @@
|
|||||||
// unicode data, built from the unicode standard on: 2020-04-06
|
// unicode data, built from the unicode standard on: 2020-08-06
|
||||||
// see gen-wcwidth.py
|
// see gen-wcwidth.py
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
|
|
||||||
@@ -8,6 +8,7 @@ START_ALLOW_CASE_RANGE
|
|||||||
bool
|
bool
|
||||||
is_combining_char(char_type code) {
|
is_combining_char(char_type code) {
|
||||||
// M category (marks) (2301 codepoints) {{{
|
// M category (marks) (2301 codepoints) {{{
|
||||||
|
if (LIKELY(code < 768)) return false;
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case 0x300 ... 0x36f:
|
case 0x300 ... 0x36f:
|
||||||
return true;
|
return true;
|
||||||
@@ -601,6 +602,7 @@ is_combining_char(char_type code) {
|
|||||||
bool
|
bool
|
||||||
is_ignored_char(char_type code) {
|
is_ignored_char(char_type code) {
|
||||||
// Control characters and non-characters (2339 codepoints) {{{
|
// Control characters and non-characters (2339 codepoints) {{{
|
||||||
|
if (LIKELY(0x20 <= code && code <= 0x7e)) return false;
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case 0x0 ... 0x1f:
|
case 0x0 ... 0x1f:
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
3
kitty/wcwidth-std.h
generated
3
kitty/wcwidth-std.h
generated
@@ -1,4 +1,4 @@
|
|||||||
// unicode data, built from the unicode standard on: 2020-04-06
|
// unicode data, built from the unicode standard on: 2020-08-06
|
||||||
// see gen-wcwidth.py
|
// see gen-wcwidth.py
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
@@ -7,6 +7,7 @@ START_ALLOW_CASE_RANGE
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
wcwidth_std(int32_t code) {
|
wcwidth_std(int32_t code) {
|
||||||
|
if (LIKELY(0x20 <= code && code <= 0x7e)) return 1;
|
||||||
switch(code) {
|
switch(code) {
|
||||||
// Flags (26 codepoints) {{{
|
// Flags (26 codepoints) {{{
|
||||||
case 0x1f1e6 ... 0x1f1ff:
|
case 0x1f1e6 ... 0x1f1ff:
|
||||||
|
|||||||
@@ -380,7 +380,6 @@ class Window:
|
|||||||
if self.destroyed:
|
if self.destroyed:
|
||||||
return
|
return
|
||||||
if self.needs_layout or new_geometry.xnum != self.screen.columns or new_geometry.ynum != self.screen.lines:
|
if self.needs_layout or new_geometry.xnum != self.screen.columns or new_geometry.ynum != self.screen.lines:
|
||||||
boss = get_boss()
|
|
||||||
self.screen.resize(new_geometry.ynum, new_geometry.xnum)
|
self.screen.resize(new_geometry.ynum, new_geometry.xnum)
|
||||||
sg = self.update_position(new_geometry)
|
sg = self.update_position(new_geometry)
|
||||||
self.needs_layout = False
|
self.needs_layout = False
|
||||||
@@ -391,7 +390,7 @@ class Window:
|
|||||||
self.screen.lines, self.screen.columns,
|
self.screen.lines, self.screen.columns,
|
||||||
max(0, new_geometry.right - new_geometry.left), max(0, new_geometry.bottom - new_geometry.top))
|
max(0, new_geometry.right - new_geometry.left), max(0, new_geometry.bottom - new_geometry.top))
|
||||||
if current_pty_size != self.last_reported_pty_size:
|
if current_pty_size != self.last_reported_pty_size:
|
||||||
boss.child_monitor.resize_pty(self.id, *current_pty_size)
|
get_boss().child_monitor.resize_pty(self.id, *current_pty_size)
|
||||||
if not self.pty_resized_once:
|
if not self.pty_resized_once:
|
||||||
self.pty_resized_once = True
|
self.pty_resized_once = True
|
||||||
self.child.mark_terminal_ready()
|
self.child.mark_terminal_ready()
|
||||||
|
|||||||
@@ -3,13 +3,8 @@
|
|||||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from . import BaseTest
|
from . import BaseTest
|
||||||
|
|
||||||
is32bit = sys.maxsize <= (1 << 32)
|
|
||||||
|
|
||||||
|
|
||||||
class TestTUI(BaseTest):
|
class TestTUI(BaseTest):
|
||||||
|
|
||||||
@@ -48,7 +43,6 @@ class TestTUI(BaseTest):
|
|||||||
le.backspace()
|
le.backspace()
|
||||||
self.assertTrue(le.pending_bell)
|
self.assertTrue(le.pending_bell)
|
||||||
|
|
||||||
@unittest.skipIf(is32bit, 'Fails for some unknown reason on 32bit builds')
|
|
||||||
def test_multiprocessing_spawn(self):
|
def test_multiprocessing_spawn(self):
|
||||||
from kitty.multiprocessing import test_spawn
|
from kitty.multiprocessing import test_spawn
|
||||||
test_spawn()
|
test_spawn()
|
||||||
|
|||||||
11
setup.py
11
setup.py
@@ -696,13 +696,17 @@ def compile_kittens(compilation_database: CompilationDatabase) -> None:
|
|||||||
kenv, dest, compilation_database, sources, all_headers + ['kitty/data-types.h'])
|
kenv, dest, compilation_database, sources, all_headers + ['kitty/data-types.h'])
|
||||||
|
|
||||||
|
|
||||||
def build(args: Options, native_optimizations: bool = True) -> None:
|
def init_env_from_args(args: Options, native_optimizations: bool = False) -> None:
|
||||||
global env
|
global env
|
||||||
env = init_env(
|
env = init_env(
|
||||||
args.debug, args.sanitize, native_optimizations, args.profile,
|
args.debug, args.sanitize, native_optimizations, args.profile,
|
||||||
args.egl_library, args.startup_notification_library, args.canberra_library,
|
args.egl_library, args.startup_notification_library, args.canberra_library,
|
||||||
args.extra_logging
|
args.extra_logging
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def build(args: Options, native_optimizations: bool = True) -> None:
|
||||||
|
init_env_from_args(args, native_optimizations)
|
||||||
sources, headers = find_c_files()
|
sources, headers = find_c_files()
|
||||||
compile_c_extension(
|
compile_c_extension(
|
||||||
kitty_env(), 'kitty/fast_data_types', args.compilation_database, sources, headers
|
kitty_env(), 'kitty/fast_data_types', args.compilation_database, sources, headers
|
||||||
@@ -1041,7 +1045,7 @@ def option_parser() -> argparse.ArgumentParser: # {{{
|
|||||||
'action',
|
'action',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
default=Options.action,
|
default=Options.action,
|
||||||
choices='build test linux-package kitty.app linux-freeze macos-freeze clean'.split(),
|
choices='build test linux-package kitty.app linux-freeze macos-freeze build-launcher clean'.split(),
|
||||||
help='Action to perform (default is build)'
|
help='Action to perform (default is build)'
|
||||||
)
|
)
|
||||||
p.add_argument(
|
p.add_argument(
|
||||||
@@ -1156,6 +1160,9 @@ def main() -> None:
|
|||||||
create_minimal_macos_bundle(args, launcher_dir)
|
create_minimal_macos_bundle(args, launcher_dir)
|
||||||
else:
|
else:
|
||||||
build_launcher(args, launcher_dir=launcher_dir)
|
build_launcher(args, launcher_dir=launcher_dir)
|
||||||
|
elif args.action == 'build-launcher':
|
||||||
|
init_env_from_args(args, False)
|
||||||
|
build_launcher(args, launcher_dir=launcher_dir)
|
||||||
elif args.action == 'linux-package':
|
elif args.action == 'linux-package':
|
||||||
build(args, native_optimizations=False)
|
build(args, native_optimizations=False)
|
||||||
package(args, bundle_type='linux-package')
|
package(args, bundle_type='linux-package')
|
||||||
|
|||||||
Reference in New Issue
Block a user