Skip to content

mouse handler and collect + store section areas for click locations#129

Draft
otomist wants to merge 5 commits intopythops:masterfrom
otomist:mouse-clicks-help-section
Draft

mouse handler and collect + store section areas for click locations#129
otomist wants to merge 5 commits intopythops:masterfrom
otomist:mouse-clicks-help-section

Conversation

@otomist
Copy link
Copy Markdown

@otomist otomist commented Feb 27, 2026

This PR is to add mouse down event handling so users can click and connect to Bluetooth keyboards when they don't have a wired option available for the keyboard.

Currently in draft mode because I wanted to get approval on the basic logic before making all the changes for different screen sizes.

fixes: #100

Comment thread src/handler.rs Outdated
Comment thread src/help.rs Outdated
Comment thread src/help.rs
@sermuns
Copy link
Copy Markdown
Collaborator

sermuns commented Apr 10, 2026

This looks promising!

I see you have done some unrelated refactoring and code-deduplication in `handler.rs` for example, can you please keep the this PR focused on mouse handling. You are very welcome to create more PRs focused on refactoring specific parts of the codebase!

Once you have removed the changes unrelated to the feature I will start reviewing!

EDIT: i am stupid. you have correctly identified reusable code for keyboard and mouse user interaction. those changes are relevant and good!

@otomist
Copy link
Copy Markdown
Author

otomist commented Apr 10, 2026

This looks promising!

I see you have done some unrelated refactoring and code-deduplication in `handler.rs` for example, can you please keep the this PR focused on mouse handling. You are very welcome to create more PRs focused on refactoring specific parts of the codebase!

Once you have removed the changes unrelated to the feature I will start reviewing!

EDIT: i am stupid. you have correctly identified reusable code for keyboard and mouse user interaction. those changes are relevant and good!

Thanks for looking at this! I kinda dropped the ball for a bit on this pr. The refactor I needed to do was much larger than I originally expected. I do still want to get it cleaned up and working though. I can try to find time this weekend or next week to look at it again.

If the review is too annoying because of the amount of code that changed I can maybe try to split it up into small prs as well.

Copy link
Copy Markdown
Collaborator

@sermuns sermuns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have started reviewing, not done reading all the changes yet!

Comment thread src/app.rs
Comment on lines +162 to +165
adapter_block_bounds: None,
paired_devices_block_bounds: None,
new_devices_block_bounds: None,
help_block_bounds: None,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love introducing partial initialization to App.

Do you think we could get with initializing them as Rect::ZERO instead, then resizing once we know?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes looks like a good switch. At first glance I thought it might make it less explicit but after a little thought I think you're right. Using zero for default bounds shouldn't be hard to swap in.

Comment thread src/help.rs
Comment on lines +23 to +78
impl<'a> HelpItem<'a> {
fn new(spans: Vec<Span<'a>>, action: Option<HelpAction>) -> Self {
let width: u16 = spans.iter().map(|s| s.content.len() as u16).sum();
Self {
spans,
x_start: 0,
x_end: width,
action,
}
}

fn width(&self) -> u16 {
self.x_end - self.x_start
}

fn set_position(&mut self, x_start: u16) {
let width = self.width();
self.x_start = x_start;
self.x_end = x_start + width;
}

fn get_spans(&self) -> Vec<Span<'a>> {
self.spans.clone()
}

fn to_clickable_item(&self, y: u16) -> ClickableHelpItem {
ClickableHelpItem {
x_start: self.x_start,
x_end: self.x_end,
y,
action: self.action,
}
}
}

fn place_items_in_row(
items: &mut [&mut HelpItem<'_>],
start_x: u16,
sep_width: u16,
y: u16,
clickable_items: &mut Vec<ClickableHelpItem>,
) {
let mut current_x = start_x;
let last_idx = items.len().saturating_sub(1);

for (idx, item) in items.iter_mut().enumerate() {
item.set_position(current_x);
clickable_items.push(item.to_clickable_item(y));

if idx < last_idx {
current_x = current_x
.saturating_add(item.width())
.saturating_add(sep_width);
}
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems very handrolled. Are you sure this is the only/best way to accomplish this? I'm not saying I know a better way of doing this of the top of my head, but maybe we can explore what Ratatui already offers:

https://ratatui.rs/recipes/layout/grid/
https://ratatui.rs/recipes/layout/dynamic/
https://ratatui.rs/examples/layout/flex/

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look at some more options to see if these you linked or other deps in the project can cover this.

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.

Missing mouse support prevents connecting when keyboard is pairing

2 participants