Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions zellij-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ impl SessionMetaData {
.options
.advanced_mouse_actions
.unwrap_or(true),
focus_follows_mouse: new_config.options.focus_follows_mouse.unwrap_or(false),
})
.unwrap();
self.senders
Expand Down
16 changes: 16 additions & 0 deletions zellij-server/src/screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ pub enum ScreenInstruction {
stacked_resize: bool,
default_editor: Option<PathBuf>,
advanced_mouse_actions: bool,
focus_follows_mouse: bool,
},
RerunCommandPane(u32), // u32 - terminal pane id
ResizePaneWithId(ResizeStrategy, PaneId),
Expand Down Expand Up @@ -745,6 +746,7 @@ pub(crate) struct Screen {
web_sharing: WebSharing,
current_pane_group: Rc<RefCell<PaneGroups>>,
advanced_mouse_actions: bool,
focus_follows_mouse: bool,
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
// the below are the configured values - the ones that will be set if and when the web server
// is brought online
Expand Down Expand Up @@ -779,6 +781,7 @@ impl Screen {
web_clients_allowed: bool,
web_sharing: WebSharing,
advanced_mouse_actions: bool,
focus_follows_mouse: bool,
web_server_ip: IpAddr,
web_server_port: u16,
) -> Self {
Expand Down Expand Up @@ -830,6 +833,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,
focus_follows_mouse,
web_server_ip,
web_server_port,
}
Expand Down Expand Up @@ -1466,6 +1470,7 @@ impl Screen {
self.current_pane_group.clone(),
self.currently_marking_pane_group.clone(),
self.advanced_mouse_actions,
self.focus_follows_mouse,
self.web_server_ip,
self.web_server_port,
);
Expand Down Expand Up @@ -2680,6 +2685,7 @@ impl Screen {
stacked_resize: bool,
default_editor: Option<PathBuf>,
advanced_mouse_actions: bool,
focus_follows_mouse: bool,
client_id: ClientId,
) -> Result<()> {
let should_support_arrow_fonts = !simplified_ui;
Expand All @@ -2695,6 +2701,7 @@ impl Screen {
self.copy_options.copy_on_select = copy_on_select;
self.draw_pane_frames = pane_frames;
self.advanced_mouse_actions = advanced_mouse_actions;
self.focus_follows_mouse = focus_follows_mouse;
self.default_mode_info
.update_arrow_fonts(should_support_arrow_fonts);
self.default_mode_info
Expand All @@ -2715,6 +2722,7 @@ impl Screen {
tab.set_pane_frames(pane_frames);
tab.update_arrow_fonts(should_support_arrow_fonts);
tab.update_advanced_mouse_actions(advanced_mouse_actions);
tab.update_focus_follows_mouse(focus_follows_mouse);
}

// client specific configuration
Expand Down Expand Up @@ -2873,6 +2881,10 @@ impl Screen {
self.clear_pane_group(&client_id);
}
}
if let Some(_pane_id) = mouse_effect.focus_changed {
// Focus change is already handled in the tab, no additional action needed
// The state_changed flag will trigger a re-render
}
if mouse_effect.state_changed {
let _ = self.log_and_report_session_state();
}
Expand Down Expand Up @@ -3268,6 +3280,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 focus_follows_mouse = config_options.focus_follows_mouse.unwrap_or(false);

let thread_senders = bus.senders.clone();
let mut screen = Screen::new(
Expand Down Expand Up @@ -3304,6 +3317,7 @@ pub(crate) fn screen_thread_main(
web_clients_allowed,
web_sharing,
advanced_mouse_actions,
focus_follows_mouse,
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -5224,6 +5238,7 @@ pub(crate) fn screen_thread_main(
stacked_resize,
default_editor,
advanced_mouse_actions,
focus_follows_mouse,
} => {
screen
.reconfigure(
Expand All @@ -5242,6 +5257,7 @@ pub(crate) fn screen_thread_main(
stacked_resize,
default_editor,
advanced_mouse_actions,
focus_follows_mouse,
client_id,
)
.non_fatal();
Expand Down
35 changes: 35 additions & 0 deletions zellij-server/src/tab/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ pub struct MouseEffect {
pub group_toggle: Option<PaneId>,
pub group_add: Option<PaneId>,
pub ungroup: bool,
pub focus_changed: Option<PaneId>,
}

impl MouseEffect {
Expand All @@ -168,6 +169,7 @@ impl MouseEffect {
group_toggle: None,
group_add: None,
ungroup: false,
focus_changed: None,
}
}
pub fn leave_clipboard_message() -> Self {
Expand All @@ -177,6 +179,7 @@ impl MouseEffect {
group_toggle: None,
group_add: None,
ungroup: false,
focus_changed: None,
}
}
pub fn state_changed_and_leave_clipboard_message() -> Self {
Expand All @@ -186,6 +189,7 @@ impl MouseEffect {
group_toggle: None,
group_add: None,
ungroup: false,
focus_changed: None,
}
}
pub fn group_toggle(pane_id: PaneId) -> Self {
Expand All @@ -195,6 +199,7 @@ impl MouseEffect {
group_toggle: Some(pane_id),
group_add: None,
ungroup: false,
focus_changed: None,
}
}
pub fn group_add(pane_id: PaneId) -> Self {
Expand All @@ -204,6 +209,7 @@ impl MouseEffect {
group_toggle: None,
group_add: Some(pane_id),
ungroup: false,
focus_changed: None,
}
}
pub fn ungroup() -> Self {
Expand All @@ -213,6 +219,17 @@ impl MouseEffect {
group_toggle: None,
group_add: None,
ungroup: true,
focus_changed: None,
}
}
pub fn focus_changed(pane_id: PaneId) -> Self {
MouseEffect {
state_changed: true,
leave_clipboard_message: true,
group_toggle: None,
group_add: None,
ungroup: false,
focus_changed: Some(pane_id),
}
}
}
Expand Down Expand Up @@ -269,6 +286,7 @@ pub(crate) struct Tab {
mouse_hover_pane_id: HashMap<ClientId, PaneId>,
current_pane_group: Rc<RefCell<PaneGroups>>,
advanced_mouse_actions: bool,
focus_follows_mouse: bool,
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
connected_clients_in_app: Rc<RefCell<HashMap<ClientId, bool>>>, // bool -> is_web_client
// the below are the configured values - the ones that will be set if and when the web server
Expand Down Expand Up @@ -694,6 +712,7 @@ impl Tab {
current_pane_group: Rc<RefCell<PaneGroups>>,
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
advanced_mouse_actions: bool,
focus_follows_mouse: bool,
web_server_ip: IpAddr,
web_server_port: u16,
) -> Self {
Expand Down Expand Up @@ -796,6 +815,7 @@ impl Tab {
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
focus_follows_mouse,
connected_clients_in_app,
web_server_ip,
web_server_port,
Expand Down Expand Up @@ -4405,6 +4425,18 @@ impl Tab {
let pane_is_selectable = pane.selectable();
if self.advanced_mouse_actions && pane_is_selectable {
self.mouse_hover_pane_id.insert(client_id, pane_id);

// Focus-follows-mouse logic
if self.focus_follows_mouse {
let current_active_pane = self.get_active_pane_id(client_id);
if current_active_pane != Some(pane_id) {
if let Err(e) = self.focus_pane_with_id(pane_id, false, client_id) {
log::error!("Failed to focus pane in focus-follows-mouse: {}", e);
} else {
return Ok(MouseEffect::focus_changed(pane_id));
}
}
}
} else if self.advanced_mouse_actions {
self.mouse_hover_pane_id.remove(&client_id);
}
Expand Down Expand Up @@ -5225,6 +5257,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_focus_follows_mouse(&mut self, focus_follows_mouse: bool) {
self.focus_follows_mouse = focus_follows_mouse;
}
pub fn update_web_sharing(&mut self, web_sharing: WebSharing) {
let old_value = self.web_sharing;
self.web_sharing = web_sharing;
Expand Down
7 changes: 7 additions & 0 deletions zellij-server/src/tab/unit/tab_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ fn create_new_tab(size: Size, default_mode: ModeInfo) -> Tab {
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -352,6 +353,7 @@ fn create_new_tab_without_pane_frames(size: Size, default_mode: ModeInfo) -> Tab
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -448,6 +450,7 @@ fn create_new_tab_with_swap_layouts(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -545,6 +548,7 @@ fn create_new_tab_with_os_api(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -628,6 +632,7 @@ fn create_new_tab_with_layout(size: Size, default_mode: ModeInfo, layout: &str)
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -725,6 +730,7 @@ fn create_new_tab_with_mock_pty_writer(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -813,6 +819,7 @@ fn create_new_tab_with_sixel_support(
current_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down
3 changes: 3 additions & 0 deletions zellij-server/src/tab/unit/tab_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ fn create_new_tab(size: Size, stacked_resize: bool) -> Tab {
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -291,6 +292,7 @@ fn create_new_tab_with_layout(size: Size, layout: TiledPaneLayout) -> Tab {
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down Expand Up @@ -377,6 +379,7 @@ fn create_new_tab_with_cell_size(
current_pane_group,
currently_marking_pane_group,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down
1 change: 1 addition & 0 deletions zellij-server/src/unit/screen_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ fn create_new_screen(size: Size, advanced_mouse_actions: bool) -> Screen {
false,
web_sharing,
advanced_mouse_actions,
false, // focus_follows_mouse
web_server_ip,
web_server_port,
);
Expand Down
11 changes: 11 additions & 0 deletions zellij-utils/src/input/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ pub struct Options {
#[serde(default)]
pub advanced_mouse_actions: Option<bool>,

/// Whether to automatically focus panes when mouse hovers over them
/// default is false
#[clap(long, value_parser)]
#[serde(default)]
pub focus_follows_mouse: Option<bool>,

// these are intentionally excluded from the CLI options as they must be specified in the
// configuration file
pub web_server_ip: Option<IpAddr>,
Expand Down Expand Up @@ -315,6 +321,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 focus_follows_mouse = other.focus_follows_mouse.or(self.focus_follows_mouse);
let web_server_ip = other.web_server_ip.or(self.web_server_ip);
let web_server_port = other.web_server_port.or(self.web_server_port);
let web_server_cert = other
Expand Down Expand Up @@ -362,6 +369,7 @@ impl Options {
show_startup_tips,
show_release_notes,
advanced_mouse_actions,
focus_follows_mouse,
web_server_ip,
web_server_port,
web_server_cert,
Expand Down Expand Up @@ -433,6 +441,7 @@ impl Options {
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 web_server_ip = other.web_server_ip.or(self.web_server_ip);
let focus_follows_mouse = other.focus_follows_mouse.or(self.focus_follows_mouse);
let web_server_port = other.web_server_port.or(self.web_server_port);
let web_server_cert = other
.web_server_cert
Expand Down Expand Up @@ -479,6 +488,7 @@ impl Options {
show_startup_tips,
show_release_notes,
advanced_mouse_actions,
focus_follows_mouse,
web_server_ip,
web_server_port,
web_server_cert,
Expand Down Expand Up @@ -556,6 +566,7 @@ impl From<CliOptions> for Options {
show_startup_tips: opts.show_startup_tips,
show_release_notes: opts.show_release_notes,
advanced_mouse_actions: opts.advanced_mouse_actions,
focus_follows_mouse: opts.focus_follows_mouse,
web_server_ip: opts.web_server_ip,
web_server_port: opts.web_server_port,
web_server_cert: opts.web_server_cert,
Expand Down
Loading