|
|
|
@ -124,7 +124,7 @@ namespace Avalonia.X11 |
|
|
|
if (!_popup && Screen != null) |
|
|
|
{ |
|
|
|
var monitor = Screen.AllScreens.OrderBy(x => x.Scaling) |
|
|
|
.FirstOrDefault(m => m.Bounds.Contains(Position)); |
|
|
|
.FirstOrDefault(m => m.Bounds.Contains(_position ?? default)); |
|
|
|
|
|
|
|
if (monitor != null) |
|
|
|
{ |
|
|
|
@ -326,23 +326,16 @@ namespace Avalonia.X11 |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
XGetWindowProperty(_x11.Display, _handle, _x11.Atoms._NET_FRAME_EXTENTS, IntPtr.Zero, |
|
|
|
new IntPtr(4), false, (IntPtr)Atom.AnyPropertyType, out var _, |
|
|
|
out var _, out var nitems, out var _, out var prop); |
|
|
|
var extents = GetFrameExtents(); |
|
|
|
|
|
|
|
if (nitems.ToInt64() != 4) |
|
|
|
if(extents == null) |
|
|
|
{ |
|
|
|
// Window hasn't been mapped by the WM yet, so can't get the extents.
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
var data = (IntPtr*)prop.ToPointer(); |
|
|
|
var extents = new Thickness(data[0].ToInt32(), data[2].ToInt32(), data[1].ToInt32(), data[3].ToInt32()); |
|
|
|
XFree(prop); |
|
|
|
|
|
|
|
return new Size( |
|
|
|
(_realSize.Width + extents.Left + extents.Right) / RenderScaling, |
|
|
|
(_realSize.Height + extents.Top + extents.Bottom) / RenderScaling); |
|
|
|
(_realSize.Width + extents.Value.Left + extents.Value.Right) / RenderScaling, |
|
|
|
(_realSize.Height + extents.Value.Top + extents.Value.Bottom) / RenderScaling); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -556,6 +549,25 @@ namespace Avalonia.X11 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private Thickness? GetFrameExtents() |
|
|
|
{ |
|
|
|
XGetWindowProperty(_x11.Display, _handle, _x11.Atoms._NET_FRAME_EXTENTS, IntPtr.Zero, |
|
|
|
new IntPtr(4), false, (IntPtr)Atom.AnyPropertyType, out var _, |
|
|
|
out var _, out var nitems, out var _, out var prop); |
|
|
|
|
|
|
|
if (nitems.ToInt64() != 4) |
|
|
|
{ |
|
|
|
// Window hasn't been mapped by the WM yet, so can't get the extents.
|
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
var data = (IntPtr*)prop.ToPointer(); |
|
|
|
var extents = new Thickness(data[0].ToInt32(), data[2].ToInt32(), data[1].ToInt32(), data[3].ToInt32()); |
|
|
|
XFree(prop); |
|
|
|
|
|
|
|
return extents; |
|
|
|
} |
|
|
|
|
|
|
|
private bool UpdateScaling(bool skipResize = false) |
|
|
|
{ |
|
|
|
double newScaling; |
|
|
|
@ -564,7 +576,7 @@ namespace Avalonia.X11 |
|
|
|
else |
|
|
|
{ |
|
|
|
var monitor = _platform.X11Screens.Screens.OrderBy(x => x.Scaling) |
|
|
|
.FirstOrDefault(m => m.Bounds.Contains(Position)); |
|
|
|
.FirstOrDefault(m => m.Bounds.Contains(_position ?? default)); |
|
|
|
newScaling = monitor?.Scaling ?? RenderScaling; |
|
|
|
} |
|
|
|
|
|
|
|
@ -916,11 +928,11 @@ namespace Avalonia.X11 |
|
|
|
|
|
|
|
public void Hide() => XUnmapWindow(_x11.Display, _handle); |
|
|
|
|
|
|
|
public Point PointToClient(PixelPoint point) => new Point((point.X - Position.X) / RenderScaling, (point.Y - Position.Y) / RenderScaling); |
|
|
|
public Point PointToClient(PixelPoint point) => new Point((point.X - (_position ?? default).X) / RenderScaling, (point.Y - (_position ?? default).Y) / RenderScaling); |
|
|
|
|
|
|
|
public PixelPoint PointToScreen(Point point) => new PixelPoint( |
|
|
|
(int)(point.X * RenderScaling + Position.X), |
|
|
|
(int)(point.Y * RenderScaling + Position.Y)); |
|
|
|
(int)(point.X * RenderScaling + (_position ?? default).X), |
|
|
|
(int)(point.Y * RenderScaling + (_position ?? default).Y)); |
|
|
|
|
|
|
|
public void SetSystemDecorations(SystemDecorations enabled) |
|
|
|
{ |
|
|
|
@ -984,20 +996,36 @@ namespace Avalonia.X11 |
|
|
|
|
|
|
|
public PixelPoint Position |
|
|
|
{ |
|
|
|
get => _position ?? default; |
|
|
|
get |
|
|
|
{ |
|
|
|
if(_position == null) |
|
|
|
{ |
|
|
|
return default; |
|
|
|
} |
|
|
|
|
|
|
|
var extents = GetFrameExtents(); |
|
|
|
|
|
|
|
if(extents == null) |
|
|
|
{ |
|
|
|
extents = default(Thickness); |
|
|
|
} |
|
|
|
|
|
|
|
return new PixelPoint(_position.Value.X - (int)extents.Value.Left, _position.Value.Y - (int)extents.Value.Top); |
|
|
|
} |
|
|
|
set |
|
|
|
{ |
|
|
|
if(!_usePositioningFlags) |
|
|
|
if (!_usePositioningFlags) |
|
|
|
{ |
|
|
|
_usePositioningFlags = true; |
|
|
|
UpdateSizeHints(null); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var changes = new XWindowChanges |
|
|
|
{ |
|
|
|
x = (int)value.X, |
|
|
|
x = value.X, |
|
|
|
y = (int)value.Y |
|
|
|
}; |
|
|
|
|
|
|
|
XConfigureWindow(_x11.Display, _handle, ChangeWindowFlags.CWX | ChangeWindowFlags.CWY, |
|
|
|
ref changes); |
|
|
|
XFlush(_x11.Display); |
|
|
|
@ -1006,7 +1034,6 @@ namespace Avalonia.X11 |
|
|
|
_position = value; |
|
|
|
PositionChanged?.Invoke(value); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|