Implement destruction of OS windows

This commit is contained in:
Kovid Goyal
2017-11-14 21:18:37 +05:30
parent e11a50ae83
commit 2ac8ad39c9
8 changed files with 70 additions and 31 deletions

View File

@@ -5,7 +5,7 @@
from gettext import gettext as _
from weakref import WeakValueDictionary
from .config import MINIMUM_FONT_SIZE
from .config import MINIMUM_FONT_SIZE, cached_values
from .constants import cell_size, set_boss, viewport_size, wakeup
from .fast_data_types import (
GLFW_KEY_DOWN, GLFW_KEY_UP, ChildMonitor, destroy_global_data,
@@ -212,6 +212,10 @@ class Boss:
if w is not None:
w.focus_changed(focused)
def on_os_window_closed(self, os_window_id, viewport_width, viewport_height):
# WIN: Implement this
cached_values['window-size'] = viewport_width, viewport_height
def display_scrollback(self, data):
if self.opts.scrollback_in_new_tab:
self.display_scrollback_in_new_tab(data)

View File

@@ -629,6 +629,7 @@ static PyObject*
main_loop(ChildMonitor *self) {
#define main_loop_doc "The main thread loop"
bool has_open_windows = true;
while (has_open_windows) {
double now = monotonic();
render(now);
@@ -639,13 +640,13 @@ main_loop(ChildMonitor *self) {
global_state.close_all_windows = false;
}
has_open_windows = false;
for (size_t w = 0; w < global_state.num_os_windows; w++) {
if (!should_os_window_close(&global_state.os_windows[w])) {
has_open_windows = true;
break;
}
for (size_t w = global_state.num_os_windows; w > 0; w--) {
OSWindow *os_window = global_state.os_windows + w - 1;
if (should_os_window_close(os_window)) {
int viewport_width, viewport_height;
if (remove_os_window(os_window->id, &viewport_width, &viewport_height)) call_boss(on_os_window_closed, "Kii", os_window->id, viewport_width, viewport_height);
} else has_open_windows = true;
}
}
if (PyErr_Occurred()) return NULL;
Py_RETURN_NONE;

View File

@@ -312,7 +312,7 @@ add_attribute_to_vao(int p, ssize_t vao_idx, const char *name, GLint size, GLenu
add_located_attribute_to_vao(vao_idx, aloc, size, data_type, stride, offset, divisor);
}
static void
void
remove_vao(ssize_t vao_idx) {
VAO *vao = vaos + vao_idx;
while (vao->num_buffers) {

View File

@@ -166,7 +166,6 @@ def run_app(opts, args):
boss.child_monitor.main_loop()
finally:
boss.destroy()
cached_values['window-size'] = viewport_size.width, viewport_size.height
save_cached_values()

View File

@@ -518,8 +518,6 @@ PYWRAP0(create_vao) {
return Py_BuildValue("i", ans);
}
ONE_INT(remove_vao)
ONE_INT(bind_vertex_array)
NO_ARG(unbind_vertex_array)
TWO_INT(unmap_vao_buffer)
@@ -546,7 +544,6 @@ PYWRAP1(layout_sprite_map) {
static PyMethodDef module_methods[] = {
M(compile_program, METH_VARARGS),
MW(create_vao, METH_NOARGS),
MW(remove_vao, METH_O),
MW(bind_vertex_array, METH_O),
MW(unbind_vertex_array, METH_NOARGS),
MW(unmap_vao_buffer, METH_VARARGS),

View File

@@ -9,11 +9,10 @@
GlobalState global_state = {{0}};
#define noop(...)
#define REMOVER(array, qid, count, structure, destroy, capacity) { \
for (size_t i = 0; i < count; i++) { \
if (array[i].id == qid) { \
destroy(array[i]); \
destroy(array + i); \
memset(array + i, 0, sizeof(structure)); \
size_t num_to_right = capacity - count - 1; \
if (num_to_right) memmove(array + i, array + i + 1, num_to_right * sizeof(structure)); \
@@ -102,28 +101,63 @@ update_window_title(id_type os_window_id, id_type tab_id, id_type window_id, PyO
}
static inline void
remove_os_window(id_type os_window_id) {
#define destroy_window(w) Py_CLEAR(w.window_title); Py_CLEAR(w.tab_bar_render_data.screen);
REMOVER(global_state.os_windows, os_window_id, global_state.num_os_windows, OSWindow, destroy_window, global_state.capacity);
#undef destroy_window
destroy_window(Window *w) {
Py_CLEAR(w->render_data.screen); Py_CLEAR(w->title);
remove_vao(w->render_data.vao_idx); remove_vao(w->render_data.gvao_idx);
}
static inline void
remove_tab(id_type os_window_id, id_type id) {
WITH_OS_WINDOW(os_window_id)
REMOVER(os_window->tabs, id, os_window->num_tabs, Tab, noop, os_window->capacity);
END_WITH_OS_WINDOW
remove_window_inner(Tab *tab, id_type id) {
REMOVER(tab->windows, id, tab->num_windows, Window, destroy_window, tab->capacity);
}
static inline void
remove_window(id_type os_window_id, id_type tab_id, id_type id) {
WITH_TAB(os_window_id, tab_id);
#define destroy_window(w) Py_CLEAR(w.render_data.screen); Py_CLEAR(w.title);
REMOVER(tab->windows, id, tab->num_windows, Window, destroy_window, tab->capacity);
#undef destroy_window
remove_window_inner(tab, id);
END_WITH_TAB;
}
static inline void
destroy_tab(Tab *tab) {
for (size_t i = tab->num_windows; i > 0; i--) remove_window_inner(tab, tab->windows[ i - 1].id);
}
static inline void
remove_tab_inner(OSWindow *os_window, id_type id) {
REMOVER(os_window->tabs, id, os_window->num_tabs, Tab, destroy_tab, os_window->capacity);
}
static inline void
remove_tab(id_type os_window_id, id_type id) {
WITH_OS_WINDOW(os_window_id)
remove_tab_inner(os_window, id);
END_WITH_OS_WINDOW
}
static inline void
destroy_os_window(OSWindow *w) {
for (size_t t = w->num_tabs; t > 0; t--) {
Tab *tab = w->tabs + t - 1;
remove_tab_inner(w, tab->id);
}
Py_CLEAR(w->window_title); Py_CLEAR(w->tab_bar_render_data.screen);
remove_vao(w->tab_bar_render_data.vao_idx);
}
bool
remove_os_window(id_type os_window_id, int *viewport_width, int *viewport_height) {
bool found = false;
WITH_OS_WINDOW(os_window_id)
*viewport_width = os_window->viewport_width; *viewport_height = os_window->viewport_height;
found = true;
END_WITH_OS_WINDOW
if (found) {
REMOVER(global_state.os_windows, os_window_id, global_state.num_os_windows, OSWindow, destroy_os_window, global_state.capacity);
}
return found;
}
static inline void
set_active_tab(id_type os_window_id, unsigned int idx) {

View File

@@ -115,6 +115,8 @@ extern GlobalState global_state;
}
void gl_init();
void remove_vao(ssize_t vao_idx);
bool remove_os_window(id_type os_window_id, int*, int*);
void mark_os_window_for_close(OSWindow* w, bool yes);
bool should_os_window_close(OSWindow* w);
bool should_os_window_be_rendered(OSWindow* w);

View File

@@ -15,16 +15,20 @@ from .constants import (
)
from .fast_data_types import (
BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_BACKGROUND_PROGRAM,
CELL_FOREGROUND_PROGRAM, CELL_PROGRAM, CELL_SPECIAL_PROGRAM, set_clipboard_string,
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,
glfw_post_empty_event, init_cell_program, init_cursor_program, remove_vao,
set_window_render_data, update_window_title, update_window_visibility
glfw_post_empty_event, init_cell_program, init_cursor_program,
set_clipboard_string, set_window_render_data, update_window_title,
update_window_visibility
)
from .keys import keyboard_mode_name
from .rgb import to_color
from .terminfo import get_capabilities
from .utils import color_as_int, load_shaders, parse_color_set, sanitize_title, open_url, open_cmd
from .utils import (
color_as_int, load_shaders, open_cmd, open_url, parse_color_set,
sanitize_title
)
class DynamicColor(Enum):
@@ -246,8 +250,6 @@ class Window:
def destroy(self):
if self.vao_id is not None:
remove_vao(self.vao_id)
remove_vao(self.gvao_id)
self.vao_id = self.gvao_id = None
def buffer_as_ansi(self):