Ensure cleanup when closing OSWindow

This commit is contained in:
Kovid Goyal
2017-11-15 23:36:26 +05:30
parent 81a465f7bc
commit e1b77f0a59
5 changed files with 24 additions and 13 deletions

View File

@@ -224,11 +224,11 @@ class Boss:
def on_os_window_closed(self, os_window_id, viewport_width, viewport_height): def on_os_window_closed(self, os_window_id, viewport_width, viewport_height):
cached_values['window-size'] = viewport_width, viewport_height cached_values['window-size'] = viewport_width, viewport_height
for window_id in tuple(w.id for w in self.window_id_map.values() if getattr(w, 'os_window_id', None) == os_window_id):
self.window_id_map.pop(window_id, None)
tm = self.os_window_map.pop(os_window_id, None) tm = self.os_window_map.pop(os_window_id, None)
if tm is not None: if tm is not None:
tm.destroy() tm.destroy()
for window_id in tuple(w.id for w in self.window_id_map.values() if getattr(w, 'os_window_id', None) == os_window_id):
self.window_id_map.pop(window_id, None)
def display_scrollback(self, data): def display_scrollback(self, data):
if self.opts.scrollback_in_new_tab: if self.opts.scrollback_in_new_tab:
@@ -263,6 +263,7 @@ class Boss:
self.child_monitor.shutdown() self.child_monitor.shutdown()
wakeup() wakeup()
self.child_monitor.join() self.child_monitor.join()
del self.child_monitor
for tm in self.os_window_map.values(): for tm in self.os_window_map.values():
tm.destroy() tm.destroy()
self.os_window_map = {} self.os_window_map = {}

View File

@@ -336,11 +336,8 @@ parse_input(ChildMonitor *self) {
} }
} }
static PyObject * static inline void
mark_for_close(ChildMonitor *self, PyObject *args) { mark_child_for_close(ChildMonitor *self, id_type window_id) {
#define mark_for_close_doc "Mark a child to be removed from the child monitor"
unsigned long window_id;
if (!PyArg_ParseTuple(args, "k", &window_id)) return NULL;
children_mutex(lock); children_mutex(lock);
for (size_t i = 0; i < self->count; i++) { for (size_t i = 0; i < self->count; i++) {
if (children[i].id == window_id) { if (children[i].id == window_id) {
@@ -350,6 +347,15 @@ mark_for_close(ChildMonitor *self, PyObject *args) {
} }
children_mutex(unlock); children_mutex(unlock);
wakeup_io_loop(); wakeup_io_loop();
}
static PyObject *
mark_for_close(ChildMonitor *self, PyObject *args) {
#define mark_for_close_doc "Mark a child to be removed from the child monitor"
id_type window_id;
if (!PyArg_ParseTuple(args, "K", &window_id)) return NULL;
mark_child_for_close(self, window_id);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@@ -640,8 +646,12 @@ main_loop(ChildMonitor *self) {
for (size_t w = global_state.num_os_windows; w > 0; w--) { for (size_t w = global_state.num_os_windows; w > 0; w--) {
OSWindow *os_window = global_state.os_windows + w - 1; OSWindow *os_window = global_state.os_windows + w - 1;
if (should_os_window_close(os_window)) { if (should_os_window_close(os_window)) {
int viewport_width, viewport_height; call_boss(on_os_window_closed, "Kii", os_window->id, os_window->viewport_width, os_window->viewport_width);
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); for (size_t t=0; t < os_window->num_tabs; t++) {
Tab *tab = os_window->tabs + t;
for (size_t w = 0; w < tab->num_windows; w++) mark_child_for_close(self, tab->windows[w].id);
}
remove_os_window(os_window->id);
} else has_open_windows = true; } else has_open_windows = true;
} }
} }

View File

@@ -145,7 +145,7 @@ remove_window(id_type os_window_id, id_type tab_id, id_type id) {
static inline void static inline void
destroy_tab(Tab *tab) { destroy_tab(Tab *tab) {
for (size_t i = tab->num_windows; i > 0; i--) remove_window_inner(tab, tab->windows[ i - 1].id); for (size_t i = tab->num_windows; i > 0; i--) remove_window_inner(tab, tab->windows[i - 1].id);
remove_vao(tab->border_rects.vao_idx); remove_vao(tab->border_rects.vao_idx);
free(tab->border_rects.rect_buf); tab->border_rects.rect_buf = NULL; free(tab->border_rects.rect_buf); tab->border_rects.rect_buf = NULL;
free(tab->windows); tab->windows = NULL; free(tab->windows); tab->windows = NULL;
@@ -175,11 +175,10 @@ destroy_os_window(OSWindow *w) {
} }
bool bool
remove_os_window(id_type os_window_id, int *viewport_width, int *viewport_height) { remove_os_window(id_type os_window_id) {
bool found = false; bool found = false;
WITH_OS_WINDOW(os_window_id) WITH_OS_WINDOW(os_window_id)
remove_os_window_reference(os_window); remove_os_window_reference(os_window);
*viewport_width = os_window->viewport_width; *viewport_height = os_window->viewport_height;
found = true; found = true;
END_WITH_OS_WINDOW END_WITH_OS_WINDOW
if (found) { if (found) {

View File

@@ -127,7 +127,7 @@ extern GlobalState global_state;
void gl_init(); void gl_init();
void remove_vao(ssize_t vao_idx); void remove_vao(ssize_t vao_idx);
bool remove_os_window(id_type os_window_id, int*, int*); bool remove_os_window(id_type os_window_id);
void remove_os_window_reference(OSWindow *w); void remove_os_window_reference(OSWindow *w);
void mark_os_window_for_close(OSWindow* w, bool yes); void mark_os_window_for_close(OSWindow* w, bool yes);
bool should_os_window_close(OSWindow* w); bool should_os_window_close(OSWindow* w);

View File

@@ -419,4 +419,5 @@ class TabManager: # {{{
t.destroy() t.destroy()
self.tab_bar.destroy() self.tab_bar.destroy()
del self.tab_bar del self.tab_bar
del self.tabs
# }}} # }}}