Browse Source

Merge pull request #10895 from AvaloniaUI/linux-frame-position

X11 - Return frame position for Window.Position
pull/10953/head
Nikita Tsukanov 3 years ago
committed by GitHub
parent
commit
cce3fea3a6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.X11/X11Window.Ime.cs
  2. 69
      src/Avalonia.X11/X11Window.cs

2
src/Avalonia.X11/X11Window.Ime.cs

@ -89,7 +89,7 @@ namespace Avalonia.X11
}
}
private void UpdateImePosition() => _imeControl?.UpdateWindowInfo(Position, RenderScaling);
private void UpdateImePosition() => _imeControl?.UpdateWindowInfo(_position ?? default, RenderScaling);
private void HandleKeyEvent(ref XEvent ev)
{

69
src/Avalonia.X11/X11Window.cs

@ -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);
}
}
}

Loading…
Cancel
Save