Compare commits

..

14 Commits

Author SHA1 Message Date
Kovid Goyal
9a103f3979 version 0.2.7 2017-07-14 10:46:35 +05:30
Kovid Goyal
270dde7020 Use erase in line instead as it is more efficient 2017-07-13 19:32:18 +05:30
Kovid Goyal
11de18e737 Fix #91 2017-07-13 19:24:26 +05:30
Kovid Goyal
62db44c71e macOS: Ensure the LANG environment variable is set
Fixes #90
2017-06-25 20:44:16 +05:30
Kovid Goyal
3d5c65eaea Fix #89 2017-06-21 10:19:45 +05:30
Kovid Goyal
ea298f95f2 Another place we can use exist_ok 2017-06-09 00:00:02 +05:30
Kovid Goyal
2f21e0e341 Merge branch 'patch-2' of https://github.com/mimi1vx/kitty 2017-06-08 23:59:14 +05:30
Ondřej Súkup
ae62d36a4a Remove unneeded try except block
os.makedirs has from python-3.2 option `exist_ok`
2017-06-08 20:25:34 +02:00
Kovid Goyal
76e3101d9b Hide all symbols 2017-06-07 11:19:53 +05:30
Kovid Goyal
c3442545a8 Add a note about changing mouse wheel scroll direction 2017-06-06 00:06:43 +05:30
Kovid Goyal
3a9b0faa06 Be more positive ;) 2017-06-06 00:03:43 +05:30
Kovid Goyal
4989b1f8bb ... 2017-06-05 23:58:36 +05:30
Kovid Goyal
348fe4ada4 Option for window padding
Fixes #85
2017-06-05 23:57:17 +05:30
Kovid Goyal
bbc6b2d86a Option to size window margin (blank area outside window borders)
Defaults to zero
2017-06-05 22:27:47 +05:30
14 changed files with 166 additions and 58 deletions

View File

@@ -5,11 +5,12 @@
from ctypes import addressof from ctypes import addressof
from itertools import chain from itertools import chain
from threading import Lock from threading import Lock
from functools import partial
from .constants import GLfloat, GLint, GLuint, viewport_size from .constants import GLfloat, GLint, GLuint, viewport_size
from .fast_data_types import GL_TRIANGLE_FAN, glMultiDrawArrays, glUniform3fv from .fast_data_types import GL_TRIANGLE_FAN, glMultiDrawArrays, glUniform3fv
from .shaders import ShaderProgram from .shaders import ShaderProgram
from .utils import get_dpi from .utils import pt_to_px
def as_color(c): def as_color(c):
@@ -31,7 +32,8 @@ def as_rect(left, top, right, bottom, color=0):
class BordersProgram(ShaderProgram): class BordersProgram(ShaderProgram):
def __init__(self): def __init__(self):
ShaderProgram.__init__(self, '''\ ShaderProgram.__init__(
self, '''\
uniform vec3 colors[3]; uniform vec3 colors[3];
in vec3 rect; in vec3 rect;
out vec3 color; out vec3 color;
@@ -57,34 +59,73 @@ void main() {
glUniform3fv(self.uniform_location('colors'), 3, addressof(color_buf)) glUniform3fv(self.uniform_location('colors'), 3, addressof(color_buf))
def border_maker(rects):
' Create a function that will add all the rectangles for drawing a border to rects '
def r(l, t, b, r, color):
rects.extend(as_rect(l, t, b, r, color))
def vertical_edge(color, width, top, bottom, left):
r(left, top, left + width, bottom, color)
def horizontal_edge(color, height, left, right, top):
r(left, top, right, top + height, color)
def edge(func, color, sz, a, b):
return partial(func, color, sz, a, b)
def border(color, sz, left, top, right, bottom):
horz = edge(horizontal_edge, color, sz, left, right)
horz(top), horz(bottom - sz) # top, bottom edges
vert = edge(vertical_edge, color, sz, top, bottom)
vert(left), vert(right - sz) # left, right edges
return border
class Borders: class Borders:
def __init__(self, opts): def __init__(self, opts):
self.is_dirty = False self.is_dirty = False
self.lock = Lock() self.lock = Lock()
self.can_render = False self.can_render = False
dpix, dpiy = get_dpi()['logical'] self.border_width = pt_to_px(opts.window_border_width)
dpi = (dpix + dpiy) / 2 self.padding_width = pt_to_px(opts.window_padding_width)
self.border_width = round(opts.window_border_width * dpi / 72)
self.color_buf = (GLfloat * 9)( self.color_buf = (GLfloat * 9)(
*as_color(opts.background), *as_color(opts.background), *as_color(opts.active_border_color),
*as_color(opts.active_border_color), *as_color(opts.inactive_border_color))
*as_color(opts.inactive_border_color)
)
def __call__(self, windows, active_window, current_layout, extra_blank_rects, draw_window_borders=True): def __call__(
self,
windows,
active_window,
current_layout,
extra_blank_rects,
draw_window_borders=True
):
rects = [] rects = []
for br in chain(current_layout.blank_rects, extra_blank_rects): for br in chain(current_layout.blank_rects, extra_blank_rects):
rects.extend(as_rect(*br)) rects.extend(as_rect(*br))
if draw_window_borders and self.border_width > 0: bw, pw = self.border_width, self.padding_width
bw = self.border_width fw = bw + pw
border = border_maker(rects)
if fw > 0:
for w in windows: for w in windows:
g = w.geometry g = w.geometry
color = 1 if w is active_window else 2 if bw > 0 and draw_window_borders:
rects.extend(as_rect(g.left - bw, g.top - bw, g.left, g.bottom + bw, color)) # Draw the border rectangles
rects.extend(as_rect(g.left - bw, g.top - bw, g.right + bw, g.top, color)) color = 1 if w is active_window else 2
rects.extend(as_rect(g.right, g.top - bw, g.right + bw, g.bottom + bw, color)) border(
rects.extend(as_rect(g.left - bw, g.bottom, g.right + bw, g.bottom + bw, color)) color, bw, g.left - fw, g.top - fw, g.right + fw,
g.bottom + fw)
if pw > 0:
# Draw the background rectangles over the padding region
color = 0
border(
color, pw, g.left - pw, g.top - pw, g.right + pw,
g.bottom + pw)
with self.lock: with self.lock:
self.num_of_rects = len(rects) // 12 self.num_of_rects = len(rects) // 12
self.rects = (GLfloat * len(rects))() self.rects = (GLfloat * len(rects))()
@@ -108,4 +149,7 @@ class Borders:
program.send_data(self.rects) program.send_data(self.rects)
program.set_colors(self.color_buf) program.set_colors(self.color_buf)
self.is_dirty = False self.is_dirty = False
glMultiDrawArrays(GL_TRIANGLE_FAN, addressof(self.starts), addressof(self.counts), self.num_of_rects) glMultiDrawArrays(
GL_TRIANGLE_FAN,
addressof(self.starts),
addressof(self.counts), self.num_of_rects)

View File

@@ -25,3 +25,18 @@ cocoa_hide_titlebar(PyObject UNUSED *self, PyObject *window_id) {
} }
Py_RETURN_NONE; Py_RETURN_NONE;
} }
PyObject*
cocoa_get_lang(PyObject UNUSED *self) {
NSString* locale = nil;
NSString* lang_code = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode];
NSString* country_code = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
if (lang_code && country_code) {
locale = [NSString stringWithFormat:@"%@_%@", lang_code, country_code];
} else {
locale = [[NSLocale currentLocale] localeIdentifier];
}
if (!locale) { Py_RETURN_NONE; }
return Py_BuildValue("s", [locale UTF8String]);
}

View File

@@ -150,28 +150,38 @@ def to_layout_names(raw):
raise ValueError('The window layout {} is unknown'.format(p)) raise ValueError('The window layout {} is unknown'.format(p))
def positive_int(x):
return max(0, int(x))
def positive_float(x):
return max(0, float(x))
type_map = { type_map = {
'scrollback_lines': int, 'scrollback_lines': positive_int,
'scrollback_pager': shlex.split, 'scrollback_pager': shlex.split,
'scrollback_in_new_tab': to_bool, 'scrollback_in_new_tab': to_bool,
'font_size': to_font_size, 'font_size': to_font_size,
'font_size_delta': float, 'font_size_delta': positive_float,
'cursor_shape': to_cursor_shape, 'cursor_shape': to_cursor_shape,
'cursor_opacity': to_opacity, 'cursor_opacity': to_opacity,
'open_url_modifiers': to_open_url_modifiers, 'open_url_modifiers': to_open_url_modifiers,
'repaint_delay': int, 'repaint_delay': positive_int,
'window_border_width': float, 'window_border_width': positive_float,
'window_margin_width': positive_float,
'window_padding_width': positive_float,
'wheel_scroll_multiplier': float, 'wheel_scroll_multiplier': float,
'visual_bell_duration': float, 'visual_bell_duration': positive_float,
'enable_audio_bell': to_bool, 'enable_audio_bell': to_bool,
'click_interval': float, 'click_interval': positive_float,
'mouse_hide_wait': float, 'mouse_hide_wait': positive_float,
'cursor_blink_interval': float, 'cursor_blink_interval': positive_float,
'cursor_stop_blinking_after': float, 'cursor_stop_blinking_after': positive_float,
'enabled_layouts': to_layout_names, 'enabled_layouts': to_layout_names,
'remember_window_size': to_bool, 'remember_window_size': to_bool,
'initial_window_width': int, 'initial_window_width': positive_int,
'initial_window_height': int, 'initial_window_height': positive_int,
'use_system_wcwidth': to_bool, 'use_system_wcwidth': to_bool,
'macos_hide_titlebar': to_bool, 'macos_hide_titlebar': to_bool,
} }

View File

@@ -15,7 +15,7 @@ from .fast_data_types import (
GLFW_KEY_LEFT_SUPER, GLFW_KEY_RIGHT_SUPER) GLFW_KEY_LEFT_SUPER, GLFW_KEY_RIGHT_SUPER)
appname = 'kitty' appname = 'kitty'
version = (0, 2, 6) version = (0, 2, 7)
str_version = '.'.join(map(str, version)) str_version = '.'.join(map(str, version))
_plat = sys.platform.lower() _plat = sys.platform.lower()
isosx = 'darwin' in _plat isosx = 'darwin' in _plat
@@ -32,10 +32,7 @@ def _get_config_dir():
candidate = os.path.abspath(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME') or ('~/Library/Preferences' if isosx else '~/.config'))) candidate = os.path.abspath(os.path.expanduser(os.environ.get('XDG_CONFIG_HOME') or ('~/Library/Preferences' if isosx else '~/.config')))
ans = os.path.join(candidate, appname) ans = os.path.join(candidate, appname)
try: os.makedirs(ans, exist_ok=True)
os.makedirs(ans)
except FileExistsError:
pass
return ans return ans

View File

@@ -58,7 +58,7 @@ static struct PyModuleDef module = {
#include <termios.h> #include <termios.h>
PyMODINIT_FUNC EXPORTED PyMODINIT_FUNC
PyInit_fast_data_types(void) { PyInit_fast_data_types(void) {
PyObject *m; PyObject *m;

View File

@@ -13,6 +13,7 @@
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#define UNUSED __attribute__ ((unused)) #define UNUSED __attribute__ ((unused))
#define EXPORTED __attribute__ ((visibility ("default")))
#define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) > (y)) ? (y) : (x)) #define MIN(x, y) (((x) > (y)) ? (y) : (x))
#define xstr(s) str(s) #define xstr(s) str(s)

View File

@@ -20,9 +20,12 @@ PyObject* glfw_get_key_name(PyObject UNUSED *self, PyObject *args);
#ifdef __APPLE__ #ifdef __APPLE__
PyObject* cocoa_hide_titlebar(PyObject UNUSED *self, PyObject *window_id); PyObject* cocoa_hide_titlebar(PyObject UNUSED *self, PyObject *window_id);
PyObject* cocoa_get_lang(PyObject UNUSED *self);
#define COCOA_HIDE_TITLEBAR {"cocoa_hide_titlebar", (PyCFunction)cocoa_hide_titlebar, METH_O, ""}, #define COCOA_HIDE_TITLEBAR {"cocoa_hide_titlebar", (PyCFunction)cocoa_hide_titlebar, METH_O, ""},
#define COCOA_GET_LANG {"cocoa_get_lang", (PyCFunction)cocoa_get_lang, METH_NOARGS, ""},
#else #else
#define COCOA_HIDE_TITLEBAR #define COCOA_HIDE_TITLEBAR
#define COCOA_GET_LANG
#endif #endif
#define GLFW_FUNC_WRAPPERS \ #define GLFW_FUNC_WRAPPERS \
@@ -35,5 +38,6 @@ PyObject* cocoa_hide_titlebar(PyObject UNUSED *self, PyObject *window_id);
{"glfw_post_empty_event", (PyCFunction)glfw_post_empty_event, METH_NOARGS, ""}, \ {"glfw_post_empty_event", (PyCFunction)glfw_post_empty_event, METH_NOARGS, ""}, \
{"glfw_get_physical_dpi", (PyCFunction)glfw_get_physical_dpi, METH_NOARGS, ""}, \ {"glfw_get_physical_dpi", (PyCFunction)glfw_get_physical_dpi, METH_NOARGS, ""}, \
{"glfw_get_key_name", (PyCFunction)glfw_get_key_name, METH_VARARGS, ""}, \ {"glfw_get_key_name", (PyCFunction)glfw_get_key_name, METH_VARARGS, ""}, \
COCOA_HIDE_TITLEBAR COCOA_HIDE_TITLEBAR \
COCOA_GET_LANG

View File

@@ -85,6 +85,7 @@ control_codes.update({
}) })
control_codes[defines.GLFW_KEY_6] = (30,) control_codes[defines.GLFW_KEY_6] = (30,)
control_codes[defines.GLFW_KEY_SLASH] = (31,) control_codes[defines.GLFW_KEY_SLASH] = (31,)
control_codes[defines.GLFW_KEY_SPACE] = (0,)
rmkx_key_map = smkx_key_map.copy() rmkx_key_map = smkx_key_map.copy()

View File

@@ -45,7 +45,7 @@ cursor_shape block
cursor_blink_interval 0.5 cursor_blink_interval 0.5
# Stop blinking cursor after the specified number of seconds of keyboard inactivity. Set to # Stop blinking cursor after the specified number of seconds of keyboard inactivity. Set to
# zero or a negative number to never stop blinking. # zero to never stop blinking.
cursor_stop_blinking_after 15.0 cursor_stop_blinking_after 15.0
# Number of lines of history to keep in memory for scrolling back # Number of lines of history to keep in memory for scrolling back
@@ -59,7 +59,8 @@ scrollback_pager less +G -R
# When viewing scrollback in a new window, put it in a new tab as well # When viewing scrollback in a new window, put it in a new tab as well
scrollback_in_new_tab no scrollback_in_new_tab no
# Wheel scroll multiplier (modify the amount scrolled by the mouse wheel) # Wheel scroll multiplier (modify the amount scrolled by the mouse wheel). Use negative
# numbers to change scroll direction.
wheel_scroll_multiplier 5.0 wheel_scroll_multiplier 5.0
# The interval between successive clicks to detect double/triple clicks (in seconds) # The interval between successive clicks to detect double/triple clicks (in seconds)
@@ -71,7 +72,7 @@ click_interval 0.5
select_by_word_characters :@-./_~?&=%+# select_by_word_characters :@-./_~?&=%+#
# Hide mouse cursor after the specified number of seconds of the mouse not being used. Set to # Hide mouse cursor after the specified number of seconds of the mouse not being used. Set to
# zero or a negative number to disable mouse cursor hiding. # zero to disable mouse cursor hiding.
mouse_hide_wait 3.0 mouse_hide_wait 3.0
# The enabled window layouts. A comma separated list of layout names. The special value * means # The enabled window layouts. A comma separated list of layout names. The special value * means
@@ -120,6 +121,12 @@ term xterm-kitty
# The width (in pts) of window borders. Will be rounded to the nearest number of pixels based on screen resolution. # The width (in pts) of window borders. Will be rounded to the nearest number of pixels based on screen resolution.
window_border_width 1 window_border_width 1
# The window margin (in pts) (blank area outside the border)
window_margin_width 0
# The window padding (in pts) (blank area between the text and the window border)
window_padding_width 0
# The color for the border of the active window # The color for the border of the active window
active_border_color #00ff00 active_border_color #00ff00

View File

@@ -6,25 +6,29 @@ from collections import namedtuple
from itertools import islice from itertools import islice
from .constants import WindowGeometry, viewport_size, cell_size, get_boss from .constants import WindowGeometry, viewport_size, cell_size, get_boss
from .utils import pt_to_px
def available_height(): def available_height():
return viewport_size.height - get_boss().current_tab_bar_height return viewport_size.height - get_boss().current_tab_bar_height
def layout_dimension(length, cell_length, number_of_windows=1, border_length=0, left_align=False): def layout_dimension(length, cell_length, number_of_windows=1, border_length=0, margin_length=0, padding_length=0, left_align=False):
number_of_cells = length // cell_length number_of_cells = length // cell_length
border_length += padding_length
space_needed_for_border = number_of_windows * 2 * border_length space_needed_for_border = number_of_windows * 2 * border_length
space_needed_for_padding = number_of_windows * 2 * margin_length
space_needed = space_needed_for_padding + space_needed_for_border
extra = length - number_of_cells * cell_length extra = length - number_of_cells * cell_length
while extra < space_needed_for_border: while extra < space_needed:
number_of_cells -= 1 number_of_cells -= 1
extra = length - number_of_cells * cell_length extra = length - number_of_cells * cell_length
cells_per_window = number_of_cells // number_of_windows cells_per_window = number_of_cells // number_of_windows
extra -= space_needed_for_border extra -= space_needed
pos = 0 if left_align else (extra // 2) pos = 0 if left_align else (extra // 2)
pos += border_length pos += border_length + margin_length
inner_length = cells_per_window * cell_length inner_length = cells_per_window * cell_length
window_length = 2 * border_length + inner_length window_length = 2 * (border_length + margin_length) + inner_length
extra = number_of_cells - (cells_per_window * number_of_windows) extra = number_of_cells - (cells_per_window * number_of_windows)
while number_of_windows > 0: while number_of_windows > 0:
number_of_windows -= 1 number_of_windows -= 1
@@ -43,6 +47,8 @@ class Layout:
def __init__(self, opts, border_width, windows): def __init__(self, opts, border_width, windows):
self.opts = opts self.opts = opts
self.border_width = border_width self.border_width = border_width
self.margin_width = pt_to_px(opts.window_margin_width)
self.padding_width = pt_to_px(opts.window_padding_width)
# A set of rectangles corresponding to the blank spaces at the edges of # A set of rectangles corresponding to the blank spaces at the edges of
# this layout, i.e. spaces that are not covered by any window # this layout, i.e. spaces that are not covered by any window
self.blank_rects = () self.blank_rects = ()
@@ -76,9 +82,9 @@ def window_geometry(xstart, xnum, ystart, ynum):
return WindowGeometry(left=xstart, top=ystart, xnum=xnum, ynum=ynum, right=xstart + cell_size.width * xnum, bottom=ystart + cell_size.height * ynum) return WindowGeometry(left=xstart, top=ystart, xnum=xnum, ynum=ynum, right=xstart + cell_size.width * xnum, bottom=ystart + cell_size.height * ynum)
def layout_single_window(): def layout_single_window(margin_length, padding_length):
xstart, xnum = next(layout_dimension(viewport_size.width, cell_size.width)) xstart, xnum = next(layout_dimension(viewport_size.width, cell_size.width, margin_length=margin_length, padding_length=padding_length))
ystart, ynum = next(layout_dimension(available_height(), cell_size.height)) ystart, ynum = next(layout_dimension(available_height(), cell_size.height, margin_length=margin_length, padding_length=padding_length))
return window_geometry(xstart, xnum, ystart, ynum) return window_geometry(xstart, xnum, ystart, ynum)
@@ -120,7 +126,7 @@ class Stack(Layout):
def __call__(self, windows, active_window_idx): def __call__(self, windows, active_window_idx):
self.blank_rects = [] self.blank_rects = []
wg = layout_single_window() wg = layout_single_window(self.margin_width, self.padding_width)
for i, w in enumerate(windows): for i, w in enumerate(windows):
w.is_visible_in_layout = i == active_window_idx w.is_visible_in_layout = i == active_window_idx
w.set_geometry(wg) w.set_geometry(wg)
@@ -135,17 +141,23 @@ class Tall(Layout):
def __call__(self, windows, active_window_idx): def __call__(self, windows, active_window_idx):
self.blank_rects = br = [] self.blank_rects = br = []
if len(windows) == 1: if len(windows) == 1:
wg = layout_single_window() wg = layout_single_window(self.margin_width, self.padding_width)
windows[0].set_geometry(wg) windows[0].set_geometry(wg)
self.blank_rects = blank_rects_for_window(windows[0]) self.blank_rects = blank_rects_for_window(windows[0])
return return
xlayout = layout_dimension(viewport_size.width, cell_size.width, 2, self.border_width) xlayout = layout_dimension(
viewport_size.width, cell_size.width, 2, self.border_width,
margin_length=self.margin_width, padding_length=self.padding_width)
xstart, xnum = next(xlayout) xstart, xnum = next(xlayout)
ystart, ynum = next(layout_dimension(available_height(), cell_size.height, 1, self.border_width, left_align=True)) ystart, ynum = next(layout_dimension(
available_height(), cell_size.height, 1, self.border_width, left_align=True,
margin_length=self.margin_width, padding_length=self.padding_width))
windows[0].set_geometry(window_geometry(xstart, xnum, ystart, ynum)) windows[0].set_geometry(window_geometry(xstart, xnum, ystart, ynum))
vh = available_height() vh = available_height()
xstart, xnum = next(xlayout) xstart, xnum = next(xlayout)
ylayout = layout_dimension(available_height(), cell_size.height, len(windows) - 1, self.border_width, left_align=True) ylayout = layout_dimension(
available_height(), cell_size.height, len(windows) - 1, self.border_width, left_align=True,
margin_length=self.margin_width, padding_length=self.padding_width)
for w, (ystart, ynum) in zip(islice(windows, 1, None), ylayout): for w, (ystart, ynum) in zip(islice(windows, 1, None), ylayout):
w.set_geometry(window_geometry(xstart, xnum, ystart, ynum)) w.set_geometry(window_geometry(xstart, xnum, ystart, ynum))
left_blank_rect(windows[0], br, vh), top_blank_rect(windows[0], br, vh), right_blank_rect(windows[-1], br, vh) left_blank_rect(windows[0], br, vh), top_blank_rect(windows[0], br, vh), right_blank_rect(windows[-1], br, vh)

View File

@@ -228,7 +228,19 @@ def on_glfw_error(code, msg):
safe_print('[glfw error] ', msg, file=sys.stderr) safe_print('[glfw error] ', msg, file=sys.stderr)
def ensure_osx_locale():
# Ensure the LANG env var is set. See
# https://github.com/kovidgoyal/kitty/issues/90
from .fast_data_types import cocoa_get_lang
if 'LANG' not in os.environ:
lang = cocoa_get_lang()
if lang is not None:
os.environ['LANG'] = lang + '.UTF-8'
def main(): def main():
if isosx:
ensure_osx_locale()
locale.setlocale(locale.LC_ALL, '') locale.setlocale(locale.LC_ALL, '')
if os.environ.pop('KITTY_LAUNCHED_BY_LAUNCH_SERVICES', if os.environ.pop('KITTY_LAUNCHED_BY_LAUNCH_SERVICES',
None) == '1' and getattr(sys, 'frozen', True): None) == '1' and getattr(sys, 'frozen', True):

View File

@@ -328,9 +328,10 @@ class TabManager:
s.cursor.bold = s.cursor.italic = False s.cursor.bold = s.cursor.italic = False
s.cursor.fg = s.cursor.bg = 0 s.cursor.fg = s.cursor.bg = 0
s.draw('') s.draw('')
if s.cursor.x > s.columns - max_title_length: if s.cursor.x > s.columns - max_title_length and t is not self.tabs[-1]:
s.draw('') s.draw('')
break break
s.erase_in_line(0, False) # Ensure no long titles bleed after the last tab
s.update_cell_data( s.update_cell_data(
sprites.backend, self.color_profile, addressof(self.sprite_map), self.default_fg, self.default_bg, True) sprites.backend, self.color_profile, addressof(self.sprite_map), self.default_fg, self.default_bg, True)
sprites.render_dirty_cells() sprites.render_dirty_cells()

View File

@@ -37,6 +37,13 @@ def wcwidth(c: str) -> int:
return wcwidth_impl(ord(c[0])) return wcwidth_impl(ord(c[0]))
@lru_cache()
def pt_to_px(pts):
dpix, dpiy = get_dpi()['logical']
dpi = (dpix + dpiy) / 2
return round(pts * dpi / 72)
@contextmanager @contextmanager
def timeit(name, do_timing=False): def timeit(name, do_timing=False):
if do_timing: if do_timing:

View File

@@ -115,7 +115,7 @@ def init_env(debug=False, sanitize=False, native_optimizations=True):
cflags = os.environ.get( cflags = os.environ.get(
'OVERRIDE_CFLAGS', ( 'OVERRIDE_CFLAGS', (
'-Wextra -Wno-missing-field-initializers -Wall -std=c99 -D_XOPEN_SOURCE=700' '-Wextra -Wno-missing-field-initializers -Wall -std=c99 -D_XOPEN_SOURCE=700'
' -pedantic-errors -Werror {} {} -D{}DEBUG -fwrapv {} {} -pipe {}' ' -pedantic-errors -Werror {} {} -D{}DEBUG -fwrapv {} {} -pipe {} -fvisibility=hidden'
).format( ).format(
optimize, ' '.join(sanitize_args), ('' if debug else 'N'), stack_protector, missing_braces, '-march=native' optimize, ' '.join(sanitize_args), ('' if debug else 'N'), stack_protector, missing_braces, '-march=native'
if native_optimizations else '' if native_optimizations else ''
@@ -288,10 +288,7 @@ def build(args, native_optimizations=True):
def safe_makedirs(path): def safe_makedirs(path):
try: os.makedirs(path, exist_ok=True)
os.makedirs(path)
except FileExistsError:
pass
def build_test_launcher(args): def build_test_launcher(args):