Add a setting tab_activity_symbol

Fixes #2515
This commit is contained in:
Kovid Goyal
2020-09-08 21:54:56 +05:30
parent 83315f7999
commit 9a54da84dc
8 changed files with 48 additions and 3 deletions
+4
View File
@@ -27,6 +27,10 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- Allow specifying watchers in session files and via a command line argument
(:iss:`2933`)
- Add a setting :opt:`tab_activity_symbol` to show a symbol in the tab title
if one of the windows has some activity after it was last focused
(:iss:`2515`)
- macOS: Switch to using the User Notifications framework for notifications.
The current notifications framework has been deprecated in Big Sur. The new
framework only allows notifications from signed and notarized applications,
+11
View File
@@ -883,6 +883,17 @@ o('tab_separator', '"{}"'.format(default_tab_separator), option_type=tab_separat
The separator between tabs in the tab bar when using :code:`separator` as the :opt:`tab_bar_style`.'''))
def tab_activity_symbol(x: str) -> Optional[str]:
if x == 'none':
return None
return x or None
o('tab_activity_symbol', 'none', option_type=tab_activity_symbol, long_text=_('''
Some text or a unicode symbol to show on the tab if a window in the tab that does
not have focus has some activity.'''))
def tab_title_template(x: str) -> str:
if x:
for q in '\'"':
+3
View File
@@ -1069,6 +1069,9 @@ class Screen:
def has_focus(self) -> bool:
pass
def has_activity_since_last_focus(self) -> bool:
pass
def set_tab_bar_render_data(
os_window_id: int, xstart: float, ystart: float, dx: float, dy: float,
+10
View File
@@ -444,6 +444,9 @@ draw_combining_char(Screen *self, char_type ch) {
void
screen_draw(Screen *self, uint32_t och) {
if (is_ignored_char(och)) return;
if (!self->has_activity_since_last_focus && !self->has_focus) {
self->has_activity_since_last_focus = true;
}
uint32_t ch = och < 256 ? self->g_charset[och] : och;
bool is_cc = is_combining_char(ch);
if (UNLIKELY(is_cc)) {
@@ -2531,6 +2534,7 @@ focus_changed(Screen *self, PyObject *has_focus_) {
bool has_focus = PyObject_IsTrue(has_focus_) ? true : false;
if (has_focus != previous) {
self->has_focus = has_focus;
if (has_focus) self->has_activity_since_last_focus = false;
if (self->modes.mFOCUS_TRACKING) write_escape_code_to_child(self, CSI, has_focus ? "I" : "O");
Py_RETURN_TRUE;
}
@@ -2543,6 +2547,11 @@ has_focus(Screen *self, PyObject *args UNUSED) {
Py_RETURN_FALSE;
}
static PyObject*
has_activity_since_last_focus(Screen *self, PyObject *args UNUSED) {
if (self->has_activity_since_last_focus) Py_RETURN_TRUE;
Py_RETURN_FALSE;
}
WRAP2(cursor_position, 1, 1)
@@ -2628,6 +2637,7 @@ static PyMethodDef methods[] = {
MND(paste_bytes, METH_O)
MND(focus_changed, METH_O)
MND(has_focus, METH_NOARGS)
MND(has_activity_since_last_focus, METH_NOARGS)
MND(copy_colors_from, METH_O)
MND(set_marker, METH_VARARGS)
MND(marked_cells, METH_NOARGS)
+1
View File
@@ -122,6 +122,7 @@ typedef struct {
DisableLigature disable_ligatures;
PyObject *marker;
bool has_focus;
bool has_activity_since_last_focus;
} Screen;
+10 -1
View File
@@ -24,6 +24,7 @@ class TabBarData(NamedTuple):
needs_attention: bool
num_windows: int
layout_name: str
has_activity_since_last_focus: bool
class DrawData(NamedTuple):
@@ -40,6 +41,7 @@ class DrawData(NamedTuple):
default_bg: Color
title_template: str
active_title_template: Optional[str]
tab_activity_symbol: Optional[str]
def as_rgb(x: int) -> int:
@@ -65,6 +67,12 @@ def draw_title(draw_data: DrawData, screen: Screen, tab: TabBarData, index: int)
screen.cursor.fg = draw_data.bell_fg
screen.draw('🔔 ')
screen.cursor.fg = fg
if tab.has_activity_since_last_focus and draw_data.tab_activity_symbol:
fg = screen.cursor.fg
screen.cursor.fg = draw_data.bell_fg
screen.draw(draw_data.tab_activity_symbol)
screen.cursor.fg = fg
template = draw_data.title_template
if tab.is_active and draw_data.active_title_template is not None:
template = draw_data.active_title_template
@@ -226,7 +234,8 @@ class TabBar:
self.opts.tab_fade, self.opts.active_tab_foreground, self.opts.active_tab_background,
self.opts.inactive_tab_foreground, self.opts.inactive_tab_background,
self.opts.tab_bar_background or self.opts.background, self.opts.tab_title_template,
self.opts.active_tab_title_template
self.opts.active_tab_title_template,
self.opts.tab_activity_symbol
)
if self.opts.tab_bar_style == 'separator':
self.draw_func = draw_tab_with_separator
+5 -2
View File
@@ -736,13 +736,16 @@ class TabManager: # {{{
for t in self.tabs:
title = (t.name or t.title or appname).strip()
needs_attention = False
has_activity_since_last_focus = False
for w in t:
if w.needs_attention:
needs_attention = True
break
if w.has_activity_since_last_focus:
has_activity_since_last_focus = True
ans.append(TabBarData(
title, t is at, needs_attention,
len(t), t.current_layout.name or ''
len(t), t.current_layout.name or '',
has_activity_since_last_focus
))
return ans
+4
View File
@@ -514,6 +514,10 @@ class Window:
def is_active(self) -> bool:
return get_boss().active_window is self
@property
def has_activity_since_last_focus(self) -> bool:
return self.screen.has_activity_since_last_focus()
def on_bell(self) -> None:
if self.opts.command_on_bell and self.opts.command_on_bell != ['none']:
import subprocess