Merge branch 'feat-draggable-window-title-bars' of https://github.com/mcrmck/kitty

This commit is contained in:
Kovid Goyal
2026-03-28 10:02:14 +05:30
22 changed files with 595 additions and 35 deletions

View File

@@ -1562,6 +1562,16 @@ opt('window_title_bar_align', 'center',
choices=('left', 'center', 'right'),
long_text='Horizontal alignment of the text in window title bars.'
)
opt('window_title_bar_drag_threshold', '5',
option_type='positive_int',
long_text='''
Pixel distance the mouse must move before a window title bar drag begins.
Zero disables dragging. Drop on a title bar swaps positions; drop on a
window body inserts in the quadrant direction (left/right/top/bottom).
Drop on the tab bar moves the window to that tab; drop outside kitty
detaches it to a new OS window.
''')
egr() # }}}
@@ -1637,6 +1647,16 @@ The horizontal alignment of the tab bar, can be one of: :code:`left`,
'''
)
opt('tab_bar_show_new_tab_button', 'no', option_type='to_bool', ctype='bool',
long_text='''
When set to :code:`yes`, a :code:`+` button is always shown at the end of the
tab bar as a clickable shortcut to open a new tab. When set to :code:`no`
(the default), the button is hidden at rest but still appears temporarily
while a window is being dragged, so it can be used as a drop target to open
the window in a new tab.
'''
)
opt('tab_bar_min_tabs', '2', option_type='tab_bar_min_tabs',
long_text='The minimum number of tabs that must exist before the tab bar is shown.'
)

View File

@@ -1359,6 +1359,9 @@ class Parser:
def tab_bar_min_tabs(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['tab_bar_min_tabs'] = tab_bar_min_tabs(val)
def tab_bar_show_new_tab_button(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['tab_bar_show_new_tab_button'] = to_bool(val)
def tab_bar_style(self, val: str, ans: dict[str, typing.Any]) -> None:
val = val.lower()
if val not in self.choices_for_tab_bar_style:
@@ -1537,6 +1540,9 @@ class Parser:
choices_for_window_title_bar_align = choices_for_tab_bar_align
def window_title_bar_drag_threshold(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['window_title_bar_drag_threshold'] = positive_int(val)
def window_title_bar_inactive_background(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['window_title_bar_inactive_background'] = to_color_or_none(val)

View File

@@ -462,6 +462,7 @@ option_names = (
'tab_bar_margin_height',
'tab_bar_margin_width',
'tab_bar_min_tabs',
'tab_bar_show_new_tab_button',
'tab_bar_style',
'tab_fade',
'tab_powerline_style',
@@ -506,6 +507,7 @@ option_names = (
'window_title_bar_active_background',
'window_title_bar_active_foreground',
'window_title_bar_align',
'window_title_bar_drag_threshold',
'window_title_bar_inactive_background',
'window_title_bar_inactive_foreground',
'window_title_bar_min_windows',
@@ -665,6 +667,7 @@ class Options:
tab_bar_margin_height: TabBarMarginHeight = TabBarMarginHeight(outer=0, inner=0)
tab_bar_margin_width: float = 0
tab_bar_min_tabs: int = 2
tab_bar_show_new_tab_button: bool = False
tab_bar_style: choices_for_tab_bar_style = 'fade'
tab_fade: tuple[float, ...] = (0.25, 0.5, 0.75, 1.0)
tab_powerline_style: choices_for_tab_powerline_style = 'angled'
@@ -708,6 +711,7 @@ class Options:
window_title_bar_active_background: kitty.fast_data_types.Color | None = None
window_title_bar_active_foreground: kitty.fast_data_types.Color | None = None
window_title_bar_align: choices_for_window_title_bar_align = 'center'
window_title_bar_drag_threshold: int = 5
window_title_bar_inactive_background: kitty.fast_data_types.Color | None = None
window_title_bar_inactive_foreground: kitty.fast_data_types.Color | None = None
window_title_bar_min_windows: int = 0