Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented resizing for non-decorated winit windows #5026

Merged
merged 7 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
96 changes: 96 additions & 0 deletions internal/backends/winit/drag_resize_window.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use winit::window::{CursorIcon, ResizeDirection};

pub fn handle_cursor_move_for_resize(
window: &winit::window::Window,
position: winit::dpi::PhysicalPosition<f64>,
current_direction: Option<ResizeDirection>,
) -> Option<ResizeDirection> {
if !window.is_decorated() {
let location = get_resize_direction(window.inner_size(), position, 8_f64);
Copy link
Member

Choose a reason for hiding this comment

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

8 seems like a huge border.
I think it should be 1 or 2 logical pixel maximum. Don't you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I tried a few numbers and 3_f64 is the smallest I could go before I felt it started to get hard to hit it properly. Is that alright with you?


if current_direction != location {
window.set_cursor_icon(resize_direction_cursor_icon(location));
}

return location;
}

None
}

pub fn handle_resize(window: &winit::window::Window, direction: Option<ResizeDirection>) {
if let Some(dir) = direction {
let _ = window.drag_resize_window(dir);
}
}

/// Get the cursor icon that corresponds to the resize direction.
fn resize_direction_cursor_icon(resize_direction: Option<ResizeDirection>) -> CursorIcon {
match resize_direction {
Some(resize_direction) => match resize_direction {
ResizeDirection::East => CursorIcon::EResize,
ResizeDirection::North => CursorIcon::NResize,
ResizeDirection::NorthEast => CursorIcon::NeResize,
ResizeDirection::NorthWest => CursorIcon::NwResize,
ResizeDirection::South => CursorIcon::SResize,
ResizeDirection::SouthEast => CursorIcon::SeResize,
ResizeDirection::SouthWest => CursorIcon::SwResize,
ResizeDirection::West => CursorIcon::WResize,
},
None => CursorIcon::Default,
}
}

fn get_resize_direction(
win_size: winit::dpi::PhysicalSize<u32>,
position: winit::dpi::PhysicalPosition<f64>,
border_size: f64,
) -> Option<ResizeDirection> {
enum X {
West,
East,
Default,
}

enum Y {
North,
South,
Default,
}

let xdir = if position.x < border_size {
X::West
} else if position.x > (win_size.width as f64 - border_size) {
X::East
} else {
X::Default
};

let ydir = if position.y < border_size {
Y::North
} else if position.y > (win_size.height as f64 - border_size) {
Y::South
} else {
Y::Default
};

Some(match xdir {
Copy link
Member

Choose a reason for hiding this comment

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

for this pattern I'd have done a match (xdir, ydir) {
But this is fine too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Funny you mention this because I wasn't sure which pattern was better for readability after trying both. I'll commit this change and you can let me know which one you like better once you read it.

X::West => match ydir {
Y::North => ResizeDirection::NorthWest,
Y::South => ResizeDirection::SouthWest,
Y::Default => ResizeDirection::West,
},

X::East => match ydir {
Y::North => ResizeDirection::NorthEast,
Y::South => ResizeDirection::SouthEast,
Y::Default => ResizeDirection::East,
},

X::Default => match ydir {
Y::North => ResizeDirection::North,
Y::South => ResizeDirection::South,
Y::Default => return None,
},
})
}
17 changes: 17 additions & 0 deletions internal/backends/winit/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[WindowAdapter] trait used by the generated code and the run-time to change
aspects of windows on the screen.
*/
use crate::drag_resize_window::{handle_cursor_move_for_resize, handle_resize};
use crate::winitwindowadapter::WinitWindowAdapter;
use crate::SlintUserEvent;
#[cfg(not(target_arch = "wasm32"))]
Expand All @@ -24,6 +25,7 @@ use std::cell::{RefCell, RefMut};
use std::rc::{Rc, Weak};
use winit::event::{Event, WindowEvent};
use winit::event_loop::EventLoopWindowTarget;
use winit::window::ResizeDirection;

#[cfg(not(target_arch = "wasm32"))]
/// The Default, and the selection clippoard
Expand Down Expand Up @@ -247,6 +249,7 @@ pub struct EventLoopState {
pressed: bool,

loop_error: Option<PlatformError>,
current_resize_direction: Option<ResizeDirection>,
}

impl EventLoopState {
Expand Down Expand Up @@ -342,6 +345,11 @@ impl EventLoopState {
runtime_window.process_key_input(event);
}
WindowEvent::CursorMoved { position, .. } => {
self.current_resize_direction = handle_cursor_move_for_resize(
window.winit_window().as_ref(),
position,
self.current_resize_direction,
);
let position = position.to_logical(runtime_window.scale_factor() as f64);
self.cursor_pos = euclid::point2(position.x, position.y);
runtime_window.process_mouse_input(MouseEvent::Moved { position: self.cursor_pos });
Expand Down Expand Up @@ -378,6 +386,15 @@ impl EventLoopState {
};
let ev = match state {
winit::event::ElementState::Pressed => {
if button == PointerEventButton::Left
&& self.current_resize_direction.is_some()
{
handle_resize(
window.winit_window().as_ref(),
self.current_resize_direction,
)
LucFauvel marked this conversation as resolved.
Show resolved Hide resolved
}

self.pressed = true;
MouseEvent::Pressed { position: self.cursor_pos, button, click_count: 0 }
}
Expand Down
2 changes: 2 additions & 0 deletions internal/backends/winit/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use i_slint_core::window::WindowAdapter;
use renderer::WinitCompatibleRenderer;
use std::rc::Rc;

mod drag_resize_window;
mod winitwindowadapter;

use i_slint_core::platform::PlatformError;
use winitwindowadapter::*;
pub(crate) mod event_loop;
Expand Down