Skip to content

Add Ctrl+click-drag to resize window splits - #9447

Merged
kovidgoyal merged 1 commit into
kovidgoyal:masterfrom
mcrmck:mouse-drag-resize
Feb 26, 2026
Merged

kovidgoyal merged 1 commit into
kovidgoyal:masterfrom
mcrmck:mouse-drag-resize

Conversation

@mcrmck

@mcrmck mcrmck commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds Ctrl+left-click-drag to resize window splits, a long-requested feature (see Using the mouse to resize splits? #5959)
  • Detects which windows border the click position using neighbor info from the layout, then resizes in cell-sized increments during drag
  • Shows a move cursor while dragging, restores default cursor on release
  • Based on the patch by @pcewing from the discussion, with a fix for sparse NeighborsMap keys and the addition of a resize cursor

Changes

  • kitty/mouse.c: Intercepts Ctrl+left-click to start drag resize, tracks mouse movement, ends on release. Sets move cursor during drag.
  • kitty/boss.py: drag_resize_start/update/end methods that compute resize deltas in cell units and call resize_layout_window
  • kitty/layout/base.py: drag_resize_target_windows method that determines which windows to resize based on click position and neighbor layout
  • kitty/state.h: Adds active_drag_resize flag to GlobalState

Test plan

  • All 162 existing tests pass
  • Manual testing: horizontal resize with vertical border drag
  • Manual testing: vertical resize with horizontal border drag
  • Manual testing: mouse release stops resize
  • Manual testing: normal click/select works without Ctrl held
  • Manual testing: move cursor shown during drag, default cursor restored after

🤖 Generated with Claude Code

Enable Ctrl+left-click-drag to resize window splits. Detects which
windows border the click position using neighbor information from the
layout, then resizes in cell-sized increments as the mouse moves.
Shows a move cursor during the drag operation.

Closes kovidgoyal#5959

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@xoxorwr

xoxorwr commented Feb 19, 2026

Copy link
Copy Markdown

That is exactly what i was looking for!

However, i found a bug, when resize goes out of bounds, messes up with rendering PS1:

kitty.mp4

And i have a suggestion:

Instead of CTRL + click, why not just make the borders draggeable?

CTRL + click messes up with links

@mcrmck

mcrmck commented Feb 20, 2026

Copy link
Copy Markdown
Contributor Author

That's a good find, thanks for sharing. Happy to take a look some time later this week.

Personally, I agree that draggable borders would be preferable to Ctrl+click to resize. I believe this had been discussed in a separate thread, and this was @kovidgoyal 's preference. If he was ok with it, I would be happy to reimplement with draggable borders.

Cheers.

@kovidgoyal

Copy link
Copy Markdown
Owner

Discussion is in the original PR, see there.

@kovidgoyal
kovidgoyal merged commit 69caa7b into kovidgoyal:master Feb 26, 2026
12 of 14 checks passed
@zzhaolei

Copy link
Copy Markdown
Contributor

I can reproduce an issue where dragging the split handle sometimes moves the divider in the opposite direction. For example, dragging to the right can move the split to the left, and dragging upward can move it downward. It’s intermittent, but it tends to happen after resizing once and then dragging a border on a non‑active window.

2026-03-28.10.05.54.mov

@kovidgoyal

Copy link
Copy Markdown
Owner

It would help to know what layout and how many windows etc.

@zzhaolei

zzhaolei commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

Here’s the session file (layout) for reference:

new_tab
layout splits:split_axis=horizontal
enabled_layouts splits:split_axis=horizontal
set_layout_state {"pairs": {"horizontal": false, "bias": 0.5742753623188406, "one": 22, "two": {"one": 24, "two": 25}}, "opts": {"default_axis_is_horizontal": true}, "class": "Splits", "all_windows": {"active_group_idx": 0, "active_group_history": [18, 20, 23, 17, 22, 24, 25], "window_groups": [{"id": 22, "window_ids": [35]}, {"id": 24, "window_ids": [37]}, {"id": 25, "window_ids": [38]}]}}
cd /Users/zhaolei

launch 'kitty-unserialize-data={"id": 35}'
focus
launch 'kitty-unserialize-data={"id": 37}'
launch 'kitty-unserialize-data={"id": 38}'

focus_tab 0

@kovidgoyal

Copy link
Copy Markdown
Owner

@zhaolei see if #9785 fixes it for you

@zzhaolei

zzhaolei commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

@kovidgoyal It still has issues in some cases.

Additionally, the drag action remains unresponsive in some cases, despite the cursor changing its visual state.

2026-04-01.10.36.38.mov

session:

new_tab
layout splits:split_axis=horizontal
enabled_layouts splits:split_axis=horizontal
set_layout_state {"pairs": {"bias": 0.4302216070228032, "one": {"horizontal": false, "bias": 0.5239206534422404, "one": 9, "two": 15}, "two": {"horizontal": false, "bias": 0.5717619603267211, "one": 13, "two": 14}}, "opts": {"default_axis_is_horizontal": true}, "class": "Splits", "all_windows": {"active_group_idx": 2, "active_group_history": [2, 5, 4, 8, 7, 6, 12, 10, 1, 9, 15, 13, 14], "window_groups": [{"id": 9, "window_ids": [9]}, {"id": 15, "window_ids": [15]}, {"id": 13, "window_ids": [13]}, {"id": 14, "window_ids": [14]}]}}
cd /Users/zhaolei/Code/Repo/kitty

launch 'kitty-unserialize-data={"id": 9}'
launch 'kitty-unserialize-data={"id": 15}'
launch 'kitty-unserialize-data={"id": 13}'
focus
launch 'kitty-unserialize-data={"id": 14}'

focus_tab 0

@kovidgoyal

kovidgoyal commented Apr 1, 2026 via email

Copy link
Copy Markdown
Owner

@zzhaolei

zzhaolei commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

I suggest disabling diagonal dragging as it offers limited utility; Ghostty follows this same approach.

2026-04-01.1.47.19.mov

@kovidgoyal

kovidgoyal commented Apr 1, 2026 via email

Copy link
Copy Markdown
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants