Move the char grid render call into C
This commit is contained in:
parent
943a1575ad
commit
e6df82b255
@ -365,9 +365,6 @@ class Boss:
|
||||
self.glfw_window.set_title(self.glfw_window_title)
|
||||
if isosx:
|
||||
cocoa_update_title(self.glfw_window_title)
|
||||
for window in tab.visible_windows():
|
||||
if not window.needs_layout:
|
||||
window.char_grid.render_cells()
|
||||
active = self.active_window
|
||||
if active is not None:
|
||||
draw_cursor = True
|
||||
@ -383,7 +380,7 @@ class Boss:
|
||||
active.char_grid.render_cursor(self.window_is_focused)
|
||||
|
||||
def gui_close_window(self, window):
|
||||
window.char_grid.destroy()
|
||||
window.destroy()
|
||||
for tab in self.tab_manager:
|
||||
if window in tab:
|
||||
break
|
||||
|
||||
@ -10,8 +10,7 @@ from .config import build_ansi_color_table
|
||||
from .constants import ScreenGeometry, cell_size, viewport_size
|
||||
from .fast_data_types import (
|
||||
CELL_PROGRAM, CURSOR_BEAM, CURSOR_BLOCK, CURSOR_PROGRAM, CURSOR_UNDERLINE,
|
||||
compile_program, create_cell_vao, draw_cells, draw_cursor,
|
||||
init_cell_program, init_cursor_program, remove_vao
|
||||
compile_program, draw_cursor, init_cell_program, init_cursor_program
|
||||
)
|
||||
from .rgb import to_color
|
||||
from .utils import (
|
||||
@ -42,16 +41,11 @@ def calculate_gl_geometry(window_geometry, viewport_width, viewport_height, cell
|
||||
return ScreenGeometry(xstart, ystart, window_geometry.xnum, window_geometry.ynum, dx, dy)
|
||||
|
||||
|
||||
def render_cells(vao_id, sg, screen):
|
||||
draw_cells(vao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, screen)
|
||||
|
||||
|
||||
class CharGrid:
|
||||
|
||||
url_pat = re.compile('(?:http|https|file|ftp)://\S+', re.IGNORECASE)
|
||||
|
||||
def __init__(self, screen, opts):
|
||||
self.vao_id = create_cell_vao()
|
||||
self.screen_reversed = False
|
||||
self.screen = screen
|
||||
self.opts = opts
|
||||
@ -63,16 +57,9 @@ class CharGrid:
|
||||
self.default_cursor = Cursor(0, 0, opts.cursor_shape, opts.cursor_blink_interval > 0)
|
||||
self.opts = opts
|
||||
|
||||
def destroy(self):
|
||||
if self.vao_id is not None:
|
||||
remove_vao(self.vao_id)
|
||||
self.vao_id = None
|
||||
|
||||
def update_position(self, window_geometry):
|
||||
self.screen_geometry = calculate_gl_geometry(window_geometry, viewport_size.width, viewport_size.height, cell_size.width, cell_size.height)
|
||||
|
||||
def resize(self, window_geometry):
|
||||
self.update_position(window_geometry)
|
||||
self.screen_geometry = sg = calculate_gl_geometry(window_geometry, viewport_size.width, viewport_size.height, cell_size.width, cell_size.height)
|
||||
return sg
|
||||
|
||||
def change_colors(self, changes):
|
||||
dirtied = False
|
||||
@ -172,9 +159,6 @@ class CharGrid:
|
||||
def text_for_selection(self):
|
||||
return ''.join(self.screen.text_for_selection())
|
||||
|
||||
def render_cells(self):
|
||||
render_cells(self.vao_id, self.screen_geometry, self.screen)
|
||||
|
||||
def render_cursor(self, is_focused):
|
||||
if not self.screen.cursor_visible or self.screen.scrolled_by:
|
||||
return
|
||||
|
||||
@ -15,7 +15,7 @@ extern int pthread_setname_np(const char *name);
|
||||
#include <pthread.h>
|
||||
#undef _GNU_SOURCE
|
||||
#endif
|
||||
#include "data-types.h"
|
||||
#include "state.h"
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <float.h>
|
||||
@ -30,6 +30,7 @@ extern int pthread_setname_np(const char *name);
|
||||
|
||||
#define EXTRA_FDS 2
|
||||
|
||||
extern GlobalState global_state;
|
||||
static void (*parse_func)(Screen*, PyObject*);
|
||||
|
||||
typedef struct {
|
||||
@ -436,6 +437,16 @@ render(ChildMonitor *self, double *timeout) {
|
||||
#define TD global_state.tab_bar_render_data
|
||||
if (TD.screen && global_state.num_tabs > 1) draw_cells(TD.vao_idx, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen);
|
||||
#undef TD
|
||||
if (global_state.num_tabs) {
|
||||
Tab *tab = global_state.tabs + global_state.active_tab;
|
||||
for (size_t i = 0; i < tab->num_windows; i++) {
|
||||
Window *w = tab->windows + i;
|
||||
#define WD w->render_data
|
||||
if (w->visible && WD.screen) draw_cells(WD.vao_idx, WD.xstart, WD.ystart, WD.dx, WD.dy, WD.screen);
|
||||
#undef WD
|
||||
}
|
||||
}
|
||||
|
||||
ret = PyObject_CallFunctionObjArgs(self->render_func, NULL);
|
||||
if (ret == NULL) { PyErr_Print(); return false; }
|
||||
else Py_DECREF(ret);
|
||||
|
||||
@ -288,33 +288,6 @@ typedef struct {
|
||||
} ChildMonitor;
|
||||
PyTypeObject ChildMonitor_Type;
|
||||
|
||||
typedef struct {
|
||||
double visual_bell_duration;
|
||||
bool enable_audio_bell;
|
||||
} Options;
|
||||
|
||||
typedef struct {
|
||||
unsigned int id;
|
||||
} Tab;
|
||||
|
||||
typedef struct {
|
||||
ssize_t vao_idx;
|
||||
float xstart, ystart, dx, dy;
|
||||
Screen *screen;
|
||||
} ScreenRenderData;
|
||||
|
||||
typedef struct {
|
||||
Options opts;
|
||||
|
||||
Tab tabs[MAX_CHILDREN];
|
||||
unsigned int active_tab, num_tabs;
|
||||
ScreenRenderData tab_bar_render_data;
|
||||
} GlobalState;
|
||||
|
||||
#ifndef IS_STATE
|
||||
extern GlobalState global_state;
|
||||
#endif
|
||||
|
||||
#define clear_sprite_position(cell) (cell).sprite_x = 0; (cell).sprite_y = 0; (cell).sprite_z = 0;
|
||||
|
||||
#define left_shift_line(line, at, num) \
|
||||
@ -326,11 +299,6 @@ extern GlobalState global_state;
|
||||
clear_sprite_position((line)->cells[(at)]); \
|
||||
}
|
||||
|
||||
typedef void (*draw_borders_func)();
|
||||
extern draw_borders_func draw_borders;
|
||||
typedef void (*draw_cells_func)(ssize_t, float, float, float, float, Screen *);
|
||||
extern draw_cells_func draw_cells;
|
||||
|
||||
// Global functions
|
||||
Line* alloc_line();
|
||||
Cursor* alloc_cursor();
|
||||
|
||||
@ -122,14 +122,14 @@ class Stack(Layout):
|
||||
|
||||
def set_active_window(self, windows, active_window_idx):
|
||||
for i, w in enumerate(windows):
|
||||
w.is_visible_in_layout = i == active_window_idx
|
||||
w.set_visible_in_layout(i, i == active_window_idx)
|
||||
|
||||
def __call__(self, windows, active_window_idx):
|
||||
self.blank_rects = []
|
||||
wg = layout_single_window(self.margin_width, self.padding_width)
|
||||
for i, w in enumerate(windows):
|
||||
w.is_visible_in_layout = i == active_window_idx
|
||||
w.set_geometry(wg)
|
||||
w.set_visible_in_layout(i, i == active_window_idx)
|
||||
w.set_geometry(i, wg)
|
||||
if w.is_visible_in_layout:
|
||||
self.blank_rects = blank_rects_for_window(w)
|
||||
|
||||
@ -142,7 +142,7 @@ class Tall(Layout):
|
||||
self.blank_rects = br = []
|
||||
if len(windows) == 1:
|
||||
wg = layout_single_window(self.margin_width, self.padding_width)
|
||||
windows[0].set_geometry(wg)
|
||||
windows[0].set_geometry(0, wg)
|
||||
self.blank_rects = blank_rects_for_window(windows[0])
|
||||
return
|
||||
xlayout = layout_dimension(
|
||||
@ -152,14 +152,14 @@ class Tall(Layout):
|
||||
ystart, ynum = next(layout_dimension(
|
||||
available_height(), cell_size.height, 1, self.border_width, left_align=True,
|
||||
margin_length=self.margin_width, padding_length=self.padding_width))
|
||||
windows[0].set_geometry(window_geometry(xstart, xnum, ystart, ynum))
|
||||
windows[0].set_geometry(0, window_geometry(xstart, xnum, ystart, ynum))
|
||||
vh = available_height()
|
||||
xstart, xnum = next(xlayout)
|
||||
ylayout = layout_dimension(
|
||||
available_height(), cell_size.height, len(windows) - 1, self.border_width, left_align=True,
|
||||
margin_length=self.margin_width, padding_length=self.padding_width)
|
||||
for w, (ystart, ynum) in zip(islice(windows, 1, None), ylayout):
|
||||
w.set_geometry(window_geometry(xstart, xnum, ystart, ynum))
|
||||
for i, (w, (ystart, ynum)) in enumerate(zip(islice(windows, 1, None), ylayout)):
|
||||
w.set_geometry(i + 1, window_geometry(xstart, xnum, ystart, ynum))
|
||||
left_blank_rect(windows[0], br, vh), top_blank_rect(windows[0], br, vh), right_blank_rect(windows[-1], br, vh)
|
||||
br.append(Rect(windows[0].geometry.right, 0, windows[1].geometry.left, vh))
|
||||
br.append(Rect(0, windows[0].geometry.bottom, windows[0].geometry.right, vh))
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
#define EXTRA_INIT PyModule_AddIntMacro(module, SCROLL_LINE); PyModule_AddIntMacro(module, SCROLL_PAGE); PyModule_AddIntMacro(module, SCROLL_FULL);
|
||||
|
||||
#include "data-types.h"
|
||||
#include "state.h"
|
||||
#include "lineops.h"
|
||||
#include "screen.h"
|
||||
#include <structmember.h>
|
||||
@ -23,6 +23,7 @@
|
||||
#include "modes.h"
|
||||
#include "wcwidth9.h"
|
||||
|
||||
extern GlobalState global_state;
|
||||
static const ScreenModes empty_modes = {0, .mDECAWM=true, .mDECTCEM=true, .mDECARM=true};
|
||||
static Selection EMPTY_SELECTION = {0};
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include "data-types.h"
|
||||
#include "state.h"
|
||||
#include "screen.h"
|
||||
#include "sprites.h"
|
||||
#ifdef __APPLE__
|
||||
|
||||
@ -5,24 +5,31 @@
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#define IS_STATE
|
||||
#include "data-types.h"
|
||||
#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 REMOVER(array, qid, count, empty, structure) { \
|
||||
#define noop(...)
|
||||
#define REMOVER(array, qid, count, empty, 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; \
|
||||
size_t num_to_right = capacity - count - 1; \
|
||||
if (num_to_right) memmove(array + i, array + i + 1, num_to_right * sizeof(structure)); \
|
||||
(count)--; \
|
||||
} \
|
||||
}}
|
||||
#define WITH_TAB(tab_id) \
|
||||
for (size_t t = 0; t < global_state.num_tabs; t++) { \
|
||||
if (global_state.tabs[t].id == tab_id) { \
|
||||
Tab *tab = global_state.tabs + t;
|
||||
#define END_WITH_TAB break; }}
|
||||
|
||||
static inline void
|
||||
add_tab(unsigned int id) {
|
||||
@ -33,15 +40,43 @@ add_tab(unsigned int id) {
|
||||
}
|
||||
|
||||
static inline void
|
||||
remove_tab(unsigned int id) {
|
||||
REMOVER(global_state.tabs, id, global_state.num_tabs, EMPTY_TAB, Tab);
|
||||
add_window(unsigned int tab_id, unsigned int id) {
|
||||
WITH_TAB(tab_id);
|
||||
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].id = id;
|
||||
tab->windows[tab->num_windows].visible = true;
|
||||
tab->num_windows++;
|
||||
END_WITH_TAB;
|
||||
}
|
||||
|
||||
static inline void
|
||||
remove_tab(unsigned int id) {
|
||||
REMOVER(global_state.tabs, id, global_state.num_tabs, EMPTY_TAB, Tab, noop);
|
||||
}
|
||||
|
||||
static inline void
|
||||
remove_window(unsigned int tab_id, unsigned int id) {
|
||||
WITH_TAB(tab_id);
|
||||
#define destroy_window(w) Py_CLEAR(w.render_data.screen)
|
||||
REMOVER(tab->windows, id, tab->num_windows, EMPTY_WINDOW, Window, destroy_window);
|
||||
#undef destroy_window
|
||||
END_WITH_TAB;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
set_active_tab(unsigned int idx) {
|
||||
global_state.active_tab = idx;
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_active_window(unsigned int tab_id, unsigned int idx) {
|
||||
WITH_TAB(tab_id);
|
||||
tab->active_window = idx;
|
||||
END_WITH_TAB;
|
||||
}
|
||||
|
||||
static inline void
|
||||
swap_tabs(unsigned int a, unsigned int b) {
|
||||
Tab t = global_state.tabs[b];
|
||||
@ -49,6 +84,15 @@ swap_tabs(unsigned int a, unsigned int b) {
|
||||
global_state.tabs[a] = t;
|
||||
}
|
||||
|
||||
static inline void
|
||||
swap_windows(unsigned int tab_id, unsigned int a, unsigned int b) {
|
||||
WITH_TAB(tab_id);
|
||||
Window w = tab->windows[b];
|
||||
tab->windows[b] = tab->windows[a];
|
||||
tab->windows[a] = w;
|
||||
END_WITH_TAB;
|
||||
}
|
||||
|
||||
// Python API {{{
|
||||
#define PYWRAP0(name) static PyObject* py##name(PyObject UNUSED *self)
|
||||
#define PYWRAP1(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args)
|
||||
@ -56,6 +100,7 @@ swap_tabs(unsigned int a, unsigned int b) {
|
||||
#define PA(fmt, ...) if(!PyArg_ParseTuple(args, fmt, __VA_ARGS__)) return NULL;
|
||||
#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 THREE_UINT(name) PYWRAP1(name) { unsigned int a, b, c; PA("III", &a, &b, &c); name(a, b, c); Py_RETURN_NONE; }
|
||||
|
||||
PYWRAP1(set_options) {
|
||||
#define S(name, convert) { PyObject *ret = PyObject_GetAttrString(args, #name); if (ret == NULL) return NULL; global_state.opts.name = convert(ret); Py_DECREF(ret); }
|
||||
@ -74,15 +119,44 @@ PYWRAP1(set_tab_bar_render_data) {
|
||||
#undef A
|
||||
}
|
||||
|
||||
PYWRAP1(set_window_render_data) {
|
||||
#define A(name) &(d.name)
|
||||
unsigned int window_idx, tab_id;
|
||||
ScreenRenderData d = {0};
|
||||
PA("IIiffffO", &tab_id, &window_idx, A(vao_idx), A(xstart), A(ystart), A(dx), A(dy), A(screen));
|
||||
|
||||
WITH_TAB(tab_id);
|
||||
Py_CLEAR(tab->windows[window_idx].render_data.screen);
|
||||
tab->windows[window_idx].render_data = d;
|
||||
Py_INCREF(tab->windows[window_idx].render_data.screen);
|
||||
END_WITH_TAB;
|
||||
Py_RETURN_NONE;
|
||||
#undef A
|
||||
}
|
||||
|
||||
PYWRAP1(update_window_visibility) {
|
||||
unsigned int window_idx, tab_id;
|
||||
int visible;
|
||||
PA("IIp", &tab_id, &window_idx, &visible);
|
||||
WITH_TAB(tab_id);
|
||||
tab->windows[window_idx].visible = visible & 1;
|
||||
END_WITH_TAB;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PYWRAP0(destroy_global_data) {
|
||||
Py_CLEAR(global_state.tab_bar_render_data.screen);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
ONE_UINT(add_tab)
|
||||
TWO_UINT(add_window)
|
||||
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 MW(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}
|
||||
@ -90,10 +164,16 @@ TWO_UINT(swap_tabs)
|
||||
static PyMethodDef module_methods[] = {
|
||||
MW(set_options, METH_O),
|
||||
MW(add_tab, METH_O),
|
||||
MW(add_window, METH_VARARGS),
|
||||
MW(remove_tab, METH_O),
|
||||
MW(remove_window, METH_VARARGS),
|
||||
MW(set_active_tab, METH_O),
|
||||
MW(set_active_window, METH_VARARGS),
|
||||
MW(swap_tabs, METH_VARARGS),
|
||||
MW(swap_windows, METH_VARARGS),
|
||||
MW(set_tab_bar_render_data, METH_VARARGS),
|
||||
MW(set_window_render_data, METH_VARARGS),
|
||||
MW(update_window_visibility, METH_VARARGS),
|
||||
MW(destroy_global_data, METH_NOARGS),
|
||||
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
|
||||
43
kitty/state.h
Normal file
43
kitty/state.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "data-types.h"
|
||||
|
||||
typedef struct {
|
||||
double visual_bell_duration;
|
||||
bool enable_audio_bell;
|
||||
} Options;
|
||||
|
||||
typedef struct {
|
||||
ssize_t vao_idx;
|
||||
float xstart, ystart, dx, dy;
|
||||
Screen *screen;
|
||||
} ScreenRenderData;
|
||||
|
||||
typedef struct {
|
||||
unsigned int id;
|
||||
bool visible;
|
||||
ScreenRenderData render_data;
|
||||
} Window;
|
||||
|
||||
typedef struct {
|
||||
unsigned int id, active_window, num_windows;
|
||||
Window windows[MAX_CHILDREN];
|
||||
} Tab;
|
||||
|
||||
typedef struct {
|
||||
Options opts;
|
||||
|
||||
Tab tabs[MAX_CHILDREN];
|
||||
unsigned int active_tab, num_tabs;
|
||||
ScreenRenderData tab_bar_render_data;
|
||||
} GlobalState;
|
||||
|
||||
typedef void (*draw_borders_func)();
|
||||
extern draw_borders_func draw_borders;
|
||||
typedef void (*draw_cells_func)(ssize_t, float, float, float, float, Screen *);
|
||||
extern draw_cells_func draw_cells;
|
||||
@ -14,8 +14,9 @@ from .constants import (
|
||||
WindowGeometry, appname, cell_size, get_boss, shell_path, viewport_size
|
||||
)
|
||||
from .fast_data_types import (
|
||||
DECAWM, Screen, add_tab, create_cell_vao, glfw_post_empty_event,
|
||||
remove_tab, set_active_tab, swap_tabs, set_tab_bar_render_data
|
||||
DECAWM, Screen, add_tab, add_window, create_cell_vao,
|
||||
glfw_post_empty_event, remove_tab, remove_window, set_active_tab,
|
||||
set_active_window, set_tab_bar_render_data, swap_tabs, swap_windows
|
||||
)
|
||||
from .layout import Rect, all_layouts
|
||||
from .utils import color_as_int
|
||||
@ -36,6 +37,7 @@ class Tab: # {{{
|
||||
def __init__(self, opts, args, on_title_change, session_tab=None, special_window=None):
|
||||
global borders
|
||||
self.id = next(tab_counter)
|
||||
add_tab(self.id)
|
||||
self.opts, self.args = opts, args
|
||||
self.name = getattr(session_tab, 'name', '')
|
||||
self.on_title_change = on_title_change
|
||||
@ -104,8 +106,8 @@ class Tab: # {{{
|
||||
idx = -1
|
||||
nl = self.opts.enabled_layouts[(idx + 1) % len(self.opts.enabled_layouts)]
|
||||
self.current_layout = all_layouts[nl](self.opts, borders.border_width, self.windows)
|
||||
for w in self.windows:
|
||||
w.is_visible_in_layout = True
|
||||
for i, w in enumerate(self.windows):
|
||||
w.set_visible_in_layout(i, True)
|
||||
self.relayout()
|
||||
|
||||
def launch_child(self, use_shell=False, cmd=None, stdin=None):
|
||||
@ -125,7 +127,9 @@ class Tab: # {{{
|
||||
window.title = window.override_title = override_title
|
||||
# Must add child before laying out so that resize_pty succeeds
|
||||
get_boss().add_child(window)
|
||||
add_window(self.id, window.id)
|
||||
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)
|
||||
self.relayout_borders()
|
||||
glfw_post_empty_event()
|
||||
return window
|
||||
@ -138,7 +142,9 @@ class Tab: # {{{
|
||||
self.remove_window(self.windows[self.active_window_idx])
|
||||
|
||||
def remove_window(self, window):
|
||||
remove_window(self.id, window.id)
|
||||
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)
|
||||
self.relayout_borders()
|
||||
glfw_post_empty_event()
|
||||
|
||||
@ -146,6 +152,7 @@ class Tab: # {{{
|
||||
if idx != self.active_window_idx:
|
||||
self.current_layout.set_active_window(self.windows, idx)
|
||||
self.active_window_idx = idx
|
||||
set_active_window(self.id, self.active_window_idx)
|
||||
self.relayout_borders()
|
||||
glfw_post_empty_event()
|
||||
|
||||
@ -163,6 +170,7 @@ class Tab: # {{{
|
||||
def _next_window(self, delta=1):
|
||||
if len(self.windows) > 1:
|
||||
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)
|
||||
self.relayout_borders()
|
||||
glfw_post_empty_event()
|
||||
|
||||
@ -177,7 +185,9 @@ class Tab: # {{{
|
||||
idx = self.active_window_idx
|
||||
nidx = (idx + len(self.windows) + delta) % len(self.windows)
|
||||
self.windows[nidx], self.windows[idx] = self.windows[idx], self.windows[nidx]
|
||||
swap_windows(self.id, nidx, idx)
|
||||
self.active_window_idx = nidx
|
||||
set_active_window(self.id, self.active_window_idx)
|
||||
self.relayout()
|
||||
|
||||
def move_window_to_top(self):
|
||||
@ -295,7 +305,6 @@ class TabManager: # {{{
|
||||
self.active_tab_idx = 0
|
||||
|
||||
def _add_tab(self, tab):
|
||||
add_tab(tab.id)
|
||||
self.tabs.append(tab)
|
||||
|
||||
def _remove_tab(self, tab):
|
||||
|
||||
@ -18,7 +18,9 @@ from .fast_data_types import (
|
||||
GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT, GLFW_KEY_UP, GLFW_MOD_SHIFT,
|
||||
GLFW_MOUSE_BUTTON_1, GLFW_MOUSE_BUTTON_4, GLFW_MOUSE_BUTTON_5,
|
||||
GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, GLFW_RELEASE, MOTION_MODE,
|
||||
SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen, glfw_post_empty_event
|
||||
SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen, create_cell_vao,
|
||||
glfw_post_empty_event, remove_vao, set_window_render_data,
|
||||
update_window_visibility
|
||||
)
|
||||
from .keys import get_key_map
|
||||
from .mouse import DRAG, MOVE, PRESS, RELEASE, encode_mouse_event
|
||||
@ -45,6 +47,8 @@ class Window:
|
||||
|
||||
def __init__(self, tab, child, opts, args):
|
||||
self.id = next(window_counter)
|
||||
self.vao_id = create_cell_vao()
|
||||
self.tab_id = tab.id
|
||||
self.tabref = weakref.ref(tab)
|
||||
self.override_title = None
|
||||
self.last_mouse_cursor_pos = 0, 0
|
||||
@ -53,7 +57,7 @@ class Window:
|
||||
self.geometry = WindowGeometry(0, 0, 0, 0, 0, 0)
|
||||
self.needs_layout = True
|
||||
self.title = appname
|
||||
self._is_visible_in_layout = True
|
||||
self.is_visible_in_layout = True
|
||||
self.child, self.opts = child, opts
|
||||
self.start_visual_bell_at = None
|
||||
self.screen = Screen(self, 24, 80, opts.scrollback_lines)
|
||||
@ -63,15 +67,11 @@ class Window:
|
||||
def __repr__(self):
|
||||
return 'Window(title={}, id={})'.format(self.title, self.id)
|
||||
|
||||
@property
|
||||
def is_visible_in_layout(self):
|
||||
return self._is_visible_in_layout
|
||||
|
||||
@is_visible_in_layout.setter
|
||||
def is_visible_in_layout(self, val):
|
||||
def set_visible_in_layout(self, window_idx, val):
|
||||
val = bool(val)
|
||||
if val != self._is_visible_in_layout:
|
||||
self._is_visible_in_layout = val
|
||||
if val is not self.is_visible_in_layout:
|
||||
self.is_visible_in_layout = val
|
||||
update_window_visibility(self.tab_id, window_idx, val)
|
||||
if val:
|
||||
self.refresh()
|
||||
|
||||
@ -79,7 +79,7 @@ class Window:
|
||||
self.screen.mark_as_dirty()
|
||||
wakeup()
|
||||
|
||||
def set_geometry(self, new_geometry):
|
||||
def set_geometry(self, window_idx, new_geometry):
|
||||
if self.destroyed:
|
||||
return
|
||||
if self.needs_layout or new_geometry.xnum != self.screen.columns or new_geometry.ynum != self.screen.lines:
|
||||
@ -88,11 +88,12 @@ class Window:
|
||||
self.current_pty_size = (
|
||||
self.screen.lines, self.screen.columns,
|
||||
max(0, new_geometry.right - new_geometry.left), max(0, new_geometry.bottom - new_geometry.top))
|
||||
self.char_grid.resize(new_geometry)
|
||||
sg = self.char_grid.update_position(new_geometry)
|
||||
self.needs_layout = False
|
||||
boss.resize_pty(self.id)
|
||||
else:
|
||||
self.char_grid.update_position(new_geometry)
|
||||
sg = self.char_grid.update_position(new_geometry)
|
||||
set_window_render_data(self.tab_id, window_idx, self.vao_id, sg.xstart, sg.ystart, sg.dx, sg.dy, self.screen)
|
||||
self.geometry = new_geometry
|
||||
|
||||
def contains(self, x, y):
|
||||
@ -281,6 +282,11 @@ class Window:
|
||||
def buf_toggled(self, is_main_linebuf):
|
||||
self.screen.scroll(SCROLL_FULL, False)
|
||||
|
||||
def destroy(self):
|
||||
if self.vao_id is not None:
|
||||
remove_vao(self.vao_id)
|
||||
self.vao_id = None
|
||||
|
||||
# actions {{{
|
||||
|
||||
def show_scrollback(self):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user