@@ -23,6 +23,7 @@ use iced_native::user_interface::{self, UserInterface};
2323pub use iced_native:: application:: { Appearance , StyleSheet } ;
2424
2525use std:: mem:: ManuallyDrop ;
26+ use winit:: window:: { CursorIcon , ResizeDirection } ;
2627
2728/// An interactive, native cross-platform application.
2829///
@@ -121,6 +122,9 @@ where
121122 let mut debug = Debug :: new ( ) ;
122123 debug. startup_started ( ) ;
123124
125+ // Defines width of the window border for the resize handles.
126+ let border_size = settings. window . border_size ;
127+
124128 let event_loop = EventLoopBuilder :: with_user_event ( ) . build ( ) ;
125129 let proxy = event_loop. create_proxy ( ) ;
126130
@@ -193,6 +197,7 @@ where
193197 init_command,
194198 window,
195199 settings. exit_on_close_request ,
200+ border_size,
196201 ) ) ;
197202
198203 let mut context = task:: Context :: from_waker ( task:: noop_waker_ref ( ) ) ;
@@ -243,6 +248,7 @@ async fn run_instance<A, E, C>(
243248 init_command : Command < A :: Message > ,
244249 window : winit:: window:: Window ,
245250 exit_on_close_request : bool ,
251+ border_size : u32 ,
246252) where
247253 A : Application + ' static ,
248254 E : Executor + ' static ,
@@ -290,6 +296,11 @@ async fn run_instance<A, E, C>(
290296 & mut debug,
291297 ) ) ;
292298
299+ let mut cursor_resize_event = cursor_resize_event_func (
300+ & window,
301+ border_size as f64 * window. scale_factor ( ) ,
302+ ) ;
303+
293304 let mut mouse_interaction = mouse:: Interaction :: default ( ) ;
294305 let mut events = Vec :: new ( ) ;
295306 let mut messages = Vec :: new ( ) ;
@@ -475,6 +486,12 @@ async fn run_instance<A, E, C>(
475486 event : window_event,
476487 ..
477488 } => {
489+ if let Some ( func) = cursor_resize_event. as_mut ( ) {
490+ if func ( & window, & window_event) {
491+ continue ;
492+ }
493+ }
494+
478495 if requests_exit ( & window_event, state. modifiers ( ) )
479496 && exit_on_close_request
480497 {
@@ -766,3 +783,134 @@ mod platform {
766783 event_loop. run ( event_handler)
767784 }
768785}
786+
787+ /// If supported by winit, returns a closure that implements cursor resize support.
788+ fn cursor_resize_event_func (
789+ window : & winit:: window:: Window ,
790+ border_size : f64 ,
791+ ) -> Option <
792+ impl FnMut ( & winit:: window:: Window , & winit:: event:: WindowEvent < ' _ > ) -> bool ,
793+ > {
794+ if window. drag_resize_window ( ResizeDirection :: East ) . is_ok ( ) {
795+ // Keep track of cursor when it is within a resizeable border.
796+ let mut cursor_prev_resize_direction = None ;
797+
798+ Some (
799+ move |window : & winit:: window:: Window ,
800+ window_event : & winit:: event:: WindowEvent < ' _ > |
801+ -> bool {
802+ // Keep track of border resize state and set cursor icon when in range
803+ match window_event {
804+ winit:: event:: WindowEvent :: CursorMoved {
805+ position, ..
806+ } => {
807+ if !window. is_decorated ( ) {
808+ let location = cursor_resize_direction (
809+ window. inner_size ( ) ,
810+ * position,
811+ border_size,
812+ ) ;
813+ if location != cursor_prev_resize_direction {
814+ window. set_cursor_icon (
815+ resize_direction_cursor_icon ( location) ,
816+ ) ;
817+ cursor_prev_resize_direction = location;
818+ return true ;
819+ }
820+ }
821+ }
822+ winit:: event:: WindowEvent :: MouseInput {
823+ state : winit:: event:: ElementState :: Pressed ,
824+ button : winit:: event:: MouseButton :: Left ,
825+ ..
826+ } => {
827+ if let Some ( direction) = cursor_prev_resize_direction {
828+ let _res = window. drag_resize_window ( direction) ;
829+ return true ;
830+ }
831+ }
832+ _ => ( ) ,
833+ }
834+
835+ false
836+ } ,
837+ )
838+ } else {
839+ None
840+ }
841+ }
842+
843+ /// Get the cursor icon that corresponds to the resize direction.
844+ fn resize_direction_cursor_icon (
845+ resize_direction : Option < ResizeDirection > ,
846+ ) -> CursorIcon {
847+ match resize_direction {
848+ Some ( resize_direction) => match resize_direction {
849+ ResizeDirection :: East => CursorIcon :: EResize ,
850+ ResizeDirection :: North => CursorIcon :: NResize ,
851+ ResizeDirection :: NorthEast => CursorIcon :: NeResize ,
852+ ResizeDirection :: NorthWest => CursorIcon :: NwResize ,
853+ ResizeDirection :: South => CursorIcon :: SResize ,
854+ ResizeDirection :: SouthEast => CursorIcon :: SeResize ,
855+ ResizeDirection :: SouthWest => CursorIcon :: SwResize ,
856+ ResizeDirection :: West => CursorIcon :: WResize ,
857+ } ,
858+ None => CursorIcon :: Default ,
859+ }
860+ }
861+
862+ /// Identifies resize direction based on cursor position and window dimensions.
863+ #[ allow( clippy:: similar_names) ]
864+ fn cursor_resize_direction (
865+ win_size : winit:: dpi:: PhysicalSize < u32 > ,
866+ position : winit:: dpi:: PhysicalPosition < f64 > ,
867+ border_size : f64 ,
868+ ) -> Option < ResizeDirection > {
869+ enum XDirection {
870+ West ,
871+ East ,
872+ Default ,
873+ }
874+
875+ enum YDirection {
876+ North ,
877+ South ,
878+ Default ,
879+ }
880+
881+ let xdir = if position. x < border_size {
882+ XDirection :: West
883+ } else if position. x > ( win_size. width as f64 - border_size) {
884+ XDirection :: East
885+ } else {
886+ XDirection :: Default
887+ } ;
888+
889+ let ydir = if position. y < border_size {
890+ YDirection :: North
891+ } else if position. y > ( win_size. height as f64 - border_size) {
892+ YDirection :: South
893+ } else {
894+ YDirection :: Default
895+ } ;
896+
897+ Some ( match xdir {
898+ XDirection :: West => match ydir {
899+ YDirection :: North => ResizeDirection :: NorthWest ,
900+ YDirection :: South => ResizeDirection :: SouthWest ,
901+ YDirection :: Default => ResizeDirection :: West ,
902+ } ,
903+
904+ XDirection :: East => match ydir {
905+ YDirection :: North => ResizeDirection :: NorthEast ,
906+ YDirection :: South => ResizeDirection :: SouthEast ,
907+ YDirection :: Default => ResizeDirection :: East ,
908+ } ,
909+
910+ XDirection :: Default => match ydir {
911+ YDirection :: North => ResizeDirection :: North ,
912+ YDirection :: South => ResizeDirection :: South ,
913+ YDirection :: Default => return None ,
914+ } ,
915+ } )
916+ }
0 commit comments