Unify the two drag threshold settings

This commit is contained in:
Kovid Goyal
2026-04-02 13:49:15 +05:30
parent d1d7a442b6
commit 07f4d3c7ae
5 changed files with 23 additions and 41 deletions

View File

@@ -17,7 +17,7 @@ level. The kitty scrollback buffer grew support for :opt:`smooth scrolling
<pixel_scroll>` and :opt:`momentum based scrolling <momentum_scroll>`
for a natural, smooth and kinetic scrolling experience.
Additionally, you can now :opt:`drag kitty tabs around <tab_bar_drag_threshold>` with the mouse
Additionally, you can now :opt:`drag kitty tabs around <drag_threshold>` with the mouse
to re-order them, move them to another kitty OS Window or even detach them into
their own OS Window.
@@ -278,7 +278,7 @@ Detailed list of changes
- macOS: Implement support for Apple dictation to input text in kitty (:iss:`3732`)
- Allow dragging tabs (opt:`tab_bar_drag_threshold`) in the tab bar to re-order, move to another OS Window or
- Allow dragging tabs (opt:`drag_threshold`) in the tab bar to re-order, move to another OS Window or
detach (:pull:`9296`)
- Allow dragging window borders to resize kitty windows in all the different

View File

@@ -884,6 +884,19 @@ sets the shape when dragging in rectangular selection mode.
'''
)
opt('drag_threshold', '5', option_type='positive_int', long_text='''
The threshold distance the mouse must move to start a drag and drop. Dragging
works for tabs and windows. You can drag tabs to re-order them, detach
them into new OS Windows or move them to another OS Window. Similarly,
by dragging the titlebar of a window (see :ac:`toggle_window_title_bars`)
you can re-order it in its layout, detach it or move it to another tab.
A value of zero disables all dragging.
Note that on Wayland, :link:`because of poor design
<https://gitlab.freedesktop.org/wayland/wayland/-/issues/140>` cancelling
a drag will detach the tab. This is worked around for compositors that support
:link:`xdg-toplevel-drag <https://wayland.app/protocols/xdg-toplevel-drag-v1>`.
''')
# mouse.mousemap {{{
agr('mouse.mousemap', 'Mouse actions', '''
@@ -1580,15 +1593,6 @@ opt('window_title_bar_align', 'center',
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() # }}}
@@ -1848,23 +1852,6 @@ the window is translucent, in which case the default background is used as it
looks better.
''')
opt(
'tab_bar_drag_threshold',
'5',
option_type='positive_int',
long_text="""
Control when dragging of tabs to re-order them happens.
The value is the drag threshold in pixels, the distance the mouse must move
before a drag begins. A value of zero disables tab dragging entirely.
Dragging a tab to another kitty window moves it there, while dragging
outside any kitty window detaches it into a new OS window.
Note that on Wayland, :link:`because of poor design
<https://gitlab.freedesktop.org/wayland/wayland/-/issues/140>` cancelling
a drag will detach the tab. This is worked around for compositors that support
:link:`xdg-toplevel-drag <https://wayland.app/protocols/xdg-toplevel-drag-v1>`.
""",
)
egr() # }}}

View File

@@ -971,6 +971,9 @@ class Parser:
def disable_ligatures(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['disable_ligatures'] = disable_ligatures(val)
def drag_threshold(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['drag_threshold'] = positive_int(val)
def draw_minimal_borders(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['draw_minimal_borders'] = to_bool(val)
@@ -1346,9 +1349,6 @@ class Parser:
def tab_bar_background(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['tab_bar_background'] = to_color_or_none(val)
def tab_bar_drag_threshold(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['tab_bar_drag_threshold'] = positive_int(val)
def tab_bar_edge(self, val: str, ans: dict[str, typing.Any]) -> None:
ans['tab_bar_edge'] = tab_bar_edge(val)
@@ -1548,9 +1548,6 @@ 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

@@ -350,6 +350,7 @@ option_names = (
'detect_urls',
'dim_opacity',
'disable_ligatures',
'drag_threshold',
'draw_minimal_borders',
'draw_window_borders_for_single_window',
'dynamic_background_opacity',
@@ -457,7 +458,6 @@ option_names = (
'tab_activity_symbol',
'tab_bar_align',
'tab_bar_background',
'tab_bar_drag_threshold',
'tab_bar_edge',
'tab_bar_filter',
'tab_bar_margin_color',
@@ -509,7 +509,6 @@ 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',
@@ -568,6 +567,7 @@ class Options:
detect_urls: bool = True
dim_opacity: float = 0.4
disable_ligatures: int = 0
drag_threshold: int = 5
draw_minimal_borders: bool = True
draw_window_borders_for_single_window: bool = False
dynamic_background_opacity: bool = False
@@ -663,7 +663,6 @@ class Options:
tab_activity_symbol: str = ''
tab_bar_align: choices_for_tab_bar_align = 'left'
tab_bar_background: kitty.fast_data_types.Color | None = None
tab_bar_drag_threshold: int = 5
tab_bar_edge: int = 8
tab_bar_filter: str = ''
tab_bar_margin_color: kitty.fast_data_types.Color | None = None
@@ -714,7 +713,6 @@ 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

View File

@@ -1777,7 +1777,7 @@ class TabManager: # {{{
if button == -1: # motion
dragged_tab_id, drag_started, start_x, start_y = get_tab_being_dragged()
if dragged_tab_id and self.tab_for_id(dragged_tab_id) is not None and not drag_started:
threshold = get_options().tab_bar_drag_threshold
threshold = get_options().drag_threshold
if threshold and math.sqrt((x-start_x)**2 + (y-start_y)**2) > threshold:
set_tab_being_dragged(dragged_tab_id, True, start_x, start_y)
request_callback_with_thumbnail("start_tab_drag", self.os_window_id)
@@ -1827,7 +1827,7 @@ class TabManager: # {{{
if button == -1: # motion event
dragged_window_id, drag_started, start_x, start_y = get_window_being_dragged()
if dragged_window_id and not drag_started:
threshold = get_options().window_title_bar_drag_threshold
threshold = get_options().drag_threshold
dist_sq = (x - start_x)**2 + (y - start_y)**2
if threshold and dist_sq > threshold * threshold:
set_window_being_dragged(dragged_window_id, True, start_x, start_y)
@@ -1840,7 +1840,7 @@ class TabManager: # {{{
if action == GLFW_PRESS:
if (w := boss.window_id_map.get(window_id)) is not None:
boss.set_active_window(w, switch_os_window_if_needed=True)
threshold = get_options().window_title_bar_drag_threshold
threshold = get_options().drag_threshold
if threshold:
set_window_being_dragged(window_id, False, x, y)
return