diff --git a/kitty/boss.py b/kitty/boss.py index fbf3f7aac..72d72fb1a 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -6,11 +6,11 @@ from gettext import gettext as _ from weakref import WeakValueDictionary from .config import MINIMUM_FONT_SIZE, cached_values -from .constants import cell_size, set_boss, viewport_size, wakeup +from .constants import set_boss, wakeup from .fast_data_types import ( GLFW_KEY_DOWN, GLFW_KEY_UP, ChildMonitor, destroy_global_data, destroy_sprite_map, get_clipboard_string, glfw_post_empty_event, - layout_sprite_map, toggle_fullscreen + layout_sprite_map, toggle_fullscreen, viewport_for_window ) from .fonts.render import prerender, resize_fonts, set_font_family from .keys import get_key_map, get_shortcut @@ -24,7 +24,8 @@ from .window import load_shader_programs def initialize_renderer(): load_shader_programs() - layout_sprite_map(cell_size.width, cell_size.height) + cw, ch = viewport_for_window() + layout_sprite_map(cw, ch) prerender() @@ -57,22 +58,19 @@ class DumpCommands: # {{{ class Boss: - def __init__(self, glfw_window, opts, args): + def __init__(self, os_window_id, opts, args): self.window_id_map = WeakValueDictionary() startup_session = create_session(opts, args) self.cursor_blinking = True self.window_is_focused = True - self.glfw_window_title = None self.shutting_down = False self.child_monitor = ChildMonitor( - glfw_window.window_id(), self.on_child_death, DumpCommands(args) if args.dump_commands or args.dump_bytes else None) set_boss(self) self.current_font_size = opts.font_size - cell_size.width, cell_size.height = set_font_family(opts) + set_font_family(opts) self.opts, self.args = opts, args - self.glfw_window = glfw_window initialize_renderer() self.tab_manager = TabManager(opts, args) self.tab_manager.init(startup_session) @@ -119,7 +117,6 @@ class Boss: def on_window_resize(self, window, w, h): # WIN: Port this - viewport_size.width, viewport_size.height = w, h self.tab_manager.resize() def increase_font_size(self): @@ -141,10 +138,10 @@ class Boss: if new_size == self.current_font_size: return self.current_font_size = new_size - w, h = cell_size.width, cell_size.height + w, h = viewport_for_window()[:-2] windows = tuple(filter(None, self.window_id_map.values())) - cell_size.width, cell_size.height = resize_fonts(self.current_font_size) - layout_sprite_map(cell_size.width, cell_size.height) + cw, ch = resize_fonts(self.current_font_size) + layout_sprite_map(cw, ch) prerender() for window in windows: window.screen.rescale_images(w, h) diff --git a/kitty/glfw.c b/kitty/glfw.c index 822ee7010..8b3107f6d 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -205,7 +205,7 @@ create_new_os_window(PyObject UNUSED *self, PyObject *args) { if (glfw_window == NULL) { PyErr_SetString(PyExc_ValueError, "Failed to create GLFWwindow"); return NULL; } if (logo.pixels && logo.width && logo.height) glfwSetWindowIcon(glfw_window, 1, &logo); OSWindow *w = add_os_window(); - w->id = global_state.os_window_counter++; + w->id = ++global_state.os_window_id_counter; glfwSetWindowUserPointer(glfw_window, w); w->handle = glfw_window; glfwSetCursor(glfw_window, standard_cursor); diff --git a/kitty/state.c b/kitty/state.c index 600e439df..a7f3781d6 100644 --- a/kitty/state.c +++ b/kitty/state.c @@ -63,28 +63,30 @@ add_os_window() { return ans; } -static inline void -add_tab(id_type os_window_id, id_type id) { +static inline id_type +add_tab(id_type os_window_id) { WITH_OS_WINDOW(os_window_id) ensure_space_for(os_window, tabs, Tab, os_window->num_tabs + 1, capacity, 1, true); memset(os_window->tabs + os_window->num_tabs, 0, sizeof(Tab)); - os_window->tabs[os_window->num_tabs].id = id; + os_window->tabs[os_window->num_tabs].id = ++global_state.tab_id_counter; os_window->tabs[os_window->num_tabs].border_rects.vao_idx = create_border_vao(); - os_window->num_tabs++; + return os_window->tabs[os_window->num_tabs++].id; END_WITH_OS_WINDOW + return 0; } -static inline void -add_window(id_type os_window_id, id_type tab_id, id_type id, PyObject *title) { +static inline id_type +add_window(id_type os_window_id, id_type tab_id, PyObject *title) { WITH_TAB(os_window_id, tab_id); - ensure_space_for(tab, windows, Window, tab->num_windows + 1, capacity, 1, true); - memset(tab->windows + tab->num_windows, 0, sizeof(Window)); - tab->windows[tab->num_windows].id = id; - tab->windows[tab->num_windows].visible = true; - tab->windows[tab->num_windows].title = title; - Py_INCREF(tab->windows[tab->num_windows].title); - tab->num_windows++; + ensure_space_for(tab, windows, Window, tab->num_windows + 1, capacity, 1, true); + memset(tab->windows + tab->num_windows, 0, sizeof(Window)); + tab->windows[tab->num_windows].id = ++global_state.window_id_counter; + tab->windows[tab->num_windows].visible = true; + tab->windows[tab->num_windows].title = title; + Py_INCREF(tab->windows[tab->num_windows].title); + return tab->windows[tab->num_windows++].id; END_WITH_TAB; + return 0; } static inline void @@ -325,7 +327,8 @@ PYWRAP1(set_tab_bar_render_data) { } PYWRAP1(viewport_for_window) { - id_type os_window_id = PyLong_AsUnsignedLongLong(args); + id_type os_window_id = 0; + PA("|K", &os_window_id); WITH_OS_WINDOW(os_window_id) return Py_BuildValue("iiII", os_window->viewport_width, os_window->viewport_height, global_state.cell_width, global_state.cell_height); END_WITH_OS_WINDOW @@ -387,10 +390,10 @@ PYWRAP1(set_display_state) { Py_RETURN_NONE; } -THREE_ID_OBJ(add_window) THREE_ID_OBJ(update_window_title) THREE_ID(remove_window) -TWO_ID(add_tab) +PYWRAP1(add_tab) { return PyLong_FromUnsignedLongLong(add_tab(PyLong_AsUnsignedLongLong(args))); } +PYWRAP1(add_window) { PyObject *title; id_type a, b; PA("KKO", &a, &b, &title); return PyLong_FromUnsignedLongLong(add_window(a, b, title)); } TWO_ID(remove_tab) KI(set_active_tab) KKI(set_active_window) diff --git a/kitty/state.h b/kitty/state.h index dbefe69d7..6092e0d46 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -106,7 +106,7 @@ typedef struct { Options opts; double logical_dpi_x, logical_dpi_y; - id_type os_window_counter; + id_type os_window_id_counter, tab_id_counter, window_id_counter; float font_sz_in_pts; unsigned int cell_width, cell_height; PyObject *boss; diff --git a/kitty/tabs.py b/kitty/tabs.py index b2ca8fc19..e3b20ab18 100644 --- a/kitty/tabs.py +++ b/kitty/tabs.py @@ -4,26 +4,21 @@ from collections import deque, namedtuple from functools import partial -from itertools import count from .borders import Borders from .child import Child from .config import build_ansi_color_table -from .constants import ( - WindowGeometry, appname, cell_size, get_boss, shell_path, viewport_size -) +from .constants import WindowGeometry, appname, cell_size, get_boss, shell_path from .fast_data_types import ( - DECAWM, Screen, add_tab, add_window, create_cell_vao, - glfw_post_empty_event, remove_tab, remove_window, set_active_tab, - set_active_window, set_tab_bar_render_data, swap_tabs, swap_windows + DECAWM, Screen, add_tab, create_cell_vao, glfw_post_empty_event, + remove_tab, remove_window, set_active_tab, set_active_window, + set_tab_bar_render_data, swap_tabs, swap_windows, viewport_for_window ) from .layout import Rect, all_layouts from .utils import color_as_int from .window import Window, calculate_gl_geometry TabbarData = namedtuple('TabbarData', 'title is_active is_last') -tab_counter = count() -next(tab_counter) def SpecialWindow(cmd, stdin=None, override_title=None): @@ -33,9 +28,10 @@ def SpecialWindow(cmd, stdin=None, override_title=None): class Tab: # {{{ def __init__(self, os_window_id, opts, args, on_title_change, session_tab=None, special_window=None): - self.id = next(tab_counter) self.os_window_id = os_window_id - add_tab(os_window_id, self.id) + self.id = add_tab(os_window_id, self.id) + if not self.id: + raise Exception('No OS window with id {} found, or tab counter has wrapped'.format(os_window_id)) self.opts, self.args = opts, args self.name = getattr(session_tab, 'name', '') self.on_title_change = on_title_change @@ -119,12 +115,9 @@ class Tab: # {{{ def new_window(self, use_shell=True, cmd=None, stdin=None, override_title=None): child = self.launch_child(use_shell=use_shell, cmd=cmd, stdin=stdin) - window = Window(self, child, self.opts, self.args) - if override_title is not None: - window.title = window.override_title = override_title + window = Window(self, child, self.opts, self.args, override_title=override_title) # Must add child before laying out so that resize_pty succeeds get_boss().add_child(window) - add_window(self.os_window_id, self.id, window.id, window.override_title or window.title or appname) self.active_window_idx = self.current_layout.add_window(self.windows, window, self.active_window_idx) set_active_window(self.os_window_id, self.id, self.active_window_idx) self.relayout_borders() @@ -391,7 +384,7 @@ class TabManager: # {{{ @property def tab_bar_layout_data(self): - return viewport_size.width, viewport_size.height, cell_size.width, cell_size.height + return viewport_for_window(self.os_window_id) @property def tab_bar_data(self): diff --git a/kitty/window.py b/kitty/window.py index d0d425c4b..3f0b9a326 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -6,21 +6,19 @@ import sys import weakref from collections import deque from enum import Enum -from itertools import count from .config import build_ansi_color_table, parse_send_text_bytes from .constants import ( - ScreenGeometry, WindowGeometry, appname, cell_size, get_boss, - viewport_size, wakeup + ScreenGeometry, WindowGeometry, appname, get_boss, wakeup ) from .fast_data_types import ( BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_BACKGROUND_PROGRAM, CELL_FOREGROUND_PROGRAM, CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CURSOR_PROGRAM, GRAPHICS_PROGRAM, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, - Screen, compile_program, create_cell_vao, create_graphics_vao, + Screen, add_window, compile_program, create_cell_vao, create_graphics_vao, glfw_post_empty_event, init_cell_program, init_cursor_program, set_clipboard_string, set_window_render_data, update_window_title, - update_window_visibility + update_window_visibility, viewport_for_window ) from .keys import keyboard_mode_name from .rgb import to_color @@ -43,8 +41,6 @@ DYNAMIC_COLOR_CODES = { 19: DynamicColor.highlight_fg, } DYNAMIC_COLOR_CODES.update({k+100: v for k, v in DYNAMIC_COLOR_CODES.items()}) -window_counter = count() -next(window_counter) def calculate_gl_geometry(window_geometry, viewport_width, viewport_height, cell_width, cell_height): @@ -78,19 +74,21 @@ def setup_colors(screen, opts): class Window: - def __init__(self, tab, child, opts, args): - self.id = next(window_counter) + def __init__(self, tab, child, opts, args, override_title=None): + self.override_title = override_title + self.title = self.override_title or appname + self.id = add_window(tab.os_window_id, tab.id, self.title) + if not self.id: + raise Exception('No tab with id: {} in OS Window: {} was found, or the window counter wrapped'.format(tab.id, tab.os_window_id)) self.vao_id = create_cell_vao() self.gvao_id = create_graphics_vao() self.tab_id = tab.id self.os_window_id = tab.os_window_id self.tabref = weakref.ref(tab) - self.override_title = None self.destroyed = False self.click_queue = deque(maxlen=3) self.geometry = WindowGeometry(0, 0, 0, 0, 0, 0) self.needs_layout = True - self.title = appname self.is_visible_in_layout = True self.child, self.opts = child, opts self.screen = Screen(self, 24, 80, opts.scrollback_lines, self.id) @@ -112,7 +110,7 @@ class Window: wakeup() def update_position(self, window_geometry): - self.screen_geometry = sg = calculate_gl_geometry(window_geometry, viewport_size.width, viewport_size.height, cell_size.width, cell_size.height) + self.screen_geometry = sg = calculate_gl_geometry(window_geometry, *viewport_for_window(self.os_window_id)) return sg def set_geometry(self, window_idx, new_geometry):