Allocate window management structures on the heap

This commit is contained in:
Kovid Goyal 2017-11-14 18:01:34 +05:30
parent 47446975ac
commit 974950e7de
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 25 additions and 18 deletions

View File

@ -246,7 +246,7 @@ typedef struct {
if ((base)->capacity < num) { \
size_t _newcap = MAX(initial_cap, MAX(2 * (base)->capacity, num)); \
(base)->array = realloc((base)->array, sizeof(type) * _newcap); \
if ((base)->array == NULL) fatal("Out of memory while ensuring space in array"); \
if ((base)->array == NULL) fatal("Out of memory while ensuring space for %zu elements in array of %s", (size_t)num, #type); \
if (zero_mem) memset((base)->array + (base)->capacity, 0, sizeof(type) * (_newcap - (base)->capacity)); \
(base)->capacity = _newcap; \
}

View File

@ -177,7 +177,7 @@ create_new_os_window(PyObject UNUSED *self, PyObject *args) {
}
GLFWwindow *glfw_window = glfwCreateWindow(width, height, title, NULL, global_state.num_os_windows ? global_state.os_windows[0].handle : NULL);
if (glfw_window == NULL) { Py_CLEAR(self); PyErr_SetString(PyExc_ValueError, "Failed to create GLFWwindow"); return NULL; }
OSWindow *w = global_state.os_windows + global_state.num_os_windows++;
OSWindow *w = add_os_window();
w->window_id = global_state.os_window_counter++;
glfwSetWindowUserPointer(glfw_window, w);
w->handle = glfw_window;

View File

@ -8,18 +8,16 @@
#include "state.h"
GlobalState global_state = {{0}};
static const Tab EMPTY_TAB = {0};
static const Window EMPTY_WINDOW = {0};
#define ensure_can_add(array, count, msg) if (count >= sizeof(array)/sizeof(array[0]) - 1) fatal(msg);
#define noop(...)
#define REMOVER(array, qid, count, empty, structure, destroy) { \
#define REMOVER(array, qid, count, structure, destroy) { \
size_t capacity = sizeof(array)/sizeof(array[0]); \
for (size_t i = 0; i < count; i++) { \
if (array[i].id == qid) { \
destroy(array[i]); \
array[i] = empty; \
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)); \
(count)--; \
@ -61,11 +59,19 @@ os_window_for_kitty_window(id_type kitty_window_id) {
return NULL;
}
OSWindow*
add_os_window() {
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));
return ans;
}
static inline void
add_tab(id_type os_window_id, id_type id) {
WITH_OS_WINDOW(os_window_id)
ensure_can_add(os_window->tabs, os_window->num_tabs, "Too many children (add_tab)");
os_window->tabs[os_window->num_tabs] = EMPTY_TAB;
ensure_space_for(os_window, tabs, Tab, os_window->num_tabs + 1, capacity, 1, true);
memset(os_window->tabs + os_window->num_tabs, 0, sizeof(Tab));
os_window->tabs[os_window->num_tabs].id = id;
os_window->num_tabs++;
END_WITH_OS_WINDOW
@ -74,8 +80,8 @@ add_tab(id_type os_window_id, id_type id) {
static inline void
add_window(id_type os_window_id, id_type tab_id, id_type id, PyObject *title) {
WITH_TAB(os_window_id, tab_id);
ensure_can_add(tab->windows, tab->num_windows, "Too many children (add_window)");
tab->windows[tab->num_windows] = EMPTY_WINDOW;
ensure_space_for(tab, windows, Window, tab->num_windows + 1, capacity, 1, true);
memset(tab->windows + tab->num_windows, 0, sizeof(Window));
tab->windows[tab->num_windows].id = id;
tab->windows[tab->num_windows].visible = true;
tab->windows[tab->num_windows].title = title;
@ -101,7 +107,7 @@ update_window_title(id_type os_window_id, id_type tab_id, id_type window_id, PyO
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, EMPTY_TAB, Tab, noop);
REMOVER(os_window->tabs, id, os_window->num_tabs, Tab, noop);
END_WITH_OS_WINDOW
}
@ -109,7 +115,7 @@ 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, EMPTY_WINDOW, Window, destroy_window);
REMOVER(tab->windows, id, tab->num_windows, Window, destroy_window);
#undef destroy_window
END_WITH_TAB;
}

View File

@ -58,8 +58,8 @@ typedef struct {
typedef struct {
id_type id;
unsigned int active_window, num_windows;
Window windows[MAX_CHILDREN];
unsigned int active_window, num_windows, capacity;
Window *windows;
} Tab;
#define MAX_KEY_COUNT 512
@ -76,8 +76,8 @@ typedef struct {
OSWindowGeometry before_fullscreen;
int viewport_width, viewport_height;
double viewport_x_ratio, viewport_y_ratio;
Tab tabs[MAX_CHILDREN];
unsigned int active_tab, num_tabs, last_active_tab, last_num_tabs, last_active_window_id;
Tab *tabs;
unsigned int active_tab, num_tabs, capacity, last_active_tab, last_num_tabs, last_active_window_id;
ScreenRenderData tab_bar_render_data;
bool is_focused;
double cursor_blink_zero_time, last_mouse_activity_at;
@ -98,8 +98,8 @@ typedef struct {
float font_sz_in_pts;
unsigned int cell_width, cell_height;
PyObject *boss;
OSWindow os_windows[MAX_CHILDREN];
size_t num_os_windows;
OSWindow *os_windows;
size_t num_os_windows, capacity;
OSWindow *callback_os_window, *focused_os_window;
bool close_all_windows;
} GlobalState;
@ -122,6 +122,7 @@ void make_window_context_current(OSWindow *w);
void hide_mouse(OSWindow *w);
void set_os_window_title(OSWindow *w, const char *title);
OSWindow* os_window_for_kitty_window(id_type);
OSWindow* add_os_window();
OSWindow* current_os_window();
bool drag_scroll(Window *, OSWindow*);
void draw_borders();