@@ -59,7 +59,7 @@ use smithay::{
5959 reexports:: {
6060 input:: Device as InputDevice , wayland_server:: protocol:: wl_shm:: Format as ShmFormat ,
6161 } ,
62- utils:: { Point , Rectangle , SERIAL_COUNTER , Serial } ,
62+ utils:: { Coordinate , Point , Rectangle , SERIAL_COUNTER , Serial } ,
6363 wayland:: {
6464 image_copy_capture:: { BufferConstraints , CursorSessionRef } ,
6565 keyboard_shortcuts_inhibit:: KeyboardShortcutsInhibitorSeat ,
@@ -350,21 +350,48 @@ impl State {
350350 let original_position = position;
351351 position += event. delta ( ) . as_global ( ) ;
352352
353- let output = shell
354- . outputs ( )
355- . find ( |output| output. geometry ( ) . to_f64 ( ) . contains ( position) )
353+ let output_containing_position =
354+ State :: output_containing_point ( position, & shell) ;
355+
356+ let output = output_containing_position
356357 . cloned ( )
357358 . unwrap_or ( current_output. clone ( ) ) ;
358359
359360 let output_geometry = output. geometry ( ) ;
360- position. x = position. x . clamp (
361- output_geometry. loc . x as f64 ,
362- ( output_geometry. loc . x + output_geometry. size . w - 1 ) as f64 ,
363- ) ;
364- position. y = position. y . clamp (
365- output_geometry. loc . y as f64 ,
366- ( output_geometry. loc . y + output_geometry. size . h - 1 ) as f64 ,
367- ) ;
361+
362+ {
363+ // Clamp the position to the output geometry
364+ let top_left: Point < f64 , Global > =
365+ Point :: new ( output_geometry. loc . x as f64 , output_geometry. loc . y as f64 ) ;
366+ let bottom_right: Point < f64 , Global > = Point :: new (
367+ top_left. x . saturating_add ( output_geometry. size . w as f64 ) - 1.0 ,
368+ top_left. y . saturating_add ( output_geometry. size . h as f64 ) - 1.0 ,
369+ ) ;
370+ if output_containing_position. is_none ( ) {
371+ position. x = position. x . clamp ( top_left. x , bottom_right. x ) ;
372+ position. y = position. y . clamp ( top_left. y , bottom_right. y ) ;
373+ } else {
374+ let old_position = position. clone ( ) ;
375+ if position. x > bottom_right. x
376+ && State :: output_containing_point (
377+ Point :: new ( bottom_right. x + 1.0 , old_position. y ) ,
378+ & shell,
379+ )
380+ . is_none ( )
381+ {
382+ position. x = bottom_right. x ;
383+ }
384+ if position. y > bottom_right. y
385+ && State :: output_containing_point (
386+ Point :: new ( old_position. x , bottom_right. y + 1.0 ) ,
387+ & shell,
388+ )
389+ . is_none ( )
390+ {
391+ position. y = bottom_right. y ;
392+ }
393+ }
394+ }
368395
369396 let new_under = State :: surface_under ( position, & output, & shell)
370397 . map ( |( target, pos) | ( target, pos. as_logical ( ) ) ) ;
@@ -2166,6 +2193,12 @@ impl State {
21662193 . flatten ( )
21672194 }
21682195
2196+ pub fn output_containing_point ( point : Point < f64 , Global > , shell : & Shell ) -> Option < & Output > {
2197+ shell
2198+ . outputs ( )
2199+ . find ( |output| output. geometry ( ) . to_f64 ( ) . contains ( point) )
2200+ }
2201+
21692202 #[ profiling:: function]
21702203 pub fn surface_under (
21712204 global_pos : Point < f64 , Global > ,
0 commit comments