Browse Source

Fix X11Screen info update incorrectly when screen changed. (#19262)

release/11.3.3
Handsome08 6 months ago
committed by Julien Lebosquain
parent
commit
59e4daa358
  1. 35
      src/Avalonia.X11/Screens/X11Screen.Providers.cs
  2. 11
      src/Avalonia.X11/Screens/X11Screens.cs

35
src/Avalonia.X11/Screens/X11Screen.Providers.cs

@ -15,22 +15,21 @@ internal partial class X11Screens
// Length of a EDID-Block-Length(128 bytes), XRRGetOutputProperty multiplies offset and length by 4 // Length of a EDID-Block-Length(128 bytes), XRRGetOutputProperty multiplies offset and length by 4
private const int EDIDStructureLength = 32; private const int EDIDStructureLength = 32;
public virtual void Refresh() public virtual void Refresh(MonitorInfo newInfo)
{ {
if (scalingProvider == null) if (scalingProvider == null)
return; return;
var namePtr = XGetAtomName(x11.Display, info.Name); var namePtr = XGetAtomName(x11.Display, newInfo.Name);
var name = Marshal.PtrToStringAnsi(namePtr); var name = Marshal.PtrToStringAnsi(namePtr);
XFree(namePtr); XFree(namePtr);
DisplayName = name; DisplayName = name;
IsPrimary = info.IsPrimary; IsPrimary = newInfo.IsPrimary;
Bounds = new PixelRect(info.X, info.Y, info.Width, info.Height); Bounds = new PixelRect(newInfo.X, newInfo.Y, newInfo.Width, newInfo.Height);
Size? pSize = null; Size? pSize = null;
for (int o = 0; o < info.Outputs.Length; o++) for (int o = 0; o < newInfo.Outputs.Length; o++)
{ {
var outputSize = GetPhysicalMonitorSizeFromEDID(info.Outputs[o]); var outputSize = GetPhysicalMonitorSizeFromEDID(newInfo.Outputs[o]);
if (outputSize != null) if (outputSize != null)
{ {
pSize = outputSize; pSize = outputSize;
@ -121,7 +120,7 @@ internal partial class X11Screens
PhysicalSize = pixelRect.Size.ToSize(Scaling); PhysicalSize = pixelRect.Size.ToSize(Scaling);
UpdateWorkArea(); UpdateWorkArea();
} }
public override void Refresh() public override void Refresh(MonitorInfo newInfo)
{ {
} }
} }
@ -131,6 +130,7 @@ internal partial class X11Screens
nint[] ScreenKeys { get; } nint[] ScreenKeys { get; }
event Action? Changed; event Action? Changed;
X11Screen CreateScreenFromKey(nint key); X11Screen CreateScreenFromKey(nint key);
MonitorInfo GetMonitorInfoByKey(nint key);
} }
internal unsafe struct MonitorInfo internal unsafe struct MonitorInfo
@ -224,6 +224,20 @@ internal partial class X11Screens
throw new ArgumentOutOfRangeException(nameof(key)); throw new ArgumentOutOfRangeException(nameof(key));
} }
public MonitorInfo GetMonitorInfoByKey(nint key)
{
var infos = MonitorInfos;
for (var i = 0; i < infos.Length; i++)
{
if (infos[i].Name == key)
{
return infos[i];
}
}
throw new ArgumentOutOfRangeException(nameof(key));
}
} }
private class FallbackScreensImpl : IX11RawScreenInfoProvider private class FallbackScreensImpl : IX11RawScreenInfoProvider
@ -251,6 +265,11 @@ internal partial class X11Screens
return new FallBackScreen(new PixelRect(0, 0, _geo.width, _geo.height), _info); return new FallBackScreen(new PixelRect(0, 0, _geo.width, _geo.height), _info);
} }
public MonitorInfo GetMonitorInfoByKey(nint key)
{
return default;
}
public nint[] ScreenKeys => new[] { IntPtr.Zero }; public nint[] ScreenKeys => new[] { IntPtr.Zero };
} }
} }

11
src/Avalonia.X11/Screens/X11Screens.cs

@ -15,7 +15,7 @@ namespace Avalonia.X11.Screens
_impl = (info.RandrVersion != null && info.RandrVersion >= new Version(1, 5)) _impl = (info.RandrVersion != null && info.RandrVersion >= new Version(1, 5))
? new Randr15ScreensImpl(platform) ? new Randr15ScreensImpl(platform)
: (IX11RawScreenInfoProvider)new FallbackScreensImpl(platform); : (IX11RawScreenInfoProvider)new FallbackScreensImpl(platform);
_impl.Changed += () => Changed?.Invoke(); _impl.Changed += OnChanged;
} }
protected override int GetScreenCount() => _impl.ScreenKeys.Length; protected override int GetScreenCount() => _impl.ScreenKeys.Length;
@ -24,6 +24,13 @@ namespace Avalonia.X11.Screens
protected override X11Screen CreateScreenFromKey(nint key) => _impl.CreateScreenFromKey(key); protected override X11Screen CreateScreenFromKey(nint key) => _impl.CreateScreenFromKey(key);
protected override void ScreenChanged(X11Screen screen) => screen.Refresh(); protected override void ScreenChanged(X11Screen screen)
{
var handle = screen.TryGetPlatformHandle()?.Handle;
if (handle != null)
{
screen.Refresh(_impl.GetMonitorInfoByKey(handle.Value));
}
}
} }
} }

Loading…
Cancel
Save