fix: popup position clamping to avoid exceeding output boundaries

This commit is contained in:
drendog 2025-11-05 07:42:06 +01:00
parent a5e48f1b9f
commit 11f17a4fc1
Signed by: dwenya
GPG key ID: 8DD77074645332D0
3 changed files with 47 additions and 13 deletions

View file

@ -179,12 +179,21 @@ impl PopupManager {
params.positioning_mode
);
let output_size = self.output_size();
#[allow(clippy::cast_precision_loss)]
let output_logical_size = (
output_size.width as f32 / scale_factor,
output_size.height as f32 / scale_factor,
);
let popup_config = PopupConfig::new(
params.reference_x,
params.reference_y,
params.width,
params.height,
params.positioning_mode,
output_logical_size.0,
output_logical_size.1,
);
#[allow(clippy::cast_possible_truncation)]

View file

@ -28,11 +28,7 @@ use std::time::{Duration, Instant};
enum PopupCommand {
Show(PopupRequest),
Close(PopupHandle),
Resize {
key: usize,
width: f32,
height: f32,
},
Resize { key: usize, width: f32, height: f32 },
}
pub struct EventLoopHandle {
@ -142,7 +138,11 @@ impl RuntimeState<'_> {
self.window_state.compilation_result()
}
pub fn show_popup(&mut self, req: PopupRequest, resize_sender: Option<channel::Sender<PopupCommand>>) -> Result<PopupHandle> {
pub fn show_popup(
&mut self,
req: PopupRequest,
resize_sender: Option<channel::Sender<PopupCommand>>,
) -> Result<PopupHandle> {
let compilation_result = self.compilation_result().ok_or_else(|| {
Error::Domain(DomainError::Configuration {
message: "No compilation result available for popup creation".to_string(),
@ -229,7 +229,13 @@ impl RuntimeState<'_> {
Ok(())
}
pub fn resize_popup(&mut self, key: usize, width: f32, height: f32, resize_sender: Option<channel::Sender<PopupCommand>>) -> Result<()> {
pub fn resize_popup(
&mut self,
key: usize,
width: f32,
height: f32,
resize_sender: Option<channel::Sender<PopupCommand>>,
) -> Result<()> {
let popup_manager = self
.window_state
.popup_manager()
@ -416,7 +422,9 @@ impl WindowingSystem {
match command {
PopupCommand::Show(request) => {
if let Err(e) = runtime_state.show_popup(request, Some(sender_for_handler.clone())) {
if let Err(e) =
runtime_state.show_popup(request, Some(sender_for_handler.clone()))
{
log::error!("Failed to show popup: {}", e);
}
}
@ -426,7 +434,12 @@ impl WindowingSystem {
}
}
PopupCommand::Resize { key, width, height } => {
if let Err(e) = runtime_state.resize_popup(key, width, height, Some(sender_for_handler.clone())) {
if let Err(e) = runtime_state.resize_popup(
key,
width,
height,
Some(sender_for_handler.clone()),
) {
log::error!("Failed to resize popup: {}", e);
}
}

View file

@ -7,6 +7,8 @@ pub struct PopupConfig {
width: f32,
height: f32,
positioning_mode: PopupPositioningMode,
output_width: f32,
output_height: f32,
}
impl PopupConfig {
@ -17,6 +19,8 @@ impl PopupConfig {
width: f32,
height: f32,
positioning_mode: PopupPositioningMode,
output_width: f32,
output_height: f32,
) -> Self {
Self {
reference_x,
@ -24,6 +28,8 @@ impl PopupConfig {
width,
height,
positioning_mode,
output_width,
output_height,
}
}
@ -54,19 +60,25 @@ impl PopupConfig {
#[must_use]
pub fn calculated_top_left_x(&self) -> f32 {
if self.positioning_mode.center_x() {
let unclamped_x = if self.positioning_mode.center_x() {
self.reference_x - (self.width / 2.0)
} else {
self.reference_x
}
};
let max_x = self.output_width - self.width;
unclamped_x.max(0.0).min(max_x)
}
#[must_use]
pub fn calculated_top_left_y(&self) -> f32 {
if self.positioning_mode.center_y() {
let unclamped_y = if self.positioning_mode.center_y() {
self.reference_y - (self.height / 2.0)
} else {
self.reference_y
}
};
let max_y = self.output_height - self.height;
unclamped_y.max(0.0).min(max_y)
}
}