Move render call for tab bar to C code
This commit is contained in:
parent
2e0cbb88bb
commit
943a1575ad
@ -15,8 +15,8 @@ from .constants import (
|
|||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
GLFW_CURSOR, GLFW_CURSOR_HIDDEN, GLFW_CURSOR_NORMAL, GLFW_MOUSE_BUTTON_1,
|
GLFW_CURSOR, GLFW_CURSOR_HIDDEN, GLFW_CURSOR_NORMAL, GLFW_MOUSE_BUTTON_1,
|
||||||
GLFW_PRESS, GLFW_REPEAT, ChildMonitor, Timers as _Timers,
|
GLFW_PRESS, GLFW_REPEAT, ChildMonitor, Timers as _Timers,
|
||||||
destroy_sprite_map, glfw_post_empty_event, layout_sprite_map,
|
destroy_global_data, destroy_sprite_map, glfw_post_empty_event,
|
||||||
resize_gl_viewport
|
layout_sprite_map, resize_gl_viewport
|
||||||
)
|
)
|
||||||
from .fonts.render import render_cell_wrapper, set_font_family
|
from .fonts.render import render_cell_wrapper, set_font_family
|
||||||
from .keys import (
|
from .keys import (
|
||||||
@ -365,7 +365,6 @@ class Boss:
|
|||||||
self.glfw_window.set_title(self.glfw_window_title)
|
self.glfw_window.set_title(self.glfw_window_title)
|
||||||
if isosx:
|
if isosx:
|
||||||
cocoa_update_title(self.glfw_window_title)
|
cocoa_update_title(self.glfw_window_title)
|
||||||
self.tab_manager.render()
|
|
||||||
for window in tab.visible_windows():
|
for window in tab.visible_windows():
|
||||||
if not window.needs_layout:
|
if not window.needs_layout:
|
||||||
window.char_grid.render_cells()
|
window.char_grid.render_cells()
|
||||||
@ -408,6 +407,7 @@ class Boss:
|
|||||||
t.destroy()
|
t.destroy()
|
||||||
del self.tab_manager
|
del self.tab_manager
|
||||||
destroy_sprite_map()
|
destroy_sprite_map()
|
||||||
|
destroy_global_data()
|
||||||
del self.glfw_window
|
del self.glfw_window
|
||||||
|
|
||||||
def paste_from_clipboard(self):
|
def paste_from_clipboard(self):
|
||||||
|
|||||||
@ -424,6 +424,7 @@ pyset_iutf8(ChildMonitor *self, PyObject *args) {
|
|||||||
|
|
||||||
static double last_render_at = -DBL_MAX;
|
static double last_render_at = -DBL_MAX;
|
||||||
draw_borders_func draw_borders = NULL;
|
draw_borders_func draw_borders = NULL;
|
||||||
|
draw_cells_func draw_cells = NULL;
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
render(ChildMonitor *self, double *timeout) {
|
render(ChildMonitor *self, double *timeout) {
|
||||||
@ -432,6 +433,9 @@ render(ChildMonitor *self, double *timeout) {
|
|||||||
double time_since_last_render = now - last_render_at;
|
double time_since_last_render = now - last_render_at;
|
||||||
if (time_since_last_render > self->repaint_delay) {
|
if (time_since_last_render > self->repaint_delay) {
|
||||||
draw_borders();
|
draw_borders();
|
||||||
|
#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
|
||||||
ret = PyObject_CallFunctionObjArgs(self->render_func, NULL);
|
ret = PyObject_CallFunctionObjArgs(self->render_func, NULL);
|
||||||
if (ret == NULL) { PyErr_Print(); return false; }
|
if (ret == NULL) { PyErr_Print(); return false; }
|
||||||
else Py_DECREF(ret);
|
else Py_DECREF(ret);
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#define MIN(x, y) (((x) > (y)) ? (y) : (x))
|
#define MIN(x, y) (((x) > (y)) ? (y) : (x))
|
||||||
#define xstr(s) str(s)
|
#define xstr(s) str(s)
|
||||||
#define str(s) #s
|
#define str(s) #s
|
||||||
|
#define fatal(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); exit(EXIT_FAILURE); }
|
||||||
|
|
||||||
typedef uint32_t char_type;
|
typedef uint32_t char_type;
|
||||||
typedef uint32_t color_type;
|
typedef uint32_t color_type;
|
||||||
@ -292,8 +293,22 @@ typedef struct {
|
|||||||
bool enable_audio_bell;
|
bool enable_audio_bell;
|
||||||
} Options;
|
} Options;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int id;
|
||||||
|
} Tab;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ssize_t vao_idx;
|
||||||
|
float xstart, ystart, dx, dy;
|
||||||
|
Screen *screen;
|
||||||
|
} ScreenRenderData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Options opts;
|
Options opts;
|
||||||
|
|
||||||
|
Tab tabs[MAX_CHILDREN];
|
||||||
|
unsigned int active_tab, num_tabs;
|
||||||
|
ScreenRenderData tab_bar_render_data;
|
||||||
} GlobalState;
|
} GlobalState;
|
||||||
|
|
||||||
#ifndef IS_STATE
|
#ifndef IS_STATE
|
||||||
@ -313,6 +328,8 @@ extern GlobalState global_state;
|
|||||||
|
|
||||||
typedef void (*draw_borders_func)();
|
typedef void (*draw_borders_func)();
|
||||||
extern draw_borders_func draw_borders;
|
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
|
// Global functions
|
||||||
Line* alloc_line();
|
Line* alloc_line();
|
||||||
|
|||||||
@ -33,8 +33,6 @@ static char glbuf[4096];
|
|||||||
#define GL_STACK_OVERFLOW 0x0503
|
#define GL_STACK_OVERFLOW 0x0503
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define fatal(...) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); exit(EXIT_FAILURE); }
|
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUG_GL
|
#ifdef ENABLE_DEBUG_GL
|
||||||
static void
|
static void
|
||||||
check_for_gl_error(int line) {
|
check_for_gl_error(int line) {
|
||||||
@ -596,7 +594,7 @@ create_cell_vao() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
draw_cells(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen) {
|
draw_cells_impl(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen) {
|
||||||
size_t sz;
|
size_t sz;
|
||||||
void *address;
|
void *address;
|
||||||
bool inverted = screen_invert_colors(screen);
|
bool inverted = screen_invert_colors(screen);
|
||||||
@ -842,7 +840,7 @@ PYWRAP1(draw_cells) {
|
|||||||
Screen *screen;
|
Screen *screen;
|
||||||
|
|
||||||
PA("iffffO", &vao_idx, &xstart, &ystart, &dx, &dy, &screen);
|
PA("iffffO", &vao_idx, &xstart, &ystart, &dx, &dy, &screen);
|
||||||
draw_cells(vao_idx, xstart, ystart, dx, dy, screen);
|
draw_cells_impl(vao_idx, xstart, ystart, dx, dy, screen);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
NO_ARG(destroy_sprite_map)
|
NO_ARG(destroy_sprite_map)
|
||||||
@ -900,6 +898,7 @@ PYWRAP0(check_for_extensions) {
|
|||||||
#define MW(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}
|
#define MW(name, arg_type) {#name, (PyCFunction)py##name, arg_type, NULL}
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
{"glewInit", (PyCFunction)glew_init, METH_NOARGS, NULL},
|
{"glewInit", (PyCFunction)glew_init, METH_NOARGS, NULL},
|
||||||
|
{"draw_cells", (PyCFunction)pydraw_cells, METH_VARARGS, NULL},
|
||||||
M(compile_program, METH_VARARGS),
|
M(compile_program, METH_VARARGS),
|
||||||
MW(check_for_extensions, METH_NOARGS),
|
MW(check_for_extensions, METH_NOARGS),
|
||||||
MW(create_vao, METH_NOARGS),
|
MW(create_vao, METH_NOARGS),
|
||||||
@ -917,7 +916,6 @@ static PyMethodDef module_methods[] = {
|
|||||||
MW(send_borders_rects, METH_VARARGS),
|
MW(send_borders_rects, METH_VARARGS),
|
||||||
MW(init_cell_program, METH_NOARGS),
|
MW(init_cell_program, METH_NOARGS),
|
||||||
MW(create_cell_vao, METH_NOARGS),
|
MW(create_cell_vao, METH_NOARGS),
|
||||||
MW(draw_cells, METH_VARARGS),
|
|
||||||
MW(layout_sprite_map, METH_VARARGS),
|
MW(layout_sprite_map, METH_VARARGS),
|
||||||
MW(destroy_sprite_map, METH_NOARGS),
|
MW(destroy_sprite_map, METH_NOARGS),
|
||||||
MW(resize_gl_viewport, METH_VARARGS),
|
MW(resize_gl_viewport, METH_VARARGS),
|
||||||
@ -965,6 +963,7 @@ init_shaders(PyObject *module) {
|
|||||||
PyModule_AddObject(module, "GL_VERSION_REQUIRED", Py_BuildValue("II", REQUIRED_VERSION_MAJOR, REQUIRED_VERSION_MINOR));
|
PyModule_AddObject(module, "GL_VERSION_REQUIRED", Py_BuildValue("II", REQUIRED_VERSION_MAJOR, REQUIRED_VERSION_MINOR));
|
||||||
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
if (PyModule_AddFunctions(module, module_methods) != 0) return false;
|
||||||
draw_borders = &draw_borders_impl;
|
draw_borders = &draw_borders_impl;
|
||||||
|
draw_cells = &draw_cells_impl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|||||||
@ -8,15 +8,55 @@
|
|||||||
#define IS_STATE
|
#define IS_STATE
|
||||||
#include "data-types.h"
|
#include "data-types.h"
|
||||||
|
|
||||||
|
GlobalState global_state = {{0}};
|
||||||
|
static const Tab EMPTY_TAB = {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) { \
|
||||||
|
size_t capacity = sizeof(array)/sizeof(array[0]); \
|
||||||
|
for (size_t i = 0; i < count; i++) { \
|
||||||
|
if (array[i].id == qid) { \
|
||||||
|
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)--; \
|
||||||
|
} \
|
||||||
|
}}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
add_tab(unsigned int id) {
|
||||||
|
ensure_can_add(global_state.tabs, global_state.num_tabs, "Too many children (add_tab)");
|
||||||
|
global_state.tabs[global_state.num_tabs] = EMPTY_TAB;
|
||||||
|
global_state.tabs[global_state.num_tabs].id = id;
|
||||||
|
global_state.num_tabs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
remove_tab(unsigned int id) {
|
||||||
|
REMOVER(global_state.tabs, id, global_state.num_tabs, EMPTY_TAB, Tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
set_active_tab(unsigned int idx) {
|
||||||
|
global_state.active_tab = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
swap_tabs(unsigned int a, unsigned int b) {
|
||||||
|
Tab t = global_state.tabs[b];
|
||||||
|
global_state.tabs[b] = global_state.tabs[a];
|
||||||
|
global_state.tabs[a] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Python API {{{
|
||||||
#define PYWRAP0(name) static PyObject* py##name(PyObject UNUSED *self)
|
#define PYWRAP0(name) static PyObject* py##name(PyObject UNUSED *self)
|
||||||
#define PYWRAP1(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args)
|
#define PYWRAP1(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args)
|
||||||
#define PYWRAP2(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args, PyObject *kw)
|
#define PYWRAP2(name) static PyObject* py##name(PyObject UNUSED *self, PyObject *args, PyObject *kw)
|
||||||
#define PA(fmt, ...) if(!PyArg_ParseTuple(args, fmt, __VA_ARGS__)) return NULL;
|
#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; }
|
||||||
|
|
||||||
GlobalState global_state = {{0}};
|
|
||||||
|
|
||||||
|
|
||||||
// Python API {{{
|
|
||||||
PYWRAP1(set_options) {
|
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); }
|
#define S(name, convert) { PyObject *ret = PyObject_GetAttrString(args, #name); if (ret == NULL) return NULL; global_state.opts.name = convert(ret); Py_DECREF(ret); }
|
||||||
S(visual_bell_duration, PyFloat_AsDouble);
|
S(visual_bell_duration, PyFloat_AsDouble);
|
||||||
@ -25,10 +65,36 @@ PYWRAP1(set_options) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PYWRAP1(set_tab_bar_render_data) {
|
||||||
|
#define A(name) &(global_state.tab_bar_render_data.name)
|
||||||
|
Py_CLEAR(global_state.tab_bar_render_data.screen);
|
||||||
|
PA("iffffO", A(vao_idx), A(xstart), A(ystart), A(dx), A(dy), A(screen));
|
||||||
|
Py_INCREF(global_state.tab_bar_render_data.screen);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
#undef A
|
||||||
|
}
|
||||||
|
|
||||||
|
PYWRAP0(destroy_global_data) {
|
||||||
|
Py_CLEAR(global_state.tab_bar_render_data.screen);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ONE_UINT(add_tab)
|
||||||
|
ONE_UINT(remove_tab)
|
||||||
|
ONE_UINT(set_active_tab)
|
||||||
|
TWO_UINT(swap_tabs)
|
||||||
|
|
||||||
#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}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
MW(set_options, METH_O),
|
MW(set_options, METH_O),
|
||||||
|
MW(add_tab, METH_O),
|
||||||
|
MW(remove_tab, METH_O),
|
||||||
|
MW(set_active_tab, METH_O),
|
||||||
|
MW(swap_tabs, METH_VARARGS),
|
||||||
|
MW(set_tab_bar_render_data, METH_VARARGS),
|
||||||
|
MW(destroy_global_data, METH_NOARGS),
|
||||||
|
|
||||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,17 +4,18 @@
|
|||||||
|
|
||||||
from collections import deque, namedtuple
|
from collections import deque, namedtuple
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from itertools import count
|
||||||
|
|
||||||
from .borders import Borders
|
from .borders import Borders
|
||||||
from .char_grid import calculate_gl_geometry, render_cells
|
from .char_grid import calculate_gl_geometry
|
||||||
from .child import Child
|
from .child import Child
|
||||||
from .config import build_ansi_color_table
|
from .config import build_ansi_color_table
|
||||||
from .constants import (
|
from .constants import (
|
||||||
WindowGeometry, appname, cell_size, get_boss, shell_path,
|
WindowGeometry, appname, cell_size, get_boss, shell_path, viewport_size
|
||||||
viewport_size
|
|
||||||
)
|
)
|
||||||
from .fast_data_types import (
|
from .fast_data_types import (
|
||||||
DECAWM, Screen, create_cell_vao, glfw_post_empty_event
|
DECAWM, Screen, add_tab, create_cell_vao, glfw_post_empty_event,
|
||||||
|
remove_tab, set_active_tab, swap_tabs, set_tab_bar_render_data
|
||||||
)
|
)
|
||||||
from .layout import Rect, all_layouts
|
from .layout import Rect, all_layouts
|
||||||
from .utils import color_as_int
|
from .utils import color_as_int
|
||||||
@ -22,16 +23,19 @@ from .window import Window
|
|||||||
|
|
||||||
TabbarData = namedtuple('TabbarData', 'title is_active is_last')
|
TabbarData = namedtuple('TabbarData', 'title is_active is_last')
|
||||||
borders = None
|
borders = None
|
||||||
|
tab_counter = count()
|
||||||
|
next(tab_counter)
|
||||||
|
|
||||||
|
|
||||||
def SpecialWindow(cmd, stdin=None, override_title=None):
|
def SpecialWindow(cmd, stdin=None, override_title=None):
|
||||||
return (cmd, stdin, override_title)
|
return (cmd, stdin, override_title)
|
||||||
|
|
||||||
|
|
||||||
class Tab:
|
class Tab: # {{{
|
||||||
|
|
||||||
def __init__(self, opts, args, on_title_change, session_tab=None, special_window=None):
|
def __init__(self, opts, args, on_title_change, session_tab=None, special_window=None):
|
||||||
global borders
|
global borders
|
||||||
|
self.id = next(tab_counter)
|
||||||
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
|
||||||
@ -199,9 +203,10 @@ class Tab:
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Tab(title={}, id={})'.format(self.name or self.title, hex(id(self)))
|
return 'Tab(title={}, id={})'.format(self.name or self.title, hex(id(self)))
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class TabBar:
|
class TabBar: # {{{
|
||||||
|
|
||||||
def __init__(self, opts):
|
def __init__(self, opts):
|
||||||
self.num_tabs = 1
|
self.num_tabs = 1
|
||||||
@ -238,7 +243,8 @@ class TabBar:
|
|||||||
self.tab_bar_blank_rects = (Rect(0, g.top, g.left, g.bottom), Rect(g.right - 1, g.top, viewport_width, g.bottom))
|
self.tab_bar_blank_rects = (Rect(0, g.top, g.left, g.bottom), Rect(g.right - 1, g.top, viewport_width, g.bottom))
|
||||||
else:
|
else:
|
||||||
self.tab_bar_blank_rects = ()
|
self.tab_bar_blank_rects = ()
|
||||||
self.screen_geometry = 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)
|
||||||
|
|
||||||
def update(self, data):
|
def update(self, data):
|
||||||
if self.layout_changed is None:
|
if self.layout_changed is None:
|
||||||
@ -270,18 +276,15 @@ class TabBar:
|
|||||||
self.cell_ranges = cr
|
self.cell_ranges = cr
|
||||||
glfw_post_empty_event()
|
glfw_post_empty_event()
|
||||||
|
|
||||||
def render(self):
|
|
||||||
if self.layout_changed is not None:
|
|
||||||
render_cells(self.vao_id, self.screen_geometry, self.screen)
|
|
||||||
|
|
||||||
def tab_at(self, x):
|
def tab_at(self, x):
|
||||||
x = (x - self.window_geometry.left) // self.cell_width
|
x = (x - self.window_geometry.left) // self.cell_width
|
||||||
for i, (a, b) in enumerate(self.cell_ranges):
|
for i, (a, b) in enumerate(self.cell_ranges):
|
||||||
if a <= x <= b:
|
if a <= x <= b:
|
||||||
return i
|
return i
|
||||||
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
class TabManager:
|
class TabManager: # {{{
|
||||||
|
|
||||||
def __init__(self, opts, args):
|
def __init__(self, opts, args):
|
||||||
self.opts, self.args = opts, args
|
self.opts, self.args = opts, args
|
||||||
@ -291,9 +294,22 @@ class TabManager:
|
|||||||
self.tab_bar.layout(*self.tab_bar_layout_data)
|
self.tab_bar.layout(*self.tab_bar_layout_data)
|
||||||
self.active_tab_idx = 0
|
self.active_tab_idx = 0
|
||||||
|
|
||||||
|
def _add_tab(self, tab):
|
||||||
|
add_tab(tab.id)
|
||||||
|
self.tabs.append(tab)
|
||||||
|
|
||||||
|
def _remove_tab(self, tab):
|
||||||
|
remove_tab(tab.id)
|
||||||
|
self.tabs.remove(tab)
|
||||||
|
|
||||||
|
def _set_active_tab(self, idx):
|
||||||
|
self.active_tab_idx = idx
|
||||||
|
set_active_tab(idx)
|
||||||
|
|
||||||
def init(self, startup_session):
|
def init(self, startup_session):
|
||||||
self.tabs = [Tab(self.opts, self.args, self.title_changed, t) for t in startup_session.tabs]
|
for t in startup_session.tabs:
|
||||||
self.active_tab_idx = startup_session.active_tab_idx
|
self._add_tab(Tab(self.opts, self.args, self.title_changed, t))
|
||||||
|
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()
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
@ -310,7 +326,7 @@ class TabManager:
|
|||||||
tab.relayout()
|
tab.relayout()
|
||||||
|
|
||||||
def set_active_tab(self, idx):
|
def set_active_tab(self, idx):
|
||||||
self.active_tab_idx = idx
|
self._set_active_tab(idx)
|
||||||
self.active_tab.relayout_borders()
|
self.active_tab.relayout_borders()
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
|
|
||||||
@ -337,7 +353,8 @@ 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]
|
||||||
self.active_tab_idx = nidx
|
swap_tabs(idx, nidx)
|
||||||
|
self._set_active_tab(nidx)
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
|
|
||||||
def title_changed(self, new_title):
|
def title_changed(self, new_title):
|
||||||
@ -345,16 +362,17 @@ 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
|
||||||
self.active_tab_idx = len(self.tabs)
|
idx = len(self.tabs)
|
||||||
self.tabs.append(Tab(self.opts, self.args, self.title_changed, special_window=special_window))
|
self._add_tab(Tab(self.opts, self.args, self.title_changed, special_window=special_window))
|
||||||
|
self._set_active_tab(idx)
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
if needs_resize:
|
if needs_resize:
|
||||||
get_boss().tabbar_visibility_changed()
|
get_boss().tabbar_visibility_changed()
|
||||||
|
|
||||||
def remove(self, tab):
|
def remove(self, tab):
|
||||||
needs_resize = len(self.tabs) == 2
|
needs_resize = len(self.tabs) == 2
|
||||||
self.tabs.remove(tab)
|
self._remove_tab(tab)
|
||||||
self.active_tab_idx = max(0, min(self.active_tab_idx, len(self.tabs) - 1))
|
self._set_active_tab(max(0, min(self.active_tab_idx, len(self.tabs) - 1)))
|
||||||
self.update_tab_bar()
|
self.update_tab_bar()
|
||||||
tab.destroy()
|
tab.destroy()
|
||||||
if needs_resize:
|
if needs_resize:
|
||||||
@ -386,3 +404,4 @@ class TabManager:
|
|||||||
if len(self.tabs) < 2:
|
if len(self.tabs) < 2:
|
||||||
return
|
return
|
||||||
self.tab_bar.render()
|
self.tab_bar.render()
|
||||||
|
# }}}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user