aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWeZZard <960509+WeZZard@users.noreply.github.com>2026-07-17 15:20:38 +0800
committerGitHub <noreply@github.com>2026-07-17 09:20:38 +0200
commitcd50d723b54c3b63e33b4292ccca5797a4d378da (patch)
tree2a12a988937012c52ce75d93abf8ca5837e97c0c
parentfix(config): allow binding theme actions in config.kdl (#5302) (diff)
downloadsl0ppij-cd50d723b54c3b63e33b4292ccca5797a4d378da.tar.gz
sl0ppij-cd50d723b54c3b63e33b4292ccca5797a4d378da.tar.xz
sl0ppij-cd50d723b54c3b63e33b4292ccca5797a4d378da.zip
feat(config): add mouse_scroll_resize option (#5283)
-rw-r--r--example/default.kdl5
-rw-r--r--zellij-server/src/lib.rs1
-rw-r--r--zellij-server/src/panes/floating_panes/mod.rs2
-rw-r--r--zellij-server/src/panes/tiled_panes/mod.rs2
-rw-r--r--zellij-server/src/screen.rs12
-rw-r--r--zellij-server/src/tab/mod.rs11
-rw-r--r--zellij-server/src/tab/mouse_handler.rs44
-rw-r--r--zellij-server/src/tab/unit/tab_integration_tests.rs105
-rw-r--r--zellij-server/src/tab/unit/tab_tests.rs6
-rw-r--r--zellij-server/src/ui/hint_text.rs80
-rw-r--r--zellij-server/src/ui/pane_boundaries_frame.rs154
-rw-r--r--zellij-server/src/ui/pane_contents_and_ui.rs5
-rw-r--r--zellij-server/src/unit/screen_tests.rs6
-rw-r--r--zellij-utils/assets/config/default.kdl5
-rw-r--r--zellij-utils/assets/prost_ipc/client_server_contract.rs2
-rw-r--r--zellij-utils/src/client_server_contract/common_types.proto1
-rw-r--r--zellij-utils/src/input/options.rs10
-rw-r--r--zellij-utils/src/ipc/protobuf_conversion.rs2
-rw-r--r--zellij-utils/src/ipc/tests/roundtrip_tests.rs1
-rw-r--r--zellij-utils/src/kdl/mod.rs32
-rw-r--r--zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap4
-rw-r--r--zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap4
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap1
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap1
31 files changed, 464 insertions, 39 deletions
diff --git a/example/default.kdl b/example/default.kdl
index 8493511e..eb198c94 100644
--- a/example/default.kdl
+++ b/example/default.kdl
@@ -522,6 +522,11 @@ load_plugins {
//
// advanced_mouse_actions false
+// Whether Ctrl+ScrollWheel resizes panes
+// Default: true
+//
+// mouse_scroll_resize false
+
// Whether to enable mouse hover visual effects (frame highlight and help text)
// Default: true
//
diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs
index 783080dc..cd9dcb5e 100644
--- a/zellij-server/src/lib.rs
+++ b/zellij-server/src/lib.rs
@@ -433,6 +433,7 @@ impl SessionMetaData {
.options
.advanced_mouse_actions
.unwrap_or(true),
+ mouse_scroll_resize: new_config.options.mouse_scroll_resize.unwrap_or(true),
mouse_hover_effects: new_config.options.mouse_hover_effects.unwrap_or(true),
visual_bell: new_config.options.visual_bell.unwrap_or(true),
focus_follows_mouse: new_config.options.focus_follows_mouse.unwrap_or(false),
diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs
index b9afb18e..0ff972cf 100644
--- a/zellij-server/src/panes/floating_panes/mod.rs
+++ b/zellij-server/src/panes/floating_panes/mod.rs
@@ -398,6 +398,7 @@ impl FloatingPanes {
current_pane_group: HashMap<ClientId, Vec<PaneId>>,
client_id_override: Option<ClientId>,
help_text_visible: &HashMap<ClientId, bool>,
+ mouse_scroll_resize: bool,
) -> Result<()> {
let err_context = || "failed to render output";
let mut connected_clients: HashSet<ClientId> =
@@ -492,6 +493,7 @@ impl FloatingPanes {
current_pane_group.clone(),
show_help_text,
false,
+ mouse_scroll_resize,
);
for client_id in &connected_clients {
let client_mode = self
diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs
index ba0ba51c..88bec53a 100644
--- a/zellij-server/src/panes/tiled_panes/mod.rs
+++ b/zellij-server/src/panes/tiled_panes/mod.rs
@@ -1085,6 +1085,7 @@ impl TiledPanes {
current_pane_group: HashMap<ClientId, Vec<PaneId>>,
client_id_override: Option<ClientId>,
help_text_visible: &HashMap<ClientId, bool>,
+ mouse_scroll_resize: bool,
) -> Result<()> {
let err_context = || "failed to render tiled panes";
@@ -1208,6 +1209,7 @@ impl TiledPanes {
current_pane_group.clone(),
show_help_text,
omit_pane_title && reserved_rows_for_pane == 0,
+ mouse_scroll_resize,
);
pane_contents_and_ui.set_frame_geom_override(visible_member_frame_override);
pane_contents_and_ui.set_blank_title(reserved_rows_for_pane > 0);
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index 773e390b..b72e5a3b 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -751,6 +751,7 @@ pub enum ScreenInstruction {
stacked_pane_list: bool,
default_editor: Option<PathBuf>,
advanced_mouse_actions: bool,
+ mouse_scroll_resize: bool,
mouse_hover_effects: bool,
visual_bell: bool,
focus_follows_mouse: bool,
@@ -1458,6 +1459,7 @@ pub(crate) struct Screen {
web_sharing: WebSharing,
current_pane_group: Rc<RefCell<PaneGroups>>,
advanced_mouse_actions: bool,
+ mouse_scroll_resize: bool,
mouse_hover_effects: bool,
visual_bell: bool,
focus_follows_mouse: bool,
@@ -1560,6 +1562,7 @@ impl Screen {
web_clients_allowed: bool,
web_sharing: WebSharing,
advanced_mouse_actions: bool,
+ mouse_scroll_resize: bool,
mouse_hover_effects: bool,
visual_bell: bool,
focus_follows_mouse: bool,
@@ -1620,6 +1623,7 @@ impl Screen {
current_pane_group: Rc::new(RefCell::new(current_pane_group)),
currently_marking_pane_group: Rc::new(RefCell::new(HashMap::new())),
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
focus_follows_mouse,
@@ -3348,6 +3352,7 @@ impl Screen {
self.current_pane_group.clone(),
self.currently_marking_pane_group.clone(),
self.advanced_mouse_actions,
+ self.mouse_scroll_resize,
self.mouse_hover_effects,
self.focus_follows_mouse,
self.mouse_click_through,
@@ -5042,6 +5047,7 @@ impl Screen {
stacked_pane_list: bool,
default_editor: Option<PathBuf>,
advanced_mouse_actions: bool,
+ mouse_scroll_resize: bool,
mouse_hover_effects: bool,
visual_bell: bool,
focus_follows_mouse: bool,
@@ -5067,6 +5073,7 @@ impl Screen {
self.copy_options.copy_on_select = copy_on_select;
self.pane_frame_style = pane_frame_style;
self.advanced_mouse_actions = advanced_mouse_actions;
+ self.mouse_scroll_resize = mouse_scroll_resize;
self.mouse_hover_effects = mouse_hover_effects;
self.visual_bell = visual_bell;
self.focus_follows_mouse = focus_follows_mouse;
@@ -5094,6 +5101,7 @@ impl Screen {
tab.set_pane_frames(pane_frame_style);
tab.update_arrow_fonts(should_support_arrow_fonts);
tab.update_advanced_mouse_actions(advanced_mouse_actions);
+ tab.update_mouse_scroll_resize(mouse_scroll_resize);
tab.update_mouse_hover_effects(mouse_hover_effects);
tab.update_focus_follows_mouse(focus_follows_mouse);
tab.update_mouse_click_through(mouse_click_through);
@@ -6228,6 +6236,7 @@ pub(crate) fn screen_thread_main(
.unwrap_or(false);
let web_sharing = config_options.web_sharing.unwrap_or_else(Default::default);
let advanced_mouse_actions = config_options.advanced_mouse_actions.unwrap_or(true);
+ let mouse_scroll_resize = config_options.mouse_scroll_resize.unwrap_or(true);
let mouse_hover_effects = config_options.mouse_hover_effects.unwrap_or(true);
let visual_bell = config_options.visual_bell.unwrap_or(true);
let focus_follows_mouse = config_options.focus_follows_mouse.unwrap_or(false);
@@ -6270,6 +6279,7 @@ pub(crate) fn screen_thread_main(
web_clients_allowed,
web_sharing,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
focus_follows_mouse,
@@ -9459,6 +9469,7 @@ pub(crate) fn screen_thread_main(
stacked_pane_list,
default_editor,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
focus_follows_mouse,
@@ -9484,6 +9495,7 @@ pub(crate) fn screen_thread_main(
stacked_pane_list,
default_editor,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
focus_follows_mouse,
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index 3189e69a..488da7a5 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -251,6 +251,7 @@ pub(crate) struct Tab {
last_active_pane_scroll: HashMap<ClientId, Option<(usize, usize)>>,
current_pane_group: Rc<RefCell<PaneGroups>>,
advanced_mouse_actions: bool,
+ mouse_scroll_resize: bool,
mouse_hover_effects: bool,
focus_follows_mouse: bool,
mouse_click_through: bool,
@@ -807,6 +808,7 @@ impl Tab {
current_pane_group: Rc<RefCell<PaneGroups>>,
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
advanced_mouse_actions: bool,
+ mouse_scroll_resize: bool,
mouse_hover_effects: bool,
focus_follows_mouse: bool,
mouse_click_through: bool,
@@ -941,6 +943,7 @@ impl Tab {
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
focus_follows_mouse,
mouse_click_through,
@@ -1583,6 +1586,7 @@ impl Tab {
current_pane_group.clone(),
false,
false,
+ self.mouse_scroll_resize,
);
pane_contents_and_ui.set_frame_geom_override(Some(header_geom));
pane_contents_and_ui.set_stack_list_entry(
@@ -2009,7 +2013,7 @@ impl Tab {
+ self.get_selectable_floating_panes().count();
if selectable_pane_count > 1 && !self.is_fullscreen_active() {
let focused_pane_is_floating = self.floating_panes.panes_are_visible();
- return resize_hint_variants(focused_pane_is_floating);
+ return resize_hint_variants(focused_pane_is_floating, self.mouse_scroll_resize);
}
}
BTreeMap::new()
@@ -4444,6 +4448,7 @@ impl Tab {
current_pane_group.clone(),
client_id_override,
&self.mouse_help_text_visible,
+ self.mouse_scroll_resize,
)
.with_context(err_context)?;
self.render_stack_list_headers(output, client_id_override)
@@ -4458,6 +4463,7 @@ impl Tab {
current_pane_group,
client_id_override,
&self.mouse_help_text_visible,
+ self.mouse_scroll_resize,
)
.with_context(err_context)?;
}
@@ -7008,6 +7014,9 @@ impl Tab {
pub fn update_advanced_mouse_actions(&mut self, advanced_mouse_actions: bool) {
self.advanced_mouse_actions = advanced_mouse_actions;
}
+ pub fn update_mouse_scroll_resize(&mut self, mouse_scroll_resize: bool) {
+ self.mouse_scroll_resize = mouse_scroll_resize;
+ }
pub fn update_mouse_hover_effects(&mut self, mouse_hover_effects: bool) {
self.mouse_hover_effects = mouse_hover_effects;
}
diff --git a/zellij-server/src/tab/mouse_handler.rs b/zellij-server/src/tab/mouse_handler.rs
index d04b511c..51ff2cca 100644
--- a/zellij-server/src/tab/mouse_handler.rs
+++ b/zellij-server/src/tab/mouse_handler.rs
@@ -230,6 +230,7 @@ struct MouseEventContext {
pinned_unselectable: Option<PaneId>,
focus_follows_mouse: bool,
mouse_click_through: bool,
+ mouse_scroll_resize: bool,
}
fn edge_and_delta_to_strategies(
@@ -405,6 +406,7 @@ impl MouseHandler {
pinned_unselectable,
focus_follows_mouse: tab.focus_follows_mouse,
mouse_click_through: tab.mouse_click_through,
+ mouse_scroll_resize: tab.mouse_scroll_resize,
})
}
@@ -1282,6 +1284,9 @@ impl MouseHandler {
}
if event.wheel_up || event.wheel_down {
+ if event.ctrl && !ctx.mouse_scroll_resize {
+ return Ok(MouseAction::NoAction);
+ }
if let Some(pane_id) = ctx.pane_id_at_position {
if event.ctrl {
if event.wheel_up {
@@ -1760,3 +1765,42 @@ impl MouseHandler {
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ fn mouse_event_context(mouse_scroll_resize: bool) -> MouseEventContext {
+ MouseEventContext {
+ pane_id_at_position: Some(PaneId::Terminal(1)),
+ active_pane_id: Some(PaneId::Terminal(1)),
+ floating_visible: false,
+ pane_being_resized: false,
+ selecting_with_mouse: false,
+ pane_being_moved: false,
+ clicked_pane: None,
+ pinned_selectable: None,
+ pinned_unselectable: None,
+ focus_follows_mouse: false,
+ mouse_click_through: false,
+ mouse_scroll_resize,
+ }
+ }
+
+ #[test]
+ fn disabled_ctrl_scroll_does_not_fall_through_to_regular_scrolling() {
+ let context = mouse_event_context(false);
+ let position = Position::new(1, 1);
+ let events = [
+ MouseEvent::new_ctrl_scroll_up_event(position),
+ MouseEvent::new_ctrl_scroll_down_event(position),
+ ];
+
+ for event in events {
+ assert_eq!(
+ MouseHandler::determine_mouse_action(&event, &context).unwrap(),
+ MouseAction::NoAction
+ );
+ }
+ }
+}
diff --git a/zellij-server/src/tab/unit/tab_integration_tests.rs b/zellij-server/src/tab/unit/tab_integration_tests.rs
index 35a2e9bd..46ab7950 100644
--- a/zellij-server/src/tab/unit/tab_integration_tests.rs
+++ b/zellij-server/src/tab/unit/tab_integration_tests.rs
@@ -236,6 +236,7 @@ fn create_new_tab(size: Size, default_mode: ModeInfo) -> Tab {
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -274,6 +275,7 @@ fn create_new_tab(size: Size, default_mode: ModeInfo) -> Tab {
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -325,6 +327,7 @@ fn create_new_tab_without_pane_frames(size: Size, default_mode: ModeInfo) -> Tab
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -363,6 +366,7 @@ fn create_new_tab_without_pane_frames(size: Size, default_mode: ModeInfo) -> Tab
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -429,6 +433,7 @@ fn create_new_tab_with_swap_layouts(
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -471,6 +476,7 @@ fn create_new_tab_with_swap_layouts(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -538,6 +544,7 @@ fn create_new_tab_with_os_api(
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -576,6 +583,7 @@ fn create_new_tab_with_os_api(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -629,6 +637,7 @@ fn create_new_tab_with_layout(size: Size, default_mode: ModeInfo, layout: &str)
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -667,6 +676,7 @@ fn create_new_tab_with_layout(size: Size, default_mode: ModeInfo, layout: &str)
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -734,6 +744,7 @@ fn create_new_tab_with_mock_pty_writer(
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -772,6 +783,7 @@ fn create_new_tab_with_mock_pty_writer(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -830,6 +842,7 @@ fn create_new_tab_with_sixel_support(
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -868,6 +881,7 @@ fn create_new_tab_with_sixel_support(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -12557,6 +12571,94 @@ fn test_ctrl_scroll_down_decreases_pinned_floating_pane_size_when_floating_panes
}
#[test]
+fn test_ctrl_scroll_up_does_not_resize_pane_when_mouse_scroll_resize_disabled() {
+ let size = Size {
+ cols: 120,
+ rows: 20,
+ };
+ let client_id = 1;
+ let mut tab = create_new_tab(size, ModeInfo::default());
+ let new_pane_id = PaneId::Terminal(2);
+
+ tab.vertical_split(new_pane_id, None, client_id, None, None)
+ .unwrap();
+ tab.update_mouse_scroll_resize(false);
+
+ let pane_geom_before = tab.get_active_pane(client_id).unwrap().position_and_size();
+
+ let active_pane_position = Position::new(5, 70);
+ let effect = tab
+ .handle_mouse_event(
+ &MouseEvent::new_ctrl_scroll_up_event(active_pane_position),
+ client_id,
+ )
+ .unwrap();
+
+ let pane_geom_after = tab.get_active_pane(client_id).unwrap().position_and_size();
+
+ assert!(!effect.state_changed);
+ assert_eq!(pane_geom_before, pane_geom_after);
+}
+
+#[test]
+fn test_ctrl_scroll_down_does_not_resize_pane_when_mouse_scroll_resize_disabled() {
+ let size = Size {
+ cols: 120,
+ rows: 20,
+ };
+ let client_id = 1;
+ let mut tab = create_new_tab(size, ModeInfo::default());
+ let new_pane_id = PaneId::Terminal(2);
+
+ tab.vertical_split(new_pane_id, None, client_id, None, None)
+ .unwrap();
+ tab.update_mouse_scroll_resize(false);
+
+ let pane_geom_before = tab.get_active_pane(client_id).unwrap().position_and_size();
+
+ let active_pane_position = Position::new(5, 70);
+ let effect = tab
+ .handle_mouse_event(
+ &MouseEvent::new_ctrl_scroll_down_event(active_pane_position),
+ client_id,
+ )
+ .unwrap();
+
+ let pane_geom_after = tab.get_active_pane(client_id).unwrap().position_and_size();
+
+ assert!(!effect.state_changed);
+ assert_eq!(pane_geom_before, pane_geom_after);
+}
+
+#[test]
+fn resize_hint_text_tracks_mouse_scroll_resize_updates() {
+ let size = Size {
+ cols: 120,
+ rows: 20,
+ };
+ let client_id = 1;
+ let mut tab = create_new_tab(size, ModeInfo::default());
+
+ tab.vertical_split(PaneId::Terminal(2), None, client_id, None, None)
+ .unwrap();
+ tab.mouse_help_text_visible.insert(client_id, true);
+
+ tab.update_mouse_scroll_resize(false);
+ let disabled_hints = tab.resolve_hint_text(client_id);
+ assert!(!disabled_hints.is_empty());
+ assert!(disabled_hints
+ .values()
+ .all(|hint| !hint.text.contains("MouseScroll")));
+
+ tab.update_mouse_scroll_resize(true);
+ let enabled_hints = tab.resolve_hint_text(client_id);
+ assert!(!enabled_hints.is_empty());
+ assert!(enabled_hints
+ .values()
+ .all(|hint| hint.text.contains("MouseScroll")));
+}
+
+#[test]
fn in_place_pane_with_close_replaced_pane_false_restores_original() {
// When an in-place pane is closed and close_replaced_pane=false (the default),
// the pane that was replaced is restored to its original position.
@@ -12724,6 +12826,7 @@ fn create_new_tab_with_plugin_receiver(
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -12762,6 +12865,7 @@ fn create_new_tab_with_plugin_receiver(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -14548,6 +14652,7 @@ fn create_new_tab_with_server_receiver(
current_group,
currently_marking_pane_group,
true, // advanced_mouse_actions
+ true, // mouse_scroll_resize
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
diff --git a/zellij-server/src/tab/unit/tab_tests.rs b/zellij-server/src/tab/unit/tab_tests.rs
index 75a6695b..11a42e29 100644
--- a/zellij-server/src/tab/unit/tab_tests.rs
+++ b/zellij-server/src/tab/unit/tab_tests.rs
@@ -178,6 +178,7 @@ fn create_new_tab(size: Size, stacked_resize: bool) -> Tab {
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -216,6 +217,7 @@ fn create_new_tab(size: Size, stacked_resize: bool) -> Tab {
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -266,6 +268,7 @@ fn create_new_tab_with_layout(size: Size, layout: TiledPaneLayout) -> Tab {
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -304,6 +307,7 @@ fn create_new_tab_with_layout(size: Size, layout: TiledPaneLayout) -> Tab {
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
@@ -360,6 +364,7 @@ fn create_new_tab_with_cell_size(
let osc8_hyperlinks = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let advanced_mouse_actions = true;
+ let mouse_scroll_resize = true;
let web_sharing = WebSharing::Off;
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
@@ -398,6 +403,7 @@ fn create_new_tab_with_cell_size(
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
+ mouse_scroll_resize,
true, // mouse_hover_effects
false, // focus_follows_mouse
false, // mouse_click_through
diff --git a/zellij-server/src/ui/hint_text.rs b/zellij-server/src/ui/hint_text.rs
index 84a8406d..2ccbb8db 100644
--- a/zellij-server/src/ui/hint_text.rs
+++ b/zellij-server/src/ui/hint_text.rs
@@ -200,7 +200,52 @@ pub fn hover_hint_variants() -> BTreeMap<usize, StyledText> {
variants
}
-pub fn resize_segments(is_floating: bool, tier: HintTier) -> Vec<HintSegment> {
+pub fn resize_segments(
+ is_floating: bool,
+ mouse_scroll_resize: bool,
+ tier: HintTier,
+) -> Vec<HintSegment> {
+ if !mouse_scroll_resize {
+ return match (is_floating, tier) {
+ (true, HintTier::Full) => vec![
+ HintSegment::plain(" "),
+ HintSegment::emphasis_2("Ctrl"),
+ HintSegment::plain(" <"),
+ HintSegment::emphasis_2("drag borders"),
+ HintSegment::plain("> to resize "),
+ ],
+ (false, HintTier::Full) => vec![
+ HintSegment::plain(" <"),
+ HintSegment::emphasis_2("drag borders"),
+ HintSegment::plain("> to resize "),
+ ],
+ (true, HintTier::Medium) => vec![
+ HintSegment::plain(" <"),
+ HintSegment::emphasis_2("Ctrl"),
+ HintSegment::plain(" "),
+ HintSegment::emphasis_2("drag borders"),
+ HintSegment::plain("> resize "),
+ ],
+ (false, HintTier::Medium) => vec![
+ HintSegment::plain(" <"),
+ HintSegment::emphasis_2("drag borders"),
+ HintSegment::plain("> resize "),
+ ],
+ (true, HintTier::Minimal) => vec![
+ HintSegment::plain(" <"),
+ HintSegment::emphasis_2("Ctrl"),
+ HintSegment::plain(" "),
+ HintSegment::emphasis_2("drag borders"),
+ HintSegment::plain("> "),
+ ],
+ (false, HintTier::Minimal) => vec![
+ HintSegment::plain(" <"),
+ HintSegment::emphasis_2("drag borders"),
+ HintSegment::plain("> "),
+ ],
+ };
+ }
+
match tier {
HintTier::Full => {
if is_floating {
@@ -276,10 +321,14 @@ pub fn resize_segments(is_floating: bool, tier: HintTier) -> Vec<HintSegment> {
}
}
-pub fn resize_hint_variants(is_floating: bool) -> BTreeMap<usize, StyledText> {
+pub fn resize_hint_variants(
+ is_floating: bool,
+ mouse_scroll_resize: bool,
+) -> BTreeMap<usize, StyledText> {
let mut variants = BTreeMap::new();
for tier in ALL_TIERS {
- let styled_text = segments_to_styled_text(&resize_segments(is_floating, tier));
+ let styled_text =
+ segments_to_styled_text(&resize_segments(is_floating, mouse_scroll_resize, tier));
variants.insert(styled_text.text.width(), styled_text);
}
variants
@@ -301,3 +350,28 @@ pub fn held_hint_variants(
}
variants
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn disabled_resize_hint_variants_omit_mouse_scroll_at_every_tier() {
+ for is_floating in [false, true] {
+ for hint in resize_hint_variants(is_floating, false).into_values() {
+ assert!(!hint.text.contains("MouseScroll"));
+ assert!(hint.text.contains("drag borders"));
+ }
+ }
+ }
+
+ #[test]
+ fn enabled_resize_hint_variants_include_mouse_scroll_at_every_tier() {
+ for is_floating in [false, true] {
+ for hint in resize_hint_variants(is_floating, true).into_values() {
+ assert!(hint.text.contains("MouseScroll"));
+ assert!(hint.text.contains("drag borders"));
+ }
+ }
+ }
+}
diff --git a/zellij-server/src/ui/pane_boundaries_frame.rs b/zellij-server/src/ui/pane_boundaries_frame.rs
index 5aca749d..5c62bfa0 100644
--- a/zellij-server/src/ui/pane_boundaries_frame.rs
+++ b/zellij-server/src/ui/pane_boundaries_frame.rs
@@ -4,8 +4,8 @@ use crate::panes::{
};
use crate::ui::boundaries::boundary_type;
use crate::ui::hint_text::{
- exit_code_segments, hover_segments, rerun_segments, HintExitStatus, HintLevel, HintSegment,
- HintTier,
+ exit_code_segments, hover_segments, rerun_segments, resize_segments, HintExitStatus, HintLevel,
+ HintSegment, HintTier,
};
use crate::ClientId;
use zellij_utils::data::{client_id_to_colors, PaletteColor, Style};
@@ -95,6 +95,7 @@ pub struct FrameParams {
pub frame_geom_override: Option<PaneGeom>,
pub stack_list_entry: Option<StackListEntry>,
pub blank_title: bool,
+ pub mouse_scroll_resize: bool,
}
#[derive(Default, PartialEq)]
@@ -124,6 +125,7 @@ pub struct PaneFrame {
omit_title: bool,
stack_list_entry: Option<StackListEntry>,
color_override: Option<PaletteColor>,
+ mouse_scroll_resize: bool,
}
impl PaneFrame {
@@ -159,6 +161,7 @@ impl PaneFrame {
omit_title: frame_params.omit_title,
stack_list_entry: frame_params.stack_list_entry,
color_override: None,
+ mouse_scroll_resize: frame_params.mouse_scroll_resize,
}
}
pub fn is_pinned(mut self, is_pinned: bool) -> Self {
@@ -1123,51 +1126,31 @@ impl PaneFrame {
}
fn help_text_version_full(&self, max_length: usize) -> Option<(Vec<TerminalCharacter>, usize)> {
- let text = if self.is_floating {
- " Ctrl <MouseScroll> or Ctrl <drag borders> to resize "
- } else {
- " Ctrl <MouseScroll> or <drag borders> to resize "
- };
- let len = text.chars().count();
- if len <= max_length {
- Some((foreground_color(text, self.color), len))
- } else {
- None
- }
+ self.help_text_version(max_length, HintTier::Full)
}
fn help_text_version_medium(
&self,
max_length: usize,
) -> Option<(Vec<TerminalCharacter>, usize)> {
- let text = if self.is_floating {
- " <Ctrl MouseScroll/drag borders> resize "
- } else {
- " <Ctrl MouseScroll>/<drag borders> resize "
- };
- let len = text.chars().count();
- if len <= max_length {
- Some((foreground_color(text, self.color), len))
- } else {
- None
- }
+ self.help_text_version(max_length, HintTier::Medium)
}
fn help_text_version_short(
&self,
max_length: usize,
) -> Option<(Vec<TerminalCharacter>, usize)> {
- let text = if self.is_floating {
- " <Ctrl MouseScroll/drag borders> "
- } else {
- " <Ctrl MouseScroll>/<drag borders> "
- };
- let len = text.chars().count();
- if len <= max_length {
- Some((foreground_color(text, self.color), len))
- } else {
- None
- }
+ self.help_text_version(max_length, HintTier::Minimal)
+ }
+
+ fn help_text_version(
+ &self,
+ max_length: usize,
+ tier: HintTier,
+ ) -> Option<(Vec<TerminalCharacter>, usize)> {
+ let segments = resize_segments(self.is_floating, self.mouse_scroll_resize, tier);
+ let (characters, length) = self.render_hint_segments(&segments);
+ (length <= max_length).then_some((characters, length))
}
fn render_held_undertitle(&self) -> Result<Vec<TerminalCharacter>> {
@@ -1444,3 +1427,104 @@ impl PaneFrame {
ret
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use zellij_utils::data::Style;
+ use zellij_utils::pane_size::{Offset, Viewport};
+
+ fn pane_frame_with(mouse_scroll_resize: bool, is_floating: bool, cols: usize) -> PaneFrame {
+ PaneFrame::new(
+ Viewport {
+ x: 0,
+ y: 0,
+ cols,
+ rows: 10,
+ },
+ (0, 0),
+ String::new(),
+ FrameParams {
+ focused_client: None,
+ is_main_client: true,
+ other_focused_clients: vec![],
+ style: Style::default(),
+ color: None,
+ other_cursors_exist_in_session: false,
+ pane_is_stacked_over: false,
+ pane_is_stacked_under: false,
+ pane_is_stacked: false,
+ should_draw_pane_frames: true,
+ pane_is_floating: is_floating,
+ content_offset: Offset::default(),
+ mouse_is_hovering_over_pane: false,
+ pane_is_selectable: true,
+ show_help_text: true,
+ highlight_tooltip: None,
+ omit_title: false,
+ frame_geom_override: None,
+ stack_list_entry: None,
+ blank_title: false,
+ mouse_scroll_resize,
+ },
+ )
+ }
+
+ fn characters_to_string(chars: &[TerminalCharacter]) -> String {
+ chars.iter().map(|c| c.character).collect()
+ }
+
+ #[test]
+ fn help_text_full_includes_ctrl_scroll_when_enabled_for_tiled_pane() {
+ let frame = pane_frame_with(true, false, 80);
+ let (chars, _) = frame.help_text_version_full(80).unwrap();
+ let text = characters_to_string(&chars);
+ assert!(text.contains("Ctrl <MouseScroll>"));
+ assert!(text.contains("<drag borders>"));
+ }
+
+ #[test]
+ fn help_text_full_omits_ctrl_scroll_when_disabled_for_tiled_pane() {
+ let frame = pane_frame_with(false, false, 80);
+ let (chars, _) = frame.help_text_version_full(80).unwrap();
+ let text = characters_to_string(&chars);
+ assert!(!text.contains("MouseScroll"));
+ assert!(text.contains("<drag borders> to resize"));
+ }
+
+ #[test]
+ fn help_text_full_includes_ctrl_scroll_when_enabled_for_floating_pane() {
+ let frame = pane_frame_with(true, true, 80);
+ let (chars, _) = frame.help_text_version_full(80).unwrap();
+ let text = characters_to_string(&chars);
+ assert!(text.contains("Ctrl <MouseScroll>"));
+ assert!(text.contains("Ctrl <drag borders>"));
+ }
+
+ #[test]
+ fn help_text_full_omits_ctrl_scroll_when_disabled_for_floating_pane() {
+ let frame = pane_frame_with(false, true, 80);
+ let (chars, _) = frame.help_text_version_full(80).unwrap();
+ let text = characters_to_string(&chars);
+ assert!(!text.contains("MouseScroll"));
+ assert!(text.contains("Ctrl <drag borders> to resize"));
+ }
+
+ #[test]
+ fn help_text_medium_omits_ctrl_scroll_when_disabled() {
+ let frame = pane_frame_with(false, false, 40);
+ let (chars, _) = frame.help_text_version_medium(40).unwrap();
+ let text = characters_to_string(&chars);
+ assert!(!text.contains("MouseScroll"));
+ assert!(text.contains("<drag borders> resize"));
+ }
+
+ #[test]
+ fn help_text_short_omits_ctrl_scroll_when_disabled() {
+ let frame = pane_frame_with(false, false, 20);
+ let (chars, _) = frame.help_text_version_short(20).unwrap();
+ let text = characters_to_string(&chars);
+ assert!(!text.contains("MouseScroll"));
+ assert!(text.contains("<drag borders>"));
+ }
+}
diff --git a/zellij-server/src/ui/pane_contents_and_ui.rs b/zellij-server/src/ui/pane_contents_and_ui.rs
index 2f260620..668caec3 100644
--- a/zellij-server/src/ui/pane_contents_and_ui.rs
+++ b/zellij-server/src/ui/pane_contents_and_ui.rs
@@ -27,6 +27,7 @@ pub struct PaneContentsAndUi<'a> {
stack_list_entry_is_selected: bool,
stack_list_entry_stack_is_focused: bool,
blank_title: bool,
+ mouse_scroll_resize: bool,
}
impl<'a> PaneContentsAndUi<'a> {
@@ -44,6 +45,7 @@ impl<'a> PaneContentsAndUi<'a> {
current_pane_group: HashMap<ClientId, Vec<PaneId>>,
show_help_text: bool,
omit_title: bool,
+ mouse_scroll_resize: bool,
) -> Self {
let mut focused_clients: Vec<ClientId> = active_panes
.iter()
@@ -80,6 +82,7 @@ impl<'a> PaneContentsAndUi<'a> {
stack_list_entry_is_selected: false,
stack_list_entry_stack_is_focused: false,
blank_title: false,
+ mouse_scroll_resize,
}
}
pub fn set_frame_geom_override(&mut self, frame_geom_override: Option<PaneGeom>) {
@@ -310,6 +313,7 @@ impl<'a> PaneContentsAndUi<'a> {
frame_geom_override: self.frame_geom_override,
stack_list_entry: stack_list_entry.clone(),
blank_title: self.blank_title,
+ mouse_scroll_resize: self.mouse_scroll_resize,
}
} else {
FrameParams {
@@ -335,6 +339,7 @@ impl<'a> PaneContentsAndUi<'a> {
frame_geom_override: self.frame_geom_override,
stack_list_entry,
blank_title: self.blank_title,
+ mouse_scroll_resize: self.mouse_scroll_resize,
}
};
diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs
index 17c9ac36..03ed31de 100644
--- a/zellij-server/src/unit/screen_tests.rs
+++ b/zellij-server/src/unit/screen_tests.rs
@@ -284,6 +284,7 @@ fn create_new_screen(
let web_server_ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let web_server_port = 8080;
let visual_bell = true;
+ let mouse_scroll_resize = true;
let screen = Screen::new(
bus,
&client_attributes,
@@ -311,6 +312,7 @@ fn create_new_screen(
false,
web_sharing,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
false, // focus_follows_mouse
@@ -5444,6 +5446,7 @@ fn create_new_screen_with_message_capture(
web_sharing,
true,
true,
+ true,
visual_bell,
false, // focus_follows_mouse
false, // mouse_click_through
@@ -8526,6 +8529,7 @@ fn create_new_screen_with_forward_capture(size: Size) -> (Screen, ForwardCapture
web_sharing,
true,
true,
+ true,
visual_bell,
false, // focus_follows_mouse
false, // mouse_click_through
@@ -9111,6 +9115,7 @@ fn create_new_screen_with_theme_capture(size: Size) -> (Screen, ThemeCapture) {
true,
true,
true,
+ true,
false,
false,
web_server_ip,
@@ -9589,6 +9594,7 @@ fn create_non_mirrored_screen(size: Size) -> Screen {
false,
WebSharing::Off,
true, // advanced_mouse_actions
+ true, // mouse_scroll_resize
true, // mouse_hover_effects
true, // visual_bell
false, // focus_follows_mouse
diff --git a/zellij-utils/assets/config/default.kdl b/zellij-utils/assets/config/default.kdl
index ec230adf..22ae3699 100644
--- a/zellij-utils/assets/config/default.kdl
+++ b/zellij-utils/assets/config/default.kdl
@@ -520,6 +520,11 @@ load_plugins {
//
// advanced_mouse_actions false
+// Whether Ctrl+ScrollWheel resizes panes
+// Default: true
+//
+// mouse_scroll_resize false
+
// Whether to enable mouse hover visual effects (frame highlight and help text)
// Default: true
//
diff --git a/zellij-utils/assets/prost_ipc/client_server_contract.rs b/zellij-utils/assets/prost_ipc/client_server_contract.rs
index 79b0b95a..7cb4a620 100644
--- a/zellij-utils/assets/prost_ipc/client_server_contract.rs
+++ b/zellij-utils/assets/prost_ipc/client_server_contract.rs
@@ -1967,6 +1967,8 @@ pub struct Options {
pub show_release_notes: ::core::option::Option<bool>,
#[prost(bool, optional, tag="33")]
pub advanced_mouse_actions: ::core::option::Option<bool>,
+ #[prost(bool, optional, tag="53")]
+ pub mouse_scroll_resize: ::core::option::Option<bool>,
#[prost(string, optional, tag="34")]
pub web_server_ip: ::core::option::Option<::prost::alloc::string::String>,
#[prost(uint32, optional, tag="35")]
diff --git a/zellij-utils/src/client_server_contract/common_types.proto b/zellij-utils/src/client_server_contract/common_types.proto
index 4c2f8395..a6debf92 100644
--- a/zellij-utils/src/client_server_contract/common_types.proto
+++ b/zellij-utils/src/client_server_contract/common_types.proto
@@ -1181,6 +1181,7 @@ message Options {
optional bool show_startup_tips = 31;
optional bool show_release_notes = 32;
optional bool advanced_mouse_actions = 33;
+ optional bool mouse_scroll_resize = 53;
optional string web_server_ip = 34;
optional uint32 web_server_port = 35;
optional string web_server_cert = 36;
diff --git a/zellij-utils/src/input/options.rs b/zellij-utils/src/input/options.rs
index fb1e8af8..da5f0248 100644
--- a/zellij-utils/src/input/options.rs
+++ b/zellij-utils/src/input/options.rs
@@ -351,6 +351,12 @@ pub struct Options {
#[serde(default)]
pub advanced_mouse_actions: Option<bool>,
+ /// Whether Ctrl+ScrollWheel resizes panes
+ /// default is true
+ #[clap(long, value_parser)]
+ #[serde(default)]
+ pub mouse_scroll_resize: Option<bool>,
+
/// Whether to enable mouse hover visual effects (frame highlight and help text)
/// default is true
#[clap(long, value_parser)]
@@ -498,6 +504,7 @@ impl Options {
let show_startup_tips = other.show_startup_tips.or(self.show_startup_tips);
let show_release_notes = other.show_release_notes.or(self.show_release_notes);
let advanced_mouse_actions = other.advanced_mouse_actions.or(self.advanced_mouse_actions);
+ let mouse_scroll_resize = other.mouse_scroll_resize.or(self.mouse_scroll_resize);
let mouse_hover_effects = other.mouse_hover_effects.or(self.mouse_hover_effects);
let visual_bell = other.visual_bell.or(self.visual_bell);
let focus_follows_mouse = other.focus_follows_mouse.or(self.focus_follows_mouse);
@@ -560,6 +567,7 @@ impl Options {
show_startup_tips,
show_release_notes,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
focus_follows_mouse,
@@ -643,6 +651,7 @@ impl Options {
let show_startup_tips = other.show_startup_tips.or(self.show_startup_tips);
let show_release_notes = other.show_release_notes.or(self.show_release_notes);
let advanced_mouse_actions = other.advanced_mouse_actions.or(self.advanced_mouse_actions);
+ let mouse_scroll_resize = other.mouse_scroll_resize.or(self.mouse_scroll_resize);
let mouse_hover_effects = other.mouse_hover_effects.or(self.mouse_hover_effects);
let visual_bell = other.visual_bell.or(self.visual_bell);
let focus_follows_mouse = merge_bool(other.focus_follows_mouse, self.focus_follows_mouse);
@@ -705,6 +714,7 @@ impl Options {
show_startup_tips,
show_release_notes,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
focus_follows_mouse,
diff --git a/zellij-utils/src/ipc/protobuf_conversion.rs b/zellij-utils/src/ipc/protobuf_conversion.rs
index ebaae103..c129b6f7 100644
--- a/zellij-utils/src/ipc/protobuf_conversion.rs
+++ b/zellij-utils/src/ipc/protobuf_conversion.rs
@@ -743,6 +743,7 @@ impl From<crate::input::options::Options>
show_startup_tips: options.show_startup_tips,
show_release_notes: options.show_release_notes,
advanced_mouse_actions: options.advanced_mouse_actions,
+ mouse_scroll_resize: options.mouse_scroll_resize,
mouse_hover_effects: options.mouse_hover_effects,
web_server_ip: options.web_server_ip.map(|ip| ip.to_string()),
web_server_port: options.web_server_port.map(|p| p as u32),
@@ -863,6 +864,7 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Options>
show_startup_tips: options.show_startup_tips,
show_release_notes: options.show_release_notes,
advanced_mouse_actions: options.advanced_mouse_actions,
+ mouse_scroll_resize: options.mouse_scroll_resize,
mouse_hover_effects: options.mouse_hover_effects,
web_server_ip: options
.web_server_ip
diff --git a/zellij-utils/src/ipc/tests/roundtrip_tests.rs b/zellij-utils/src/ipc/tests/roundtrip_tests.rs
index eb8a06de..37214782 100644
--- a/zellij-utils/src/ipc/tests/roundtrip_tests.rs
+++ b/zellij-utils/src/ipc/tests/roundtrip_tests.rs
@@ -472,6 +472,7 @@ fn test_client_messages() {
show_startup_tips: Some(true),
show_release_notes: Some(true),
advanced_mouse_actions: Some(true),
+ mouse_scroll_resize: Some(true),
web_server_ip: Some("1.1.1.1".parse().unwrap()),
web_server_port: Some(8080),
web_server_cert: Some(PathBuf::from("web_server_cert")),
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index 5a8e1b34..b16e7f12 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -2839,6 +2839,9 @@ impl Options {
let advanced_mouse_actions =
kdl_property_first_arg_as_bool_or_error!(kdl_options, "advanced_mouse_actions")
.map(|(v, _)| v);
+ let mouse_scroll_resize =
+ kdl_property_first_arg_as_bool_or_error!(kdl_options, "mouse_scroll_resize")
+ .map(|(v, _)| v);
let mouse_hover_effects =
kdl_property_first_arg_as_bool_or_error!(kdl_options, "mouse_hover_effects")
.map(|(v, _)| v);
@@ -2963,6 +2966,7 @@ impl Options {
show_startup_tips,
show_release_notes,
advanced_mouse_actions,
+ mouse_scroll_resize,
mouse_hover_effects,
visual_bell,
focus_follows_mouse,
@@ -4196,6 +4200,31 @@ impl Options {
None
}
}
+ fn mouse_scroll_resize_to_kdl(&self, add_comments: bool) -> Option<KdlNode> {
+ let comment_text = format!(
+ "{}\n{}\n{}",
+ " ", "// Whether Ctrl+ScrollWheel resizes panes", "// default is true",
+ );
+
+ let create_node = |node_value: bool| -> KdlNode {
+ let mut node = KdlNode::new("mouse_scroll_resize");
+ node.push(KdlValue::Bool(node_value));
+ node
+ };
+ if let Some(mouse_scroll_resize) = self.mouse_scroll_resize {
+ let mut node = create_node(mouse_scroll_resize);
+ if add_comments {
+ node.set_leading(format!("{}\n", comment_text));
+ }
+ Some(node)
+ } else if add_comments {
+ let mut node = create_node(false);
+ node.set_leading(format!("{}\n// ", comment_text));
+ Some(node)
+ } else {
+ None
+ }
+ }
fn mouse_hover_effects_to_kdl(&self, add_comments: bool) -> Option<KdlNode> {
let comment_text = format!(
"{}\n{}\n{}",
@@ -4633,6 +4662,9 @@ impl Options {
if let Some(advanced_mouse_actions) = self.advanced_mouse_actions_to_kdl(add_comments) {
nodes.push(advanced_mouse_actions);
}
+ if let Some(mouse_scroll_resize) = self.mouse_scroll_resize_to_kdl(add_comments) {
+ nodes.push(mouse_scroll_resize);
+ }
if let Some(mouse_hover_effects) = self.mouse_hover_effects_to_kdl(add_comments) {
nodes.push(mouse_hover_effects);
}
diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
index 106157e7..bf816932 100644
--- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
+++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__bare_config_from_default_assets_to_string_with_comments.snap
@@ -556,6 +556,10 @@ web_client {
// default is true
// advanced_mouse_actions false
+// Whether Ctrl+ScrollWheel resizes panes
+// default is true
+// mouse_scroll_resize false
+
// Whether to enable mouse hover visual effects (frame highlight and help text)
// default is true
// mouse_hover_effects false
diff --git a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
index fdf50189..8dcbaadd 100644
--- a/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
+++ b/zellij-utils/src/kdl/snapshots/zellij_utils__kdl__config_options_to_string_with_comments.snap
@@ -274,6 +274,10 @@ web_sharing "disabled"
// default is true
// advanced_mouse_actions false
+// Whether Ctrl+ScrollWheel resizes panes
+// default is true
+// mouse_scroll_resize false
+
// Whether to enable mouse hover visual effects (frame highlight and help text)
// default is true
// mouse_hover_effects false
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
index d2cbc7b2..1bef8e12 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_config_options.snap
@@ -43,6 +43,7 @@ Options {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
index 0d4980ed..71d15cbe 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__cli_arguments_override_layout_options.snap
@@ -43,6 +43,7 @@ Options {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
index effd9b78..85885291 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-3.snap
@@ -41,6 +41,7 @@ Options {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
index 9b6ac7fe..54404196 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
@@ -6020,6 +6020,7 @@ Config {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
index 6c210eeb..6758d313 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
@@ -6020,6 +6020,7 @@ Config {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
index c8917b0b..e38dc3bc 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap
@@ -128,6 +128,7 @@ Config {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
index 18b39171..58a3028b 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_options_override_config_options.snap
@@ -43,6 +43,7 @@ Options {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
index 7f1625d3..c68392b2 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
@@ -6020,6 +6020,7 @@ Config {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
index c7db95cd..0609b74b 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
@@ -6020,6 +6020,7 @@ Config {
show_startup_tips: None,
show_release_notes: None,
advanced_mouse_actions: None,
+ mouse_scroll_resize: None,
mouse_hover_effects: None,
visual_bell: None,
focus_follows_mouse: None,