Allow controlling placement of bell and activity symbols in the tab title template

Fixes #4581
This commit is contained in:
Kovid Goyal 2022-02-01 08:58:49 +05:30
parent 68d2ea3f27
commit 9c13e8a549
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 46 additions and 43 deletions

View File

@ -92,8 +92,9 @@ Detailed list of changes
- Improve the UI of the ask kitten (:iss:`4545`)
- Allow using templates with text formatting for :opt:`tab_activity_symbol`
(:pull:`4507`)
- Allow customizing the placement and formatting of the
:opt:`tab_activity_symbol` and :opt:`bell_on_tab` symbols
by adding them to the :opt:`tab_title_template` (:iss:`4581`, :pull:`4507`)
- macOS: Persist "Secure Keyboard Entry" across restarts to match the behavior
of Terminal.app (:iss:`4471`)

View File

@ -695,11 +695,17 @@ taskbar flash on linux.
'''
)
opt('bell_on_tab', 'yes',
option_type='to_bool',
opt('bell_on_tab', '"🔔 "',
option_type='bell_on_tab',
long_text='''
Show a bell symbol on the tab if a bell occurs in one of the windows in the tab
and the window is not the currently focused window
Some text or a unicode symbol to show on the tab if a window in the tab that
does not have focus has a bell. If you want to use leading or trailing
spaces surround the text with quotes. See :opt:`tab_title_template` for how
this is rendered.
For backwards compatibility, values of :code:`yes`, :code:`y`, :code:`true` are
converted to the default bell symbol and :code:`no`, :code:`n`, :code:`false`,
:code:`none` are converted to the empty string.
'''
)
@ -1054,16 +1060,15 @@ opt('tab_activity_symbol', 'none',
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. If you want to use leading or trailing spaces
surround the text with quotes. You can also use text formatting via the same templating
system as for :opt:`tab_title_template`.
surround the text with quotes. See :opt:`tab_title_template` for how this is rendered.
'''
)
opt('tab_title_template', '"{title}"',
opt('tab_title_template', '"{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.default}{title}"',
option_type='tab_title_template',
long_text='''
A template to render the tab title. The default just renders the title. If you
wish to include the tab-index as well, use something like: :code:`{index}:
A template to render the tab title. The default just renders the title with optional symbols for bell and activity.
If you wish to include the tab-index as well, use something like: :code:`{index}:
{title}`. Useful if you have shortcuts mapped for :code:`goto_tab N`. If you
prefer to see the index as a superscript, use {sup.index}. In
addition you can use :code:`{layout_name}` for the current layout name,
@ -1077,6 +1082,8 @@ directives, for example:
:code:`{fmt.fg.red}red{fmt.fg.default}normal{fmt.bg._00FF00}green
bg{fmt.bg.tab}`. Similarly, for bold and italic:
:code:`{fmt.bold}bold{fmt.nobold}normal{fmt.italic}italic{fmt.noitalic}`.
Note that for backward compatibility, if :code:`{bell_symbol}` or :code:`{activity_symbol}`
are not present in the template, they are prepended to it.
'''
)

View File

@ -7,7 +7,7 @@ from kitty.conf.utils import (
)
from kitty.options.utils import (
action_alias, active_tab_title_template, adjust_baseline, adjust_line_height, allow_hyperlinks,
allow_remote_control, box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts,
allow_remote_control, bell_on_tab, box_drawing_scale, clear_all_mouse_actions, clear_all_shortcuts,
clipboard_control, config_or_absolute_path, copy_on_select, cursor_text_color,
deprecated_hide_window_decorations_aliases, deprecated_macos_show_window_title_in_menubar_alias,
deprecated_send_text, disable_ligatures, edge_width, env, font_features, hide_window_decorations,
@ -83,7 +83,7 @@ class Parser:
ans['bell_border_color'] = to_color(val)
def bell_on_tab(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['bell_on_tab'] = to_bool(val)
ans['bell_on_tab'] = bell_on_tab(val)
def bell_path(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['bell_path'] = config_or_absolute_path(val)

View File

@ -465,7 +465,7 @@ class Options:
background_opacity: float = 1.0
background_tint: float = 0
bell_border_color: Color = Color(255, 90, 0)
bell_on_tab: bool = True
bell_on_tab: str = '🔔 '
bell_path: typing.Optional[str] = None
bold_font: str = 'auto'
bold_italic_font: str = 'auto'
@ -552,7 +552,7 @@ class Options:
startup_session: typing.Optional[str] = None
strip_trailing_spaces: choices_for_strip_trailing_spaces = 'never'
sync_to_monitor: bool = True
tab_activity_symbol: typing.Optional[str] = None
tab_activity_symbol: str = ''
tab_bar_align: choices_for_tab_bar_align = 'left'
tab_bar_background: typing.Optional[kitty.fast_data_types.Color] = None
tab_bar_edge: int = 3
@ -565,7 +565,7 @@ class Options:
tab_powerline_style: choices_for_tab_powerline_style = 'angled'
tab_separator: str = ''
tab_switch_strategy: choices_for_tab_switch_strategy = 'previous'
tab_title_template: str = '{title}'
tab_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.default}{title}'
term: str = 'xterm-kitty'
touch_scroll_multiplier: float = 1.0
update_check_interval: float = 24.0

View File

@ -639,10 +639,19 @@ def tab_fade(x: str) -> Tuple[float, ...]:
return tuple(map(unit_float, x.split()))
def tab_activity_symbol(x: str) -> Optional[str]:
def tab_activity_symbol(x: str) -> str:
if x == 'none':
return None
return tab_title_template(x) or None
return ''
return tab_title_template(x)
def bell_on_tab(x: str) -> str:
xl = x.lower()
if xl in ('yes', 'y', 'true'):
return '🔔 '
if xl in ('no', 'n', 'false', 'none'):
return ''
return tab_title_template(x)
def tab_title_template(x: str) -> str:

View File

@ -38,8 +38,7 @@ class DrawData(NamedTuple):
leading_spaces: int
sep: str
trailing_spaces: int
bell_on_tab: bool
bell_fg: int
bell_on_tab: str
alpha: Sequence[float]
active_fg: Color
active_bg: Color
@ -48,7 +47,7 @@ class DrawData(NamedTuple):
default_bg: Color
title_template: str
active_title_template: Optional[str]
tab_activity_symbol: Optional[str]
tab_activity_symbol: str
powerline_style: PowerlineStyle
tab_bar_edge: EdgeLiteral
@ -182,28 +181,16 @@ def draw_title(draw_data: DrawData, screen: Screen, tab: TabBarData, index: int)
'fmt': Formatter,
'sup': SupSub(data),
'sub': SupSub(data, True),
'bell_symbol': draw_data.bell_on_tab if tab.needs_attention else '',
'activity_symbol': draw_data.tab_activity_symbol if tab.has_activity_since_last_focus else '',
}
if tab.needs_attention and draw_data.bell_on_tab:
fg = screen.cursor.fg
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:
template = draw_data.tab_activity_symbol
fg = screen.cursor.fg
screen.cursor.fg = draw_data.bell_fg
try:
text = eval(compile_template(template), {'__builtins__': {}}, eval_locals)
except Exception as e:
report_template_failure(template, str(e))
else:
draw_attributed_string(text, screen)
if screen.cursor.fg == draw_data.bell_fg:
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
if '{activity_symbol' not in template:
template = '{fmt.fg.red}{activity_symbol}{fmt.fg.default}' + template
if '{bell_symbol' not in template:
template = '{fmt.fg.red}{bell_symbol}{fmt.fg.default}' + template
try:
title = eval(compile_template(template), {'__builtins__': {}}, eval_locals)
except Exception as e:
@ -445,9 +432,8 @@ class TabBar:
self.active_bg = as_rgb(color_as_int(opts.active_tab_background))
self.active_fg = as_rgb(color_as_int(opts.active_tab_foreground))
self.bell_fg = as_rgb(0xff0000)
self.draw_data = DrawData(
self.leading_spaces, self.sep, self.trailing_spaces, opts.bell_on_tab, self.bell_fg,
self.leading_spaces, self.sep, self.trailing_spaces, opts.bell_on_tab,
opts.tab_fade, opts.active_tab_foreground, opts.active_tab_background,
opts.inactive_tab_foreground, opts.inactive_tab_background,
opts.tab_bar_background or opts.background, opts.tab_title_template,
@ -567,7 +553,7 @@ class TabBar:
if s.cursor.x > s.columns - max_title_length and t is not last_tab:
s.cursor.x = s.columns - 2
s.cursor.bg = as_rgb(color_as_int(self.draw_data.default_bg))
s.cursor.fg = self.bell_fg
s.cursor.fg = as_rgb(0xff0000)
s.draw('')
break
s.erase_in_line(0, False) # Ensure no long titles bleed after the last tab