mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-19 06:54:58 +02:00
Fix rendering when multiple windows are visible
This commit is contained in:
@@ -213,6 +213,7 @@ class CharGrid:
|
||||
|
||||
def __init__(self, screen, opts):
|
||||
self.buffer_lock = Lock()
|
||||
self.buffer_id = None
|
||||
self.current_selection = Selection()
|
||||
self.last_rendered_selection = self.current_selection.limits(0, screen.lines, screen.columns)
|
||||
self.render_buf_is_dirty = True
|
||||
@@ -409,6 +410,8 @@ class CharGrid:
|
||||
sg = self.render_data
|
||||
if sg is None:
|
||||
return
|
||||
if self.buffer_id is None:
|
||||
self.buffer_id = sprites.add_sprite_map()
|
||||
buf = self.render_buf
|
||||
start, end = sel = self.current_selection.limits(self.scrolled_by, self.screen.lines, self.screen.columns)
|
||||
if start != end:
|
||||
@@ -417,12 +420,13 @@ class CharGrid:
|
||||
memmove(buf, self.render_buf, sizeof(type(buf)))
|
||||
self.screen.apply_selection(addressof(buf), start[0], start[1], end[0], end[1], self.selection_foreground, self.selection_background)
|
||||
if self.render_buf_is_dirty or self.last_rendered_selection != sel:
|
||||
sprites.set_sprite_map(buf)
|
||||
sprites.set_sprite_map(self.buffer_id, buf)
|
||||
self.render_buf_is_dirty = False
|
||||
self.last_rendered_selection = sel
|
||||
return sg
|
||||
|
||||
def render_cells(self, sg, cell_program, sprites):
|
||||
sprites.bind_sprite_map(self.buffer_id)
|
||||
ul = cell_program.uniform_location
|
||||
glUniform2ui(ul('dimensions'), sg.xnum, sg.ynum)
|
||||
glUniform4f(ul('steps'), sg.xstart, sg.ystart, sg.dx, sg.dy)
|
||||
|
||||
@@ -46,7 +46,7 @@ class Sprites:
|
||||
self.first_cell_cache = {}
|
||||
self.second_cell_cache = {}
|
||||
self.x = self.y = self.z = 0
|
||||
self.texture_id = self.buffer_id = self.buffer_texture_id = None
|
||||
self.texture_id = self.buffer_texture_id = None
|
||||
self.last_num_of_layers = 1
|
||||
self.last_ynum = -1
|
||||
self.texture_unit = GL_TEXTURE0
|
||||
@@ -135,18 +135,25 @@ class Sprites:
|
||||
self.texture_id = None
|
||||
if self.buffer_texture_id is not None:
|
||||
glDeleteTexture(self.buffer_texture_id)
|
||||
if self.buffer_id is not None:
|
||||
glDeleteBuffer(self.buffer_id)
|
||||
|
||||
def ensure_state(self):
|
||||
if self.texture_id is None:
|
||||
self.realloc_texture()
|
||||
self.buffer_id = glGenBuffers(1)
|
||||
self.buffer_texture_id = glGenTextures(1)
|
||||
self.buffer_texture_unit = GL_TEXTURE1
|
||||
|
||||
def set_sprite_map(self, data, usage=GL_STREAM_DRAW):
|
||||
glNamedBufferData(self.buffer_id, sizeof(data), addressof(data), usage)
|
||||
def add_sprite_map(self):
|
||||
return glGenBuffers(1)
|
||||
|
||||
def set_sprite_map(self, buf_id, data, usage=GL_STREAM_DRAW):
|
||||
glNamedBufferData(buf_id, sizeof(data), addressof(data), usage)
|
||||
|
||||
def bind_sprite_map(self, buf_id):
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, buf_id)
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32UI, buf_id)
|
||||
|
||||
def destroy_sprite_map(self, buf_id):
|
||||
glDeleteBuffer(buf_id)
|
||||
|
||||
def __enter__(self):
|
||||
self.ensure_state()
|
||||
@@ -155,8 +162,6 @@ class Sprites:
|
||||
|
||||
glActiveTexture(self.buffer_texture_unit)
|
||||
glBindTexture(GL_TEXTURE_BUFFER, self.buffer_texture_id)
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, self.buffer_id)
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGB32UI, self.buffer_id)
|
||||
|
||||
def __exit__(self, *a):
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0)
|
||||
|
||||
@@ -266,7 +266,7 @@ class TabManager(Thread):
|
||||
glfw_post_empty_event()
|
||||
|
||||
def close_window(self, window=None):
|
||||
' Can be called in either thread, will first kill the child (with SIGHUP), then remove the window from the gui '
|
||||
' Can be called in either thread, will first kill the child, then remove the window from the gui '
|
||||
if window is None:
|
||||
window = self.active_window
|
||||
if current_thread() is main_thread:
|
||||
@@ -276,6 +276,18 @@ class TabManager(Thread):
|
||||
window.destroy()
|
||||
self.queue_ui_action(self.gui_close_window, window)
|
||||
|
||||
def close_tab(self, tab=None):
|
||||
' Can be called in either thread, will first kill all children, then remove the tab from the gui '
|
||||
if tab is None:
|
||||
tab = self.active_tab
|
||||
if current_thread() is main_thread:
|
||||
self.queue_action(self.close_tab, tab)
|
||||
else:
|
||||
for window in tab:
|
||||
self.remove_child_fd(window.child_fd)
|
||||
window.destroy()
|
||||
self.queue_ui_action(self.gui_close_window, window)
|
||||
|
||||
def run(self):
|
||||
if self.args.profile:
|
||||
import cProfile
|
||||
@@ -478,6 +490,9 @@ class TabManager(Thread):
|
||||
active.char_grid.render_cursor(rd, self.cursor_program)
|
||||
|
||||
def gui_close_window(self, window):
|
||||
if window.char_grid.buffer_id is not None:
|
||||
self.sprites.destroy_sprite_map(window.char_grid.buffer_id)
|
||||
window.char_grid.buffer_id = None
|
||||
for tab in self.tabs:
|
||||
if window in tab:
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user