mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
Ensure OSWindow references are not stale
This commit is contained in:
19
kitty/glfw.c
19
kitty/glfw.c
@@ -29,13 +29,11 @@ extern bool cocoa_make_window_resizable(void *w);
|
||||
|
||||
static GLFWcursor *standard_cursor = NULL, *click_cursor = NULL, *arrow_cursor = NULL;
|
||||
|
||||
#define GLFW_WINDOW(w) ((GLFWwindow*)((w)->handle))
|
||||
|
||||
static void
|
||||
update_viewport(OSWindow *window) {
|
||||
int w, h;
|
||||
glfwGetFramebufferSize(GLFW_WINDOW(window), &window->viewport_width, &window->viewport_height);
|
||||
glfwGetWindowSize(GLFW_WINDOW(window), &w, &h);
|
||||
glfwGetFramebufferSize(window->handle, &window->viewport_width, &window->viewport_height);
|
||||
glfwGetWindowSize(window->handle, &w, &h);
|
||||
window->viewport_x_ratio = (double)window->viewport_width / (double)w;
|
||||
window->viewport_y_ratio = (double)window->viewport_height / (double)h;
|
||||
window->viewport_size_dirty = true;
|
||||
@@ -43,6 +41,17 @@ update_viewport(OSWindow *window) {
|
||||
|
||||
// callbacks {{{
|
||||
|
||||
void
|
||||
remove_os_window_reference(OSWindow *w) { if (w->handle) glfwSetWindowUserPointer(w->handle, NULL); }
|
||||
|
||||
static inline void
|
||||
update_os_window_references() {
|
||||
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
||||
OSWindow *w = global_state.os_windows + i;
|
||||
if (w->handle) glfwSetWindowUserPointer(w->handle, w);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
set_callback_window(GLFWwindow *w) {
|
||||
global_state.callback_os_window = glfwGetWindowUserPointer(w);
|
||||
@@ -229,8 +238,8 @@ create_os_window(PyObject UNUSED *self, PyObject *args) {
|
||||
OSWindow *w = add_os_window();
|
||||
w->id = ++global_state.os_window_id_counter;
|
||||
w->handle = glfw_window;
|
||||
update_os_window_references();
|
||||
if (logo.pixels && logo.width && logo.height) glfwSetWindowIcon(glfw_window, 1, &logo);
|
||||
glfwSetWindowUserPointer(glfw_window, w);
|
||||
glfwSetCursor(glfw_window, standard_cursor);
|
||||
update_viewport(w);
|
||||
glfwSetFramebufferSizeCallback(glfw_window, framebuffer_size_callback);
|
||||
|
||||
@@ -36,6 +36,20 @@ GlobalState global_state = {{0}};
|
||||
Tab *tab = osw->tabs + t;
|
||||
#define END_WITH_TAB break; }}}}
|
||||
|
||||
#define WITH_OS_WINDOW_REFS \
|
||||
id_type cb_window_id = 0, focused_window_id = 0; \
|
||||
if (global_state.callback_os_window) cb_window_id = global_state.callback_os_window->id; \
|
||||
if (global_state.focused_os_window) focused_window_id = global_state.focused_os_window->id;
|
||||
|
||||
#define END_WITH_OS_WINDOW_REFS \
|
||||
if (cb_window_id || focused_window_id) { \
|
||||
for (size_t wn = 0; wn < global_state.num_os_windows; wn++) { \
|
||||
OSWindow *wp = global_state.os_windows + wn; \
|
||||
if (wp->id == cb_window_id && cb_window_id) global_state.callback_os_window = wp; \
|
||||
if (wp->id == focused_window_id && focused_window_id) global_state.focused_os_window = wp; \
|
||||
}}
|
||||
|
||||
|
||||
OSWindow*
|
||||
current_os_window() {
|
||||
if (global_state.callback_os_window) return global_state.callback_os_window;
|
||||
@@ -59,10 +73,12 @@ os_window_for_kitty_window(id_type kitty_window_id) {
|
||||
|
||||
OSWindow*
|
||||
add_os_window() {
|
||||
WITH_OS_WINDOW_REFS
|
||||
ensure_space_for(&global_state, os_windows, OSWindow, global_state.num_os_windows + 1, capacity, 1, true);
|
||||
OSWindow *ans = global_state.os_windows + global_state.num_os_windows++;
|
||||
memset(ans, 0, sizeof(OSWindow));
|
||||
ans->tab_bar_render_data.vao_idx = create_cell_vao();
|
||||
END_WITH_OS_WINDOW_REFS
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -159,11 +175,14 @@ bool
|
||||
remove_os_window(id_type os_window_id, int *viewport_width, int *viewport_height) {
|
||||
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) {
|
||||
REMOVER(global_state.os_windows, os_window_id, global_state.num_os_windows, OSWindow, destroy_os_window, global_state.capacity);
|
||||
WITH_OS_WINDOW_REFS
|
||||
REMOVER(global_state.os_windows, os_window_id, global_state.num_os_windows, OSWindow, destroy_os_window, global_state.capacity);
|
||||
END_WITH_OS_WINDOW_REFS
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
@@ -129,6 +129,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*);
|
||||
void remove_os_window_reference(OSWindow *w);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user