Show a bell on the tab if a bell occurs in one of the windows in the tab and the window is not the currently focused window. Fixes #514
This commit is contained in:
parent
2a52acdef4
commit
efcd3a5df7
@ -6,6 +6,9 @@ kitty is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
|||||||
version 0.9.1 [future]
|
version 0.9.1 [future]
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
- Show a bell on the tab if a bell occurs in one of the windows in the tab and
|
||||||
|
the window is not the currently focused window
|
||||||
|
|
||||||
- macOS: Add support for dead keys
|
- macOS: Add support for dead keys
|
||||||
|
|
||||||
- Unicode input: When searching by name search for prefix matches as well as
|
- Unicode input: When searching by name search for prefix matches as well as
|
||||||
|
|||||||
@ -451,6 +451,7 @@ 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()
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@ -1077,6 +1077,7 @@ void
|
|||||||
screen_bell(Screen *self) {
|
screen_bell(Screen *self) {
|
||||||
request_window_attention(self->window_id, OPT(enable_audio_bell));
|
request_window_attention(self->window_id, OPT(enable_audio_bell));
|
||||||
if (OPT(visual_bell_duration) > 0.0f) self->start_visual_bell_at = monotonic();
|
if (OPT(visual_bell_duration) > 0.0f) self->start_visual_bell_at = monotonic();
|
||||||
|
CALLBACK("on_bell", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@ -20,7 +20,7 @@ from .session import resolved_shell
|
|||||||
from .utils import color_as_int, log_error
|
from .utils import color_as_int, log_error
|
||||||
from .window import Window, calculate_gl_geometry
|
from .window import Window, calculate_gl_geometry
|
||||||
|
|
||||||
TabbarData = namedtuple('TabbarData', 'title is_active is_last')
|
TabbarData = namedtuple('TabbarData', 'title is_active is_last needs_attention')
|
||||||
SpecialWindowInstance = namedtuple('SpecialWindow', 'cmd stdin override_title cwd_from cwd overlay_for env')
|
SpecialWindowInstance = namedtuple('SpecialWindow', 'cmd stdin override_title cwd_from cwd overlay_for env')
|
||||||
|
|
||||||
|
|
||||||
@ -110,6 +110,11 @@ class Tab: # {{{
|
|||||||
if tm is not None:
|
if tm is not None:
|
||||||
tm.update_tab_bar()
|
tm.update_tab_bar()
|
||||||
|
|
||||||
|
def on_bell(self, window):
|
||||||
|
tm = self.tab_manager_ref()
|
||||||
|
if tm is not None:
|
||||||
|
tm.update_tab_bar()
|
||||||
|
|
||||||
def visible_windows(self):
|
def visible_windows(self):
|
||||||
for w in self.windows:
|
for w in self.windows:
|
||||||
if w.is_visible_in_layout:
|
if w.is_visible_in_layout:
|
||||||
@ -310,6 +315,7 @@ class TabBar: # {{{
|
|||||||
|
|
||||||
self.active_bg = as_rgb(color_as_int(opts.active_tab_background))
|
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.active_fg = as_rgb(color_as_int(opts.active_tab_foreground))
|
||||||
|
self.bell_fg = as_rgb(0xff0000)
|
||||||
|
|
||||||
def patch_colors(self, spec):
|
def patch_colors(self, spec):
|
||||||
if 'active_tab_foreground' in spec:
|
if 'active_tab_foreground' in spec:
|
||||||
@ -353,10 +359,18 @@ class TabBar: # {{{
|
|||||||
|
|
||||||
for t in data:
|
for t in data:
|
||||||
s.cursor.bg = self.active_bg if t.is_active else 0
|
s.cursor.bg = self.active_bg if t.is_active else 0
|
||||||
s.cursor.fg = self.active_fg if t.is_active else 0
|
s.cursor.fg = fg = self.active_fg if t.is_active else 0
|
||||||
s.cursor.bold, s.cursor.italic = self.active_font_style if t.is_active else self.inactive_font_style
|
s.cursor.bold, s.cursor.italic = self.active_font_style if t.is_active else self.inactive_font_style
|
||||||
before = s.cursor.x
|
before = s.cursor.x
|
||||||
s.draw(' ' * self.leading_spaces + t.title + ' ' * self.trailing_spaces)
|
if self.leading_spaces:
|
||||||
|
s.draw(' ' * self.leading_spaces)
|
||||||
|
if t.needs_attention:
|
||||||
|
s.cursor.fg = self.bell_fg
|
||||||
|
s.draw('🔔 ')
|
||||||
|
s.cursor.fg = fg
|
||||||
|
s.draw(t.title)
|
||||||
|
if self.trailing_spaces:
|
||||||
|
s.draw(' ' * self.trailing_spaces)
|
||||||
extra = s.cursor.x - before - max_title_length
|
extra = s.cursor.x - before - max_title_length
|
||||||
if extra > 0:
|
if extra > 0:
|
||||||
s.cursor.x -= extra + 1
|
s.cursor.x -= extra + 1
|
||||||
@ -536,7 +550,12 @@ class TabManager: # {{{
|
|||||||
ans = []
|
ans = []
|
||||||
for t in self.tabs:
|
for t in self.tabs:
|
||||||
title = (t.name or t.title or appname).strip()
|
title = (t.name or t.title or appname).strip()
|
||||||
ans.append(TabbarData(title, t is at, t is self.tabs[-1]))
|
needs_attention = False
|
||||||
|
for w in t:
|
||||||
|
if w.needs_attention:
|
||||||
|
needs_attention = True
|
||||||
|
break
|
||||||
|
ans.append(TabbarData(title, t is at, t is self.tabs[-1], needs_attention))
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
def activate_tab_at(self, x):
|
def activate_tab_at(self, x):
|
||||||
|
|||||||
@ -90,6 +90,7 @@ class Window:
|
|||||||
|
|
||||||
def __init__(self, tab, child, opts, args, override_title=None):
|
def __init__(self, tab, child, opts, args, override_title=None):
|
||||||
self.action_on_close = None
|
self.action_on_close = None
|
||||||
|
self.needs_attention = False
|
||||||
self.override_title = override_title
|
self.override_title = override_title
|
||||||
self.overlay_window_id = None
|
self.overlay_window_id = None
|
||||||
self.overlay_for = None
|
self.overlay_for = None
|
||||||
@ -214,6 +215,7 @@ class Window:
|
|||||||
|
|
||||||
def focus_changed(self, focused):
|
def focus_changed(self, focused):
|
||||||
if focused:
|
if focused:
|
||||||
|
self.needs_attention = False
|
||||||
if self.screen.focus_tracking_enabled:
|
if self.screen.focus_tracking_enabled:
|
||||||
self.screen.send_escape_code_to_child(CSI, 'I')
|
self.screen.send_escape_code_to_child(CSI, 'I')
|
||||||
else:
|
else:
|
||||||
@ -228,6 +230,17 @@ class Window:
|
|||||||
def icon_changed(self, new_icon):
|
def icon_changed(self, new_icon):
|
||||||
pass # TODO: Implement this
|
pass # TODO: Implement this
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_active(self):
|
||||||
|
return get_boss().active_window is self
|
||||||
|
|
||||||
|
def on_bell(self):
|
||||||
|
if not self.is_active:
|
||||||
|
self.needs_attention = True
|
||||||
|
tab = self.tabref()
|
||||||
|
if tab is not None:
|
||||||
|
tab.on_bell(self)
|
||||||
|
|
||||||
def change_titlebar_color(self):
|
def change_titlebar_color(self):
|
||||||
val = self.opts.macos_titlebar_color
|
val = self.opts.macos_titlebar_color
|
||||||
if val:
|
if val:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user