Ensure cleanup when closing OSWindow

This commit is contained in:
Kovid Goyal 2017-11-15 23:36:26 +05:30
parent 81a465f7bc
commit e1b77f0a59
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
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):
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)
if tm is not None:
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):
if self.opts.scrollback_in_new_tab:
@ -263,6 +263,7 @@ class Boss:
self.child_monitor.shutdown()
wakeup()
self.child_monitor.join()
del self.child_monitor
for tm in self.os_window_map.values():
tm.destroy()
self.os_window_map = {}

View File

@ -336,11 +336,8 @@ parse_input(ChildMonitor *self) {
}
}
static PyObject *
mark_for_close(ChildMonitor *self, PyObject *args) {
#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;
static inline void
mark_child_for_close(ChildMonitor *self, id_type window_id) {
children_mutex(lock);
for (size_t i = 0; i < self->count; i++) {
if (children[i].id == window_id) {
@ -350,6 +347,15 @@ mark_for_close(ChildMonitor *self, PyObject *args) {
}
children_mutex(unlock);
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;
}
@ -640,8 +646,12 @@ main_loop(ChildMonitor *self) {
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);
call_boss(on_os_window_closed, "Kii", os_window->id, os_window->viewport_width, os_window->viewport_width);
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;
}
}

View File

@ -145,7 +145,7 @@ remove_window(id_type os_window_id, id_type tab_id, id_type id) {
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);
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);
free(tab->border_rects.rect_buf); tab->border_rects.rect_buf = NULL;
free(tab->windows); tab->windows = NULL;
@ -175,11 +175,10 @@ destroy_os_window(OSWindow *w) {
}
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;
WITH_OS_WINDOW(os_window_id)
remove_os_window_reference(os_window);
*viewport_width = os_window->viewport_width; *viewport_height = os_window->viewport_height;
found = true;
END_WITH_OS_WINDOW
if (found) {

View File

@ -127,7 +127,7 @@ 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*);
bool remove_os_window(id_type os_window_id);
void remove_os_window_reference(OSWindow *w);
void mark_os_window_for_close(OSWindow* w, bool yes);
bool should_os_window_close(OSWindow* w);

View File

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