Browse Source

Merge pull request #1647 from CommonGuy/window-topmost

Implement Topmost on Window
pull/1586/merge
Jumar Macato 8 years ago
committed by GitHub
parent
commit
c2a113d693
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs
  2. 5
      src/Avalonia.Controls/Platform/IWindowBaseImpl.cs
  3. 16
      src/Avalonia.Controls/Primitives/Popup.cs
  4. 14
      src/Avalonia.Controls/WindowBase.cs
  5. 4
      src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
  6. 4
      src/Avalonia.DesignerSupport/Remote/Stubs.cs
  7. 6
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  8. 2
      src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs
  9. 2
      src/Gtk/Avalonia.Gtk3/WindowImpl.cs
  10. 1
      src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs
  11. 8
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  12. 19
      src/Windows/Avalonia.Win32/WindowImpl.cs

5
src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs

@ -110,7 +110,10 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{ {
//Not supported //Not supported
} }
public void SetTopmost(bool value)
{
//Not supported
}
} }
} }

5
src/Avalonia.Controls/Platform/IWindowBaseImpl.cs

@ -72,6 +72,11 @@ namespace Avalonia.Platform
/// ///
void SetMinMaxSize(Size minSize, Size maxSize); void SetMinMaxSize(Size minSize, Size maxSize);
/// <summary>
/// Sets whether this window appears on top of all other windows
/// </summary>
void SetTopmost(bool value);
/// <summary> /// <summary>
/// Gets platform specific display information /// Gets platform specific display information
/// </summary> /// </summary>

16
src/Avalonia.Controls/Primitives/Popup.cs

@ -70,6 +70,12 @@ namespace Avalonia.Controls.Primitives
public static readonly StyledProperty<bool> StaysOpenProperty = public static readonly StyledProperty<bool> StaysOpenProperty =
AvaloniaProperty.Register<Popup, bool>(nameof(StaysOpen), true); AvaloniaProperty.Register<Popup, bool>(nameof(StaysOpen), true);
/// <summary>
/// Defines the <see cref="Topmost"/> property.
/// </summary>
public static readonly StyledProperty<bool> TopmostProperty =
AvaloniaProperty.Register<Popup, bool>(nameof(Topmost));
private bool _isOpen; private bool _isOpen;
private PopupRoot _popupRoot; private PopupRoot _popupRoot;
private TopLevel _topLevel; private TopLevel _topLevel;
@ -84,6 +90,7 @@ namespace Avalonia.Controls.Primitives
IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false); IsHitTestVisibleProperty.OverrideDefaultValue<Popup>(false);
ChildProperty.Changed.AddClassHandler<Popup>(x => x.ChildChanged); ChildProperty.Changed.AddClassHandler<Popup>(x => x.ChildChanged);
IsOpenProperty.Changed.AddClassHandler<Popup>(x => x.IsOpenChanged); IsOpenProperty.Changed.AddClassHandler<Popup>(x => x.IsOpenChanged);
TopmostProperty.Changed.AddClassHandler<Popup>((p, e) => p.PopupRoot.Topmost = (bool)e.NewValue);
} }
/// <summary> /// <summary>
@ -194,6 +201,15 @@ namespace Avalonia.Controls.Primitives
set { SetValue(StaysOpenProperty, value); } set { SetValue(StaysOpenProperty, value); }
} }
/// <summary>
/// Gets or sets whether this popup appears on top of all other windows
/// </summary>
public bool Topmost
{
get { return GetValue(TopmostProperty); }
set { SetValue(TopmostProperty, value); }
}
/// <summary> /// <summary>
/// Gets the root of the popup window. /// Gets the root of the popup window.
/// </summary> /// </summary>

14
src/Avalonia.Controls/WindowBase.cs

@ -38,6 +38,9 @@ namespace Avalonia.Controls
o => o.Owner, o => o.Owner,
(o, v) => o.Owner = v); (o, v) => o.Owner = v);
public static readonly StyledProperty<bool> TopmostProperty =
AvaloniaProperty.Register<WindowBase, bool>(nameof(Topmost));
private bool _hasExecutedInitialLayoutPass; private bool _hasExecutedInitialLayoutPass;
private bool _isActive; private bool _isActive;
private bool _ignoreVisibilityChange; private bool _ignoreVisibilityChange;
@ -52,6 +55,8 @@ namespace Avalonia.Controls
MinHeightProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, (double)e.NewValue), new Size(w.MaxWidth, w.MaxHeight))); MinHeightProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, (double)e.NewValue), new Size(w.MaxWidth, w.MaxHeight)));
MaxWidthProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, w.MinHeight), new Size((double)e.NewValue, w.MaxHeight))); MaxWidthProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, w.MinHeight), new Size((double)e.NewValue, w.MaxHeight)));
MaxHeightProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, w.MinHeight), new Size(w.MaxWidth, (double)e.NewValue))); MaxHeightProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetMinMaxSize(new Size(w.MinWidth, w.MinHeight), new Size(w.MaxWidth, (double)e.NewValue)));
TopmostProperty.Changed.AddClassHandler<WindowBase>((w, e) => w.PlatformImpl?.SetTopmost((bool)e.NewValue));
} }
public WindowBase(IWindowBaseImpl impl) : this(impl, AvaloniaLocator.Current) public WindowBase(IWindowBaseImpl impl) : this(impl, AvaloniaLocator.Current)
@ -124,6 +129,15 @@ namespace Avalonia.Controls
set { SetAndRaise(OwnerProperty, ref _owner, value); } set { SetAndRaise(OwnerProperty, ref _owner, value); }
} }
/// <summary>
/// Gets or sets whether this window appears on top of all other windows
/// </summary>
public bool Topmost
{
get { return GetValue(TopmostProperty); }
set { SetValue(TopmostProperty, value); }
}
/// <summary> /// <summary>
/// Activates the window. /// Activates the window.
/// </summary> /// </summary>

4
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@ -102,5 +102,9 @@ namespace Avalonia.DesignerSupport.Remote
public void CanResize(bool value) public void CanResize(bool value)
{ {
} }
public void SetTopmost(bool value)
{
}
} }
} }

4
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@ -104,6 +104,10 @@ namespace Avalonia.DesignerSupport.Remote
public void CanResize(bool value) public void CanResize(bool value)
{ {
} }
public void SetTopmost(bool value)
{
}
} }
class ClipboardStub : IClipboard class ClipboardStub : IClipboard

6
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@ -261,10 +261,13 @@ namespace Avalonia.Gtk3.Interop
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_unmaximize(GtkWindow window); public delegate void gtk_window_unmaximize(GtkWindow window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_close(GtkWindow window); public delegate void gtk_window_close(GtkWindow window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_keep_above(GtkWindow gtkWindow, bool setting);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)] [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
public delegate void gtk_window_set_geometry_hints(GtkWindow window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask); public delegate void gtk_window_set_geometry_hints(GtkWindow window, IntPtr geometry_widget, ref GdkGeometry geometry, GdkWindowHints geom_mask);
@ -472,6 +475,7 @@ namespace Avalonia.Gtk3.Interop
public static D.gtk_window_maximize GtkWindowMaximize; public static D.gtk_window_maximize GtkWindowMaximize;
public static D.gtk_window_unmaximize GtkWindowUnmaximize; public static D.gtk_window_unmaximize GtkWindowUnmaximize;
public static D.gtk_window_close GtkWindowClose; public static D.gtk_window_close GtkWindowClose;
public static D.gtk_window_set_keep_above GtkWindowSetKeepAbove;
public static D.gdk_window_begin_move_drag GdkWindowBeginMoveDrag; public static D.gdk_window_begin_move_drag GdkWindowBeginMoveDrag;
public static D.gdk_window_begin_resize_drag GdkWindowBeginResizeDrag; public static D.gdk_window_begin_resize_drag GdkWindowBeginResizeDrag;
public static D.gdk_event_request_motions GdkEventRequestMotions; public static D.gdk_event_request_motions GdkEventRequestMotions;

2
src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs

@ -416,6 +416,8 @@ namespace Avalonia.Gtk3
public void Hide() => Native.GtkWidgetHide(GtkWidget); public void Hide() => Native.GtkWidgetHide(GtkWidget);
public void SetTopmost(bool value) => Native.GtkWindowSetKeepAbove(GtkWidget, value);
void GetGlobalPointer(out int x, out int y) void GetGlobalPointer(out int x, out int y)
{ {
int mask; int mask;

2
src/Gtk/Avalonia.Gtk3/WindowImpl.cs

@ -81,7 +81,7 @@ namespace Avalonia.Gtk3
public void ShowTaskbarIcon(bool value) => Native.GtkWindowSetSkipTaskbarHint(GtkWidget, !value); public void ShowTaskbarIcon(bool value) => Native.GtkWindowSetSkipTaskbarHint(GtkWidget, !value);
public void CanResize(bool value) => Native.GtkWindowSetResizable(GtkWidget, value); public void CanResize(bool value) => Native.GtkWindowSetResizable(GtkWidget, value);
class EmptyDisposable : IDisposable class EmptyDisposable : IDisposable
{ {

1
src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs

@ -123,6 +123,7 @@ namespace Avalonia.MonoMac
public void Hide() => Window?.OrderOut(Window); public void Hide() => Window?.OrderOut(Window);
public void SetTopmost(bool value) => Window.Level = value ? NSWindowLevel.Floating : NSWindowLevel.Normal;
public void BeginMoveDrag() public void BeginMoveDrag()
{ {

8
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@ -78,6 +78,14 @@ namespace Avalonia.Win32.Interop
SWP_RESIZE = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER SWP_RESIZE = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER
} }
public static class WindowPosZOrder
{
public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
public static readonly IntPtr HWND_TOP = new IntPtr(0);
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
}
public enum SizeCommand public enum SizeCommand
{ {
Restored, Restored,

19
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -32,6 +32,7 @@ namespace Avalonia.Win32
private bool _trackingMouse; private bool _trackingMouse;
private bool _decorated = true; private bool _decorated = true;
private bool _resizable = true; private bool _resizable = true;
private bool _topmost = false;
private double _scaling = 1; private double _scaling = 1;
private WindowState _showWindowState; private WindowState _showWindowState;
private WindowState _lastWindowState; private WindowState _lastWindowState;
@ -838,7 +839,7 @@ namespace Avalonia.Win32
var cx = Math.Abs(monitorInfo.rcWork.right - x); var cx = Math.Abs(monitorInfo.rcWork.right - x);
var cy = Math.Abs(monitorInfo.rcWork.bottom - y); var cy = Math.Abs(monitorInfo.rcWork.bottom - y);
SetWindowPos(_hwnd, new IntPtr(-2), x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW); SetWindowPos(_hwnd, WindowPosZOrder.HWND_NOTOPMOST, x, y, cx, cy, SetWindowPosFlags.SWP_SHOWWINDOW);
} }
} }
} }
@ -901,5 +902,21 @@ namespace Avalonia.Win32
_resizable = value; _resizable = value;
} }
public void SetTopmost(bool value)
{
if (value == _topmost)
{
return;
}
IntPtr hWndInsertAfter = value ? WindowPosZOrder.HWND_TOPMOST : WindowPosZOrder.HWND_NOTOPMOST;
UnmanagedMethods.SetWindowPos(_hwnd,
hWndInsertAfter,
0, 0, 0, 0,
SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE);
_topmost = value;
}
} }
} }

Loading…
Cancel
Save