Allow specifying initial window size in number of cells
This commit is contained in:
parent
fe8cf46d56
commit
997c244664
@ -12,7 +12,7 @@ from weakref import WeakValueDictionary
|
||||
|
||||
from .cli import create_opts, parse_args
|
||||
from .config import (
|
||||
MINIMUM_FONT_SIZE, initial_window_size, prepare_config_file_for_editing
|
||||
MINIMUM_FONT_SIZE, initial_window_size_func, prepare_config_file_for_editing
|
||||
)
|
||||
from .config_utils import to_cmdline
|
||||
from .constants import (
|
||||
@ -99,11 +99,11 @@ class Boss:
|
||||
startup_session = create_session(opts, args)
|
||||
self.add_os_window(startup_session, os_window_id=os_window_id)
|
||||
|
||||
def add_os_window(self, startup_session, os_window_id=None, wclass=None, wname=None, size=None, startup_id=None):
|
||||
def add_os_window(self, startup_session, os_window_id=None, wclass=None, wname=None, opts_for_size=None, startup_id=None):
|
||||
if os_window_id is None:
|
||||
w, h = initial_window_size(self.opts, self.cached_values) if size is None else size
|
||||
opts_for_size = opts_for_size or self.opts
|
||||
cls = wclass or self.args.cls or appname
|
||||
os_window_id = create_os_window(w, h, appname, wname or self.args.name or cls, cls)
|
||||
os_window_id = create_os_window(initial_window_size_func(opts_for_size, self.cached_values), appname, wname or self.args.name or cls, cls)
|
||||
if startup_id:
|
||||
ctx = init_startup_notification(os_window_id, startup_id)
|
||||
show_window(os_window_id)
|
||||
@ -238,7 +238,7 @@ class Boss:
|
||||
if not os.path.isabs(args.directory):
|
||||
args.directory = os.path.join(msg['cwd'], args.directory)
|
||||
session = create_session(opts, args, respect_cwd=True)
|
||||
self.add_os_window(session, wclass=args.cls, wname=args.name, size=initial_window_size(opts, self.cached_values), startup_id=startup_id)
|
||||
self.add_os_window(session, wclass=args.cls, wname=args.name, opts_for_size=opts, startup_id=startup_id)
|
||||
else:
|
||||
log_error('Unknown message received from peer, ignoring')
|
||||
|
||||
|
||||
@ -361,6 +361,12 @@ def url_style(x):
|
||||
return url_style.map.get(x, url_style.map['curly'])
|
||||
|
||||
|
||||
def window_size(val):
|
||||
val = val.lower()
|
||||
unit = 'cells' if val.endswith('c') else 'px'
|
||||
return positive_int(val.rstrip('c')), unit
|
||||
|
||||
|
||||
url_style.map = dict(
|
||||
((v, i) for i, v in enumerate('none single double curly'.split()))
|
||||
)
|
||||
@ -393,8 +399,8 @@ type_map = {
|
||||
'cursor_stop_blinking_after': positive_float,
|
||||
'enabled_layouts': to_layout_names,
|
||||
'remember_window_size': to_bool,
|
||||
'initial_window_width': positive_int,
|
||||
'initial_window_height': positive_int,
|
||||
'initial_window_width': window_size,
|
||||
'initial_window_height': window_size,
|
||||
'macos_hide_titlebar': to_bool,
|
||||
'macos_hide_from_tasks': to_bool,
|
||||
'macos_option_as_alt': to_bool,
|
||||
@ -549,15 +555,34 @@ def cached_values_for(name):
|
||||
err))
|
||||
|
||||
|
||||
def initial_window_size(opts, cached_values):
|
||||
w, h = opts.initial_window_width, opts.initial_window_height
|
||||
def initial_window_size_func(opts, cached_values):
|
||||
|
||||
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):
|
||||
return w, h
|
||||
return initial_window_size
|
||||
except Exception:
|
||||
log_error('Invalid cached window size, ignoring')
|
||||
return w, h
|
||||
|
||||
w, w_unit = opts.initial_window_width
|
||||
h, h_unit = opts.initial_window_height
|
||||
|
||||
def get_window_size(cell_width, cell_height, dpi_x, dpi_y):
|
||||
if w_unit == 'cells':
|
||||
width = cell_width * w + (dpi_x / 72) * (opts.window_margin_width + opts.window_padding_width) + 1
|
||||
else:
|
||||
width = w
|
||||
if h_unit == 'cells':
|
||||
height = cell_height * h + (dpi_y / 72) * (opts.window_margin_width + opts.window_padding_width) + 1
|
||||
else:
|
||||
height = h
|
||||
return width, height
|
||||
|
||||
return get_window_size
|
||||
|
||||
|
||||
def commented_out_default_config():
|
||||
|
||||
@ -1123,11 +1123,10 @@ initialize_font_group(FontGroup *fg) {
|
||||
send_prerendered_sprites(fg);
|
||||
}
|
||||
|
||||
void
|
||||
load_fonts_for_window(OSWindow *w) {
|
||||
w->fonts_data = NULL;
|
||||
FontGroup *fg = font_group_for(w->font_sz_in_pts, w->logical_dpi_x, w->logical_dpi_y);
|
||||
w->fonts_data = (FONTS_DATA_HANDLE)fg;
|
||||
FONTS_DATA_HANDLE
|
||||
load_fonts_data(double font_sz_in_pts, double dpi_x, double dpi_y) {
|
||||
FontGroup *fg = font_group_for(font_sz_in_pts, dpi_x, dpi_y);
|
||||
return (FONTS_DATA_HANDLE)fg;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
53
kitty/glfw.c
53
kitty/glfw.c
@ -303,11 +303,10 @@ current_monitor(GLFWwindow *window) {
|
||||
return bestmonitor;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_os_window_dpi(OSWindow *w) {
|
||||
static inline void
|
||||
get_window_dpi(GLFWwindow *w, double *x, double *y) {
|
||||
GLFWmonitor *monitor = NULL;
|
||||
if (w && w->handle) { monitor = current_monitor(w->handle); }
|
||||
if (w) monitor = current_monitor(w);
|
||||
if (monitor == NULL) monitor = glfwGetPrimaryMonitor();
|
||||
float xscale = 1, yscale = 1;
|
||||
if (monitor) glfwGetMonitorContentScale(monitor, &xscale, &yscale);
|
||||
@ -316,8 +315,13 @@ set_os_window_dpi(OSWindow *w) {
|
||||
#else
|
||||
double factor = 96.0;
|
||||
#endif
|
||||
w->logical_dpi_x = xscale * factor;
|
||||
w->logical_dpi_y = yscale * factor;
|
||||
*x = xscale * factor;
|
||||
*y = yscale * factor;
|
||||
}
|
||||
|
||||
void
|
||||
set_os_window_dpi(OSWindow *w) {
|
||||
get_window_dpi(w->handle, &w->logical_dpi_x, &w->logical_dpi_y);
|
||||
}
|
||||
|
||||
static bool is_first_window = true;
|
||||
@ -341,10 +345,10 @@ set_titlebar_color(OSWindow *w, color_type color) {
|
||||
|
||||
static PyObject*
|
||||
create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
int width, height, x = -1, y = -1;
|
||||
int x = -1, y = -1;
|
||||
char *title, *wm_class_class, *wm_class_name;
|
||||
PyObject *load_programs = NULL;
|
||||
if (!PyArg_ParseTuple(args, "iisss|Oii", &width, &height, &title, &wm_class_name, &wm_class_class, &load_programs, &x, &y)) return NULL;
|
||||
PyObject *load_programs = NULL, *get_window_size;
|
||||
if (!PyArg_ParseTuple(args, "Osss|Oii", &get_window_size, &title, &wm_class_name, &wm_class_class, &load_programs, &x, &y)) return NULL;
|
||||
|
||||
if (is_first_window) {
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
@ -379,21 +383,32 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
}
|
||||
bool want_semi_transparent = (1.0 - OPT(background_opacity) >= 0.01) || OPT(dynamic_background_opacity);
|
||||
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, want_semi_transparent);
|
||||
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, global_state.num_os_windows ? global_state.os_windows[0].handle : NULL);
|
||||
if (glfw_window == NULL) {
|
||||
log_error("Failed to create a window at size: %dx%d, using a standard size instead.", width, height);
|
||||
glfw_window = glfwCreateWindow(640, 400, title, NULL, global_state.num_os_windows ? global_state.os_windows[0].handle : NULL);
|
||||
// We use a temp window to avoid the need to set the window size after
|
||||
// creation, which causes a resize event and all the associated processing.
|
||||
// The temp window is used to get the DPI.
|
||||
GLFWwindow *temp_window = glfwCreateWindow(640, 480, "temp", NULL, global_state.num_os_windows ? global_state.os_windows[0].handle : NULL);
|
||||
double dpi_x, dpi_y;
|
||||
get_window_dpi(temp_window, &dpi_x, &dpi_y);
|
||||
glfwMakeContextCurrent(temp_window);
|
||||
if (is_first_window) {
|
||||
gl_init();
|
||||
PyObject *ret = PyObject_CallFunction(load_programs, "i", glfwGetWindowAttrib(temp_window, GLFW_TRANSPARENT_FRAMEBUFFER));
|
||||
if (ret == NULL) return NULL;
|
||||
Py_DECREF(ret);
|
||||
}
|
||||
FONTS_DATA_HANDLE fonts_data = load_fonts_data(global_state.font_sz_in_pts, dpi_x, dpi_y);
|
||||
PyObject *ret = PyObject_CallFunction(get_window_size, "IIdd", fonts_data->cell_width, fonts_data->cell_height, fonts_data->logical_dpi_x, fonts_data->logical_dpi_y);
|
||||
if (ret == NULL) return NULL;
|
||||
int width = PyLong_AsLong(PyTuple_GET_ITEM(ret, 0)), height = PyLong_AsLong(PyTuple_GET_ITEM(ret, 1));
|
||||
Py_CLEAR(ret);
|
||||
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, temp_window);
|
||||
glfwDestroyWindow(temp_window); temp_window = NULL;
|
||||
if (glfw_window == NULL) { PyErr_SetString(PyExc_ValueError, "Failed to create GLFWwindow"); return NULL; }
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
if (x != -1 && y != -1) glfwSetWindowPos(glfw_window, x, y);
|
||||
current_os_window_ctx = glfw_window;
|
||||
glfwSwapInterval(OPT(sync_to_monitor) ? 1 : 0); // a value of 1 makes mouse selection laggy
|
||||
if (is_first_window) {
|
||||
gl_init();
|
||||
PyObject *ret = PyObject_CallFunction(load_programs, "i", glfwGetWindowAttrib(glfw_window, GLFW_TRANSPARENT_FRAMEBUFFER));
|
||||
if (ret == NULL) return NULL;
|
||||
Py_DECREF(ret);
|
||||
#ifdef __APPLE__
|
||||
cocoa_create_global_menu();
|
||||
// This needs to be done only after the first window has been created, because glfw only sets the activation policy once upon initialization.
|
||||
@ -413,8 +428,8 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
OSWindow *q = global_state.os_windows + i;
|
||||
q->is_focused = q == w ? true : false;
|
||||
}
|
||||
set_os_window_dpi(w);
|
||||
load_fonts_for_window(w);
|
||||
w->logical_dpi_x = dpi_x; w->logical_dpi_y = dpi_y;
|
||||
w->fonts_data = fonts_data;
|
||||
if (logo.pixels && logo.width && logo.height) glfwSetWindowIcon(glfw_window, 1, &logo);
|
||||
glfwSetCursor(glfw_window, standard_cursor);
|
||||
update_os_window_viewport(w, false);
|
||||
|
||||
@ -177,7 +177,8 @@ bell_on_tab yes
|
||||
# Window layout {{{
|
||||
# If enabled, the window size will be remembered so that new instances of kitty will have the same
|
||||
# size as the previous instance. If disabled, the window will initially have size configured
|
||||
# by initial_window_width/height, in pixels.
|
||||
# by initial_window_width/height, in pixels. You can use a suffix of "c" on the width/height values
|
||||
# to have them interpreted as number of cells instead of pixels.
|
||||
remember_window_size yes
|
||||
initial_window_width 640
|
||||
initial_window_height 400
|
||||
|
||||
@ -10,7 +10,7 @@ from contextlib import contextmanager
|
||||
from .borders import load_borders_program
|
||||
from .boss import Boss
|
||||
from .cli import create_opts, parse_args
|
||||
from .config import cached_values_for, initial_window_size
|
||||
from .config import cached_values_for, initial_window_size_func
|
||||
from .constants import (
|
||||
appname, config_dir, glfw_path, is_macos, is_wayland, logo_data_file
|
||||
)
|
||||
@ -44,8 +44,10 @@ def run_app(opts, args):
|
||||
set_options(opts, is_wayland, args.debug_gl, args.debug_font_fallback)
|
||||
set_font_family(opts)
|
||||
with cached_values_for(run_app.cached_values_name) as cached_values:
|
||||
w, h = run_app.initial_window_size(opts, cached_values)
|
||||
window_id = create_os_window(w, h, appname, args.name or args.cls or appname, args.cls or appname, load_all_shaders)
|
||||
window_id = create_os_window(
|
||||
run_app.initial_window_size_func(opts, cached_values),
|
||||
appname, args.name or args.cls or appname,
|
||||
args.cls or appname, load_all_shaders)
|
||||
run_app.first_window_callback(opts, window_id)
|
||||
startup_ctx = init_startup_notification(window_id)
|
||||
show_window(window_id)
|
||||
@ -63,7 +65,7 @@ def run_app(opts, args):
|
||||
|
||||
run_app.cached_values_name = 'main'
|
||||
run_app.first_window_callback = lambda opts, window_id: None
|
||||
run_app.initial_window_size = initial_window_size
|
||||
run_app.initial_window_size_func = initial_window_size_func
|
||||
|
||||
|
||||
def ensure_osx_locale():
|
||||
|
||||
@ -626,7 +626,8 @@ PYWRAP1(os_window_font_size) {
|
||||
WITH_OS_WINDOW(os_window_id)
|
||||
if (new_sz > 0 && (force || new_sz != os_window->font_sz_in_pts)) {
|
||||
os_window->font_sz_in_pts = new_sz;
|
||||
load_fonts_for_window(os_window);
|
||||
os_window->fonts_data = NULL;
|
||||
os_window->fonts_data = load_fonts_data(os_window->font_sz_in_pts, os_window->logical_dpi_x, os_window->logical_dpi_y);
|
||||
resize_screen(os_window, os_window->tab_bar_render_data.screen, false);
|
||||
for (size_t ti = 0; ti < os_window->num_tabs; ti++) {
|
||||
Tab *tab = os_window->tabs + ti;
|
||||
|
||||
@ -186,4 +186,4 @@ void free_texture(uint32_t*);
|
||||
void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool);
|
||||
void send_sprite_to_gpu(FONTS_DATA_HANDLE fg, unsigned int, unsigned int, unsigned int, pixel*);
|
||||
void set_titlebar_color(OSWindow *w, color_type color);
|
||||
void load_fonts_for_window(OSWindow*);
|
||||
FONTS_DATA_HANDLE load_fonts_data(double, double, double);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user