Avoid rendering tab bar more than once per tick

This commit is contained in:
Kovid Goyal 2018-05-03 17:00:18 +05:30
parent 3f316c39d1
commit 86686bfac7
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 37 additions and 16 deletions

View File

@ -451,7 +451,12 @@ class Boss:
w = tm.active_window w = tm.active_window
if w is not None: if w is not None:
w.focus_changed(focused) w.focus_changed(focused)
tm.update_tab_bar() tm.mark_tab_bar_dirty()
def update_tab_bar_data(self, os_window_id):
tm = self.os_window_map.get(os_window_id)
if tm is not None:
tm.update_tab_bar_data()
def on_drop(self, os_window_id, paths): def on_drop(self, os_window_id, paths):
tm = self.os_window_map.get(os_window_id) tm = self.os_window_map.get(os_window_id)

View File

@ -572,6 +572,10 @@ prepare_to_render_os_window(OSWindow *os_window, double now, unsigned int *activ
bool needs_render = os_window->needs_render; bool needs_render = os_window->needs_render;
os_window->needs_render = false; os_window->needs_render = false;
if (TD.screen && os_window->num_tabs > 1) { if (TD.screen && os_window->num_tabs > 1) {
if (!os_window->tab_bar_data_updated) {
call_boss(update_tab_bar_data, "K", os_window->id);
os_window->tab_bar_data_updated = true;
}
if (send_cell_data_to_gpu(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, os_window)) needs_render = true; if (send_cell_data_to_gpu(TD.vao_idx, 0, TD.xstart, TD.ystart, TD.dx, TD.dy, TD.screen, os_window)) needs_render = true;
} }
if (OPT(mouse_hide_wait) > 0 && now - os_window->last_mouse_activity_at > OPT(mouse_hide_wait)) hide_mouse(os_window); if (OPT(mouse_hide_wait) > 0 && now - os_window->last_mouse_activity_at > OPT(mouse_hide_wait)) hide_mouse(os_window);

View File

@ -490,6 +490,14 @@ PYWRAP1(set_titlebar_color) {
Py_RETURN_FALSE; Py_RETURN_FALSE;
} }
PYWRAP1(mark_tab_bar_dirty) {
id_type os_window_id = PyLong_AsUnsignedLongLong(args);
WITH_OS_WINDOW(os_window_id)
os_window->tab_bar_data_updated = false;
END_WITH_OS_WINDOW
Py_RETURN_NONE;
}
static inline bool static inline bool
fix_window_idx(Tab *tab, id_type window_id, unsigned int *window_idx) { fix_window_idx(Tab *tab, id_type window_id, unsigned int *window_idx) {
for (id_type fix = 0; fix < tab->num_windows; fix++) { for (id_type fix = 0; fix < tab->num_windows; fix++) {
@ -615,6 +623,7 @@ static PyMethodDef module_methods[] = {
MW(viewport_for_window, METH_VARARGS), MW(viewport_for_window, METH_VARARGS),
MW(mark_os_window_for_close, METH_VARARGS), MW(mark_os_window_for_close, METH_VARARGS),
MW(set_titlebar_color, METH_VARARGS), MW(set_titlebar_color, METH_VARARGS),
MW(mark_tab_bar_dirty, METH_O),
MW(update_window_visibility, METH_VARARGS), MW(update_window_visibility, METH_VARARGS),
MW(set_boss, METH_O), MW(set_boss, METH_O),
MW(set_display_state, METH_VARARGS), MW(set_display_state, METH_VARARGS),

View File

@ -105,6 +105,7 @@ typedef struct {
unsigned int active_tab, num_tabs, capacity, last_active_tab, last_num_tabs, last_active_window_id; unsigned int active_tab, num_tabs, capacity, last_active_tab, last_num_tabs, last_active_window_id;
bool focused_at_last_render, needs_render; bool focused_at_last_render, needs_render;
ScreenRenderData tab_bar_render_data; ScreenRenderData tab_bar_render_data;
bool tab_bar_data_updated;
bool is_focused; bool is_focused;
double cursor_blink_zero_time, last_mouse_activity_at; double cursor_blink_zero_time, last_mouse_activity_at;
double mouse_x, mouse_y; double mouse_x, mouse_y;

View File

@ -11,9 +11,9 @@ from .child import Child
from .config import build_ansi_color_table from .config import build_ansi_color_table
from .constants import WindowGeometry, appname, get_boss, is_macos, is_wayland from .constants import WindowGeometry, appname, get_boss, is_macos, is_wayland
from .fast_data_types import ( from .fast_data_types import (
DECAWM, Screen, add_tab, glfw_post_empty_event, remove_tab, remove_window, DECAWM, Screen, add_tab, glfw_post_empty_event, mark_tab_bar_dirty,
set_active_tab, set_tab_bar_render_data, swap_tabs, viewport_for_window, remove_tab, remove_window, set_active_tab, set_tab_bar_render_data,
x11_window_id swap_tabs, viewport_for_window, x11_window_id
) )
from .layout import Rect, all_layouts from .layout import Rect, all_layouts
from .session import resolved_shell from .session import resolved_shell
@ -89,7 +89,7 @@ class Tab: # {{{
tm = self.tab_manager_ref() tm = self.tab_manager_ref()
if tm is not None: if tm is not None:
self.relayout_borders() self.relayout_borders()
tm.update_tab_bar() tm.mark_tab_bar_dirty()
@property @property
def active_window(self): def active_window(self):
@ -103,19 +103,19 @@ class Tab: # {{{
self.name = title or '' self.name = title or ''
tm = self.tab_manager_ref() tm = self.tab_manager_ref()
if tm is not None: if tm is not None:
tm.update_tab_bar() tm.mark_tab_bar_dirty()
def title_changed(self, window): def title_changed(self, window):
if window is self.active_window: if window is self.active_window:
tm = self.tab_manager_ref() tm = self.tab_manager_ref()
if tm is not None: if tm is not None:
tm.update_tab_bar() tm.mark_tab_bar_dirty()
def on_bell(self, window): def on_bell(self, window):
tm = self.tab_manager_ref() tm = self.tab_manager_ref()
if tm is not None: if tm is not None:
self.relayout_borders() self.relayout_borders()
tm.update_tab_bar() tm.mark_tab_bar_dirty()
def visible_windows(self): def visible_windows(self):
for w in self.windows: for w in self.windows:
@ -412,7 +412,6 @@ class TabManager: # {{{
for t in startup_session.tabs: for t in startup_session.tabs:
self._add_tab(Tab(self, session_tab=t)) self._add_tab(Tab(self, session_tab=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)))
self.update_tab_bar()
@property @property
def active_tab_idx(self): def active_tab_idx(self):
@ -464,21 +463,24 @@ class TabManager: # {{{
self.resize(only_tabs=True) self.resize(only_tabs=True)
glfw_post_empty_event() glfw_post_empty_event()
def update_tab_bar(self): def mark_tab_bar_dirty(self):
if len(self.tabs) > 1: if len(self.tabs) > 1:
self.tab_bar.update(self.tab_bar_data) mark_tab_bar_dirty(self.os_window_id)
def update_tab_bar_data(self):
self.tab_bar.update(self.tab_bar_data)
def resize(self, only_tabs=False): def resize(self, only_tabs=False):
if not only_tabs: if not only_tabs:
self.tab_bar.layout() self.tab_bar.layout()
self.update_tab_bar() self.mark_tab_bar_dirty()
for tab in self.tabs: for tab in self.tabs:
tab.relayout() tab.relayout()
def set_active_tab_idx(self, idx): def set_active_tab_idx(self, idx):
self._set_active_tab(idx) self._set_active_tab(idx)
self.active_tab.relayout_borders() self.active_tab.relayout_borders()
self.update_tab_bar() self.mark_tab_bar_dirty()
def set_active_tab(self, tab): def set_active_tab(self, tab):
try: try:
@ -531,19 +533,19 @@ class TabManager: # {{{
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(self.os_window_id, 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.mark_tab_bar_dirty()
def new_tab(self, special_window=None, cwd_from=None): def new_tab(self, special_window=None, cwd_from=None):
idx = len(self.tabs) idx = len(self.tabs)
self._add_tab(Tab(self, special_window=special_window, cwd_from=cwd_from)) self._add_tab(Tab(self, special_window=special_window, cwd_from=cwd_from))
self._set_active_tab(idx) self._set_active_tab(idx)
self.update_tab_bar() self.mark_tab_bar_dirty()
return self.tabs[idx] return self.tabs[idx]
def remove(self, tab): def remove(self, tab):
self._remove_tab(tab) self._remove_tab(tab)
self._set_active_tab(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.mark_tab_bar_dirty()
tab.destroy() tab.destroy()
@property @property