Files
Nebula-Auth/NebulaAuth/Theme/WindowStyle/WindowChromeRenderedBehavior.cs
T
achiez 8ff960189e 1.5.6 Bug fixes and code clean-ups
- Update: Added "Copy Password" to Mafile context menu (if available)
- Update: "Save Password" now pre-fills the current password in the "Login Again" dialog when encryption is enabled
- Fix: Prevented overlapping confirmation cycles in AutoConfirmer
- Fix: Added a Snackbar notification when a confirmation cycle is skipped due to a too frequent timer interval
- Fix: Fixed a rare bug where the previous proxy was used instead of the current one during session refresh
- Fix: Corrected "Session Permanently Expired" message showing on unrelated errors (e.g. network issues)
- UI-Fix: Fixed visual glitch where proxy input appeared non-empty when switching to a mafile-specific proxy
- Cleanup: Refactored and cleaned up codebase, improved styling and formatting via ReSharper
2025-05-02 23:29:24 +03:00

115 lines
3.7 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Shell;
using Microsoft.Xaml.Behaviors;
namespace NebulaAuth.Theme.WindowStyle;
public class WindowChromeRenderedBehavior : Behavior<Window>
{
private Window? _window;
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.ContentRendered += OnContentRendered;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.ContentRendered -= OnContentRendered;
}
private void OnContentRendered(object? sender, EventArgs e)
{
_window = Window.GetWindow(AssociatedObject);
if (_window == null) return;
var oldWindowChrome = WindowChrome.GetWindowChrome(_window);
if (oldWindowChrome == null) return;
var newWindowChrome = new WindowChrome
{
CaptionHeight = oldWindowChrome.CaptionHeight,
CornerRadius = oldWindowChrome.CornerRadius,
GlassFrameThickness = new Thickness(0, 0, 0, 1),
NonClientFrameEdges = NonClientFrameEdges.Bottom,
ResizeBorderThickness = oldWindowChrome.ResizeBorderThickness,
UseAeroCaptionButtons = oldWindowChrome.UseAeroCaptionButtons
};
WindowChrome.SetWindowChrome(_window, newWindowChrome);
var hWnd = new WindowInteropHelper(_window).Handle;
HwndSource.FromHwnd(hWnd)?.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case NativeMethods.WM_NCPAINT:
handled = false;
RemoveFrame();
break;
case NativeMethods.WM_NCCALCSIZE:
handled = true;
var rcClientArea = (RECT) Marshal.PtrToStructure(lParam, typeof(RECT));
rcClientArea.Bottom += (int) (WindowChromeHelper.WindowResizeBorderThickness.Bottom / 2);
Marshal.StructureToPtr(rcClientArea, lParam, false);
return wParam == new IntPtr(1) ? new IntPtr((int) NativeMethods.WVR.REDRAW) : IntPtr.Zero;
}
return IntPtr.Zero;
}
private void RemoveFrame()
{
if (Environment.OSVersion.Version.Major >= 6 && NativeMethods.IsDwmAvailable())
{
if (NativeMethods.DwmIsCompositionEnabled() && SystemParameters.DropShadow)
{
// to get the aero shadow back, margins have to be set on at least one side
// don't use negative values for the margins because it causes flickering when restoring or maximizing the window
// setting the margin on the left or top sides seem best, since the window never appears to flicker there on resizing
// but the right and bottom sometimes do, otherwise there will occasionally be white flicker when resizing the window.
NativeMethods.MARGINS margins;
margins.bottomHeight = 0;
margins.leftWidth = 1;
margins.rightWidth = 0;
margins.topHeight = 0;
var helper = new WindowInteropHelper(_window);
NativeMethods.DwmExtendFrameIntoClientArea(helper.Handle, ref margins);
}
}
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public static RECT Empty;
public RECT(int left, int top, int right, int bottom)
{
Left = left;
Top = top;
Right = right;
Bottom = bottom;
}
}
}