Skip to content
Merged
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
76 changes: 75 additions & 1 deletion src/backend/wayland/handlers/pointer/axis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use log::debug;
use smithay_client_toolkit::seat::pointer::{AxisScroll, PointerEvent};

use crate::input::Tool;
use crate::input::state::COMMAND_PALETTE_MAX_VISIBLE;
use crate::input::state::{COMMAND_PALETTE_MAX_VISIBLE, InputState};

use super::*;

Expand Down Expand Up @@ -87,6 +87,13 @@ impl WaylandState {
}
return;
}
if try_handle_board_picker_page_panel_axis(
&mut self.input_state,
event.position,
scroll_direction,
) {
return;
}
if on_toolbar || self.pointer_over_toolbar() {
return;
}
Expand Down Expand Up @@ -164,3 +171,70 @@ impl WaylandState {
}
}
}

fn try_handle_board_picker_page_panel_axis(
input_state: &mut InputState,
position: (f64, f64),
scroll_direction: i32,
) -> bool {
if !input_state.is_board_picker_open() || scroll_direction == 0 {
return false;
}
let x = position.0.round() as i32;
let y = position.1.round() as i32;
if !input_state.board_picker_page_panel_content_at(x, y) {
return false;
}
let delta = if scroll_direction > 0 { 1 } else { -1 };
let _ = input_state.board_picker_scroll_page_panel_rows(delta);
true
}

#[cfg(test)]
mod tests {
use super::*;
use crate::draw::Frame;
use crate::input::state::{BoardPickerFocus, test_support::make_test_input_state};

fn update_picker_layout(input_state: &mut InputState) {
let surface =
cairo::ImageSurface::create(cairo::Format::ARgb32, 1280, 720).expect("image surface");
let ctx = cairo::Context::new(&surface).expect("cairo context");
input_state.update_board_picker_layout(&ctx, 1280, 720);
}

fn set_board_page_count(input_state: &mut InputState, board_index: usize, page_count: usize) {
let pages = input_state.boards.board_states_mut()[board_index]
.pages
.pages_mut();
pages.clear();
pages.extend((0..page_count.max(1)).map(|_| Frame::new()));
}

#[test]
fn board_picker_page_panel_axis_consumes_before_thickness_changes() {
let mut input_state = make_test_input_state();
input_state.open_board_picker();
let board_index = input_state
.board_picker_page_panel_board_index()
.expect("page panel board index");
set_board_page_count(&mut input_state, board_index, 80);
update_picker_layout(&mut input_state);

let layout = *input_state.board_picker_layout().expect("layout");
let position = (layout.page_viewport_x + 1.0, layout.page_viewport_y + 1.0);
let thickness = input_state.current_thickness;
input_state.board_picker_set_focus(BoardPickerFocus::PagePanel);

assert!(try_handle_board_picker_page_panel_axis(
&mut input_state,
position,
1,
));
assert_eq!(input_state.current_thickness, thickness);
update_picker_layout(&mut input_state);

let layout = *input_state.board_picker_layout().expect("layout");
assert_eq!(layout.page_scroll_row, 1);
}
}
101 changes: 75 additions & 26 deletions src/input/state/actions/key_press/panels.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::draw::PageDeleteOutcome;
use crate::input::events::Key;
use crate::input::state::BoardPickerFocus;
use crate::input::state::InputState;
Expand Down Expand Up @@ -80,6 +81,10 @@ impl InputState {
}
} else if self.board_picker_edit_state().is_some() {
match key {
Key::F2 => {
self.board_picker_rename_selected();
true
}
Key::Escape => {
self.board_picker_cancel_edit();
true
Expand Down Expand Up @@ -216,8 +221,19 @@ impl InputState {
fn handle_board_picker_page_panel_key(&mut self, key: Key) -> bool {
let layout = self.board_picker_layout;
let page_cols = layout.map(|l| l.page_cols.max(1)).unwrap_or(1);
let visible = layout.map(|l| l.page_visible_count).unwrap_or(0);
let current = self.board_picker_page_focus_index().unwrap_or(0);
let page_count = self
.board_picker_page_panel_board_index()
.and_then(|bi| self.boards.board_states().get(bi))
.map(|b| b.pages.page_count())
.unwrap_or(0);
let current = self
.board_picker_page_focus_page_index()
.unwrap_or_else(|| {
self.board_picker_page_panel_board_index()
.and_then(|bi| self.boards.board_states().get(bi))
.map_or(0, |board| board.pages.active_index())
})
.min(page_count.saturating_sub(1));

match key {
Key::Escape => {
Expand All @@ -231,48 +247,81 @@ impl InputState {
true
}
Key::Left => {
let col = current % page_cols;
if col == 0 {
if current == 0 {
self.board_picker_set_focus(BoardPickerFocus::BoardList);
} else if visible > 0 {
self.board_picker_set_page_focus_index(current.saturating_sub(1));
} else if page_count > 0 {
self.board_picker_set_page_focus_page_index(current.saturating_sub(1));
}
true
}
Key::Right => {
if visible > 0 {
let next = current.saturating_add(1).min(visible.saturating_sub(1));
self.board_picker_set_page_focus_index(next);
if page_count > 0 {
let next = current.saturating_add(1).min(page_count.saturating_sub(1));
self.board_picker_set_page_focus_page_index(next);
}
true
}
Key::Up => {
if visible > 0 {
if page_count > 0 {
let next = current.saturating_sub(page_cols);
self.board_picker_set_page_focus_index(next);
self.board_picker_set_page_focus_page_index(next);
}
true
}
Key::Down => {
if visible > 0 {
if page_count > 0 {
let next = current
.saturating_add(page_cols)
.min(visible.saturating_sub(1));
self.board_picker_set_page_focus_index(next);
.min(page_count.saturating_sub(1));
self.board_picker_set_page_focus_page_index(next);
}
true
}
Key::Home => {
if page_count > 0 {
self.board_picker_set_page_focus_page_index(0);
}
true
}
Key::End => {
if page_count > 0 {
self.board_picker_set_page_focus_page_index(page_count.saturating_sub(1));
}
true
}
Key::PageUp => {
if page_count > 0 {
let step = layout
.map(|l| l.page_visible_slots.max(page_cols))
.unwrap_or(page_cols);
self.board_picker_set_page_focus_page_index(current.saturating_sub(step));
}
true
}
Key::PageDown => {
if page_count > 0 {
let step = layout
.map(|l| l.page_visible_slots.max(page_cols))
.unwrap_or(page_cols);
let next = current
.saturating_add(step)
.min(page_count.saturating_sub(1));
self.board_picker_set_page_focus_page_index(next);
}
true
}
Key::Return | Key::Space => {
if visible > 0 {
if page_count > 0 {
self.board_picker_activate_page(current);
}
true
}
Key::Delete => {
if visible > 0 {
self.board_picker_delete_page(current);
// Clamp focus using post-delete page count from actual board state,
// since the layout's page_visible_count is stale after deletion.
if page_count > 0 {
let outcome = self.board_picker_delete_page(current);
if matches!(outcome, PageDeleteOutcome::Pending) {
return true;
}
let remaining = self
.board_picker_page_panel_board_index()
.and_then(|bi| self.boards.board_states().get(bi))
Expand All @@ -281,24 +330,24 @@ impl InputState {
if remaining == 0 {
self.board_picker_set_focus(BoardPickerFocus::BoardList);
} else {
let max_visible = layout
.map(|l| l.page_cols * l.page_max_rows)
.unwrap_or(remaining);
let new_visible = remaining.min(max_visible);
let clamped = current.min(new_visible.saturating_sub(1));
self.board_picker_set_page_focus_index(clamped);
let clamped = current.min(remaining.saturating_sub(1));
self.board_picker_set_page_focus_page_index(clamped);
}
}
true
}
Key::F2 => {
if visible > 0
if page_count > 0
&& let Some(board_index) = self.board_picker_page_panel_board_index()
{
self.board_picker_start_page_rename(board_index, current);
}
true
}
Key::Char('n') | Key::Char('N') if self.modifiers.ctrl => {
self.board_picker_add_page();
true
}
Key::Backspace => {
self.board_picker_backspace_search();
true
Expand Down
26 changes: 26 additions & 0 deletions src/input/state/core/board_picker/layout/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,22 @@ struct BoardPickerPagePanelMetrics {
enabled: bool,
width: f64,
height: f64,
viewport_x: f64,
viewport_y: f64,
viewport_width: f64,
viewport_height: f64,
add_button_x: f64,
add_button_y: f64,
add_button_width: f64,
add_button_height: f64,
thumb_width: f64,
cols: usize,
rows: usize,
total_rows: usize,
scroll_row: usize,
max_scroll_row: usize,
first_visible_index: usize,
visible_slots: usize,
count: usize,
visible_count: usize,
board_index: Option<usize>,
Expand Down Expand Up @@ -246,12 +259,25 @@ impl InputState {
page_panel_y: geometry.page_panel_y,
page_panel_width: page_panel.width,
page_panel_height: page_panel.height,
page_viewport_x: page_panel.viewport_x + geometry.page_panel_x,
page_viewport_y: page_panel.viewport_y + geometry.page_panel_y,
page_viewport_width: page_panel.viewport_width,
page_viewport_height: page_panel.viewport_height,
page_add_button_x: page_panel.add_button_x + geometry.page_panel_x,
page_add_button_y: page_panel.add_button_y + geometry.page_panel_y,
page_add_button_width: page_panel.add_button_width,
page_add_button_height: page_panel.add_button_height,
page_thumb_width: page_panel.thumb_width,
page_thumb_height: PAGE_THUMB_HEIGHT,
page_thumb_gap: PAGE_THUMB_GAP,
page_cols: page_panel.cols,
page_rows: page_panel.rows,
page_max_rows: PAGE_PANEL_MAX_ROWS,
page_total_rows: page_panel.total_rows,
page_scroll_row: page_panel.scroll_row,
page_max_scroll_row: page_panel.max_scroll_row,
page_first_visible_index: page_panel.first_visible_index,
page_visible_slots: page_panel.visible_slots,
page_count: page_panel.count,
page_visible_count: page_panel.visible_count,
page_board_index: page_panel.board_index,
Expand Down
Loading
Loading