Skip to content

Commit

Permalink
Disable resizable automatically with fixed roots
Browse files Browse the repository at this point in the history
Closes #188
  • Loading branch information
ecton committed Oct 19, 2024
1 parent 171cf3f commit bc54893
Showing 3 changed files with 62 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -81,6 +81,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `WrapperWidget::activate`'s default implementation now activates the wrapped
widget.
- `Space` now intercepts mouse events if its color has a non-zero alpha channel.
- If the root widget of a window is a `Resize` with an exact width and height,
the window will have its resizable attribute disabled. This will not update
the resizable `Dynamic<bool>` on `Window`.

### Fixed

11 changes: 11 additions & 0 deletions src/value.rs
Original file line number Diff line number Diff line change
@@ -4095,6 +4095,17 @@ where
self.current_generation = self.source.generation();
}
}

/// Updates the value stored in the source.
pub fn set(&mut self, new_value: Source::Value)
where
Source::Value: PartialEq + Clone,
{
self.current = new_value;
if self.source.set(self.current.clone()) {
self.current_generation = self.source.generation();
}
}
}

/// A [`Source`] that can be used in a [`Tracked`] instance.
63 changes: 48 additions & 15 deletions src/window.rs
Original file line number Diff line number Diff line change
@@ -1377,6 +1377,7 @@ struct OpenWindow<T> {
modifiers: Dynamic<Modifiers>,
shortcuts: Value<ShortcutMap>,
on_file_drop: Option<Callback<FileDrop>>,
disabled_resize_automatically: bool,
}

impl<T> OpenWindow<T>
@@ -1814,6 +1815,7 @@ where
fullscreen: Tracked::from(settings.fullscreen).ignoring_first(),
shortcuts: settings.shortcuts,
on_file_drop: settings.on_file_drop,
disabled_resize_automatically: false,
};

this.synchronize_platform_window(&mut window);
@@ -1854,7 +1856,7 @@ where
self.new_frame(graphics);

let resize_to_fit = self.resize_to_fit.get();
let resizable = window.is_resizable() || resize_to_fit;
let resizable = *self.resizable.peek() || resize_to_fit;
let mut window = RunningWindow::new(
window,
graphics.id(),
@@ -1883,13 +1885,9 @@ where
),
gfx: Exclusive::Owned(Graphics::new(graphics)),
};
if self.initial_frame {
self.root
.lock()
.as_widget()
.mounted(&mut context.as_event_context());
}
self.theme_mode.redraw_when_changed(&context);
self.inner_size.invalidate_when_changed(&context);
self.resize_to_fit.invalidate_when_changed(&context);
let mut layout_context = LayoutContext::new(&mut context);
let window_size = layout_context.gfx.size();

@@ -1910,19 +1908,12 @@ where
layout_size
};
let render_size = actual_size.min(window_size);
layout_context.invalidate_when_changed(&self.inner_size);
layout_context.invalidate_when_changed(&self.resize_to_fit);

self.root.set_layout(Rect::from(render_size.into_signed()));

if self.initial_frame {
self.initial_frame = false;
self.root
.lock()
.as_widget()
.mounted(&mut layout_context.as_event_context());
layout_context.focus();
layout_context.as_event_context().apply_pending_state();
Self::mount_and_focus_root(&self.root, &mut layout_context);
}

if render_size.width < window_size.width || render_size.height < window_size.height {
@@ -1933,6 +1924,15 @@ where
layout_context.redraw();
}

let resizable = resizable
&& !Self::enforce_fixed_size(
self.max_inner_size,
self.max_inner_size,
&self.resizable,
&mut self.disabled_resize_automatically,
&mut layout_context,
);

let new_size = if let Some(new_size) = self.inner_size.updated() {
layout_context.request_inner_size(*new_size)
} else if actual_size != window_size && !resizable {
@@ -1959,6 +1959,38 @@ where
layout_context.as_event_context().update_hovered_widget();
}

fn mount_and_focus_root(root: &MountedWidget, context: &mut LayoutContext<'_, '_, '_, '_>) {
root.lock()
.as_widget()
.mounted(&mut context.as_event_context());
context.focus();
context.as_event_context().apply_pending_state();
}

fn enforce_fixed_size(
min_inner_size: Option<Size<UPx>>,
max_inner_size: Option<Size<UPx>>,
resizable: &Tracked<Value<bool>>,
disabled_resize_automatically: &mut bool,
context: &mut LayoutContext<'_, '_, '_, '_>,
) -> bool {
let fixed_size = max_inner_size.is_some()
&& min_inner_size.is_some()
&& max_inner_size == min_inner_size;
if fixed_size && *resizable.peek() && !*disabled_resize_automatically {
*disabled_resize_automatically = true;
if let Some(winit) = context.window().winit() {
winit.set_resizable(false);
}
} else if !fixed_size && *resizable.peek() && *disabled_resize_automatically {
*disabled_resize_automatically = false;
if let Some(winit) = context.window().winit() {
winit.set_resizable(true);
}
}
fixed_size
}

fn close_requested<W>(&mut self, window: W, kludgine: &mut Kludgine) -> bool
where
W: PlatformWindowImplementation,
@@ -2066,6 +2098,7 @@ where
});
when_updated!(resizable, handle, {
winit.set_resizable(*resizable);
println!("Setting resizable {resizable}");

This comment has been minimized.

Copy link
@bluenote10

bluenote10 Oct 22, 2024

Contributor

Was keeping the println! on purpose or rather a debug left-over?

This comment has been minimized.

Copy link
@ecton

ecton Oct 22, 2024

Author Member

Debug leftover, I'll remove it. Thank you for catching that! I thought I had run without seeing any logging oops.

redraw = true;
});
when_updated!(window_icon, handle, {

0 comments on commit bc54893

Please sign in to comment.