Port state.c and all code that calls into it
This commit is contained in:
parent
141a08ec7c
commit
c69145b6bc
@ -24,6 +24,7 @@
|
|||||||
#define str(s) #s
|
#define str(s) #s
|
||||||
#define fatal(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); exit(EXIT_FAILURE); }
|
#define fatal(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); exit(EXIT_FAILURE); }
|
||||||
|
|
||||||
|
typedef unsigned long long id_type;
|
||||||
typedef uint32_t char_type;
|
typedef uint32_t char_type;
|
||||||
typedef uint32_t color_type;
|
typedef uint32_t color_type;
|
||||||
typedef uint32_t combining_type;
|
typedef uint32_t combining_type;
|
||||||
@ -284,4 +285,4 @@ void scroll_event(double, double);
|
|||||||
void set_special_key_combo(int glfw_key, int mods);
|
void set_special_key_combo(int glfw_key, int mods);
|
||||||
void on_text_input(unsigned int codepoint, int mods);
|
void on_text_input(unsigned int codepoint, int mods);
|
||||||
void on_key_input(int key, int scancode, int action, int mods);
|
void on_key_input(int key, int scancode, int action, int mods);
|
||||||
void request_window_attention(unsigned int);
|
void request_window_attention(id_type);
|
||||||
|
|||||||
@ -178,7 +178,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);
|
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; }
|
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 = global_state.os_windows + global_state.num_os_windows++;
|
||||||
w->window_id = global_state.window_counter++;
|
w->window_id = global_state.os_window_counter++;
|
||||||
glfwSetWindowUserPointer(glfw_window, w);
|
glfwSetWindowUserPointer(glfw_window, w);
|
||||||
w->handle = glfw_window;
|
w->handle = glfw_window;
|
||||||
glfwSetCursor(glfw_window, standard_cursor);
|
glfwSetCursor(glfw_window, standard_cursor);
|
||||||
@ -196,6 +196,10 @@ create_new_os_window(PyObject UNUSED *self, PyObject *args) {
|
|||||||
if (!cocoa_make_window_resizable(glfwGetCocoaWindow(glfw_window))) { PyErr_Print(); }
|
if (!cocoa_make_window_resizable(glfwGetCocoaWindow(glfw_window))) { PyErr_Print(); }
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
double now = monotonic();
|
||||||
|
w->is_focused = true;
|
||||||
|
w->cursor_blink_zero_time = now;
|
||||||
|
w->last_mouse_activity_at = now;
|
||||||
return PyLong_FromUnsignedLongLong(w->window_id);
|
return PyLong_FromUnsignedLongLong(w->window_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +388,7 @@ toggle_fullscreen(PyObject UNUSED *self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
request_window_attention(unsigned int kitty_window_id) {
|
request_window_attention(id_type kitty_window_id) {
|
||||||
OSWindow *w = os_window_for_kitty_window(kitty_window_id);
|
OSWindow *w = os_window_for_kitty_window(kitty_window_id);
|
||||||
if (w) {
|
if (w) {
|
||||||
#ifdef has_request_attention
|
#ifdef has_request_attention
|
||||||
|
|||||||
@ -51,8 +51,9 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
|||||||
Screen *self;
|
Screen *self;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
PyObject *callbacks = Py_None, *test_child = Py_None;
|
PyObject *callbacks = Py_None, *test_child = Py_None;
|
||||||
unsigned int columns=80, lines=24, scrollback=0, window_id=0;
|
unsigned int columns=80, lines=24, scrollback=0;
|
||||||
if (!PyArg_ParseTuple(args, "|OIIIIO", &callbacks, &lines, &columns, &scrollback, &window_id, &test_child)) return NULL;
|
id_type window_id=0;
|
||||||
|
if (!PyArg_ParseTuple(args, "|OIIIKO", &callbacks, &lines, &columns, &scrollback, &window_id, &test_child)) return NULL;
|
||||||
|
|
||||||
self = (Screen *)type->tp_alloc(type, 0);
|
self = (Screen *)type->tp_alloc(type, 0);
|
||||||
if (self != NULL) {
|
if (self != NULL) {
|
||||||
|
|||||||
@ -29,7 +29,8 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by, last_selection_scrolled_by, window_id;
|
unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by, last_selection_scrolled_by;
|
||||||
|
id_type window_id;
|
||||||
uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset, *g_charset;
|
uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset, *g_charset;
|
||||||
Selection selection;
|
Selection selection;
|
||||||
SelectionBoundary last_rendered_selection_start, last_rendered_selection_end;
|
SelectionBoundary last_rendered_selection_start, last_rendered_selection_end;
|
||||||
|
|||||||
154
kitty/state.c
154
kitty/state.c
@ -25,11 +25,20 @@ static const Window EMPTY_WINDOW = {0};
|
|||||||
(count)--; \
|
(count)--; \
|
||||||
} \
|
} \
|
||||||
}}
|
}}
|
||||||
#define WITH_TAB(tab_id) \
|
#define WITH_OS_WINDOW(os_window_id) \
|
||||||
for (size_t t = 0; t < global_state.num_tabs; t++) { \
|
for (size_t o = 0; o < global_state.num_os_windows; o++) { \
|
||||||
if (global_state.tabs[t].id == tab_id) { \
|
OSWindow *os_window = global_state.os_windows + o; \
|
||||||
Tab *tab = global_state.tabs + t;
|
if (os_window->window_id == os_window_id) {
|
||||||
#define END_WITH_TAB break; }}
|
#define END_WITH_OS_WINDOW break; }}
|
||||||
|
|
||||||
|
#define WITH_TAB(os_window_id, tab_id) \
|
||||||
|
for (size_t o = 0; o < global_state.num_os_windows; o++) { \
|
||||||
|
OSWindow *osw = global_state.os_windows + o; \
|
||||||
|
if (osw->window_id == os_window_id) { \
|
||||||
|
for (size_t t = 0; t < osw->num_tabs; t++) { \
|
||||||
|
if (osw->tabs[t].id == tab_id) { \
|
||||||
|
Tab *tab = osw->tabs + t;
|
||||||
|
#define END_WITH_TAB break; }}}}
|
||||||
|
|
||||||
OSWindow*
|
OSWindow*
|
||||||
current_os_window() {
|
current_os_window() {
|
||||||
@ -39,7 +48,7 @@ current_os_window() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OSWindow*
|
OSWindow*
|
||||||
os_window_for_kitty_window(unsigned int kitty_window_id) {
|
os_window_for_kitty_window(id_type kitty_window_id) {
|
||||||
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
for (size_t i = 0; i < global_state.num_os_windows; i++) {
|
||||||
OSWindow *w = global_state.os_windows + i;
|
OSWindow *w = global_state.os_windows + i;
|
||||||
for (size_t t = 0; t < w->num_tabs; t++) {
|
for (size_t t = 0; t < w->num_tabs; t++) {
|
||||||
@ -53,16 +62,18 @@ os_window_for_kitty_window(unsigned int kitty_window_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
add_tab(unsigned int id) {
|
add_tab(id_type os_window_id, id_type id) {
|
||||||
ensure_can_add(global_state.tabs, global_state.num_tabs, "Too many children (add_tab)");
|
WITH_OS_WINDOW(os_window_id)
|
||||||
global_state.tabs[global_state.num_tabs] = EMPTY_TAB;
|
ensure_can_add(os_window->tabs, os_window->num_tabs, "Too many children (add_tab)");
|
||||||
global_state.tabs[global_state.num_tabs].id = id;
|
os_window->tabs[os_window->num_tabs] = EMPTY_TAB;
|
||||||
global_state.num_tabs++;
|
os_window->tabs[os_window->num_tabs].id = id;
|
||||||
|
os_window->num_tabs++;
|
||||||
|
END_WITH_OS_WINDOW
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
add_window(unsigned int tab_id, unsigned int id, PyObject *title) {
|
add_window(id_type os_window_id, id_type tab_id, id_type id, PyObject *title) {
|
||||||
WITH_TAB(tab_id);
|
WITH_TAB(os_window_id, tab_id);
|
||||||
ensure_can_add(tab->windows, tab->num_windows, "Too many children (add_window)");
|
ensure_can_add(tab->windows, tab->num_windows, "Too many children (add_window)");
|
||||||
tab->windows[tab->num_windows] = EMPTY_WINDOW;
|
tab->windows[tab->num_windows] = EMPTY_WINDOW;
|
||||||
tab->windows[tab->num_windows].id = id;
|
tab->windows[tab->num_windows].id = id;
|
||||||
@ -74,8 +85,8 @@ add_window(unsigned int tab_id, unsigned int id, PyObject *title) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
update_window_title(unsigned int tab_id, unsigned int window_id, PyObject *title) {
|
update_window_title(id_type os_window_id, id_type tab_id, id_type window_id, PyObject *title) {
|
||||||
WITH_TAB(tab_id);
|
WITH_TAB(os_window_id, tab_id);
|
||||||
for (size_t i = 0; i < tab->num_windows; i++) {
|
for (size_t i = 0; i < tab->num_windows; i++) {
|
||||||
if (tab->windows[i].id == window_id) {
|
if (tab->windows[i].id == window_id) {
|
||||||
Py_CLEAR(tab->windows[i].title);
|
Py_CLEAR(tab->windows[i].title);
|
||||||
@ -88,13 +99,15 @@ update_window_title(unsigned int tab_id, unsigned int window_id, PyObject *title
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
remove_tab(unsigned int id) {
|
remove_tab(id_type os_window_id, id_type id) {
|
||||||
REMOVER(global_state.tabs, id, global_state.num_tabs, EMPTY_TAB, Tab, noop);
|
WITH_OS_WINDOW(os_window_id)
|
||||||
|
REMOVER(os_window->tabs, id, os_window->num_tabs, EMPTY_TAB, Tab, noop);
|
||||||
|
END_WITH_OS_WINDOW
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
remove_window(unsigned int tab_id, unsigned int id) {
|
remove_window(id_type os_window_id, id_type tab_id, id_type id) {
|
||||||
WITH_TAB(tab_id);
|
WITH_TAB(os_window_id, tab_id);
|
||||||
#define destroy_window(w) Py_CLEAR(w.render_data.screen); Py_CLEAR(w.title);
|
#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, EMPTY_WINDOW, Window, destroy_window);
|
||||||
#undef destroy_window
|
#undef destroy_window
|
||||||
@ -103,27 +116,31 @@ remove_window(unsigned int tab_id, unsigned int id) {
|
|||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_active_tab(unsigned int idx) {
|
set_active_tab(id_type os_window_id, unsigned int idx) {
|
||||||
global_state.active_tab = idx;
|
WITH_OS_WINDOW(os_window_id)
|
||||||
|
os_window->active_tab = idx;
|
||||||
|
END_WITH_OS_WINDOW
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
set_active_window(unsigned int tab_id, unsigned int idx) {
|
set_active_window(id_type os_window_id, id_type tab_id, unsigned int idx) {
|
||||||
WITH_TAB(tab_id);
|
WITH_TAB(os_window_id, tab_id)
|
||||||
tab->active_window = idx;
|
tab->active_window = idx;
|
||||||
END_WITH_TAB;
|
END_WITH_TAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
swap_tabs(unsigned int a, unsigned int b) {
|
swap_tabs(id_type os_window_id, unsigned int a, unsigned int b) {
|
||||||
Tab t = global_state.tabs[b];
|
WITH_OS_WINDOW(os_window_id)
|
||||||
global_state.tabs[b] = global_state.tabs[a];
|
Tab t = os_window->tabs[b];
|
||||||
global_state.tabs[a] = t;
|
os_window->tabs[b] = os_window->tabs[a];
|
||||||
|
os_window->tabs[a] = t;
|
||||||
|
END_WITH_OS_WINDOW
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
swap_windows(unsigned int tab_id, unsigned int a, unsigned int b) {
|
swap_windows(id_type os_window_id, id_type tab_id, unsigned int a, unsigned int b) {
|
||||||
WITH_TAB(tab_id);
|
WITH_TAB(os_window_id, tab_id);
|
||||||
Window w = tab->windows[b];
|
Window w = tab->windows[b];
|
||||||
tab->windows[b] = tab->windows[a];
|
tab->windows[b] = tab->windows[a];
|
||||||
tab->windows[a] = w;
|
tab->windows[a] = w;
|
||||||
@ -138,6 +155,13 @@ swap_windows(unsigned int tab_id, unsigned int a, unsigned int b) {
|
|||||||
#define ONE_UINT(name) PYWRAP1(name) { name((unsigned int)PyLong_AsUnsignedLong(args)); Py_RETURN_NONE; }
|
#define ONE_UINT(name) PYWRAP1(name) { name((unsigned int)PyLong_AsUnsignedLong(args)); Py_RETURN_NONE; }
|
||||||
#define TWO_UINT(name) PYWRAP1(name) { unsigned int a, b; PA("II", &a, &b); name(a, b); Py_RETURN_NONE; }
|
#define TWO_UINT(name) PYWRAP1(name) { unsigned int a, b; PA("II", &a, &b); name(a, b); Py_RETURN_NONE; }
|
||||||
#define THREE_UINT(name) PYWRAP1(name) { unsigned int a, b, c; PA("III", &a, &b, &c); name(a, b, c); Py_RETURN_NONE; }
|
#define THREE_UINT(name) PYWRAP1(name) { unsigned int a, b, c; PA("III", &a, &b, &c); name(a, b, c); Py_RETURN_NONE; }
|
||||||
|
#define TWO_ID(name) PYWRAP1(name) { id_type a, b; PA("KK", &a, &b); name(a, b); Py_RETURN_NONE; }
|
||||||
|
#define THREE_ID(name) PYWRAP1(name) { id_type a, b, c; PA("KKK", &a, &b, &c); name(a, b, c); Py_RETURN_NONE; }
|
||||||
|
#define THREE_ID_OBJ(name) PYWRAP1(name) { id_type a, b, c; PyObject *o; PA("KKKO", &a, &b, &c, &o); name(a, b, c, o); Py_RETURN_NONE; }
|
||||||
|
#define KI(name) PYWRAP1(name) { id_type a; unsigned int b; PA("KI", &a, &b); name(a, b); Py_RETURN_NONE; }
|
||||||
|
#define KII(name) PYWRAP1(name) { id_type a; unsigned int b, c; PA("KII", &a, &b, &c); name(a, b, c); Py_RETURN_NONE; }
|
||||||
|
#define KKI(name) PYWRAP1(name) { id_type a, b; unsigned int c; PA("KKI", &a, &b, &c); name(a, b, c); Py_RETURN_NONE; }
|
||||||
|
#define KKII(name) PYWRAP1(name) { id_type a, b; unsigned int c, d; PA("KKII", &a, &b, &c, &d); name(a, b, c, d); Py_RETURN_NONE; }
|
||||||
|
|
||||||
static inline color_type
|
static inline color_type
|
||||||
color_as_int(PyObject *color) {
|
color_as_int(PyObject *color) {
|
||||||
@ -211,10 +235,14 @@ PYWRAP1(set_options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PYWRAP1(set_tab_bar_render_data) {
|
PYWRAP1(set_tab_bar_render_data) {
|
||||||
#define A(name) &(global_state.tab_bar_render_data.name)
|
#define A(name) &(d.name)
|
||||||
Py_CLEAR(global_state.tab_bar_render_data.screen);
|
ScreenRenderData d = {0};
|
||||||
PA("iffffO", A(vao_idx), A(xstart), A(ystart), A(dx), A(dy), A(screen));
|
id_type os_window_id;
|
||||||
Py_INCREF(global_state.tab_bar_render_data.screen);
|
PA("KiffffO", &os_window_id, A(vao_idx), A(xstart), A(ystart), A(dx), A(dy), A(screen));
|
||||||
|
WITH_OS_WINDOW(os_window_id)
|
||||||
|
Py_CLEAR(os_window->tab_bar_render_data.screen);
|
||||||
|
Py_INCREF(os_window->tab_bar_render_data.screen);
|
||||||
|
END_WITH_OS_WINDOW
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
#undef A
|
#undef A
|
||||||
}
|
}
|
||||||
@ -222,16 +250,17 @@ PYWRAP1(set_tab_bar_render_data) {
|
|||||||
PYWRAP1(set_window_render_data) {
|
PYWRAP1(set_window_render_data) {
|
||||||
#define A(name) &(d.name)
|
#define A(name) &(d.name)
|
||||||
#define B(name) &(g.name)
|
#define B(name) &(g.name)
|
||||||
unsigned int window_idx, tab_id;
|
id_type os_window_id, tab_id;
|
||||||
static ScreenRenderData d = {0};
|
unsigned int window_idx;
|
||||||
static WindowGeometry g = {0};
|
ScreenRenderData d = {0};
|
||||||
PA("IIiiffffOIIII", &tab_id, &window_idx, A(vao_idx), A(gvao_idx), A(xstart), A(ystart), A(dx), A(dy), A(screen), B(left), B(top), B(right), B(bottom));
|
WindowGeometry g = {0};
|
||||||
|
PA("KIiiffffOIIII", &os_window_id, &tab_id, &window_idx, A(vao_idx), A(gvao_idx), A(xstart), A(ystart), A(dx), A(dy), A(screen), B(left), B(top), B(right), B(bottom));
|
||||||
|
|
||||||
WITH_TAB(tab_id);
|
WITH_TAB(os_window_id, tab_id);
|
||||||
Py_CLEAR(tab->windows[window_idx].render_data.screen);
|
Py_CLEAR(tab->windows[window_idx].render_data.screen);
|
||||||
tab->windows[window_idx].render_data = d;
|
tab->windows[window_idx].render_data = d;
|
||||||
tab->windows[window_idx].geometry = g;
|
tab->windows[window_idx].geometry = g;
|
||||||
Py_INCREF(tab->windows[window_idx].render_data.screen);
|
Py_INCREF(tab->windows[window_idx].render_data.screen);
|
||||||
END_WITH_TAB;
|
END_WITH_TAB;
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
#undef A
|
#undef A
|
||||||
@ -239,10 +268,11 @@ PYWRAP1(set_window_render_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PYWRAP1(update_window_visibility) {
|
PYWRAP1(update_window_visibility) {
|
||||||
|
id_type os_window_id;
|
||||||
unsigned int window_idx, tab_id;
|
unsigned int window_idx, tab_id;
|
||||||
int visible;
|
int visible;
|
||||||
PA("IIp", &tab_id, &window_idx, &visible);
|
PA("KIIp", &os_window_id, &tab_id, &window_idx, &visible);
|
||||||
WITH_TAB(tab_id);
|
WITH_TAB(os_window_id, tab_id);
|
||||||
tab->windows[window_idx].visible = visible & 1;
|
tab->windows[window_idx].visible = visible & 1;
|
||||||
END_WITH_TAB;
|
END_WITH_TAB;
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@ -261,33 +291,25 @@ PYWRAP1(set_boss) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PYWRAP0(destroy_global_data) {
|
PYWRAP0(destroy_global_data) {
|
||||||
Py_CLEAR(global_state.tab_bar_render_data.screen);
|
|
||||||
Py_CLEAR(global_state.boss);
|
Py_CLEAR(global_state.boss);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PYWRAP1(set_display_state) {
|
PYWRAP1(set_display_state) {
|
||||||
PA("iiII", &global_state.viewport_width, &global_state.viewport_height, &global_state.cell_width, &global_state.cell_height);
|
int vw, vh;
|
||||||
|
PA("iiII", &vw, &vh, &global_state.cell_width, &global_state.cell_height);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WF(name) PYWRAP1(name) { \
|
THREE_ID_OBJ(add_window)
|
||||||
unsigned int tab_id, window_id; \
|
THREE_ID_OBJ(update_window_title)
|
||||||
PyObject *title; \
|
THREE_ID(remove_window)
|
||||||
PA("IIO", &tab_id, &window_id, &title); \
|
TWO_ID(add_tab)
|
||||||
name(tab_id, window_id, title); \
|
TWO_ID(remove_tab)
|
||||||
Py_RETURN_NONE; \
|
KI(set_active_tab)
|
||||||
}
|
KKI(set_active_window)
|
||||||
WF(add_window)
|
KII(swap_tabs)
|
||||||
WF(update_window_title)
|
KKII(swap_windows)
|
||||||
|
|
||||||
ONE_UINT(add_tab)
|
|
||||||
ONE_UINT(remove_tab)
|
|
||||||
TWO_UINT(remove_window)
|
|
||||||
ONE_UINT(set_active_tab)
|
|
||||||
TWO_UINT(set_active_window)
|
|
||||||
TWO_UINT(swap_tabs)
|
|
||||||
THREE_UINT(swap_windows)
|
|
||||||
|
|
||||||
#define M(name, arg_type) {#name, (PyCFunction)name, arg_type, NULL}
|
#define M(name, arg_type) {#name, (PyCFunction)name, arg_type, NULL}
|
||||||
#define MW(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}
|
#define MW(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}
|
||||||
@ -317,10 +339,6 @@ static PyMethodDef module_methods[] = {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
init_state(PyObject *module) {
|
init_state(PyObject *module) {
|
||||||
double now = monotonic();
|
|
||||||
global_state.application_focused = true;
|
|
||||||
global_state.cursor_blink_zero_time = now;
|
|
||||||
global_state.last_mouse_activity_at = now;
|
|
||||||
global_state.cell_width = 1; global_state.cell_height = 1;
|
global_state.cell_width = 1; global_state.cell_height = 1;
|
||||||
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -46,7 +46,7 @@ typedef struct {
|
|||||||
} ClickQueue;
|
} ClickQueue;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int id;
|
id_type id;
|
||||||
bool visible;
|
bool visible;
|
||||||
PyObject *title;
|
PyObject *title;
|
||||||
ScreenRenderData render_data;
|
ScreenRenderData render_data;
|
||||||
@ -57,7 +57,8 @@ typedef struct {
|
|||||||
} Window;
|
} Window;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int id, active_window, num_windows;
|
id_type id;
|
||||||
|
unsigned int active_window, num_windows;
|
||||||
Window windows[MAX_CHILDREN];
|
Window windows[MAX_CHILDREN];
|
||||||
} Tab;
|
} Tab;
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *handle;
|
void *handle;
|
||||||
unsigned long long window_id;
|
id_type window_id;
|
||||||
OSWindowGeometry before_fullscreen;
|
OSWindowGeometry before_fullscreen;
|
||||||
int viewport_width, viewport_height;
|
int viewport_width, viewport_height;
|
||||||
double viewport_x_ratio, viewport_y_ratio;
|
double viewport_x_ratio, viewport_y_ratio;
|
||||||
@ -93,7 +94,7 @@ typedef struct {
|
|||||||
Options opts;
|
Options opts;
|
||||||
|
|
||||||
double logical_dpi_x, logical_dpi_y;
|
double logical_dpi_x, logical_dpi_y;
|
||||||
unsigned long long window_counter;
|
id_type os_window_counter;
|
||||||
float font_sz_in_pts;
|
float font_sz_in_pts;
|
||||||
unsigned int cell_width, cell_height;
|
unsigned int cell_width, cell_height;
|
||||||
PyObject *boss;
|
PyObject *boss;
|
||||||
@ -120,7 +121,7 @@ void swap_window_buffers(OSWindow *w);
|
|||||||
void make_window_context_current(OSWindow *w);
|
void make_window_context_current(OSWindow *w);
|
||||||
void hide_mouse(OSWindow *w);
|
void hide_mouse(OSWindow *w);
|
||||||
void set_os_window_title(OSWindow *w, const char *title);
|
void set_os_window_title(OSWindow *w, const char *title);
|
||||||
OSWindow* os_window_for_kitty_window(unsigned int);
|
OSWindow* os_window_for_kitty_window(id_type);
|
||||||
OSWindow* current_os_window();
|
OSWindow* current_os_window();
|
||||||
bool drag_scroll(Window *, OSWindow*);
|
bool drag_scroll(Window *, OSWindow*);
|
||||||
void draw_borders();
|
void draw_borders();
|
||||||
|
|||||||
@ -33,10 +33,11 @@ def SpecialWindow(cmd, stdin=None, override_title=None):
|
|||||||
|
|
||||||
class Tab: # {{{
|
class Tab: # {{{
|
||||||
|
|
||||||
def __init__(self, opts, args, on_title_change, session_tab=None, special_window=None):
|
def __init__(self, os_window_id, opts, args, on_title_change, session_tab=None, special_window=None):
|
||||||
global borders
|
global borders
|
||||||
self.id = next(tab_counter)
|
self.id = next(tab_counter)
|
||||||
add_tab(self.id)
|
self.os_window_id = os_window_id
|
||||||
|
add_tab(os_window_id, self.id)
|
||||||
self.opts, self.args = opts, args
|
self.opts, self.args = opts, args
|
||||||
self.name = getattr(session_tab, 'name', '')
|
self.name = getattr(session_tab, 'name', '')
|
||||||
self.on_title_change = on_title_change
|
self.on_title_change = on_title_change
|
||||||
@ -126,9 +127,9 @@ class Tab: # {{{
|
|||||||
window.title = window.override_title = override_title
|
window.title = window.override_title = override_title
|
||||||
# Must add child before laying out so that resize_pty succeeds
|
# Must add child before laying out so that resize_pty succeeds
|
||||||
get_boss().add_child(window)
|
get_boss().add_child(window)
|
||||||
add_window(self.id, window.id, window.override_title or window.title or appname)
|
add_window(self.os_window_id, self.id, window.id, window.override_title or window.title or appname)
|
||||||
self.active_window_idx = self.current_layout.add_window(self.windows, window, self.active_window_idx)
|
self.active_window_idx = self.current_layout.add_window(self.windows, window, self.active_window_idx)
|
||||||
set_active_window(self.id, self.active_window_idx)
|
set_active_window(self.os_window_id, self.id, self.active_window_idx)
|
||||||
self.relayout_borders()
|
self.relayout_borders()
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
return window
|
return window
|
||||||
@ -141,9 +142,9 @@ class Tab: # {{{
|
|||||||
self.remove_window(self.windows[self.active_window_idx])
|
self.remove_window(self.windows[self.active_window_idx])
|
||||||
|
|
||||||
def remove_window(self, window):
|
def remove_window(self, window):
|
||||||
remove_window(self.id, window.id)
|
remove_window(self.os_window_id, self.id, window.id)
|
||||||
self.active_window_idx = self.current_layout.remove_window(self.windows, window, self.active_window_idx)
|
self.active_window_idx = self.current_layout.remove_window(self.windows, window, self.active_window_idx)
|
||||||
set_active_window(self.id, self.active_window_idx)
|
set_active_window(self.os_window_id, self.id, self.active_window_idx)
|
||||||
self.relayout_borders()
|
self.relayout_borders()
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ class Tab: # {{{
|
|||||||
if idx != self.active_window_idx:
|
if idx != self.active_window_idx:
|
||||||
self.current_layout.set_active_window(self.windows, idx)
|
self.current_layout.set_active_window(self.windows, idx)
|
||||||
self.active_window_idx = idx
|
self.active_window_idx = idx
|
||||||
set_active_window(self.id, self.active_window_idx)
|
set_active_window(self.os_window_id, self.id, self.active_window_idx)
|
||||||
self.relayout_borders()
|
self.relayout_borders()
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|
||||||
@ -169,7 +170,7 @@ class Tab: # {{{
|
|||||||
def _next_window(self, delta=1):
|
def _next_window(self, delta=1):
|
||||||
if len(self.windows) > 1:
|
if len(self.windows) > 1:
|
||||||
self.active_window_idx = self.current_layout.next_window(self.windows, self.active_window_idx, delta)
|
self.active_window_idx = self.current_layout.next_window(self.windows, self.active_window_idx, delta)
|
||||||
set_active_window(self.id, self.active_window_idx)
|
set_active_window(self.os_window_id, self.id, self.active_window_idx)
|
||||||
self.relayout_borders()
|
self.relayout_borders()
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|
||||||
@ -184,9 +185,9 @@ class Tab: # {{{
|
|||||||
idx = self.active_window_idx
|
idx = self.active_window_idx
|
||||||
nidx = (idx + len(self.windows) + delta) % len(self.windows)
|
nidx = (idx + len(self.windows) + delta) % len(self.windows)
|
||||||
self.windows[nidx], self.windows[idx] = self.windows[idx], self.windows[nidx]
|
self.windows[nidx], self.windows[idx] = self.windows[idx], self.windows[nidx]
|
||||||
swap_windows(self.id, nidx, idx)
|
swap_windows(self.os_window_id, self.id, nidx, idx)
|
||||||
self.active_window_idx = nidx
|
self.active_window_idx = nidx
|
||||||
set_active_window(self.id, self.active_window_idx)
|
set_active_window(self.os_window_id, self.id, self.active_window_idx)
|
||||||
self.relayout()
|
self.relayout()
|
||||||
|
|
||||||
def move_window_to_top(self):
|
def move_window_to_top(self):
|
||||||
@ -253,7 +254,7 @@ class TabBar: # {{{
|
|||||||
else:
|
else:
|
||||||
self.tab_bar_blank_rects = ()
|
self.tab_bar_blank_rects = ()
|
||||||
self.screen_geometry = sg = calculate_gl_geometry(g, viewport_width, viewport_height, cell_width, cell_height)
|
self.screen_geometry = sg = calculate_gl_geometry(g, viewport_width, viewport_height, cell_width, cell_height)
|
||||||
set_tab_bar_render_data(self.vao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, self.screen)
|
set_tab_bar_render_data(self.os_window_id, self.vao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, self.screen)
|
||||||
|
|
||||||
def update(self, data):
|
def update(self, data):
|
||||||
if self.layout_changed is None:
|
if self.layout_changed is None:
|
||||||
@ -299,7 +300,8 @@ class TabBar: # {{{
|
|||||||
|
|
||||||
class TabManager: # {{{
|
class TabManager: # {{{
|
||||||
|
|
||||||
def __init__(self, opts, args):
|
def __init__(self, os_window_id, opts, args):
|
||||||
|
self.os_window_id = os_window_id
|
||||||
self.opts, self.args = opts, args
|
self.opts, self.args = opts, args
|
||||||
self.tabs = []
|
self.tabs = []
|
||||||
self.tab_bar = TabBar(opts)
|
self.tab_bar = TabBar(opts)
|
||||||
@ -311,16 +313,16 @@ class TabManager: # {{{
|
|||||||
self.tabs.append(tab)
|
self.tabs.append(tab)
|
||||||
|
|
||||||
def _remove_tab(self, tab):
|
def _remove_tab(self, tab):
|
||||||
remove_tab(tab.id)
|
remove_tab(self.os_window_id, tab.id)
|
||||||
self.tabs.remove(tab)
|
self.tabs.remove(tab)
|
||||||
|
|
||||||
def _set_active_tab(self, idx):
|
def _set_active_tab(self, idx):
|
||||||
self.active_tab_idx = idx
|
self.active_tab_idx = idx
|
||||||
set_active_tab(idx)
|
set_active_tab(self.os_window_id, idx)
|
||||||
|
|
||||||
def init(self, startup_session):
|
def init(self, startup_session):
|
||||||
for t in startup_session.tabs:
|
for t in startup_session.tabs:
|
||||||
self._add_tab(Tab(self.opts, self.args, self.title_changed, t))
|
self._add_tab(Tab(self.os_window_id, self.opts, self.args, self.title_changed, t))
|
||||||
self._set_active_tab(max(0, min(startup_session.active_tab_idx, len(self.tabs) - 1)))
|
self._set_active_tab(max(0, min(startup_session.active_tab_idx, len(self.tabs) - 1)))
|
||||||
if len(self.tabs) > 1:
|
if len(self.tabs) > 1:
|
||||||
get_boss().tabbar_visibility_changed()
|
get_boss().tabbar_visibility_changed()
|
||||||
@ -365,7 +367,7 @@ class TabManager: # {{{
|
|||||||
idx = self.active_tab_idx
|
idx = self.active_tab_idx
|
||||||
nidx = (idx + len(self.tabs) + delta) % len(self.tabs)
|
nidx = (idx + len(self.tabs) + delta) % len(self.tabs)
|
||||||
self.tabs[idx], self.tabs[nidx] = self.tabs[nidx], self.tabs[idx]
|
self.tabs[idx], self.tabs[nidx] = self.tabs[nidx], self.tabs[idx]
|
||||||
swap_tabs(idx, nidx)
|
swap_tabs(self.os_window_id, idx, nidx)
|
||||||
self._set_active_tab(nidx)
|
self._set_active_tab(nidx)
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
|
|
||||||
@ -375,7 +377,7 @@ class TabManager: # {{{
|
|||||||
def new_tab(self, special_window=None):
|
def new_tab(self, special_window=None):
|
||||||
needs_resize = len(self.tabs) == 1
|
needs_resize = len(self.tabs) == 1
|
||||||
idx = len(self.tabs)
|
idx = len(self.tabs)
|
||||||
self._add_tab(Tab(self.opts, self.args, self.title_changed, special_window=special_window))
|
self._add_tab(Tab(self.os_window_id, self.opts, self.args, self.title_changed, special_window=special_window))
|
||||||
self._set_active_tab(idx)
|
self._set_active_tab(idx)
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
if needs_resize:
|
if needs_resize:
|
||||||
|
|||||||
@ -79,6 +79,7 @@ class Window:
|
|||||||
self.vao_id = create_cell_vao()
|
self.vao_id = create_cell_vao()
|
||||||
self.gvao_id = create_graphics_vao()
|
self.gvao_id = create_graphics_vao()
|
||||||
self.tab_id = tab.id
|
self.tab_id = tab.id
|
||||||
|
self.os_window_id = tab.os_window_id
|
||||||
self.tabref = weakref.ref(tab)
|
self.tabref = weakref.ref(tab)
|
||||||
self.override_title = None
|
self.override_title = None
|
||||||
self.destroyed = False
|
self.destroyed = False
|
||||||
@ -98,7 +99,7 @@ class Window:
|
|||||||
val = bool(val)
|
val = bool(val)
|
||||||
if val is not self.is_visible_in_layout:
|
if val is not self.is_visible_in_layout:
|
||||||
self.is_visible_in_layout = val
|
self.is_visible_in_layout = val
|
||||||
update_window_visibility(self.tab_id, window_idx, val)
|
update_window_visibility(self.os_window_id, self.tab_id, window_idx, val)
|
||||||
if val:
|
if val:
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ class Window:
|
|||||||
else:
|
else:
|
||||||
sg = self.update_position(new_geometry)
|
sg = self.update_position(new_geometry)
|
||||||
self.geometry = g = new_geometry
|
self.geometry = g = new_geometry
|
||||||
set_window_render_data(self.tab_id, window_idx, self.vao_id, self.gvao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, self.screen, *g[:4])
|
set_window_render_data(self.os_window_id, self.tab_id, window_idx, self.vao_id, self.gvao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, self.screen, *g[:4])
|
||||||
|
|
||||||
def contains(self, x, y):
|
def contains(self, x, y):
|
||||||
g = self.geometry
|
g = self.geometry
|
||||||
@ -175,7 +176,7 @@ class Window:
|
|||||||
def title_changed(self, new_title):
|
def title_changed(self, new_title):
|
||||||
if self.override_title is None:
|
if self.override_title is None:
|
||||||
self.title = sanitize_title(new_title or appname)
|
self.title = sanitize_title(new_title or appname)
|
||||||
update_window_title(self.tab_id, self.id, self.title)
|
update_window_title(self.os_window_id, self.tab_id, self.id, self.title)
|
||||||
t = self.tabref()
|
t = self.tabref()
|
||||||
if t is not None:
|
if t is not None:
|
||||||
t.title_changed(self)
|
t.title_changed(self)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user