mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-17 14:07:44 +02:00
Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5fea33757 | ||
|
|
8cc360e344 | ||
|
|
a285d09459 | ||
|
|
e646596c5b | ||
|
|
f3d9ad3244 | ||
|
|
752fcb6424 | ||
|
|
0042288e92 | ||
|
|
7ea0af6f6d | ||
|
|
69c0eaaf74 | ||
|
|
a0424bf1bd | ||
|
|
481eccfe3c | ||
|
|
c5c3f98595 | ||
|
|
3c19b6f734 | ||
|
|
2d8deb86bb | ||
|
|
5e0185d3eb | ||
|
|
aee84c32e5 | ||
|
|
19a9594143 | ||
|
|
32f0da2e77 | ||
|
|
d329cb3fff | ||
|
|
3bb9e36fc8 | ||
|
|
76ae5f5b9b | ||
|
|
393169f79d | ||
|
|
f5570c38dd | ||
|
|
0153c9bb85 | ||
|
|
1712a317d5 | ||
|
|
10cff577d6 | ||
|
|
86c59016c6 | ||
|
|
7821ae39ab | ||
|
|
039d144c84 | ||
|
|
af0d570725 | ||
|
|
288fa0128b | ||
|
|
77125798a4 | ||
|
|
c26954c69e | ||
|
|
9667da307c | ||
|
|
baa3ec0a62 | ||
|
|
478fc766b6 | ||
|
|
6c49066cde | ||
|
|
a839af04dc | ||
|
|
3950632517 | ||
|
|
297ac9c3fe | ||
|
|
60d4ed3a1c | ||
|
|
a1b40cc8f5 | ||
|
|
5a9cf82564 |
2
.github/workflows/ci.py
vendored
2
.github/workflows/ci.py
vendored
@@ -75,7 +75,7 @@ def install_deps():
|
||||
run('sudo apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev ca-certificates'
|
||||
' libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libx11-xcb-dev zsh'
|
||||
' libpng-dev liblcms2-dev libfontconfig-dev libxkbcommon-x11-dev libcanberra-dev libxxhash-dev uuid-dev'
|
||||
' libsimde-dev zsh bash dash')
|
||||
' libsimde-dev zsh bash dash systemd-coredump gdb')
|
||||
# for some reason these directories are world writable which causes zsh
|
||||
# compinit to break
|
||||
run('sudo chmod -R og-w /usr/share/zsh')
|
||||
|
||||
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@@ -2,7 +2,7 @@ name: CI
|
||||
on: [push, pull_request]
|
||||
env:
|
||||
CI: 'true'
|
||||
ASAN_OPTIONS: leak_check_at_exit=0
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
LC_ALL: en_US.UTF-8
|
||||
LANG: en_US.UTF-8
|
||||
|
||||
@@ -28,11 +28,11 @@ jobs:
|
||||
|
||||
- python: b
|
||||
pyver: "3.11"
|
||||
sanitize: 1
|
||||
sanitize: 0 # disabled because causes segfaults
|
||||
|
||||
- python: c
|
||||
pyver: "3.9"
|
||||
sanitize: 1
|
||||
sanitize: 0 # disabled because causes segfaults
|
||||
|
||||
|
||||
exclude:
|
||||
|
||||
@@ -47,6 +47,18 @@ rsync algorithm to speed up repeated transfers of large files.
|
||||
Detailed list of changes
|
||||
-------------------------------------
|
||||
|
||||
0.33.1 [2024-03-21]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Fix a regression in the previous release that caused requesting data from the clipboard via OSC 52 to instead return data from the primary selection (:iss:`7213`)
|
||||
|
||||
- Splits layout: Allow resizing until one of the halves in a split is minimally sized (:iss:`7220`)
|
||||
|
||||
- macOS: Fix text rendered with fallback fonts not respecting bold/italic styling (:disc:`7241`)
|
||||
|
||||
- macOS: When CoreText fails to find a fallback font for a character in the first Private Use Unicode Area, preferentially use the NERD font, if available, for it (:iss:`6043`)
|
||||
|
||||
|
||||
0.33.0 [2024-03-12]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -449,9 +449,6 @@ do not use them, if at all possible. kitty contains features that do all of what
|
||||
tmux does, but better, with the exception of remote persistence (:iss:`391`).
|
||||
If you still want to use tmux, read on.
|
||||
|
||||
Image display will not work, see `tmux issue
|
||||
<https://github.com/tmux/tmux/issues/1391>`__.
|
||||
|
||||
Using ancient versions of tmux such as 1.8 will cause gibberish on screen when
|
||||
pressing keys (:iss:`3541`).
|
||||
|
||||
@@ -460,6 +457,10 @@ and then switch to another and these terminals have different :envvar:`TERM`
|
||||
variables, tmux will break. You will need to restart it as tmux does not support
|
||||
multiple terminfo definitions.
|
||||
|
||||
Displaying images with inside programs such nvim or ranger may not work
|
||||
depending on whether those programs have adopted support for the unicode
|
||||
placeholders workaround that kitty created for tmux refusing to support images.
|
||||
|
||||
If you use any of the advanced features that kitty has innovated, such as
|
||||
:doc:`styled underlines </underlines>`, :doc:`desktop notifications
|
||||
</desktop-notifications>`, :doc:`extended keyboard support
|
||||
|
||||
@@ -141,7 +141,7 @@ The Splits Layout
|
||||
--------------------
|
||||
|
||||
This is the most flexible layout. You can create any arrangement of windows
|
||||
by splitting exiting windows repeatedly. To best use this layout you should
|
||||
by splitting existing windows repeatedly. To best use this layout you should
|
||||
define a few extra key bindings in :file:`kitty.conf`::
|
||||
|
||||
# Create a new window splitting the space used by the existing one so that
|
||||
|
||||
@@ -81,7 +81,7 @@ control scripts. To run a kitten on a key press::
|
||||
|
||||
map f1 kitten mykitten.py
|
||||
|
||||
Many of kitty;s features are themselves implemented as kittens, for example,
|
||||
Many of kitty's features are themselves implemented as kittens, for example,
|
||||
:doc:`/kittens/unicode_input`, :doc:`/kittens/hints` and
|
||||
:doc:`/kittens/themes`. To learn about writing your own kittens, see
|
||||
:doc:`/kittens/custom`.
|
||||
|
||||
20
glfw/glfw.py
20
glfw/glfw.py
@@ -46,6 +46,11 @@ class BinaryArch(NamedTuple):
|
||||
isa: ISA = ISA.AMD64
|
||||
|
||||
|
||||
class CompilerType(Enum):
|
||||
gcc = 'gcc'
|
||||
clang = 'clang'
|
||||
unknown = 'unknown'
|
||||
|
||||
|
||||
class Env:
|
||||
|
||||
@@ -81,6 +86,7 @@ class Env:
|
||||
self.binary_arch = binary_arch
|
||||
self.native_optimizations = native_optimizations
|
||||
self._cc_version_string = ''
|
||||
self._compiler_type: Optional[CompilerType] = None
|
||||
|
||||
@property
|
||||
def cc_version_string(self) -> str:
|
||||
@@ -89,8 +95,16 @@ class Env:
|
||||
return self._cc_version_string
|
||||
|
||||
@property
|
||||
def is_gcc(self) -> bool:
|
||||
return 'gcc' in self.cc_version_string.split(maxsplit=1)[0].lower()
|
||||
def compiler_type(self) -> CompilerType:
|
||||
if self._compiler_type is None:
|
||||
raw = self.cc_version_string
|
||||
if 'Free Software Foundation' in raw:
|
||||
self._compiler_type = CompilerType.gcc
|
||||
elif 'clang' in raw.lower().split():
|
||||
self._compiler_type = CompilerType.clang
|
||||
else:
|
||||
self._compiler_type = CompilerType.unknown
|
||||
return self._compiler_type
|
||||
|
||||
def copy(self) -> 'Env':
|
||||
ans = Env(self.cc, list(self.cppflags), list(self.cflags), list(self.ldflags), dict(self.library_paths), list(self.ldpaths), self.ccver)
|
||||
@@ -286,7 +300,7 @@ def generate_wrappers(glfw_header: str) -> None:
|
||||
int glfwCocoaSetBackgroundBlur(GLFWwindow *w, int blur_radius)
|
||||
bool glfwSetX11WindowBlurred(GLFWwindow *w, bool enable_blur)
|
||||
void* glfwGetX11Display(void)
|
||||
int32_t glfwGetX11Window(GLFWwindow* window)
|
||||
unsigned long glfwGetX11Window(GLFWwindow* window)
|
||||
void glfwSetPrimarySelectionString(GLFWwindow* window, const char* string)
|
||||
void glfwCocoaSetWindowChrome(GLFWwindow* window, unsigned int color, bool use_system_color, unsigned int system_color,\
|
||||
int background_blur, unsigned int hide_window_decorations, bool show_text_in_titlebar, int color_space, float background_opacity, bool resizable)
|
||||
|
||||
3
glfw/x11_window.c
vendored
3
glfw/x11_window.c
vendored
@@ -41,7 +41,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Action for EWMH client messages
|
||||
#define _NET_WM_STATE_REMOVE 0
|
||||
@@ -3227,7 +3226,7 @@ GLFWAPI Display* glfwGetX11Display(void)
|
||||
return _glfw.x11.display;
|
||||
}
|
||||
|
||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* handle)
|
||||
GLFWAPI unsigned long glfwGetX11Window(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(None);
|
||||
|
||||
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ go 1.22
|
||||
|
||||
require (
|
||||
github.com/ALTree/bigfloat v0.2.0
|
||||
github.com/alecthomas/chroma/v2 v2.12.0
|
||||
github.com/alecthomas/chroma/v2 v2.13.0
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/dlclark/regexp2 v1.11.0
|
||||
|
||||
12
go.sum
12
go.sum
@@ -1,11 +1,11 @@
|
||||
github.com/ALTree/bigfloat v0.2.0 h1:AwNzawrpFuw55/YDVlcPw0F0cmmXrmngBHhVrvdXPvM=
|
||||
github.com/ALTree/bigfloat v0.2.0/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4=
|
||||
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
|
||||
github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
|
||||
github.com/alecthomas/chroma/v2 v2.12.0 h1:Wh8qLEgMMsN7mgyG8/qIpegky2Hvzr4By6gEF7cmWgw=
|
||||
github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw=
|
||||
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
||||
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU=
|
||||
github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/chroma/v2 v2.13.0 h1:VP72+99Fb2zEcYM0MeaWJmV+xQvz5v5cxRHd+ooU1lI=
|
||||
github.com/alecthomas/chroma/v2 v2.13.0/go.mod h1:BUGjjsD+ndS6eX37YgTchSEG+Jg9Jv1GiZs9sqPqztk=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -406,7 +406,7 @@ class ClipboardRequestManager:
|
||||
def parse_osc_52(self, data: memoryview, is_partial: bool = False) -> None:
|
||||
idx = find_in_memoryview(data, ord(b';'))
|
||||
if idx > -1:
|
||||
where = str(data[idx:], "utf-8", 'replace')
|
||||
where = str(data[:idx], "utf-8", 'replace')
|
||||
data = data[idx+1:]
|
||||
else:
|
||||
where = str(data, "utf-8", 'replace')
|
||||
|
||||
@@ -441,7 +441,13 @@ cocoa_send_notification(PyObject *self UNUSED, PyObject *args) {
|
||||
|
||||
static void
|
||||
schedule_notification(const char *identifier, const char *title, const char *body, const char *subtitle) {
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
UNUserNotificationCenter *center = nil;
|
||||
@try {
|
||||
center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
} @catch (NSException *e) {
|
||||
log_error("Failed to get current UNUserNotificationCenter object with error: %s (%s)",
|
||||
[[e name] UTF8String], [[e reason] UTF8String]);
|
||||
}
|
||||
if (!center) return;
|
||||
// Configure the notification's payload.
|
||||
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
|
||||
@@ -503,7 +509,13 @@ cocoa_send_notification(PyObject *self UNUSED, PyObject *args) {
|
||||
char *identifier = NULL, *title = NULL, *body = NULL, *subtitle = NULL;
|
||||
if (!PyArg_ParseTuple(args, "zsz|z", &identifier, &title, &body, &subtitle)) return NULL;
|
||||
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
UNUserNotificationCenter *center = nil;
|
||||
@try {
|
||||
center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
} @catch (NSException *e) {
|
||||
log_error("Failed to get current UNUserNotificationCenter object with error: %s (%s)",
|
||||
[[e name] UTF8String], [[e reason] UTF8String]);
|
||||
}
|
||||
if (!center) Py_RETURN_NONE;
|
||||
if (!center.delegate) center.delegate = [[NotificationDelegate alloc] init];
|
||||
queue_notification(identifier, title, body, subtitle);
|
||||
|
||||
@@ -22,7 +22,7 @@ class Version(NamedTuple):
|
||||
|
||||
appname: str = 'kitty'
|
||||
kitty_face = '🐱'
|
||||
version: Version = Version(0, 33, 0)
|
||||
version: Version = Version(0, 33, 1)
|
||||
str_version: str = '.'.join(map(str, version))
|
||||
_plat = sys.platform.lower()
|
||||
is_macos: bool = 'darwin' in _plat
|
||||
|
||||
@@ -184,38 +184,79 @@ glyph_id_for_codepoint_ctfont(CTFontRef ct_font, char_type ch) {
|
||||
return glyphs[0];
|
||||
}
|
||||
|
||||
static bool
|
||||
cf_string_equals(CFStringRef a, CFStringRef b) { return CFStringCompare(a, b, 0) == kCFCompareEqualTo; }
|
||||
|
||||
#define LAST_RESORT_FONT_NAME "LastResort"
|
||||
|
||||
static bool
|
||||
is_last_resort_font(CTFontRef new_font) {
|
||||
CFStringRef name = CTFontCopyPostScriptName(new_font);
|
||||
CFComparisonResult cr = CFStringCompare(name, CFSTR("LastResort"), 0);
|
||||
bool ans = cf_string_equals(name, CFSTR(LAST_RESORT_FONT_NAME));
|
||||
CFRelease(name);
|
||||
return cr == kCFCompareEqualTo;
|
||||
return ans;
|
||||
}
|
||||
|
||||
static CTFontDescriptorRef _nerd_font_descriptor = NULL;
|
||||
|
||||
static CTFontRef nerd_font(CGFloat sz) {
|
||||
static bool searched = false;
|
||||
if (!searched) {
|
||||
searched = true;
|
||||
CFArrayRef fonts = CTFontCollectionCreateMatchingFontDescriptors(all_fonts_collection());
|
||||
const CFIndex count = CFArrayGetCount(fonts);
|
||||
for (CFIndex i = 0; i < count; i++) {
|
||||
CTFontDescriptorRef descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);
|
||||
CFStringRef name = CTFontDescriptorCopyAttribute(descriptor, kCTFontNameAttribute);
|
||||
bool is_nerd_font = cf_string_equals(name, CFSTR("SymbolsNFM"));
|
||||
CFRelease(name);
|
||||
if (is_nerd_font) {
|
||||
_nerd_font_descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, CTFontDescriptorCopyAttributes(descriptor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
CFRelease(fonts);
|
||||
}
|
||||
return _nerd_font_descriptor ? CTFontCreateWithFontDescriptor(_nerd_font_descriptor, sz, NULL) : NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
font_can_render_cell(CTFontRef font, CPUCell *cell) {
|
||||
char_type ch = cell->ch ? cell->ch : ' ';
|
||||
bool found = true;
|
||||
if (!glyph_id_for_codepoint_ctfont(font, ch)) found = false;
|
||||
for (unsigned i = 0; i < arraysz(cell->cc_idx) && cell->cc_idx[i] && found; i++) {
|
||||
char_type cch = codepoint_for_mark(cell->cc_idx[i]);
|
||||
if (!glyph_id_for_codepoint_ctfont(font, cch)) found = false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
static CTFontRef
|
||||
manually_search_fallback_fonts(CTFontRef current_font, CPUCell *cell) {
|
||||
char_type ch = cell->ch ? cell->ch : ' ';
|
||||
const bool in_first_pua = 0xe000 <= ch && ch <= 0xf8ff;
|
||||
// preferentially load from NERD fonts
|
||||
if (in_first_pua) {
|
||||
CTFontRef nf = nerd_font(CTFontGetSize(current_font));
|
||||
if (nf) {
|
||||
if (font_can_render_cell(nf, cell)) return nf;
|
||||
CFRelease(nf);
|
||||
}
|
||||
}
|
||||
CFArrayRef fonts = CTFontCollectionCreateMatchingFontDescriptors(all_fonts_collection());
|
||||
CTFontRef ans = NULL;
|
||||
const CFIndex count = CFArrayGetCount(fonts);
|
||||
for (CFIndex i = 0; i < count; i++) {
|
||||
CTFontDescriptorRef descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i);
|
||||
CTFontRef new_font = CTFontCreateWithFontDescriptor(descriptor, CTFontGetSize(current_font), NULL);
|
||||
if (new_font) {
|
||||
if (!is_last_resort_font(new_font)) {
|
||||
char_type ch = cell->ch ? cell->ch : ' ';
|
||||
bool found = true;
|
||||
if (!glyph_id_for_codepoint_ctfont(new_font, ch)) found = false;
|
||||
for (unsigned i = 0; i < arraysz(cell->cc_idx) && cell->cc_idx[i] && found; i++) {
|
||||
ch = codepoint_for_mark(cell->cc_idx[i]);
|
||||
if (!glyph_id_for_codepoint_ctfont(new_font, ch)) found = false;
|
||||
}
|
||||
if (found) {
|
||||
ans = new_font;
|
||||
break;
|
||||
}
|
||||
if (!is_last_resort_font(new_font)) {
|
||||
if (font_can_render_cell(new_font, cell)) {
|
||||
ans = new_font;
|
||||
break;
|
||||
}
|
||||
CFRelease(new_font);
|
||||
}
|
||||
CFRelease(new_font);
|
||||
}
|
||||
CFRelease(fonts);
|
||||
return ans;
|
||||
@@ -231,16 +272,15 @@ find_substitute_face(CFStringRef str, CTFontRef old_font, CPUCell *cpu_cell) {
|
||||
CTFontRef new_font = CTFontCreateForString(old_font, str, CFRangeMake(start, amt));
|
||||
if (amt == len && len != 1) amt = 1;
|
||||
else start++;
|
||||
if (new_font == NULL) { PyErr_SetString(PyExc_ValueError, "Failed to find fallback CTFont"); return NULL; }
|
||||
if (new_font == old_font) { CFRelease(new_font); continue; }
|
||||
if (is_last_resort_font(new_font)) {
|
||||
CFRelease(new_font);
|
||||
if (!new_font || is_last_resort_font(new_font)) {
|
||||
if (new_font) CFRelease(new_font);
|
||||
if (is_private_use(cpu_cell->ch)) {
|
||||
// CoreTexts fallback font mechanism does not work for private use characters
|
||||
new_font = manually_search_fallback_fonts(old_font, cpu_cell);
|
||||
if (new_font) return new_font;
|
||||
}
|
||||
PyErr_Format(PyExc_ValueError, "Failed to find fallback CTFont other than the LastResort font for: %s", [(NSString *)str UTF8String]);
|
||||
PyErr_Format(PyExc_ValueError, "Failed to find fallback CTFont other than the %s font for: %s", LAST_RESORT_FONT_NAME, [(NSString *)str UTF8String]);
|
||||
return NULL;
|
||||
}
|
||||
return new_font;
|
||||
@@ -249,8 +289,26 @@ find_substitute_face(CFStringRef str, CTFontRef old_font, CPUCell *cpu_cell) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CTFontRef
|
||||
apply_styles_to_fallback_font(CTFontRef original_fallback_font, bool bold, bool italic) {
|
||||
if (!original_fallback_font || is_last_resort_font(original_fallback_font)) return original_fallback_font;
|
||||
CTFontRef ans = nil;
|
||||
CTFontDescriptorRef original_descriptor = CTFontCopyFontDescriptor(original_fallback_font);
|
||||
CTFontSymbolicTraits traits = kCTFontTraitMonoSpace;
|
||||
if (bold) traits |= kCTFontTraitBold;
|
||||
if (italic) traits |= kCTFontTraitItalic;
|
||||
CTFontDescriptorRef descriptor = CTFontDescriptorCreateCopyWithSymbolicTraits(original_descriptor, traits, traits);
|
||||
CFRelease(original_descriptor);
|
||||
if (descriptor) {
|
||||
ans = CTFontCreateWithFontDescriptor(descriptor, CTFontGetSize(original_fallback_font), NULL);
|
||||
CFRelease(descriptor);
|
||||
}
|
||||
if (ans) { CFRelease(original_fallback_font); return ans; }
|
||||
return original_fallback_font;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
create_fallback_face(PyObject *base_face, CPUCell* cell, bool UNUSED bold, bool UNUSED italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) {
|
||||
create_fallback_face(PyObject *base_face, CPUCell* cell, bool bold, bool italic, bool emoji_presentation, FONTS_DATA_HANDLE fg) {
|
||||
CTFace *self = (CTFace*)base_face;
|
||||
CTFontRef new_font;
|
||||
#define search_for_fallback() \
|
||||
@@ -268,21 +326,19 @@ create_fallback_face(PyObject *base_face, CPUCell* cell, bool UNUSED bold, bool
|
||||
search_for_fallback();
|
||||
}
|
||||
}
|
||||
else { search_for_fallback(); }
|
||||
else { search_for_fallback(); new_font = apply_styles_to_fallback_font(new_font, bold, italic); }
|
||||
if (new_font == NULL) return NULL;
|
||||
NSURL *url = (NSURL*)CTFontCopyAttribute(new_font, kCTFontURLAttribute);
|
||||
const char *font_path = [[url path] UTF8String];
|
||||
PyObject *postscript_name = Py_BuildValue("s", convert_cfstring(CTFontCopyPostScriptName(new_font), true));
|
||||
ssize_t idx = -1;
|
||||
PyObject *q, *ans = NULL;
|
||||
while ((q = iter_fallback_faces(fg, &idx))) {
|
||||
CTFace *qf = (CTFace*)q;
|
||||
const char *qpath;
|
||||
if (qf->path && (qpath = PyUnicode_AsUTF8(qf->path)) && strcmp(qpath, font_path) == 0) {
|
||||
if (PyObject_RichCompareBool(postscript_name, qf->postscript_name, Py_EQ) == 1) {
|
||||
ans = PyLong_FromSsize_t(idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
[url release];
|
||||
Py_CLEAR(postscript_name);
|
||||
if (ans == NULL) return (PyObject*)ct_face(new_font, fg);
|
||||
CFRelease(new_font);
|
||||
return ans;
|
||||
@@ -449,6 +505,7 @@ finalize(void) {
|
||||
if (all_fonts_collection_data) CFRelease(all_fonts_collection_data);
|
||||
if (window_title_font) CFRelease(window_title_font);
|
||||
window_title_font = nil;
|
||||
if (_nerd_font_descriptor) CFRelease(_nerd_font_descriptor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ queue_canberra_sound(const char *which_sound, const char *event_id, bool is_path
|
||||
current_sound.event_id = strdup(event_id);
|
||||
current_sound.media_role = strdup(media_role);
|
||||
current_sound.is_path = is_path;
|
||||
current_sound.theme_name = strdup(theme_name);
|
||||
current_sound.theme_name = theme_name ? strdup(theme_name) : NULL;
|
||||
pthread_mutex_unlock(&canberra_lock);
|
||||
while (true) {
|
||||
ssize_t ret = write(canberra_pipe_w, "w", 1);
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include "state.h"
|
||||
#include "cleanup.h"
|
||||
#include "lineops.h"
|
||||
#include "fonts.h"
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include <dlfcn.h>
|
||||
#include "emoji.h"
|
||||
#include "freetype_render_ui_text.h"
|
||||
#ifndef FC_COLOR
|
||||
#define FC_COLOR "color"
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
#define MISSING_GLYPH (NUM_UNDERLINE_STYLES + 2)
|
||||
#define MAX_NUM_EXTRA_GLYPHS_PUA 4u
|
||||
|
||||
typedef void (*send_sprite_to_gpu_func)(FONTS_DATA_HANDLE fg, unsigned int, unsigned int, unsigned int, pixel*);
|
||||
send_sprite_to_gpu_func current_send_sprite_to_gpu = NULL;
|
||||
static PyObject *python_send_to_gpu_impl = NULL;
|
||||
#define current_send_sprite_to_gpu(...) (python_send_to_gpu_impl ? python_send_to_gpu(__VA_ARGS__) : send_sprite_to_gpu(__VA_ARGS__))
|
||||
extern PyTypeObject Line_Type;
|
||||
|
||||
enum {NO_FONT=-3, MISSING_FONT=-2, BLANK_FONT=-1, BOX_FONT=0};
|
||||
@@ -453,7 +452,7 @@ has_cell_text(Font *self, CPUCell *cell) {
|
||||
}
|
||||
|
||||
static void
|
||||
output_cell_fallback_data(CPUCell *cell, bool bold, bool italic, bool emoji_presentation, PyObject *face, bool new_face) {
|
||||
output_cell_fallback_data(CPUCell *cell, bool bold, bool italic, bool emoji_presentation, PyObject *face) {
|
||||
printf("U+%x ", cell->ch);
|
||||
for (unsigned i = 0; i < arraysz(cell->cc_idx) && cell->cc_idx[i]; i++) {
|
||||
printf("U+%x ", codepoint_for_mark(cell->cc_idx[i]));
|
||||
@@ -461,8 +460,8 @@ output_cell_fallback_data(CPUCell *cell, bool bold, bool italic, bool emoji_pres
|
||||
if (bold) printf("bold ");
|
||||
if (italic) printf("italic ");
|
||||
if (emoji_presentation) printf("emoji_presentation ");
|
||||
if (PyLong_Check(face)) printf("using previous fallback font at index: ");
|
||||
PyObject_Print(face, stdout, 0);
|
||||
if (new_face) printf(" (new face)");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -488,7 +487,7 @@ load_fallback_font(FontGroup *fg, CPUCell *cell, bool bold, bool italic, bool em
|
||||
PyObject *face = create_fallback_face(fg->fonts[f].face, cell, bold, italic, emoji_presentation, (FONTS_DATA_HANDLE)fg);
|
||||
if (face == NULL) { PyErr_Print(); return MISSING_FONT; }
|
||||
if (face == Py_None) { Py_DECREF(face); return MISSING_FONT; }
|
||||
if (global_state.debug_font_fallback) output_cell_fallback_data(cell, bold, italic, emoji_presentation, face, true);
|
||||
if (global_state.debug_font_fallback) output_cell_fallback_data(cell, bold, italic, emoji_presentation, face);
|
||||
if (PyLong_Check(face)) { ssize_t ans = fg->first_fallback_font_idx + PyLong_AsSsize_t(face); Py_DECREF(face); return ans; }
|
||||
set_size_for_face(face, fg->cell_height, true, (FONTS_DATA_HANDLE)fg);
|
||||
|
||||
@@ -1580,7 +1579,6 @@ set_send_sprite_to_gpu(PyObject UNUSED *self, PyObject *func) {
|
||||
python_send_to_gpu_impl = func;
|
||||
Py_INCREF(python_send_to_gpu_impl);
|
||||
}
|
||||
current_send_sprite_to_gpu = python_send_to_gpu_impl ? python_send_to_gpu : send_sprite_to_gpu;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -1738,6 +1736,5 @@ init_fonts(PyObject *module) {
|
||||
create_feature("-calt", CALT_FEATURE);
|
||||
#undef create_feature
|
||||
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
||||
current_send_sprite_to_gpu = send_sprite_to_gpu;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -38,10 +38,6 @@ check_for_gl_error(void UNUSED *ret, const char *name, GLADapiproc UNUSED funcpt
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_nvidia = false;
|
||||
|
||||
bool is_nvidia_gpu_driver(void) { return is_nvidia; }
|
||||
|
||||
void
|
||||
gl_init(void) {
|
||||
static bool glad_loaded = false;
|
||||
@@ -64,7 +60,6 @@ gl_init(void) {
|
||||
int gl_major = GLAD_VERSION_MAJOR(gl_version);
|
||||
int gl_minor = GLAD_VERSION_MINOR(gl_version);
|
||||
const char *gvs = (const char*)glGetString(GL_VERSION);
|
||||
if (strstr(gvs, "NVIDIA")) is_nvidia = true;
|
||||
if (global_state.debug_rendering) printf("GL version string: '%s' Detected version: %d.%d\n", gvs, gl_major, gl_minor);
|
||||
if (gl_major < OPENGL_REQUIRED_VERSION_MAJOR || (gl_major == OPENGL_REQUIRED_VERSION_MAJOR && gl_minor < OPENGL_REQUIRED_VERSION_MINOR)) {
|
||||
fatal("OpenGL version is %d.%d, version >= 3.3 required for kitty", gl_major, gl_minor);
|
||||
|
||||
@@ -56,4 +56,3 @@ void bind_vao_uniform_buffer(ssize_t vao_idx, size_t bufnum, GLuint block_index)
|
||||
void unbind_vertex_array(void);
|
||||
void unbind_program(void);
|
||||
GLuint compile_shaders(GLenum shader_type, GLsizei count, const GLchar * const * string);
|
||||
bool is_nvidia_gpu_driver(void);
|
||||
|
||||
2
kitty/glfw-wrapper.h
generated
2
kitty/glfw-wrapper.h
generated
@@ -2258,7 +2258,7 @@ typedef void* (*glfwGetX11Display_func)(void);
|
||||
GFW_EXTERN glfwGetX11Display_func glfwGetX11Display_impl;
|
||||
#define glfwGetX11Display glfwGetX11Display_impl
|
||||
|
||||
typedef int32_t (*glfwGetX11Window_func)(GLFWwindow*);
|
||||
typedef unsigned long (*glfwGetX11Window_func)(GLFWwindow*);
|
||||
GFW_EXTERN glfwGetX11Window_func glfwGetX11Window_impl;
|
||||
#define glfwGetX11Window glfwGetX11Window_impl
|
||||
|
||||
|
||||
@@ -1044,7 +1044,7 @@ native_window_handle(GLFWwindow *w) {
|
||||
void *ans = glfwGetCocoaWindow(w);
|
||||
return PyLong_FromVoidPtr(ans);
|
||||
#endif
|
||||
if (glfwGetX11Window) return PyLong_FromLong((long)glfwGetX11Window(w));
|
||||
if (glfwGetX11Window) return PyLong_FromUnsignedLong(glfwGetX11Window(w));
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
@@ -1077,7 +1077,10 @@ create_os_window(PyObject UNUSED *self, PyObject *args, PyObject *kw) {
|
||||
// Request SRGB output buffer
|
||||
// Prevents kitty from starting on Wayland + NVIDIA, sigh: https://github.com/kovidgoyal/kitty/issues/7021
|
||||
// Remove after https://github.com/NVIDIA/egl-wayland/issues/85 is fixed.
|
||||
if (!global_state.is_wayland || !is_nvidia_gpu_driver()) glfwWindowHint(GLFW_SRGB_CAPABLE, true);
|
||||
// Also apparently mesa has introduced a bug with sRGB surfaces and Wayland.
|
||||
// Sigh. Wayland is such a pile of steaming crap.
|
||||
// See https://github.com/kovidgoyal/kitty/issues/7174#issuecomment-2000033873
|
||||
if (!global_state.is_wayland) glfwWindowHint(GLFW_SRGB_CAPABLE, true);
|
||||
#ifdef __APPLE__
|
||||
cocoa_set_activation_policy(OPT(macos_hide_from_tasks));
|
||||
glfwWindowHint(GLFW_COCOA_GRAPHICS_SWITCHING, true);
|
||||
@@ -1768,7 +1771,7 @@ x11_window_id(PyObject UNUSED *self, PyObject *os_wid) {
|
||||
OSWindow *w = os_window_for_id(PyLong_AsUnsignedLongLong(os_wid));
|
||||
if (!w) { PyErr_SetString(PyExc_ValueError, "No OSWindow with the specified id found"); return NULL; }
|
||||
if (!glfwGetX11Window) { PyErr_SetString(PyExc_RuntimeError, "Failed to load glfwGetX11Window"); return NULL; }
|
||||
return Py_BuildValue("l", (long)glfwGetX11Window(w->handle));
|
||||
return PyLong_FromUnsignedLong(glfwGetX11Window(w->handle));
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
||||
@@ -165,6 +165,36 @@ class Pair:
|
||||
return id_window_map[wid].effective_border()
|
||||
return 0
|
||||
|
||||
def minimum_width(self, id_window_map: Dict[int, WindowGroup]) -> int:
|
||||
if self.one is None or self.two is None or not self.horizontal:
|
||||
return lgd.cell_width
|
||||
bw = self.effective_border(id_window_map) if lgd.draw_minimal_borders else 0
|
||||
ans = 2 * bw
|
||||
if isinstance(self.one, Pair):
|
||||
ans += self.one.minimum_width(id_window_map)
|
||||
else:
|
||||
ans += lgd.cell_width
|
||||
if isinstance(self.two, Pair):
|
||||
ans += self.two.minimum_width(id_window_map)
|
||||
else:
|
||||
ans += lgd.cell_width
|
||||
return ans
|
||||
|
||||
def minimum_height(self, id_window_map: Dict[int, WindowGroup]) -> int:
|
||||
if self.one is None or self.two is None or self.horizontal:
|
||||
return lgd.cell_height
|
||||
bw = self.effective_border(id_window_map) if lgd.draw_minimal_borders else 0
|
||||
ans = 2 * bw
|
||||
if isinstance(self.one, Pair):
|
||||
ans += self.one.minimum_height(id_window_map)
|
||||
else:
|
||||
ans += lgd.cell_height
|
||||
if isinstance(self.two, Pair):
|
||||
ans += self.two.minimum_height(id_window_map)
|
||||
else:
|
||||
ans += lgd.cell_height
|
||||
return ans
|
||||
|
||||
def layout_pair(
|
||||
self,
|
||||
left: int, top: int, width: int, height: int,
|
||||
@@ -191,8 +221,13 @@ class Pair:
|
||||
self.apply_window_geometry(q, geom, id_window_map, layout_object)
|
||||
return
|
||||
if self.horizontal:
|
||||
w1 = max(2*lgd.cell_width + 1, int(self.bias * width) - bw)
|
||||
w2 = max(2*lgd.cell_width + 1, width - w1 - bw2)
|
||||
min_w1 = self.one.minimum_width(id_window_map) if isinstance(self.one, Pair) else lgd.cell_width
|
||||
min_w2 = self.two.minimum_width(id_window_map) if isinstance(self.two, Pair) else lgd.cell_width
|
||||
w1 = max(min_w1, int(self.bias * width) - bw)
|
||||
w2 = width - w1 - bw2
|
||||
if w2 < min_w2 and w1 >= min_w1 + bw2:
|
||||
w2 = min_w2
|
||||
w1 = width - w2
|
||||
self.first_extent = Extent(max(0, left - bw), left + w1 + bw)
|
||||
self.second_extent = Extent(left + w1 + bw, left + width + bw)
|
||||
if isinstance(self.one, Pair):
|
||||
@@ -217,8 +252,13 @@ class Pair:
|
||||
geom = window_geometry_from_layouts(xl, yl)
|
||||
self.apply_window_geometry(self.two, geom, id_window_map, layout_object)
|
||||
else:
|
||||
h1 = max(2*lgd.cell_height + 1, int(self.bias * height) - bw)
|
||||
h2 = max(2*lgd.cell_height + 1, height - h1 - bw2)
|
||||
min_h1 = self.one.minimum_height(id_window_map) if isinstance(self.one, Pair) else lgd.cell_height
|
||||
min_h2 = self.two.minimum_height(id_window_map) if isinstance(self.two, Pair) else lgd.cell_height
|
||||
h1 = max(min_h1, int(self.bias * height) - bw)
|
||||
h2 = height - h1 - bw2
|
||||
if h2 < min_h2 and h1 >= min_h1 + bw2:
|
||||
h2 = min_h2
|
||||
h1 = height - h2
|
||||
self.first_extent = Extent(max(0, top - bw), top + h1 + bw)
|
||||
self.second_extent = Extent(top + h1 + bw, top + height + bw)
|
||||
if isinstance(self.one, Pair):
|
||||
@@ -247,7 +287,7 @@ class Pair:
|
||||
if is_horizontal == self.horizontal and not self.is_redundant:
|
||||
if which == 2:
|
||||
increment *= -1
|
||||
new_bias = max(0.1, min(self.bias + increment, 0.9))
|
||||
new_bias = max(0, min(self.bias + increment, 1))
|
||||
if new_bias != self.bias:
|
||||
self.bias = new_bias
|
||||
return True
|
||||
|
||||
@@ -67,13 +67,25 @@ def get_process_pool_executor(
|
||||
|
||||
def test_spawn() -> None:
|
||||
monkey_patch_multiprocessing()
|
||||
import shutil
|
||||
import subprocess
|
||||
from queue import Empty
|
||||
try:
|
||||
from multiprocessing import get_context
|
||||
ctx = get_context('spawn')
|
||||
q = ctx.Queue()
|
||||
p = ctx.Process(target=q.put, args=('hello',))
|
||||
p.start()
|
||||
x = q.get(timeout=8)
|
||||
try:
|
||||
x = q.get(timeout=8)
|
||||
except Empty:
|
||||
p.join()
|
||||
rc = p.exitcode
|
||||
if rc == 0:
|
||||
raise TimeoutError('Timed out waiting for response from spawned process')
|
||||
if shutil.which('coredumpctl'):
|
||||
subprocess.run(['sh', '-c', 'echo bt | coredumpctl debug'])
|
||||
raise SystemExit(f'Spawned process exited with return code: {rc}')
|
||||
assert x == 'hello'
|
||||
p.join()
|
||||
finally:
|
||||
|
||||
@@ -58,7 +58,7 @@ opt('bold_italic_font', 'auto')
|
||||
|
||||
opt('font_size', '11.0',
|
||||
option_type='to_font_size', ctype='double',
|
||||
long_text='Font size (in pts)'
|
||||
long_text='Font size (in pts).'
|
||||
)
|
||||
|
||||
opt('force_ltr', 'no',
|
||||
@@ -311,7 +311,7 @@ opt('cursor_text_color', '#111111',
|
||||
long_text='''
|
||||
The color of text under the cursor. If you want it rendered with the
|
||||
background color of the cell underneath instead, use the special keyword:
|
||||
background. Note that if :opt:`cursor` is set to :code:`none` then this option
|
||||
`background`. Note that if :opt:`cursor` is set to :code:`none` then this option
|
||||
is ignored. Note that some themes set this value, so if you want to override it,
|
||||
place your value after the lines where the theme file is included.
|
||||
'''
|
||||
@@ -791,7 +791,7 @@ mma('Select line from point',
|
||||
'select_line_from_point ctrl+alt+left triplepress ungrabbed mouse_selection line_from_point',
|
||||
long_text='Select from the clicked point to the end of the line.'
|
||||
' If you would like to select the word at the point and then extend to the rest of the line,'
|
||||
' change line_from_point to word_and_line_from_point.'
|
||||
' change `line_from_point` to `word_and_line_from_point`.'
|
||||
)
|
||||
|
||||
mma('Extend the current selection',
|
||||
@@ -830,7 +830,7 @@ mma('Select line from point even when grabbed',
|
||||
'select_line_from_point_grabbed ctrl+shift+alt+left triplepress ungrabbed,grabbed mouse_selection line_from_point',
|
||||
long_text='Select from the clicked point to the end of the line even when grabbed.'
|
||||
' If you would like to select the word at the point and then extend to the rest of the line,'
|
||||
' change line_from_point to word_and_line_from_point.'
|
||||
' change `line_from_point` to `word_and_line_from_point`.'
|
||||
)
|
||||
|
||||
mma('Extend the current selection even when grabbed',
|
||||
@@ -915,7 +915,7 @@ opt('window_alert_on_bell', 'yes',
|
||||
option_type='to_bool', ctype='bool',
|
||||
long_text='''
|
||||
Request window attention on bell. Makes the dock icon bounce on macOS or the
|
||||
taskbar flash on linux.
|
||||
taskbar flash on Linux.
|
||||
'''
|
||||
)
|
||||
|
||||
@@ -948,7 +948,7 @@ opt('bell_path', 'none',
|
||||
Path to a sound file to play as the bell sound. If set to :code:`none`, the
|
||||
system default bell sound is used. Must be in a format supported by the
|
||||
operating systems sound API, such as WAV or OGA on Linux (libcanberra) or AIFF,
|
||||
MP3 or WAV on macOS (NSSound)
|
||||
MP3 or WAV on macOS (NSSound).
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#define NOSIMD { fatal("No SIMD implementations for this CPU"); }
|
||||
bool FUNC(utf8_decode_to_esc)(UTF8Decoder *d UNUSED, const uint8_t *src UNUSED, size_t src_sz UNUSED) NOSIMD
|
||||
const uint8_t* FUNC(find_either_of_two_bytes)(const uint8_t *haystack UNUSED, const size_t sz UNUSED, const uint8_t a UNUSED, const uint8_t b UNUSED) NOSIMD
|
||||
void FUNC(xor_data64)(const uint8_t key[64], uint8_t* data, const size_t data_sz);
|
||||
void FUNC(xor_data64)(const uint8_t key[64] UNUSED, uint8_t* data UNUSED, const size_t data_sz UNUSED) NOSIMD
|
||||
#undef NOSIMD
|
||||
#else
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ init_simd(void *x) {
|
||||
#ifdef __APPLE__
|
||||
#ifdef __arm64__
|
||||
// simde takes care of NEON on Apple Silicon
|
||||
// ARM has only 128 bit registers buy using the avx2 code is still slightly faster
|
||||
// ARM has only 128 bit registers but using the avx2 code is still slightly faster
|
||||
has_sse4_2 = true; has_avx2 = true;
|
||||
#else
|
||||
do_check();
|
||||
@@ -215,9 +215,9 @@ init_simd(void *x) {
|
||||
#ifdef __aarch64__
|
||||
// no idea how to probe ARM cpu for NEON support. This file uses pretty
|
||||
// basic AVX2 and SSE4.2 intrinsics, so hopefully they work on ARM
|
||||
// ARM has only 128 bit registers buy using the avx2 code is still slightly faster
|
||||
// ARM has only 128 bit registers but using the avx2 code is still slightly faster
|
||||
has_sse4_2 = true; has_avx2 = true;
|
||||
#else
|
||||
#elif !defined(KITTY_NO_SIMD)
|
||||
do_check();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -265,6 +265,7 @@ def run_tests(report_env: bool = False) -> None:
|
||||
if args.name and args.name[0] in ('type-check', 'type_check', 'mypy'):
|
||||
type_check()
|
||||
go_pkgs = reduce_go_pkgs(args.module, args.name)
|
||||
os.environ['ASAN_OPTIONS'] = 'detect_leaks=0' # ensure subprocesses dont fail because of leak detection
|
||||
if go_pkgs:
|
||||
go_proc: 'Optional[GoProc]' = run_go(go_pkgs, args.name)
|
||||
else:
|
||||
|
||||
30
setup.py
30
setup.py
@@ -23,7 +23,7 @@ from pathlib import Path
|
||||
from typing import Callable, Dict, FrozenSet, Iterable, Iterator, List, Optional, Sequence, Set, Tuple, Union, cast
|
||||
|
||||
from glfw import glfw
|
||||
from glfw.glfw import ISA, BinaryArch, Command, CompileKey
|
||||
from glfw.glfw import ISA, BinaryArch, Command, CompileKey, CompilerType
|
||||
|
||||
if sys.version_info[:2] < (3, 8):
|
||||
raise SystemExit('kitty requires python >= 3.8')
|
||||
@@ -507,6 +507,9 @@ def init_env(
|
||||
cflags.append('-g3')
|
||||
ldflags.append('-lprofiler')
|
||||
|
||||
if debug or profile:
|
||||
cflags.append('-fno-omit-frame-pointer')
|
||||
|
||||
library_paths: Dict[str, List[str]] = {}
|
||||
|
||||
def add_lpath(which: str, name: str, val: Optional[str]) -> None:
|
||||
@@ -536,6 +539,8 @@ def init_env(
|
||||
set_arches(ldflags, building_arch)
|
||||
ba = test_compile(cc, *(cppflags + cflags), ldflags=ldflags, get_output_arch=True)
|
||||
assert isinstance(ba, BinaryArch)
|
||||
if ba.isa not in (ISA.AMD64, ISA.X86, ISA.ARM64):
|
||||
cppflags.append('-DKITTY_NO_SIMD')
|
||||
|
||||
control_flow_protection = ''
|
||||
if ba.isa == ISA.AMD64:
|
||||
@@ -557,7 +562,8 @@ def init_env(
|
||||
ccver=ccver, ldpaths=ldpaths, vcs_rev=vcs_rev,
|
||||
)
|
||||
if verbose:
|
||||
print(ans.cc_version_string)
|
||||
print(ans.cc_version_string.strip())
|
||||
print('Detected:', ans.compiler_type)
|
||||
return ans
|
||||
|
||||
|
||||
@@ -701,13 +707,11 @@ def get_source_specific_cflags(env: Env, src: str) -> List[str]:
|
||||
ans.append('-msse4.2' if '128' in src else '-mavx2')
|
||||
if '256' in src:
|
||||
# We have manual vzeroupper so prevent compiler from emitting it causing duplicates
|
||||
if env.is_gcc:
|
||||
ans.append('-mno-vzeroupper')
|
||||
else:
|
||||
if env.compiler_type is CompilerType.clang:
|
||||
ans.append('-mllvm')
|
||||
ans.append('-x86-use-vzeroupper=0')
|
||||
elif env.binary_arch.isa != ISA.ARM64:
|
||||
ans.append('-DKITTY_NO_SIMD')
|
||||
else:
|
||||
ans.append('-mno-vzeroupper')
|
||||
elif src.startswith('3rdparty/base64/lib/arch/'):
|
||||
if env.binary_arch.isa in (ISA.AMD64, ISA.X86):
|
||||
q = src.split(os.path.sep)
|
||||
@@ -1066,9 +1070,11 @@ def update_go_generated_files(args: Options, kitty_exe: str) -> None:
|
||||
|
||||
env = os.environ.copy()
|
||||
env['ASAN_OPTIONS'] = 'detect_leaks=0'
|
||||
cp = subprocess.run([kitty_exe, '+launch', os.path.join(src_base, 'gen/go_code.py')], stdout=subprocess.PIPE, env=env)
|
||||
cp = subprocess.run([kitty_exe, '+launch', os.path.join(src_base, 'gen/go_code.py')], stdout=subprocess.DEVNULL, env=env)
|
||||
if cp.returncode != 0:
|
||||
raise SystemExit(cp.returncode)
|
||||
if os.environ.get('CI') == 'true' and cp.returncode < 0 and shutil.which('coredumpctl'):
|
||||
subprocess.run(['sh', '-c', 'echo bt | coredumpctl debug'])
|
||||
raise SystemExit(f'Generating go code failed with exit code: {cp.returncode}')
|
||||
|
||||
|
||||
def parse_go_version(x: str) -> Tuple[int, int, int]:
|
||||
@@ -1165,14 +1171,12 @@ def build_launcher(args: Options, launcher_dir: str = '.', bundle_type: str = 's
|
||||
libs: List[str] = []
|
||||
ldflags = shlex.split(os.environ.get('LDFLAGS', ''))
|
||||
if args.profile or args.sanitize:
|
||||
cflags.append('-g3')
|
||||
if args.sanitize:
|
||||
cflags.append('-g3')
|
||||
sanitize_args = get_sanitize_args(env.cc, env.ccver)
|
||||
cflags.extend(sanitize_args)
|
||||
ldflags.extend(sanitize_args)
|
||||
libs += ['-lasan'] if not is_macos and env.is_gcc else []
|
||||
else:
|
||||
cflags.append('-g')
|
||||
libs += ['-lasan'] if not is_macos and env.compiler_type is not CompilerType.clang else []
|
||||
if args.profile:
|
||||
libs.append('-lprofiler')
|
||||
else:
|
||||
|
||||
@@ -1151,7 +1151,7 @@ func (s *Function) OutputASM(w io.Writer) {
|
||||
}
|
||||
fmt.Fprint(w, "// ")
|
||||
s.print_signature(w)
|
||||
fmt.Fprintf(w, "\nTEXT ·%s(SB), NOSPLIT, $0-%d\n", s.Name, s.Size)
|
||||
fmt.Fprintf(w, "\nTEXT ·%s(SB), NOSPLIT|TOPFRAME|NOFRAME, $0-%d\n", s.Name, s.Size)
|
||||
|
||||
has_trailing_return := false
|
||||
for _, i := range s.Instructions {
|
||||
|
||||
Reference in New Issue
Block a user