1
0
Fork 0
forked from wry/wry

it: fix integration geometry and tab scrolling

This commit is contained in:
atagen 2026-05-31 18:11:58 +10:00
parent b6502e1d8a
commit f777b4c521
30 changed files with 123 additions and 72 deletions

View file

@ -29,6 +29,17 @@ impl TestViewport {
Ok(())
}
pub fn unset_source(&self) -> Result<(), TestError> {
self.tran.send(SetSource {
self_id: self.id,
x: Fixed::from_int(-1),
y: Fixed::from_int(-1),
width: Fixed::from_int(-1),
height: Fixed::from_int(-1),
})?;
Ok(())
}
pub fn set_destination(&self, width: i32, height: i32) -> Result<(), TestError> {
self.tran.send(SetDestination {
self_id: self.id,
@ -37,6 +48,15 @@ impl TestViewport {
})?;
Ok(())
}
pub fn unset_destination(&self) -> Result<(), TestError> {
self.tran.send(SetDestination {
self_id: self.id,
width: -1,
height: -1,
})?;
Ok(())
}
}
impl Drop for TestViewport {

View file

@ -1,7 +1,6 @@
use {
crate::{
it::{test_error::TestError, testrun::TestRun},
rect::Rect,
tree::Node,
},
std::rc::Rc,
@ -11,29 +10,19 @@ testcase!();
/// Create and map a single surface
async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
run.backend.install_default()?;
let ds = run.create_default_setup().await?;
let client = run.create_client().await?;
let window = client.create_window().await?;
window.map().await?;
tassert_eq!(window.tl.core.width.get(), 800);
tassert_eq!(
window.tl.core.height.get(),
600 - 2 * run.state.theme.title_plus_underline_height()
);
let workspace_rect = ds.output.workspace_rect.get();
tassert_eq!(
window.tl.server.node_absolute_position(),
Rect::new_sized(
0,
2 * run.state.theme.title_plus_underline_height(),
window.tl.core.width.get(),
window.tl.core.height.get(),
)
.unwrap()
);
tassert_eq!(window.tl.core.width.get(), workspace_rect.width());
tassert_eq!(window.tl.core.height.get(), workspace_rect.height());
tassert_eq!(window.tl.server.node_absolute_position(), workspace_rect);
Ok(())
}

View file

@ -11,7 +11,7 @@ testcase!();
/// Create and map two surfaces
async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
run.backend.install_default()?;
let ds = run.create_default_setup().await?;
let client = run.create_client().await?;
@ -21,17 +21,30 @@ async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
let window2 = client.create_window().await?;
window2.map().await?;
let otop = 2 * run.state.theme.title_plus_underline_height();
let workspace_rect = ds.output.workspace_rect.get();
let bw = run.state.theme.sizes.border_width.get();
let child_width = (workspace_rect.width() - bw) / 2;
tassert_eq!(
window.tl.server.node_absolute_position(),
Rect::new_sized(0, otop, (800 - bw) / 2, 600 - otop).unwrap()
Rect::new_sized(
workspace_rect.x1(),
workspace_rect.y1(),
child_width,
workspace_rect.height(),
)
.unwrap()
);
tassert_eq!(
window2.tl.server.node_absolute_position(),
Rect::new_sized((800 - bw) / 2 + bw, otop, (800 - bw) / 2, 600 - otop).unwrap()
Rect::new_sized(
workspace_rect.x1() + child_width + bw,
workspace_rect.y1(),
child_width,
workspace_rect.height(),
)
.unwrap()
);
Ok(())

View file

@ -48,13 +48,18 @@ async fn test(run: Rc<TestRun>) -> TestResult {
let mono_container = w_mono2.tl.container_parent()?;
let container_pos = mono_container.tl_data().pos.get();
let w_mono1_title = mono_container.render_data.borrow_mut().title_rects[0]
.move_(container_pos.x1(), container_pos.y1());
ds.mouse.abs(
&ds.connector,
w_mono1_title.x1() as _,
w_mono1_title.y1() as _,
);
let (tab_x, tab_y) = {
let tab_bar = mono_container.tab_bar.borrow();
let Some(tab_bar) = tab_bar.as_ref() else {
bail!("no tab bar");
};
let w_mono1_title = &tab_bar.entries[0];
(
container_pos.x1() + w_mono1_title.x.get() + w_mono1_title.width.get() / 2,
container_pos.y1() + tab_bar.height / 2,
)
};
ds.mouse.abs(&ds.connector, tab_x as _, tab_y as _);
client.sync().await;
tassert!(enters.next().is_err());

View file

@ -26,12 +26,18 @@ async fn test(run: Rc<TestRun>) -> TestResult {
let container = w_mono2.tl.container_parent()?;
let pos = container.tl_data().pos.get();
let w_mono1_title = container.render_data.borrow_mut().title_rects[0].move_(pos.x1(), pos.y1());
ds.mouse.abs(
&ds.connector,
w_mono1_title.x1() as f64,
w_mono1_title.y1() as f64,
);
let (tab_x, tab_y) = {
let tab_bar = container.tab_bar.borrow();
let Some(tab_bar) = tab_bar.as_ref() else {
bail!("no tab bar");
};
let w_mono1_title = &tab_bar.entries[0];
(
pos.x1() + w_mono1_title.x.get() + w_mono1_title.width.get() / 2,
pos.y1() + tab_bar.height / 2,
)
};
ds.mouse.abs(&ds.connector, tab_x as f64, tab_y as f64);
client.sync().await;
let enters = dss.kb.enter.expect()?;

View file

@ -308,9 +308,8 @@ async fn test(run: Rc<TestRun>) -> TestResult {
let output_damage = connector_data.damage.borrow();
tassert!(!output_damage.is_empty());
// Buffer damage is transformed by the damage matrix which includes the surface position
// The buffer damage (0,0,1,1) should be transformed to surface coordinates
let expected_buffer_damage = buffer_damage.move_(surface_pos.x1(), surface_pos.y1());
// The test window maps its 1x1 buffer through a viewport to the full window size.
let expected_buffer_damage = surface_pos;
// Find the exact output damage that matches our expected buffer damage
let mut found_exact_buffer_damage = false;
@ -331,10 +330,12 @@ async fn test(run: Rc<TestRun>) -> TestResult {
// Test 7: Check output damage from existing window's viewport (which already has scaling)
connector_data.damage.borrow_mut().clear();
// The existing window was created with create_surface_ext() which automatically creates a viewport
// Let's verify that the viewport's existing scaling affects buffer damage correctly
// First, let's modify the viewport scaling that already exists on the window
window.surface.viewport.set_destination(150, 100)?; // Change scaling to 150x100
// The existing window was created with create_surface_ext() which automatically creates a viewport.
// Commit the viewport size change separately; that commit intentionally damages the old/new extents.
window.surface.viewport.set_destination(150, 100)?;
window.surface.commit()?;
client.sync().await;
connector_data.damage.borrow_mut().clear();
// Add buffer damage to test viewport scaling coordinate transformation
window.surface.damage_buffer(0, 0, 1, 1)?; // Damage entire 1x1 buffer
@ -346,8 +347,8 @@ async fn test(run: Rc<TestRun>) -> TestResult {
let output_damage = connector_data.damage.borrow();
tassert!(!output_damage.is_empty());
// With viewporter scaling, the 1x1 buffer damage should scale to 150x100
// and be moved by surface position (0, 36) to get output coordinates (0, 36, 150, 136)
// With viewporter scaling, the 1x1 buffer damage should scale to the viewport destination.
let surface_pos = window.surface.server.buffer_abs_pos.get();
let expected_scaled_damage = Rect::new_sized(0, 0, 150, 100).unwrap();
let expected_output_damage =
expected_scaled_damage.move_(surface_pos.x1(), surface_pos.y1());
@ -402,8 +403,9 @@ async fn test(run: Rc<TestRun>) -> TestResult {
rotation_window.map().await?;
client.sync().await;
// Disable viewporter by setting destination to 0x0 to rely purely on buffer dimensions
rotation_window.surface.viewport.set_destination(0, 0)?; // Disable viewporter
// Disable viewporter to rely purely on buffer dimensions.
rotation_window.surface.viewport.unset_source()?;
rotation_window.surface.viewport.unset_destination()?;
// Use a rectangular buffer (4x2) so rotation has a visible geometric effect
// Attach AFTER mapping to avoid being overwritten by map()'s single-pixel buffer