Browse Source

Implement topmost on window

pull/1647/head
CommonGuy 8 years ago
parent
commit
0af6dd2c0a
  1. 5
      src/Avalonia.Controls/Platform/IWindowImpl.cs
  2. 14
      src/Avalonia.Controls/Window.cs
  3. 4
      src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs
  4. 4
      src/Avalonia.DesignerSupport/Remote/Stubs.cs
  5. 6
      src/Gtk/Avalonia.Gtk3/Interop/Native.cs
  6. 4
      src/Gtk/Avalonia.Gtk3/WindowImpl.cs
  7. 5
      src/OSX/Avalonia.MonoMac/WindowImpl.cs
  8. 8
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  9. 17
      src/Windows/Avalonia.Win32/WindowImpl.cs

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

@ -55,6 +55,11 @@ namespace Avalonia.Platform
/// </summary>
void CanResize(bool value);
/// <summary>
/// Gets or sets whether this window appears on top of all other windows
/// </summary>
void SetTopmost(bool value);
/// <summary>
/// Gets or sets a method called before the underlying implementation is destroyed.
/// Return true to prevent the underlying implementation from closing.

14
src/Avalonia.Controls/Window.cs

@ -104,6 +104,9 @@ namespace Avalonia.Controls
public static readonly StyledProperty<bool> CanResizeProperty =
AvaloniaProperty.Register<Window, bool>(nameof(CanResize), true);
public static readonly StyledProperty<bool> TopmostProperty =
AvaloniaProperty.Register<Window, bool>(nameof(Topmost));
private readonly NameScope _nameScope = new NameScope();
private object _dialogResult;
private readonly Size _maxPlatformClientSize;
@ -125,6 +128,8 @@ namespace Avalonia.Controls
CanResizeProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.CanResize((bool)e.NewValue));
TopmostProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.SetTopmost((bool)e.NewValue));
WindowStateProperty.Changed.AddClassHandler<Window>(
(w, e) => { if (w.PlatformImpl != null) w.PlatformImpl.WindowState = (WindowState)e.NewValue; });
}
@ -230,6 +235,15 @@ namespace Avalonia.Controls
set { SetValue(CanResizeProperty, 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>
/// Gets or sets the icon of the window.
/// </summary>

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

@ -102,5 +102,9 @@ namespace Avalonia.DesignerSupport.Remote
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 SetTopmost(bool value)
{
}
}
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)]
public delegate void gtk_window_unmaximize(GtkWindow window);
[UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
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)]
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_unmaximize GtkWindowUnmaximize;
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_resize_drag GdkWindowBeginResizeDrag;
public static D.gdk_event_request_motions GdkEventRequestMotions;

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

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

5
src/OSX/Avalonia.MonoMac/WindowImpl.cs

@ -116,6 +116,11 @@ namespace Avalonia.MonoMac
UpdateStyle();
}
public void SetTopmost(bool value)
{
Window.Level = value ? NSWindowLevel.Floating : NSWindowLevel.Normal;
}
public void SetTitle(string title) => Window.Title = title;
class ModalDisposable : IDisposable

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

@ -78,6 +78,14 @@ namespace Avalonia.Win32.Interop
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
{
Restored,

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

@ -32,6 +32,7 @@ namespace Avalonia.Win32
private bool _trackingMouse;
private bool _decorated = true;
private bool _resizable = true;
private bool _topmost = false;
private double _scaling = 1;
private WindowState _showWindowState;
private WindowState _lastWindowState;
@ -901,5 +902,21 @@ namespace Avalonia.Win32
_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