Popup anchor system refinement - #4646
Conversation
#Conflicts: # winit-appkit/src/window_delegate.rs # winit/src/changelog/unreleased.md
ogoffart
left a comment
There was a problem hiding this comment.
I wonder if it wouldn't be better to have a single with_positioner on the WindowAttribute / Window instead of many setter.
And use the WindowPositioner stuct.
| use dpi::{ | ||
| LogicalPosition, LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size, | ||
| }; | ||
| pub use positioner::{WindowAnchor, WindowConstraintAdjustment, WindowGravity, place_window}; |
There was a problem hiding this comment.
i don't think place_window should be public API
There was a problem hiding this comment.
This depends on the usage. If it should be possible to reuse it in other software like for the ChildWindow in Slint or if we wanna make a copy of the algorithm on the slint side
There was a problem hiding this comment.
But we can't re-use it for ChildWindow in Slint because slint-core don't depend on winit on purpose.
in fact, the implementation of that function might be better placed in winit-common
There was a problem hiding this comment.
winit-common is also not possible, because it depends on winit-core. It has to be public, because otherwise the winit-win32 and winit-appkit cannot use it
|
|
||
| self.set_outer_position(Position::Logical(origin)); | ||
| if size != current_size { | ||
| let _ = self.request_surface_size(Size::Logical(size)); |
There was a problem hiding this comment.
that's the inner size. but current_size use get_outer_size
There are other inconsistency like that.
|
|
||
| let userdata = unsafe { util::get_window_long(hwnd, GWL_USERDATA) }; | ||
| if userdata != 0 { | ||
| let userdata = unsafe { &*(userdata as *const WindowData) }; |
There was a problem hiding this comment.
seems dangerous to do if there are window that are not handled by winit, we need to filter that.
There was a problem hiding this comment.
public_window_callback will be called only for windows we handle otherwise this function is never called. We must be not take ownership of the pointer because of that this pattern. Also used a few times already in the code
| monitor_position.y - parent_origin.y, | ||
| ) | ||
| .to_logical::<f64>(scale_factor); | ||
| let clip_size = monitor_size.to_logical::<f64>(scale_factor); |
There was a problem hiding this comment.
is the monitor size the right thing, or should it be the availiable space?
Depends if the window or popup can be placed over, say, the taskbar
There was a problem hiding this comment.
Good point, I have to check also for multiwindow systems
There was a problem hiding this comment.
I used the work area instead of the display, otherwise it disappears behind the taskbar instead of flipping / sliding (if enabled)
|
@ogoffart Thanks for the feedback. I will go through it |
…having many single functions
Good idea, it looks much cleaner now with the positioner struct used directly |
ogoffart
left a comment
There was a problem hiding this comment.
maybe there should be an example?
| use dpi::{ | ||
| LogicalPosition, LogicalSize, PhysicalInsets, PhysicalPosition, PhysicalSize, Position, Size, | ||
| }; | ||
| pub use positioner::{WindowAnchor, WindowConstraintAdjustment, WindowGravity, place_window}; |
There was a problem hiding this comment.
But we can't re-use it for ChildWindow in Slint because slint-core don't depend on winit on purpose.
in fact, the implementation of that function might be better placed in winit-common
| anchor: WindowAnchor, | ||
| gravity: WindowGravity, | ||
| constraint_adjustment: WindowConstraintAdjustment, | ||
| (anchor_position, anchor_size): (LogicalPosition<f64>, LogicalSize<f64>), | ||
| offset: LogicalPosition<f64>, |
There was a problem hiding this comment.
Can we use a WindowPositioner here instead of many arguments?
| /// platform-specific behavior, and [`WindowPositioner::default`] for the values used when | ||
| /// [`WindowAttributes::with_positioner`] is never called. | ||
| #[derive(Debug, Clone, Copy, PartialEq)] | ||
| pub struct WindowPositioner { |
There was a problem hiding this comment.
form an API evolution point of view, i wonder if this should be #[non_exhaustive]
Or is the positioning protocol set in stone anyway and there will never be extra fields?
There was a problem hiding this comment.
The wayland protocol can envolve, so it is a good idea to make it non_exhaustive
| // An anchored window's position is parent-relative; it's applied in | ||
| // `WindowDelegate::new` (after the delegate exists) via the shared | ||
| // translation in `set_outer_position`. | ||
| _ if anchored => NSPoint::new(0.0, 0.0), |
There was a problem hiding this comment.
but if you don't specify a position and there is no parent, it should be in the center of the screen (i think that's the current behavior in master)
Previously every close request left the event_loop which is not correct when only a popup closes
Reason: otherwise the popup might disappear behind the task bar
winit-common depends on winit-core so we cannot use this as well. It has to be public otherwise the winit-win32 crate and the macos crate are not able to access it |
Implement possibility to change the anchor properties of a popup on wayland and imitate the behaviour for other platforms which do not support such anchoring system
changelogmodule if knowledge of this change could be valuable to usersTested on:
X11Does not support popups