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

Different behavior when assigning the Position property to a Window object across platforms #11333

Open
josephmoresena opened this issue May 11, 2023 · 1 comment

Comments

@josephmoresena
Copy link

josephmoresena commented May 11, 2023

Describe the bug
In the AvaloniaCoreRTDemo application, we have a switch for Simple and Fluent themes. To swap themes, we need to close the application's windows and reopen them. This is simply since the application only has one main window and a modal, that disables the theme switch.

When closing the previous main window and opening the new one, we want to maintain the window state, including size, position, and content. However, when assigning the position, we observe different behavior across platforms.

To Reproduce

  1. Create an instance of custom window class (the windows must contain a native menu) and display it. This will be the old window instance.
  2. Move the old window instance on the desktop to a random position.
  3. Create a second instance of the same window class. This will be the new window instance.
  4. Set the position of the new window instance to the position of the old window instance.
  5. Hide the old window instance and show the new window instance.
  6. Close the old window instance.

Expected behavior
The new window instance must be displayed exactly at the old window instance's position.

  • OS: Ubuntu 22.04, Windows 10, macOS Montery
  • Version: 11.0.0 Preview 8

Workaround
To ensure convergence in teobugslayer/AvaloniaCoreRTDemo#8 a trial and error solution was implemented for the following 3 platforms. The most concerning issue is the handling on Windows, as using reflection in the AOT context implies using rd.xml, which is not easy.

Linux + MATE:

newWindow.Position = oldWindow.Position;

Windows:

Size frameSize = oldWindow.FrameSize.Value;
Type winImpl = oldWindow.PlatformImpl.GetType();
BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic;
PropertyInfo hiddenProp = winImpl.GetProperty("HiddenBorderSize", bindingFlags);
PixelSize borderSize = (PixelSize)prop.GetValue(oldWindow.PlatformImpl);
Int32 xOffset = borderSize.Width + (Int32)(frameSize.Width - oldWindow.ClientSize.Width) / 2;
newWindow.Position = new(oldWindow.Position.X - xOffset, oldWindow.Position.Y);

macOS:

Size frameSize = oldWindow.FrameSize.Value;
Int32 yOffset = (Int32)(frameSize.Height - oldWindow.ClientSize.Height);
newWindow.Position = new(oldWindow.Position.X, oldWindow.Position.Y + yOffset);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants