// ==WindhawkMod==
// @id              window-animation-customizer
// @name            Window Animation Customizer
// @description     Customizable 3D animations without modifying theme files.
// @version         0.4.0
// @author          Lockframe, kieldbg, aromakitsune, lolstijl
// @github          https://github.com/Lockframe
// @homepage        https://github.com/kieldbg
// @include         *
// @include         dwm.exe
// @compilerOptions -ldcomp -ld3d11 -ldxgi -lgdi32 -luser32 -ladvapi32 -ldwmapi -lcomctl32 -lwinmm -luxtheme -lole32 -lwevtapi
// ==/WindhawkMod==

// ==WindhawkModSettings==
/*
- OpenAnimation:
    - enable_open: true
      $name: "Enable"
    - duration_open: 250
      $name: "Base Duration (ms)"
    - open_scale: "1.0, 1.0"
      $name: "Scale (X, Y)"
    - open_pivot_preset: "1"
      $name: "Pivot Preset"
      $options:
      - "1": "Center"
      - "2": "Top Left"
      - "3": "Top"
      - "4": "Top Right"
      - "5": "Left"
      - "6": "Right"
      - "7": "Bottom Left"
      - "8": "Bottom"
      - "9": "Bottom Right"
    - Transform:
        - open_offset: "0.0, 0.0"
          $name: "Offset (X, Y)"
        - open_pitch: 5.0
          $name: "Pitch"
        - open_yaw: 0.0
          $name: "Yaw"
        - open_roll: 0.0
          $name: "Roll"
      $name: "Transform"
    - Appearance:
        - open_opacity: 0.0
          $name: "Opacity"
        - open_blur: 0.0
          $name: "Blur"
      $name: "Appearance"
    - Physics:
        - open_spring: false
          $name: "Enable Spring"
        - open_mass: 1.0
          $name: "Mass"
        - open_stiffness: 200.0
          $name: "Stiffness"
        - open_damping: 28.0
          $name: "Damping"
      $name: "Physics"
    - open_bezier: "0.0, 0.0, 0.0, 1.0"
      $name: "Base Bezier (X1, Y1, X2, Y2)"
    - Overrides:
        - open_adv_scale:
            - enable: false
              $name: "Enable"
            - duration: 350
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Scale"
        - open_adv_opacity:
            - enable: false
              $name: "Enable"
            - duration: 200
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Opacity"
        - open_adv_blur:
            - enable: false
              $name: "Enable"
            - duration: 300
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Blur"
        - open_adv_pitch:
            - enable: false
              $name: "Enable"
            - duration: 400
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Pitch"
        - open_adv_yaw:
            - enable: false
              $name: "Enable"
            - duration: 400
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Yaw"
        - open_adv_roll:
            - enable: false
              $name: "Enable"
            - duration: 400
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Roll"
      $name: "Overrides"
  $name: "Open Animation"
- CloseAnimation:
    - enable_close: true
      $name: "Enable"
    - duration_close: 166
      $name: "Base Duration (ms)"
    - close_scale: "1.0, 1.0"
      $name: "Scale (X, Y)"
    - close_pivot_preset: "1"
      $name: "Pivot Preset"
      $options:
      - "1": "Center"
      - "2": "Top Left"
      - "3": "Top"
      - "4": "Top Right"
      - "5": "Left"
      - "6": "Right"
      - "7": "Bottom Left"
      - "8": "Bottom"
      - "9": "Bottom Right"
    - Transform:
        - close_offset: "0.0, 0.0"
          $name: "Offset (X, Y)"
        - close_pitch: 5.0
          $name: "Pitch"
        - close_yaw: 8.0
          $name: "Yaw"
        - close_roll: 0.0
          $name: "Roll"
      $name: "Transform"
    - Appearance:
        - close_opacity: 0.0
          $name: "Opacity"
        - close_blur: 0.0
          $name: "Blur"
      $name: "Appearance"
    - Physics:
        - close_spring: false
          $name: "Enable Spring"
        - close_mass: 1.0
          $name: "Mass"
        - close_stiffness: 200.0
          $name: "Stiffness"
        - close_damping: 28.0
          $name: "Damping"
      $name: "Physics"
    - close_bezier: "0.3, 0.0, 0.8, 0.15"
      $name: "Base Bezier (X1, Y1, X2, Y2)"
    - Overrides:
        - close_adv_scale:
            - enable: false
              $name: "Enable"
            - duration: 200
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Scale"
        - close_adv_opacity:
            - enable: false
              $name: "Enable"
            - duration: 150
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Opacity"
        - close_adv_blur:
            - enable: false
              $name: "Enable"
            - duration: 150
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Blur"
        - close_adv_pitch:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Pitch"
        - close_adv_yaw:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Yaw"
        - close_adv_roll:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Roll"
      $name: "Overrides"
  $name: "Close Animation"
- MinimizeAnimation:
    - enable_minimize: true
      $name: "Enable"
    - duration_minimize: 250
      $name: "Base Duration (ms)"
    - minimize_scale: "1.0, 1.0"
      $name: "Scale (X, Y)"
    - min_ignore_taskbar: false
      $name: "Ignore Taskbar"
    - min_track_taskbar: true
      $name: "Accurate Taskbar Tracking Trick"
    - minimize_pivot_preset: "1"
      $name: "Pivot Preset"
      $options:
      - "1": "Center"
      - "2": "Top Left"
      - "3": "Top"
      - "4": "Top Right"
      - "5": "Left"
      - "6": "Right"
      - "7": "Bottom Left"
      - "8": "Bottom"
      - "9": "Bottom Right"
    - Transform:
        - minimize_offset: "0.0, 0.0"
          $name: "Offset (X, Y)"
        - minimize_pitch: 0.0
          $name: "Pitch"
        - minimize_yaw: 0.0
          $name: "Yaw"
        - minimize_roll: 1.0
          $name: "Roll"
      $name: "Transform"
    - Appearance:
        - minimize_opacity: 0.0
          $name: "Opacity"
        - minimize_blur: 0.0
          $name: "Blur"
      $name: "Appearance"
    - Physics:
        - minimize_spring: false
          $name: "Enable Spring"
        - minimize_mass: 1.0
          $name: "Mass"
        - minimize_stiffness: 200.0
          $name: "Stiffness"
        - minimize_damping: 28.0
          $name: "Damping"
      $name: "Physics"
    - minimize_bezier: "0.3, 0.0, 0.8, 0.15"
      $name: "Base Bezier (X1, Y1, X2, Y2)"
    - Overrides:
        - min_adv_scale:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Scale"
        - min_adv_opacity:
            - enable: false
              $name: "Enable"
            - duration: 200
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Opacity"
        - min_adv_blur:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Blur"
        - min_adv_pitch:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Pitch"
        - min_adv_yaw:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Yaw"
        - min_adv_roll:
            - enable: false
              $name: "Enable"
            - duration: 250
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Roll"
      $name: "Overrides"
- RestoreAnimation:
    - enable_restore: true
      $name: "Enable"
    - duration_restore: 250
      $name: "Base Duration (ms)"
    - restore_scale: "1.0, 1.0"
      $name: "Scale (X, Y)"
    - res_ignore_taskbar: false
      $name: "Ignore Taskbar"
    - res_track_taskbar: true
      $name: "Accurate Taskbar Tracking Trick"
    - restore_pivot_preset: "1"
      $name: "Pivot Preset"
      $options:
      - "1": "Center"
      - "2": "Top Left"
      - "3": "Top"
      - "4": "Top Right"
      - "5": "Left"
      - "6": "Right"
      - "7": "Bottom Left"
      - "8": "Bottom"
      - "9": "Bottom Right"
    - Transform:
        - restore_offset: "0.0, 0.0"
          $name: "Offset (X, Y)"
        - restore_pitch: 0.0
          $name: "Pitch"
        - restore_yaw: 0.0
          $name: "Yaw"
        - restore_roll: 1.0
          $name: "Roll"
      $name: "Transform"
    - Appearance:
        - restore_opacity: 0.0
          $name: "Opacity"
        - restore_blur: 0.0
          $name: "Blur"
      $name: "Appearance"
    - Physics:
        - restore_spring: false
          $name: "Enable Spring"
        - restore_mass: 1.0
          $name: "Mass"
        - restore_stiffness: 200.0
          $name: "Stiffness"
        - restore_damping: 28.0
          $name: "Damping"
      $name: "Physics"
    - restore_bezier: "0.0, 0.0, 0.0, 1.0"
      $name: "Base Bezier (X1, Y1, X2, Y2)"
    - Overrides:
        - res_adv_scale:
            - enable: false
              $name: "Enable"
            - duration: 350
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Scale"
        - res_adv_opacity:
            - enable: false
              $name: "Enable"
            - duration: 200
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.3, 0.0, 0.8, 0.15"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Opacity"
        - res_adv_blur:
            - enable: false
              $name: "Enable"
            - duration: 300
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Blur"
        - res_adv_pitch:
            - enable: false
              $name: "Enable"
            - duration: 400
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Pitch"
        - res_adv_yaw:
            - enable: false
              $name: "Enable"
            - duration: 400
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Yaw"
        - res_adv_roll:
            - enable: false
              $name: "Enable"
            - duration: 400
              $name: "Duration (ms)"
            - delay: 0
              $name: "Delay (ms)"
            - bezier: "0.0, 0.0, 0.0, 1.0"
              $name: "Bezier (X1, Y1, X2, Y2)"
          $name: "Roll"
      $name: "Overrides"
  $name: "Restore Animation"
- DragAnimation:
    - enable_drag: true
      $name: "Enable Drag Tilt/Yaw"
    - drag_intensity: 1.0
      $name: "Intensity Multiplier"
    - drag_smoothing: 15.0
      $name: "Smoothing"
  $name: "Drag Animation"
- System:
    - anim_vsync: false
      $name: "Enable VSync"
    - anim_fps: 75
      $name: "Target FPS (VSync Off)"
  $name: "System"
*/
// ==/WindhawkModSettings==

#include <windows.h>
#include <windhawk_api.h>
#include <windhawk_utils.h>
#include <dcomp.h>
#include <d3d11.h>
#include <dxgi1_2.h>
#include <dwmapi.h>
#include <uxtheme.h>
#include <commctrl.h>
#include <math.h>
#include <vector>
#include <mutex>
#include <stdio.h>
#include <memory>
#include <unordered_map>
#include <atomic>

#include <winevt.h>

#define SHARED_SECTION __attribute__((section(".shared")))
asm(".section .shared,\"dws\"\n");
volatile LONG g_crashStrikes SHARED_SECTION = 0;

bool HasDwminitWarningInLastMinute() {
    const WCHAR* queryPath = L"Application";
    const WCHAR* query = L"*[System[Provider[@Name='Dwminit'] and (Level=3) and TimeCreated[timediff(@SystemTime) <= 60000]]]";
    EVT_HANDLE queryHandle = EvtQuery(nullptr, queryPath, query, EvtQueryChannelPath);
    if (!queryHandle) return false;

    bool found = false;
    EVT_HANDLE eventHandle = nullptr;
    DWORD dwReturned = 0;
    if (EvtNext(queryHandle, 1, &eventHandle, 1000, 0, &dwReturned)) {
        found = true;
        EvtClose(eventHandle);
    }
    EvtClose(queryHandle);
    return found;
}

bool CheckCrashLoopFailsafe() {
    if (!HasDwminitWarningInLastMinute()) {
        InterlockedExchange((volatile LONG*)&g_crashStrikes, 0);
        return true;
    }
    LONG strikes = InterlockedIncrement((volatile LONG*)&g_crashStrikes);
    if (strikes >= 2) return false;
    return true;
}

#define DWM_TNP_ENABLE3D 0x4000000
#define ANIM_TYPE_OPEN 0
#define ANIM_TYPE_CLOSE 1
#define ANIM_TYPE_MINIMIZE 2
#define ANIM_TYPE_RESTORE 3
#define ANIM_TYPE_DRAG 4
#define ANIM_TYPE_DRAG_END 5

#define REVEAL_DYNARRAY_SCAN_START 0x100
#define REVEAL_DYNARRAY_SCAN_END 0x250
#define REVEAL_DYNARRAY_CAPACITY_OFFSET 0x14
#define REVEAL_DYNARRAY_COUNT_OFFSET 0x18
#define REVEAL_DYNARRAY_TRACKED_COUNT_OFFSET 0x20
#define REVEAL_DYNARRAY_MAX_COUNT 8
#define REVEAL_DYNARRAY_MAX_CAPACITY 64

#define MAX_DYNARRAY_READ_BOUNDS (REVEAL_DYNARRAY_SCAN_END + REVEAL_DYNARRAY_TRACKED_COUNT_OFFSET + sizeof(void*))

// --- Fast Math Inlines & Constants ---
template<typename T> inline T FastMax(T a, T b) { return a > b ? a : b; }
template<typename T> inline T FastMin(T a, T b) { return a < b ? a : b; }

// --- Metrics Cache ---
struct CACHED_METRICS {
    int cxScreen, cyScreen, xVirtual, yVirtual, cxVirtual, cyVirtual;
} GMetrics;

void UpdateMetricsCache() {
    GMetrics.cxScreen = GetSystemMetrics(SM_CXSCREEN);
    GMetrics.cyScreen = GetSystemMetrics(SM_CYSCREEN);
    GMetrics.xVirtual = GetSystemMetrics(SM_XVIRTUALSCREEN);
    GMetrics.yVirtual = GetSystemMetrics(SM_YVIRTUALSCREEN);
    GMetrics.cxVirtual = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    GMetrics.cyVirtual = GetSystemMetrics(SM_CYVIRTUALSCREEN);
}

// --- Settings Struct & Loaders ---
float SolveCubicBezier(float x, float x1, float y1, float x2, float y2);
struct CubicBezierDef { float x1, y1, x2, y2; float LUT[512]; };
void BuildBezierLUT(CubicBezierDef& b) {
    for (int i = 0; i < 512; ++i) b.LUT[i] = SolveCubicBezier((float)i / 511.0f, b.x1, b.y1, b.x2, b.y2);
}
float FastSolveCubicBezier(float x, const CubicBezierDef& b) {
    if (x <= 0.0f) return 0.0f; if (x >= 1.0f) return 1.0f;
    float scaled = x * 511.0f; int idx = (int)scaled;
    if (idx >= 511) return b.LUT[511];
    return b.LUT[idx] + (b.LUT[idx + 1] - b.LUT[idx]) * (scaled - idx);
}

struct AdvProperty { bool enabled; DWORD duration; DWORD delay; CubicBezierDef bezier; };
struct AdvAnimSettings { AdvProperty opacity, blur, scale, pitch, yaw, roll; };

struct MOD_SETTINGS {
    bool enable_open; DWORD duration_open;
    float open_translate_x, open_translate_y;
    float open_pitch, open_yaw, open_roll, open_z, open_scale_x, open_scale_y, open_opacity, open_blur;
    int open_pivot_preset; float open_pivot_x, open_pivot_y;
    CubicBezierDef open_bezier; bool open_spring; float open_mass, open_stiffness, open_damping;
    AdvAnimSettings open_adv;
    
    bool enable_close; DWORD duration_close;
    float close_translate_x, close_translate_y;
    float close_pitch, close_yaw, close_roll, close_z, close_scale_x, close_scale_y, close_opacity, close_blur;
    int close_pivot_preset; float close_pivot_x, close_pivot_y;
    CubicBezierDef close_bezier; bool close_spring; float close_mass, close_stiffness, close_damping;
    AdvAnimSettings close_adv;
    
    bool enable_minimize; DWORD duration_minimize;
    float min_translate_x, min_translate_y;
    bool min_ignore_taskbar; bool min_track_taskbar;
    float min_pitch, min_yaw, min_roll, min_z, min_scale_x, min_scale_y, min_opacity, min_blur;
    int min_pivot_preset; float min_pivot_x, min_pivot_y;
    CubicBezierDef min_bezier; bool min_spring; float min_mass, min_stiffness, min_damping;
    AdvAnimSettings min_adv;
    
    bool enable_restore; DWORD duration_restore;
    float res_translate_x, res_translate_y;
    bool res_ignore_taskbar; bool res_track_taskbar;
    float res_pitch, res_yaw, res_roll, res_z, res_scale_x, res_scale_y, res_opacity, res_blur;
    int res_pivot_preset; float res_pivot_x, res_pivot_y;
    CubicBezierDef res_bezier; bool res_spring; float res_mass, res_stiffness, res_damping;
    AdvAnimSettings res_adv;
    
    bool enable_drag; float drag_intensity, drag_smoothing;

    bool anim_vsync; int anim_fps; int cached_vsync_fps;
};

MOD_SETTINGS GlobalSettings;
SRWLOCK GSettingsLock = SRWLOCK_INIT;

MOD_SETTINGS GetSafeSettings() {
    MOD_SETTINGS Copy;
    AcquireSRWLockShared(&GSettingsLock);
    Copy = GlobalSettings;
    ReleaseSRWLockShared(&GSettingsLock);
    return Copy;
}

// --- Parsers ---
int ParseIntOpt(LPCWSTR name, int def) {
    LPCWSTR val = Wh_GetStringSetting(name);
    if (val) { int v = _wtoi(val); Wh_FreeStringSetting(val); return v; }
    return def;
}
float ParseFloatOpt(LPCWSTR name, float def) {
    LPCWSTR val = Wh_GetStringSetting(name);
    if (val) { float v = _wtof(val); Wh_FreeStringSetting(val); return v; }
    return def;
}
void ParseOffsetXY(LPCWSTR name, float& x, float& y, float dx, float dy) {
    x=dx; y=dy; LPCWSTR val = Wh_GetStringSetting(name);
    if (val) { swscanf(val, L"%f , %f", &x, &y); Wh_FreeStringSetting(val); }
}
void ParseScale(LPCWSTR name, float& sx, float& sy, float dsx, float dsy) {
    sx=dsx; sy=dsy; LPCWSTR val = Wh_GetStringSetting(name);
    if (val) { swscanf(val, L"%f , %f", &sx, &sy); Wh_FreeStringSetting(val); }
}
CubicBezierDef ParseBezier(LPCWSTR name, float dX1, float dY1, float dX2, float dY2) {
    CubicBezierDef b = { dX1, dY1, dX2, dY2, {0} }; LPCWSTR val = Wh_GetStringSetting(name);
    if (val) { swscanf(val, L"%f , %f , %f , %f", &b.x1, &b.y1, &b.x2, &b.y2); Wh_FreeStringSetting(val); }
    BuildBezierLUT(b);
    return b;
}
void ParseAdvNew(LPCWSTR prefix, AdvProperty& prop, int dDur, float x1, float y1, float x2, float y2) {
    WCHAR key[256];
    wsprintf(key, L"%s.enable", prefix);
    prop.enabled = Wh_GetIntSetting(key) != 0;
    wsprintf(key, L"%s.duration", prefix);
    prop.duration = Wh_GetIntSetting(key);
    if (prop.duration == 0) prop.duration = dDur;
    wsprintf(key, L"%s.delay", prefix);
    prop.delay = Wh_GetIntSetting(key);
    wsprintf(key, L"%s.bezier", prefix);
    prop.bezier = ParseBezier(key, x1, y1, x2, y2);
}

void UpdateRefreshRateCache() {
    bool vsync = false;
    AcquireSRWLockShared(&GSettingsLock);
    vsync = GlobalSettings.anim_vsync;
    ReleaseSRWLockShared(&GSettingsLock);

    if (vsync) {
        int BestFps = 0; DEVMODEW DevMode = {{0}}; DevMode.dmSize = sizeof(DevMode);
        for (DWORD I = 0; EnumDisplaySettingsW(NULL, I, &DevMode); ++I) {
            if ((DevMode.dmFields & DM_DISPLAYFREQUENCY) && DevMode.dmDisplayFrequency > 1 && DevMode.dmDisplayFrequency != 0xFFFFFFFF) {
                if ((int)DevMode.dmDisplayFrequency > BestFps) BestFps = (int)DevMode.dmDisplayFrequency;
            }
        }
        
        AcquireSRWLockExclusive(&GSettingsLock);
        GlobalSettings.cached_vsync_fps = BestFps > 0 ? BestFps : 60;
        ReleaseSRWLockExclusive(&GSettingsLock);
    }
}

void LoadModSettings() {
    MOD_SETTINGS t = {0};
    
    // OPEN
    t.enable_open = Wh_GetIntSetting(L"OpenAnimation.enable_open") != 0; 
    t.duration_open = (DWORD)Wh_GetIntSetting(L"OpenAnimation.duration_open");
    if (t.duration_open == 0) t.duration_open = 250;
    t.open_pivot_preset = ParseIntOpt(L"OpenAnimation.open_pivot_preset", 1);
    t.open_pivot_x = 0.5f; t.open_pivot_y = 0.5f;
    ParseScale(L"OpenAnimation.open_scale", t.open_scale_x, t.open_scale_y, 1.0f, 1.0f);
    ParseOffsetXY(L"OpenAnimation.Transform.open_offset", t.open_translate_x, t.open_translate_y, 0, 0);
    t.open_z = 0.0f;
    t.open_pitch = ParseFloatOpt(L"OpenAnimation.Transform.open_pitch", 5.0f);
    t.open_yaw = ParseFloatOpt(L"OpenAnimation.Transform.open_yaw", 0.0f);
    t.open_roll = ParseFloatOpt(L"OpenAnimation.Transform.open_roll", 0.0f);
    t.open_opacity = ParseFloatOpt(L"OpenAnimation.Appearance.open_opacity", 0.0f);
    t.open_blur = ParseFloatOpt(L"OpenAnimation.Appearance.open_blur", 0.0f);
    t.open_spring = Wh_GetIntSetting(L"OpenAnimation.Physics.open_spring") != 0;
    t.open_mass = ParseFloatOpt(L"OpenAnimation.Physics.open_mass", 1.0f);
    t.open_stiffness = ParseFloatOpt(L"OpenAnimation.Physics.open_stiffness", 200.0f);
    t.open_damping = ParseFloatOpt(L"OpenAnimation.Physics.open_damping", 28.0f);
    t.open_bezier = ParseBezier(L"OpenAnimation.open_bezier", 0,0,0,1);
    ParseAdvNew(L"OpenAnimation.Overrides.open_adv_scale", t.open_adv.scale, 350, 0,0,0,1);
    ParseAdvNew(L"OpenAnimation.Overrides.open_adv_opacity", t.open_adv.opacity, 200, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"OpenAnimation.Overrides.open_adv_blur", t.open_adv.blur, 300, 0,0,0,1);
    ParseAdvNew(L"OpenAnimation.Overrides.open_adv_pitch", t.open_adv.pitch, 400, 0,0,0,1);
    ParseAdvNew(L"OpenAnimation.Overrides.open_adv_yaw", t.open_adv.yaw, 400, 0,0,0,1);
    ParseAdvNew(L"OpenAnimation.Overrides.open_adv_roll", t.open_adv.roll, 400, 0,0,0,1);

    // CLOSE
    t.enable_close = Wh_GetIntSetting(L"CloseAnimation.enable_close") != 0; 
    t.duration_close = (DWORD)Wh_GetIntSetting(L"CloseAnimation.duration_close");
    if (t.duration_close == 0) t.duration_close = 166;
    t.close_pivot_preset = ParseIntOpt(L"CloseAnimation.close_pivot_preset", 1);
    t.close_pivot_x = 0.5f; t.close_pivot_y = 0.5f;
    ParseScale(L"CloseAnimation.close_scale", t.close_scale_x, t.close_scale_y, 1.0f, 1.0f);
    ParseOffsetXY(L"CloseAnimation.Transform.close_offset", t.close_translate_x, t.close_translate_y, 0, 0);
    t.close_z = 0.0f;
    t.close_pitch = ParseFloatOpt(L"CloseAnimation.Transform.close_pitch", 5.0f);
    t.close_yaw = ParseFloatOpt(L"CloseAnimation.Transform.close_yaw", 8.0f);
    t.close_roll = ParseFloatOpt(L"CloseAnimation.Transform.close_roll", 0.0f);
    t.close_opacity = ParseFloatOpt(L"CloseAnimation.Appearance.close_opacity", 0.0f);
    t.close_blur = ParseFloatOpt(L"CloseAnimation.Appearance.close_blur", 0.0f);
    t.close_spring = Wh_GetIntSetting(L"CloseAnimation.Physics.close_spring") != 0;
    t.close_mass = ParseFloatOpt(L"CloseAnimation.Physics.close_mass", 1.0f);
    t.close_stiffness = ParseFloatOpt(L"CloseAnimation.Physics.close_stiffness", 200.0f);
    t.close_damping = ParseFloatOpt(L"CloseAnimation.Physics.close_damping", 28.0f);
    t.close_bezier = ParseBezier(L"CloseAnimation.close_bezier", 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"CloseAnimation.Overrides.close_adv_scale", t.close_adv.scale, 200, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"CloseAnimation.Overrides.close_adv_opacity", t.close_adv.opacity, 150, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"CloseAnimation.Overrides.close_adv_blur", t.close_adv.blur, 150, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"CloseAnimation.Overrides.close_adv_pitch", t.close_adv.pitch, 250, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"CloseAnimation.Overrides.close_adv_yaw", t.close_adv.yaw, 250, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"CloseAnimation.Overrides.close_adv_roll", t.close_adv.roll, 250, 0.3f,0,0.8f,0.15f);

    // MINIMIZE
    t.enable_minimize = Wh_GetIntSetting(L"MinimizeAnimation.enable_minimize") != 0; 
    t.duration_minimize = (DWORD)Wh_GetIntSetting(L"MinimizeAnimation.duration_minimize");
    if (t.duration_minimize == 0) t.duration_minimize = 250;
    t.min_ignore_taskbar = Wh_GetIntSetting(L"MinimizeAnimation.min_ignore_taskbar") != 0; 
    t.min_track_taskbar = Wh_GetIntSetting(L"MinimizeAnimation.min_track_taskbar") != 0;
    t.min_pivot_preset = ParseIntOpt(L"MinimizeAnimation.minimize_pivot_preset", 1);
    t.min_pivot_x = 0.5f; t.min_pivot_y = 0.5f;
    ParseScale(L"MinimizeAnimation.minimize_scale", t.min_scale_x, t.min_scale_y, 1.0f, 1.0f);
    ParseOffsetXY(L"MinimizeAnimation.Transform.minimize_offset", t.min_translate_x, t.min_translate_y, 0, 0);
    t.min_z = 0.0f;
    t.min_pitch = ParseFloatOpt(L"MinimizeAnimation.Transform.minimize_pitch", 0.0f);
    t.min_yaw = ParseFloatOpt(L"MinimizeAnimation.Transform.minimize_yaw", 0.0f);
    t.min_roll = ParseFloatOpt(L"MinimizeAnimation.Transform.minimize_roll", 1.0f);
    t.min_opacity = ParseFloatOpt(L"MinimizeAnimation.Appearance.minimize_opacity", 0.0f);
    t.min_blur = ParseFloatOpt(L"MinimizeAnimation.Appearance.minimize_blur", 0.0f);
    t.min_spring = Wh_GetIntSetting(L"MinimizeAnimation.Physics.minimize_spring") != 0;
    t.min_mass = ParseFloatOpt(L"MinimizeAnimation.Physics.minimize_mass", 1.0f);
    t.min_stiffness = ParseFloatOpt(L"MinimizeAnimation.Physics.minimize_stiffness", 200.0f);
    t.min_damping = ParseFloatOpt(L"MinimizeAnimation.Physics.minimize_damping", 28.0f);
    t.min_bezier = ParseBezier(L"MinimizeAnimation.minimize_bezier", 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"MinimizeAnimation.Overrides.min_adv_scale", t.min_adv.scale, 250, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"MinimizeAnimation.Overrides.min_adv_opacity", t.min_adv.opacity, 200, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"MinimizeAnimation.Overrides.min_adv_blur", t.min_adv.blur, 250, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"MinimizeAnimation.Overrides.min_adv_pitch", t.min_adv.pitch, 250, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"MinimizeAnimation.Overrides.min_adv_yaw", t.min_adv.yaw, 250, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"MinimizeAnimation.Overrides.min_adv_roll", t.min_adv.roll, 250, 0.3f,0,0.8f,0.15f);

    // RESTORE
    t.enable_restore = Wh_GetIntSetting(L"RestoreAnimation.enable_restore") != 0; 
    t.duration_restore = (DWORD)Wh_GetIntSetting(L"RestoreAnimation.duration_restore");
    if (t.duration_restore == 0) t.duration_restore = 250;
    t.res_ignore_taskbar = Wh_GetIntSetting(L"RestoreAnimation.res_ignore_taskbar") != 0; 
    t.res_track_taskbar = Wh_GetIntSetting(L"RestoreAnimation.res_track_taskbar") != 0;
    t.res_pivot_preset = ParseIntOpt(L"RestoreAnimation.restore_pivot_preset", 1);
    t.res_pivot_x = 0.5f; t.res_pivot_y = 0.5f;
    ParseScale(L"RestoreAnimation.restore_scale", t.res_scale_x, t.res_scale_y, 1.0f, 1.0f);
    ParseOffsetXY(L"RestoreAnimation.Transform.restore_offset", t.res_translate_x, t.res_translate_y, 0, 0);
    t.res_z = 0.0f;
    t.res_pitch = ParseFloatOpt(L"RestoreAnimation.Transform.restore_pitch", 0.0f);
    t.res_yaw = ParseFloatOpt(L"RestoreAnimation.Transform.restore_yaw", 0.0f);
    t.res_roll = ParseFloatOpt(L"RestoreAnimation.Transform.restore_roll", 1.0f);
    t.res_opacity = ParseFloatOpt(L"RestoreAnimation.Appearance.restore_opacity", 0.0f);
    t.res_blur = ParseFloatOpt(L"RestoreAnimation.Appearance.restore_blur", 0.0f);
    t.res_spring = Wh_GetIntSetting(L"RestoreAnimation.Physics.restore_spring") != 0;
    t.res_mass = ParseFloatOpt(L"RestoreAnimation.Physics.restore_mass", 1.0f);
    t.res_stiffness = ParseFloatOpt(L"RestoreAnimation.Physics.restore_stiffness", 200.0f);
    t.res_damping = ParseFloatOpt(L"RestoreAnimation.Physics.restore_damping", 28.0f);
    t.res_bezier = ParseBezier(L"RestoreAnimation.restore_bezier", 0.0f,0.0f,0.0f,1.0f);
    ParseAdvNew(L"RestoreAnimation.Overrides.res_adv_scale", t.res_adv.scale, 350, 0,0,0,1);
    ParseAdvNew(L"RestoreAnimation.Overrides.res_adv_opacity", t.res_adv.opacity, 200, 0.3f,0,0.8f,0.15f);
    ParseAdvNew(L"RestoreAnimation.Overrides.res_adv_blur", t.res_adv.blur, 300, 0,0,0,1);
    ParseAdvNew(L"RestoreAnimation.Overrides.res_adv_pitch", t.res_adv.pitch, 400, 0,0,0,1);
    ParseAdvNew(L"RestoreAnimation.Overrides.res_adv_yaw", t.res_adv.yaw, 400, 0,0,0,1);
    ParseAdvNew(L"RestoreAnimation.Overrides.res_adv_roll", t.res_adv.roll, 400, 0,0,0,1);

    // DRAG
    t.enable_drag = Wh_GetIntSetting(L"DragAnimation.enable_drag") != 0;
    t.drag_intensity = ParseFloatOpt(L"DragAnimation.drag_intensity", 1.0f);
    t.drag_smoothing = ParseFloatOpt(L"DragAnimation.drag_smoothing", 15.0f);

    t.anim_vsync = Wh_GetIntSetting(L"System.anim_vsync") != 0;
    t.anim_fps = Wh_GetIntSetting(L"System.anim_fps");
    if (t.anim_fps <= 0) t.anim_fps = 60;
    
    AcquireSRWLockShared(&GSettingsLock);
    t.cached_vsync_fps = GlobalSettings.cached_vsync_fps;
    ReleaseSRWLockShared(&GSettingsLock);


    AcquireSRWLockExclusive(&GSettingsLock);
    GlobalSettings = t;
    ReleaseSRWLockExclusive(&GSettingsLock);

    UpdateRefreshRateCache();
}

void Wh_ModSettingsChanged() { LoadModSettings(); }

// --- Physics Math Engine ---
inline float SampleCurveX(float t, float x1, float x2) {
    const float cx = 3.0f * x1; const float bx = 3.0f * (x2 - x1) - cx; const float ax = 1.0f - cx - bx;
    return t * (cx + t * (bx + t * ax));
}
inline float SampleCurveY(float t, float y1, float y2) {
    const float cy = 3.0f * y1; const float by = 3.0f * (y2 - y1) - cy; const float ay = 1.0f - cy - by;
    return t * (cy + t * (by + t * ay));
}
inline float SampleCurveDerivativeX(float t, float x1, float x2) {
    const float cx = 3.0f * x1; const float bx = 3.0f * (x2 - x1) - cx; const float ax = 1.0f - cx - bx;
    return cx + t * (2.0f * bx + 3.0f * ax * t);
}

float SolveCubicBezier(float x, float x1, float y1, float x2, float y2) {
    if (x <= 0.0f) return 0.0f; if (x >= 1.0f) return 1.0f; if (x1 == y1 && x2 == y2) return x; 
    
    float t = x; 
    bool newtonConverged = false;
    
    for (int i = 0; i < 8; i++) {
        float currentX = SampleCurveX(t, x1, x2) - x;
        if (fabsf(currentX) < 0.001f) { newtonConverged = true; break; }
        float dX = SampleCurveDerivativeX(t, x1, x2);
        if (fabsf(dX) < 1e-6f) break;
        t -= currentX / dX;
        t = FastMax(0.0f, FastMin(1.0f, t));
    }
    
    if (!newtonConverged || t < 0.0f || t > 1.0f) {
        float t0 = 0.0f, t1 = 1.0f; t = x;
        for (int i = 0; i < 20; i++) {
            float currentX = SampleCurveX(t, x1, x2);
            if (fabsf(currentX - x) < 0.001f) break;
            if (x > currentX) t0 = t; else t1 = t;
            t = (t1 - t0) * 0.5f + t0;
        }
    }
    return SampleCurveY(t, y1, y2);
}

struct SpringConstants { float w0, zeta, wd, gamma, r1, r2, A, B; int mode; };

SpringConstants InitSpring(float mass, float stiffness, float damping) {
    SpringConstants s = {0};
    if (mass <= 0.0f) mass = 1.0f;
    if (stiffness <= 0.0f) { s.mode = 3; return s; }
    s.w0 = sqrtf(stiffness / mass);
    s.zeta = damping / (2.0f * sqrtf(stiffness * mass));
    if (s.zeta < 1.0f) { s.mode = 0; s.wd = s.w0 * sqrtf(1.0f - s.zeta * s.zeta); s.A = 1.0f; s.B = (s.zeta * s.w0) / s.wd; } 
    else if (s.zeta > 1.0f) { s.mode = 1; s.gamma = s.w0 * sqrtf(s.zeta * s.zeta - 1.0f); s.r1 = -s.zeta * s.w0 + s.gamma; s.r2 = -s.zeta * s.w0 - s.gamma; s.A = -s.r2 / (s.r1 - s.r2); s.B = s.r1 / (s.r1 - s.r2); } 
    else { s.mode = 2; }
    return s;
}

float EvaluateSpring(float t, const SpringConstants& s) {
    if (s.mode == 3) return t >= 1.0f ? 1.0f : 0.0f;
    if (s.mode == 0) return 1.0f - expf(-s.zeta * s.w0 * t) * (s.A * cosf(s.wd * t) + s.B * sinf(s.wd * t));
    if (s.mode == 1) return 1.0f - (s.A * expf(s.r1 * t) + s.B * expf(s.r2 * t));
    return 1.0f - expf(-s.w0 * t) * (1.0f + s.w0 * t);
}

// ---------------------------------------------------------------------------------------------------------------------------

typedef HRESULT(WINAPI* DwmpCreateSharedThumbnailVisual_t)(HWND, HWND, DWORD, DWM_THUMBNAIL_PROPERTIES*, VOID*, VOID**, HTHUMBNAIL*);
typedef HWND(WINAPI* CreateWindowInBand_t)(DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID, DWORD);
typedef HRESULT(WINAPI* DwmUnregisterThumbnail_t)(HTHUMBNAIL);
typedef HRESULT(WINAPI* DwmUpdateThumbnailProperties_t)(HTHUMBNAIL, const DWM_THUMBNAIL_PROPERTIES*);
typedef BOOL(WINAPI* NtUserGetWindowMinimizeRect_t)(HWND, RECT*);

DwmpCreateSharedThumbnailVisual_t PDwmpCreateSharedThumbnailVisual = nullptr;
CreateWindowInBand_t PCreateWindowInBand = nullptr;
DwmUnregisterThumbnail_t PDwmUnregisterThumbnail = nullptr;
DwmUpdateThumbnailProperties_t PDwmUpdateThumbnailProperties = nullptr;
NtUserGetWindowMinimizeRect_t PNtUserGetWindowMinimizeRect = nullptr;

struct THUMB_OVERSCAN { int Left; int Top; int Right; int Bottom; };

static THUMB_OVERSCAN ComputeOverscan(const RECT& RcFrame) {
    const int W = FastMax((int)(RcFrame.right - RcFrame.left), 1);
    const int H = FastMax((int)(RcFrame.bottom - RcFrame.top), 1);
    int Pad = FastMax(W, H) / 10;
    if (Pad < 64) Pad = 64;
    if (Pad > 192) Pad = 192;
    return { Pad, Pad, Pad, Pad };
}

struct ANIM_PARAMS {
    HWND HwndOriginal; int AnimType; DWORD MasterDuration;
    RECT RcFrame; RECT RcTaskbar; THUMB_OVERSCAN Overscan; void* PWindowData;
    double CreationTimeSec;
};

struct FAST_TEARDOWN {
    IDCompositionVisual* PRootVisual;
    std::atomic<bool> Signaled;
    FAST_TEARDOWN() : PRootVisual(nullptr), Signaled(false) {}
    ~FAST_TEARDOWN() { if (PRootVisual) PRootVisual->Release(); }
};

struct ACTIVE_ANIM {
    HWND HwndHost; IDCompositionTarget* PTarget; IDCompositionVisual* PRootVisual; RECT HostRect;
    IDCompositionVisual* PTrackingVisual; IDCompositionEffectGroup* PTrackingEffectGroup;
    IDCompositionVisual* PBlurVisual; IDCompositionGaussianBlurEffect* PBlurEffect;
    IDCompositionVisual* PVisual; IDCompositionEffectGroup* PEffectGroup;
    IDCompositionMatrixTransform3D* PTransform; IDCompositionMatrixTransform3D* PTrackingTransform;
    HTHUMBNAIL HThumbnail;
    double EndTimeSec; double RevealWaitDeadlineSec;
    DWORD MasterDuration; int AnimType; HWND HwndOriginal;
    RECT InitialRcFrame; RECT LastRcFrame; RECT RcTaskbar; THUMB_OVERSCAN Overscan;
    float TrackingInitialW; float TrackingInitialH;
    std::vector<IDCompositionAnimation*> ScalarAnimations; void* PWindowData;
    std::shared_ptr<FAST_TEARDOWN> TeardownPtr;
    double CreationTimeSec;
    double CurrentPitch; double CurrentYaw;
    double TargetPitch; double TargetYaw;
    POINT LastCursorPos; double LastCursorTime;
};

struct DEFERRED_THUMB_UPDATE { HTHUMBNAIL h; DWM_THUMBNAIL_PROPERTIES props; };
struct DEFERRED_WINPOS_UPDATE { HWND hwnd; HWND hwndInsertAfter; int x; int y; int cx; int cy; UINT flags; };
struct REVEAL_OFFSET_INFO { DWORD DynArrayOffset; DWORD TotalCountOffset; };
REVEAL_OFFSET_INFO GRevealOffsetInfo = { 0, 0 };

#include <unordered_map>

HINSTANCE GHinst = NULL;
UINT GUMsgAnimateWindow = 0;
UINT GUMsgInstantTeardown = 0;
HWND GHwndAnimController = NULL;
HANDLE GHAnimThread = NULL;
DWORD GHAnimThreadId = 0;
bool GAnimationsShiftKeyEnabled = false;

typedef HRESULT(__fastcall* CTopLevelWindow3D_StartAnimation_t)(void* Self, unsigned int AnimType);
extern CTopLevelWindow3D_StartAnimation_t CTopLevelWindow3D_StartAnimation_Orig;
typedef HRESULT(__fastcall* CTopLevelWindow3D_StopAnimation_t)(void* Self);
extern CTopLevelWindow3D_StopAnimation_t CTopLevelWindow3D_StopAnimation_Orig;

thread_local DWORD GCustomAnimDuration = 0;
thread_local int GCurrentCustomAnimType = -1;
DWORD GClassHwndOffset = 0;
bool g_ScannerRan = false;

std::atomic<bool> g_ModUnloading{false};

bool IsSafeToDComp() {
    if (g_ModUnloading.load()) return false;
    static auto pRtlDllShutdownInProgress = (BOOLEAN(NTAPI*)())GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlDllShutdownInProgress");
    return !(pRtlDllShutdownInProgress && pRtlDllShutdownInProgress());
}

LRESULT CALLBACK HostWindowProc(HWND Hwnd, UINT UMsg, WPARAM WParam, LPARAM LParam) {
    if (UMsg == WM_CLOSE) return 0;
    return DefWindowProcW(Hwnd, UMsg, WParam, LParam);
}

ID3D11Device* GPD3DDevice = nullptr;
ID3D11DeviceContext* GPD3DContext = nullptr;
IDCompositionDevice* GPDCompDevice = nullptr;
IDCompositionDevice3* GPDCompDevice3 = nullptr;
bool GCommitHooked = false;
bool GIsTimerActive = false;
IUnknown* GPDCompDesktopDevice = nullptr;

typedef HRESULT(__stdcall* DCompCommit_t)(void*);
DCompCommit_t OrigDCompCommit = nullptr;
std::vector<ACTIVE_ANIM> GAnimations;
std::mutex GAnimationsMutex;
std::recursive_mutex GDCompTreeMutex;

HRESULT __stdcall HookedDCompCommit(void* pThis) {
    if (pThis != GPDCompDevice && GPDCompDevice && IsSafeToDComp()) {
        std::lock_guard<std::recursive_mutex> lock(GDCompTreeMutex);
        GPDCompDevice->Commit();
    }
    return OrigDCompCommit(pThis);
}

std::unordered_map<HWND, std::shared_ptr<FAST_TEARDOWN>> GFastTeardownMap;
SRWLOCK GTeardownLock = SRWLOCK_INIT;

std::vector<ANIM_PARAMS*> GPendingAnimations;
std::mutex GPendingMutex;

namespace CDesktopManager { DWORD CALLBACK DesktopThreadProc(HANDLE HEvent); }

static double QueryTimeSeconds() {
    static double InvFreq = 0.0;
    if (InvFreq == 0.0) { LARGE_INTEGER Freq; QueryPerformanceFrequency(&Freq); InvFreq = 1.0 / (double)Freq.QuadPart; }
    LARGE_INTEGER Now; QueryPerformanceCounter(&Now); return (double)Now.QuadPart * InvFreq;
}

static double MsToSeconds(DWORD Ms) { return (double)Ms * 0.001; }
static bool NearlyEqual(float A, float B, float Eps = 0.00001f) { return fabsf(A - B) <= Eps; }

static int GetAnimationSampleCount(DWORD DurationMs, const MOD_SETTINGS& Settings) {
    int EffectiveFps = Settings.anim_vsync ? Settings.cached_vsync_fps : Settings.anim_fps;
    if (EffectiveFps <= 0) EffectiveFps = 60;
    return (int)FastMax(1.0, FastMin(1000.0, ceil((double)DurationMs * (double)EffectiveFps * 0.001)));
}

static DWORD GetFailSafeMs(int AnimType) { return (AnimType == ANIM_TYPE_OPEN || AnimType == ANIM_TYPE_RESTORE) ? 120 : 0; }

static bool TryReadMemory(const void* Address, void* Buffer, SIZE_T Size) {
    SIZE_T BytesRead = 0; 
    return ReadProcessMemory(GetCurrentProcess(), Address, Buffer, Size, &BytesRead) && BytesRead == Size;
}

static bool IsProbablyRevealDynArray(const BYTE* LocalBuffer, DWORD Offset) {
    void* ArrayPtr = *(void**)(LocalBuffer + Offset);
    DWORD Capacity = *(DWORD*)(LocalBuffer + Offset + REVEAL_DYNARRAY_CAPACITY_OFFSET);
    DWORD Count = *(DWORD*)(LocalBuffer + Offset + REVEAL_DYNARRAY_COUNT_OFFSET);
    DWORD TrackedCount = *(DWORD*)(LocalBuffer + Offset + REVEAL_DYNARRAY_TRACKED_COUNT_OFFSET);

    if (!ArrayPtr || (ULONG_PTR)ArrayPtr < 0x10000) return false;
    if (Count == 0 || Count > REVEAL_DYNARRAY_MAX_COUNT || Capacity == 0 || Capacity > REVEAL_DYNARRAY_MAX_CAPACITY) return false;
    if (Count > Capacity || TrackedCount > Count || TrackedCount > REVEAL_DYNARRAY_MAX_COUNT) return false;

    void* FirstEntry = nullptr;
    if (!TryReadMemory(ArrayPtr, &FirstEntry, sizeof(FirstEntry)) || !FirstEntry || (ULONG_PTR)FirstEntry < 0x10000) return false;
    return true;
}

static bool ReadRevealCounter(void* PWindowData, DWORD* PSecondaryRepCount) {
    if (!PWindowData || !PSecondaryRepCount) return false;
    if (GRevealOffsetInfo.TotalCountOffset == 0) {
        BYTE Buffer[MAX_DYNARRAY_READ_BOUNDS] = {0};
        if (!TryReadMemory(PWindowData, Buffer, sizeof(Buffer))) return false;
        for (DWORD Offset = REVEAL_DYNARRAY_SCAN_START; Offset <= REVEAL_DYNARRAY_SCAN_END; Offset += sizeof(void*)) {
            if (IsProbablyRevealDynArray(Buffer, Offset)) {
                GRevealOffsetInfo.DynArrayOffset = Offset; GRevealOffsetInfo.TotalCountOffset = Offset + REVEAL_DYNARRAY_COUNT_OFFSET; break;
            }
        }
        if (GRevealOffsetInfo.TotalCountOffset == 0) return false;
    }
    return TryReadMemory((BYTE*)PWindowData + GRevealOffsetInfo.TotalCountOffset, PSecondaryRepCount, sizeof(DWORD));
}

static bool IsWindowReadyForReveal(void* PWindowData) {
    DWORD SecondaryRepCount = 0;
    return ReadRevealCounter(PWindowData, &SecondaryRepCount) && SecondaryRepCount == 1;
}

// --- Window Targeting ---
static RECT GetMonitorWorkRectFromRect(const RECT& Rc) {
    HMONITOR HMon = MonitorFromRect(&Rc, MONITOR_DEFAULTTONEAREST); MONITORINFO Mi = { sizeof(Mi) };
    if (HMon && GetMonitorInfoW(HMon, &Mi)) return Mi.rcWork;
    return { GMetrics.xVirtual, GMetrics.yVirtual, GMetrics.xVirtual + GMetrics.cxVirtual, GMetrics.yVirtual + GMetrics.cyVirtual };
}

static RECT GetAnimationHostRect(HWND HwndOriginal, int AnimType) {
    if (AnimType != ANIM_TYPE_MINIMIZE && IsWindow(HwndOriginal) && IsZoomed(HwndOriginal)) {
        RECT RcWindow = { 0 };
        if (GetWindowRect(HwndOriginal, &RcWindow)) return GetMonitorWorkRectFromRect(RcWindow);
    }
    return { GMetrics.xVirtual, GMetrics.yVirtual, GMetrics.xVirtual + GMetrics.cxVirtual, GMetrics.yVirtual + GMetrics.cyVirtual };
}

static bool IsTopmostWindow(HWND Hwnd) { return Hwnd && ((GetWindowLongPtrW(Hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) != 0); }

static void PositionAnimationHostWindow(HWND HwndHost, HWND HwndOriginal, int AnimType, RECT* PAppliedRect = nullptr, std::vector<DEFERRED_WINPOS_UPDATE>* pDeferredUpdates = nullptr) {
    if (!HwndHost || !IsWindow(HwndHost)) return;
    RECT RcHost = GetAnimationHostRect(HwndOriginal, AnimType);
    int HostW = RcHost.right - RcHost.left; int HostH = RcHost.bottom - RcHost.top;
    if (HostW <= 0 || HostH <= 0) return;

    HWND BandAnchor = HWND_NOTOPMOST; HWND ZAnchor = HWND_TOP;
    if (AnimType == ANIM_TYPE_MINIMIZE || AnimType == ANIM_TYPE_CLOSE || AnimType == ANIM_TYPE_DRAG || AnimType == ANIM_TYPE_DRAG_END) { BandAnchor = HWND_TOPMOST; ZAnchor = HWND_TOPMOST; } 
    else if (IsWindow(HwndOriginal)) { BandAnchor = IsTopmostWindow(HwndOriginal) ? HWND_TOPMOST : HWND_NOTOPMOST; ZAnchor = HwndOriginal; }

    if (pDeferredUpdates) {
        pDeferredUpdates->push_back({HwndHost, BandAnchor, RcHost.left, RcHost.top, HostW, HostH, SWP_NOACTIVATE | SWP_SHOWWINDOW});
        pDeferredUpdates->push_back({HwndHost, ZAnchor, RcHost.left, RcHost.top, HostW, HostH, SWP_NOACTIVATE | SWP_SHOWWINDOW});
    } else {
        SetWindowPos(HwndHost, BandAnchor, RcHost.left, RcHost.top, HostW, HostH, SWP_NOACTIVATE | SWP_SHOWWINDOW);
        SetWindowPos(HwndHost, ZAnchor, RcHost.left, RcHost.top, HostW, HostH, SWP_NOACTIVATE | SWP_SHOWWINDOW);
    }

    if (PAppliedRect) *PAppliedRect = RcHost;
}

#define MAX_HOST_POOL 8
struct HOST_POOL_ENTRY { HWND Hwnd; IDCompositionTarget* Target; IDCompositionVisual* RootVisual; bool InUse; };
HOST_POOL_ENTRY GHostPool[MAX_HOST_POOL] = {{0}};
std::mutex GHostPoolMutex;

static bool GetPooledHostWindow(HWND HwndOriginal, int AnimType, RECT* PHostRect, HWND& OutHwnd, IDCompositionTarget*& OutTarget, IDCompositionVisual*& OutRoot) {
    std::lock_guard<std::recursive_mutex> dcompLock(GDCompTreeMutex);
    std::lock_guard<std::mutex> lock(GHostPoolMutex);
    for (int i = 0; i < MAX_HOST_POOL; ++i) {
        if (!GHostPool[i].InUse && GHostPool[i].Hwnd != NULL) {
            GHostPool[i].InUse = true;
            OutHwnd = GHostPool[i].Hwnd;
            OutTarget = GHostPool[i].Target;
            OutRoot = GHostPool[i].RootVisual;
            
            if (AnimType == ANIM_TYPE_MINIMIZE) {
                SetWindowLongW(OutHwnd, GWL_EXSTYLE, GetWindowLongW(OutHwnd, GWL_EXSTYLE) | WS_EX_TOPMOST);
            } else {
                SetWindowLongW(OutHwnd, GWL_EXSTYLE, GetWindowLongW(OutHwnd, GWL_EXSTYLE) & ~WS_EX_TOPMOST);
            }
            
            PositionAnimationHostWindow(OutHwnd, HwndOriginal, AnimType, PHostRect);
            OutRoot->RemoveAllVisuals();
            return true;
        }
    }
    return false;
}

static void ReturnPooledHostWindow(HWND HwndHost) {
    std::lock_guard<std::recursive_mutex> dcompLock(GDCompTreeMutex);
    std::lock_guard<std::mutex> lock(GHostPoolMutex);
    for (int i = 0; i < MAX_HOST_POOL; ++i) {
        if (GHostPool[i].Hwnd == HwndHost) {
            GHostPool[i].InUse = false;
            GHostPool[i].RootVisual->RemoveAllVisuals();
            if (IsSafeToDComp() && GPDCompDevice) GPDCompDevice->Commit();
            SetWindowPos(HwndHost, NULL, -20000, -20000, 1, 1, SWP_NOACTIVATE | SWP_NOZORDER);
            break;
        }
    }
}

// --- Matrix Engine ---
struct D2DMatrix {
    float M[4][4];
    D2DMatrix() {
        memset(M, 0, sizeof(M));
        M[0][0] = 1.0f; M[1][1] = 1.0f; M[2][2] = 1.0f; M[3][3] = 1.0f;
    }
    D2DMatrix(int) {} 
    D2DMatrix operator*(const D2DMatrix& B) const {
        D2DMatrix Res(0);
        for (int I = 0; I < 4; ++I) {
            for (int J = 0; J < 4; ++J) {
                Res.M[I][J] = M[I][0] * B.M[0][J] + M[I][1] * B.M[1][J] + M[I][2] * B.M[2][J] + M[I][3] * B.M[3][J];
            }
        }
        return Res;
    }
};

struct SAMPLE_POINT { double OffsetSec; D2DMatrix Mat; float Opacity; float Blur; };

D2DMatrix D2DMatrixTranslation(float X, float Y, float Z) { D2DMatrix Res; Res.M[3][0] = X; Res.M[3][1] = Y; Res.M[3][2] = Z; return Res; }
D2DMatrix D2DMatrixRotationX(float Degrees) { float Rad = Degrees * 3.1415926535f / 180.0f; float C = cosf(Rad), S = sinf(Rad); D2DMatrix Res; Res.M[1][1] = C; Res.M[1][2] = S; Res.M[2][1] = -S; Res.M[2][2] = C; return Res; }
D2DMatrix D2DMatrixRotationY(float Degrees) { float Rad = Degrees * 3.1415926535f / 180.0f; float C = cosf(Rad), S = sinf(Rad); D2DMatrix Res; Res.M[0][0] = C; Res.M[0][2] = -S; Res.M[2][0] = S; Res.M[2][2] = C; return Res; }
D2DMatrix D2DMatrixRotationZ(float Degrees) { float Rad = Degrees * 3.1415926535f / 180.0f; float C = cosf(Rad), S = sinf(Rad); D2DMatrix Res; Res.M[0][0] = C; Res.M[0][1] = S; Res.M[1][0] = -S; Res.M[1][1] = C; return Res; }
D2DMatrix D2DMatrixPerspectiveRH(float Depth) { D2DMatrix Res; if (Depth != 0.0f) Res.M[2][3] = 1.0f / Depth; return Res; }
D2DMatrix D2DMatrixScaling(float X, float Y, float Z) { D2DMatrix Res(0); memset(Res.M, 0, sizeof(Res.M)); Res.M[0][0] = X; Res.M[1][1] = Y; Res.M[2][2] = Z; Res.M[3][3] = 1.0f; return Res; }

void GetPivotValues(int preset, float customX, float customY, float& pX, float& pY) {
    if (preset == 0) { pX = customX; pY = customY; return; }
    switch (preset) {
        case 2: pX = 0.0f; pY = 0.0f; break; // TL
        case 3: pX = 0.5f; pY = 0.0f; break; // T
        case 4: pX = 1.0f; pY = 0.0f; break; // TR
        case 5: pX = 0.0f; pY = 0.5f; break; // L
        case 6: pX = 1.0f; pY = 0.5f; break; // R
        case 7: pX = 0.0f; pY = 1.0f; break; // BL
        case 8: pX = 0.5f; pY = 1.0f; break; // B
        case 9: pX = 1.0f; pY = 1.0f; break; // BR
        default: pX = 0.5f; pY = 0.5f; break; // C
    }
}

namespace CTopLevelWindow4D {
    static bool ShouldTrackLiveWindowRect(int AnimType) { return AnimType == ANIM_TYPE_OPEN || AnimType == ANIM_TYPE_RESTORE || AnimType == ANIM_TYPE_DRAG || AnimType == ANIM_TYPE_DRAG_END; }

    static float EvaluateAnimationProgress(int AnimType, double T_sec, DWORD MasterDuration, const MOD_SETTINGS& Settings) {
        bool useSpring = false; float sMass = 1.0f, sStiffness = 200.0f, sDamping = 28.0f; int baseDurMs = 250;
        CubicBezierDef bezier = {0.0f, 0.0f, 0.0f, 1.0f};

        if (AnimType == ANIM_TYPE_OPEN) { baseDurMs = Settings.duration_open; useSpring = Settings.open_spring; sMass = Settings.open_mass; sStiffness = Settings.open_stiffness; sDamping = Settings.open_damping; bezier = Settings.open_bezier; }
        else if (AnimType == ANIM_TYPE_CLOSE) { baseDurMs = Settings.duration_close; useSpring = Settings.close_spring; sMass = Settings.close_mass; sStiffness = Settings.close_stiffness; sDamping = Settings.close_damping; bezier = Settings.close_bezier; }
        else if (AnimType == ANIM_TYPE_MINIMIZE) { baseDurMs = Settings.duration_minimize; useSpring = Settings.min_spring; sMass = Settings.min_mass; sStiffness = Settings.min_stiffness; sDamping = Settings.min_damping; bezier = Settings.min_bezier; }
        else if (AnimType == ANIM_TYPE_RESTORE) { baseDurMs = Settings.duration_restore; useSpring = Settings.res_spring; sMass = Settings.res_mass; sStiffness = Settings.res_stiffness; sDamping = Settings.res_damping; bezier = Settings.res_bezier; }

        if (useSpring) {
            SpringConstants Spring = InitSpring(sMass, sStiffness, sDamping);
            return EvaluateSpring((float)T_sec, Spring);
        } else {
            if (T_sec >= MsToSeconds(baseDurMs)) return 1.0f;
            float BaseProgress = (float)(T_sec / MsToSeconds(baseDurMs));
            return FastSolveCubicBezier(BaseProgress, bezier);
        }
    }

    struct ANIM_TRANSFORM_PARAMS {
        float Pitch, Yaw, Roll, ZTrans, XTrans, YTrans, ScaleX, ScaleY, Opacity, Blur, CurCenterX, CurCenterY, PivotX, PivotY;
        float eTrans, eP, eY, eR, eS, eO, eB;
    };

    void ComputeTransformParams(ANIM_TRANSFORM_PARAMS* pOut, int AnimType, double T_sec, float GlobalEasedProgress, RECT RcFrame, RECT RcTaskbar, const THUMB_OVERSCAN& Overscan, const MOD_SETTINGS& Settings) {
        float Opacity = 1.0f; float Blur = 0.0f;
        float W = FastMax((float)(RcFrame.right - RcFrame.left), 1.0f);
        float H = FastMax((float)(RcFrame.bottom - RcFrame.top), 1.0f);
        
        float XTransVal = 0.0f, YTransVal = 0.0f, PitchVal = 0.0f, YawVal = 0.0f, RollVal = 0.0f, ZTransVal = 0.0f, ScaleStartX = 1.0f, ScaleStartY = 1.0f, BlurMax = 0.0f;
        int PivotPreset = 1; float PivotCustX = 0.5f, PivotCustY = 0.5f;

        AdvAnimSettings Adv;

        if (AnimType == ANIM_TYPE_OPEN) { Adv = Settings.open_adv; XTransVal = Settings.open_translate_x; YTransVal = Settings.open_translate_y; PitchVal = Settings.open_pitch; YawVal = Settings.open_yaw; RollVal = Settings.open_roll; ZTransVal = Settings.open_z; ScaleStartX = Settings.open_scale_x; ScaleStartY = Settings.open_scale_y; BlurMax = Settings.open_blur; PivotPreset = Settings.open_pivot_preset; PivotCustX = Settings.open_pivot_x; PivotCustY = Settings.open_pivot_y; } 
        else if (AnimType == ANIM_TYPE_CLOSE) { Adv = Settings.close_adv; XTransVal = Settings.close_translate_x; YTransVal = Settings.close_translate_y; PitchVal = Settings.close_pitch; YawVal = Settings.close_yaw; RollVal = Settings.close_roll; ZTransVal = Settings.close_z; ScaleStartX = Settings.close_scale_x; ScaleStartY = Settings.close_scale_y; BlurMax = Settings.close_blur; PivotPreset = Settings.close_pivot_preset; PivotCustX = Settings.close_pivot_x; PivotCustY = Settings.close_pivot_y; } 
        else if (AnimType == ANIM_TYPE_MINIMIZE) { Adv = Settings.min_adv; XTransVal = Settings.min_translate_x; YTransVal = Settings.min_translate_y; PitchVal = Settings.min_pitch; YawVal = Settings.min_yaw; RollVal = Settings.min_roll; ZTransVal = Settings.min_z; ScaleStartX = Settings.min_scale_x; ScaleStartY = Settings.min_scale_y; BlurMax = Settings.min_blur; PivotPreset = Settings.min_pivot_preset; PivotCustX = Settings.min_pivot_x; PivotCustY = Settings.min_pivot_y; } 
        else if (AnimType == ANIM_TYPE_RESTORE) { Adv = Settings.res_adv; XTransVal = Settings.res_translate_x; YTransVal = Settings.res_translate_y; PitchVal = Settings.res_pitch; YawVal = Settings.res_yaw; RollVal = Settings.res_roll; ZTransVal = Settings.res_z; ScaleStartX = Settings.res_scale_x; ScaleStartY = Settings.res_scale_y; BlurMax = Settings.res_blur; PivotPreset = Settings.res_pivot_preset; PivotCustX = Settings.res_pivot_x; PivotCustY = Settings.res_pivot_y; }

        auto GetEase = [&](const AdvProperty& prop) -> float {
            if (!prop.enabled) return GlobalEasedProgress;
            double adjusted_sec = T_sec - (prop.delay * 0.001);
            if (adjusted_sec < 0.0) return 0.0f;
            float p = FastMax(0.0f, FastMin(1.0f, (float)(adjusted_sec / (prop.duration * 0.001))));
            return FastSolveCubicBezier(p, prop.bezier);
        };

        float eP = GetEase(Adv.pitch), eY = GetEase(Adv.yaw), eR = GetEase(Adv.roll);
        float eS = GetEase(Adv.scale), eO = GetEase(Adv.opacity), eB = GetEase(Adv.blur);
        float eTrans = GlobalEasedProgress;

        float Pitch = 0.0f, Yaw = 0.0f, Roll = 0.0f, ZTrans = 0.0f, XTrans = 0.0f, YTrans = 0.0f, ScaleX = 1.0f, ScaleY = 1.0f;
        
        float pX = 0.5f, pY = 0.5f;
        GetPivotValues(PivotPreset, PivotCustX, PivotCustY, pX, pY);

        float CurCenterX = W * pX + Overscan.Left;
        float CurCenterY = H * pY + Overscan.Top;

        if (AnimType == ANIM_TYPE_OPEN || AnimType == ANIM_TYPE_CLOSE) {
            if (AnimType == ANIM_TYPE_OPEN) {
                Pitch = (1.0f - eP) * PitchVal; Yaw = (1.0f - eY) * YawVal; Roll = (1.0f - eR) * RollVal;
                Opacity = Settings.open_opacity + (eO * (1.0f - Settings.open_opacity));
                Blur = (1.0f - eB) * BlurMax;
                ZTrans = (1.0f - eTrans) * (GMetrics.cxScreen * ZTransVal); XTrans = (1.0f - eTrans) * (GMetrics.cxScreen * XTransVal); YTrans = (1.0f - eTrans) * (GMetrics.cyScreen * YTransVal);
                ScaleX = 1.0f - ((1.0f - eS) * (1.0f - ScaleStartX));
                ScaleY = 1.0f - ((1.0f - eS) * (1.0f - ScaleStartY));
            } else {
                Pitch = eP * -PitchVal; Yaw = eY * -YawVal; Roll = eR * -RollVal;
                ZTrans = eTrans * (GMetrics.cxScreen * ZTransVal); XTrans = eTrans * (GMetrics.cxScreen * XTransVal); YTrans = eTrans * (GMetrics.cyScreen * YTransVal);
                ScaleX = 1.0f - (eS * (1.0f - ScaleStartX));
                ScaleY = 1.0f - (eS * (1.0f - ScaleStartY));
                Opacity = 1.0f - (eO * (1.0f - Settings.close_opacity)); Blur = eB * BlurMax;
            }
        } else {
            float V1 = (AnimType == ANIM_TYPE_MINIMIZE) ? eTrans : (1.0f - eTrans);
            float Op1 = (AnimType == ANIM_TYPE_MINIMIZE) ? eO : (1.0f - eO);
            float Bl1 = (AnimType == ANIM_TYPE_MINIMIZE) ? eB : (1.0f - eB);
            
            float targetOp = (AnimType == ANIM_TYPE_MINIMIZE) ? Settings.min_opacity : Settings.res_opacity;
            Opacity = targetOp + ((1.0f - Op1) * (1.0f - targetOp));
            Blur = Bl1 * BlurMax;

            float WinX = (float)RcFrame.left - Overscan.Left, WinY = (float)RcFrame.top - Overscan.Top;
            float FinalW = W, FinalH = H, FinalX = (float)RcFrame.left, FinalY = (float)RcFrame.top;
            bool ignoreTaskbar = (AnimType == ANIM_TYPE_MINIMIZE) ? Settings.min_ignore_taskbar : Settings.res_ignore_taskbar;

            if (!ignoreTaskbar) {
                float TbW = FastMax((float)(RcTaskbar.right - RcTaskbar.left), 1.0f);
                float TbH = FastMax((float)(RcTaskbar.bottom - RcTaskbar.top), 1.0f);
                float TbX = (float)RcTaskbar.left, TbY = (float)RcTaskbar.top;
                FinalW = TbW * 0.6f; 
                FinalH = FinalW * (H / W);
                FinalX = TbX + (TbW - FinalW) * 0.5f; 
                FinalY = TbY + (TbH - FinalH) * 0.5f; 
            }

            float CurW = (1.0f - V1) * W + V1 * FinalW; float CurH = (1.0f - V1) * H + V1 * FinalH;
            
            Pitch = (AnimType == ANIM_TYPE_MINIMIZE) ? (eP * -PitchVal) : ((1.0f - eP) * -PitchVal);
            Yaw = (AnimType == ANIM_TYPE_MINIMIZE) ? (eY * -YawVal) : ((1.0f - eY) * -YawVal);
            Roll = (AnimType == ANIM_TYPE_MINIMIZE) ? (eR * -RollVal) : ((1.0f - eR) * -RollVal);
            ZTrans = V1 * ZTransVal * (float)GMetrics.cxScreen;
            
            float VScale = (AnimType == ANIM_TYPE_MINIMIZE) ? eS : (1.0f - eS);
            float ScaleMultX = 1.0f - (VScale * (1.0f - ScaleStartX));
            float ScaleMultY = 1.0f - (VScale * (1.0f - ScaleStartY));
            
            ScaleX = (CurW * ScaleMultX) / W; ScaleY = (CurH * ScaleMultY) / H;
            
            float EndCenterX = FinalX - WinX + FinalW * pX; 
            float EndCenterY = FinalY - WinY + FinalH * pY;

            XTrans = V1 * (EndCenterX - CurCenterX) + V1 * (GMetrics.cxScreen * XTransVal);
            YTrans = V1 * (EndCenterY - CurCenterY) + V1 * (GMetrics.cyScreen * YTransVal);
        }

        pOut->Pitch = Pitch; pOut->Yaw = Yaw; pOut->Roll = Roll;
        pOut->ZTrans = ZTrans; pOut->XTrans = XTrans; pOut->YTrans = YTrans;
        pOut->ScaleX = ScaleX; pOut->ScaleY = ScaleY;
        pOut->Opacity = Opacity;
        pOut->Blur = Blur;
        pOut->CurCenterX = CurCenterX; pOut->CurCenterY = CurCenterY;
        pOut->PivotX = pX; pOut->PivotY = pY;
        pOut->eTrans = eTrans; pOut->eP = eP; pOut->eY = eY; pOut->eR = eR;
        pOut->eS = eS; pOut->eO = eO; pOut->eB = eB;
    }

    void BuildMatrixFromParams(D2DMatrix* PMatFinal, const ANIM_TRANSFORM_PARAMS& p, int AnimType, float W, float H, const THUMB_OVERSCAN& Overscan) {
        D2DMatrix MatModel; D2DMatrix MatCamera; D2DMatrix Mat2DOffset;
        float WinCenterX = W * 0.5f + Overscan.Left;
        float WinCenterY = H * 0.5f + Overscan.Top;

        MatModel = D2DMatrixTranslation(-p.CurCenterX, -p.CurCenterY, 0.0f);
        if (p.ScaleX != 1.0f || p.ScaleY != 1.0f) MatModel = MatModel * D2DMatrixScaling(p.ScaleX, p.ScaleY, 1.0f);
        if (p.Roll != 0.0f) MatModel = MatModel * D2DMatrixRotationZ(p.Roll);
        if (p.Yaw != 0.0f) MatModel = MatModel * D2DMatrixRotationY(p.Yaw);
        if (p.Pitch != 0.0f) MatModel = MatModel * D2DMatrixRotationX(p.Pitch);
        MatModel = MatModel * D2DMatrixTranslation(p.CurCenterX, p.CurCenterY, p.ZTrans);

        float PerspDepth = (AnimType == ANIM_TYPE_OPEN || AnimType == ANIM_TYPE_CLOSE) ? (H * 0.8f) : ((float)GMetrics.cxScreen);
        MatCamera = D2DMatrixTranslation(-WinCenterX, -WinCenterY, 0.0f) * D2DMatrixPerspectiveRH(PerspDepth) * D2DMatrixTranslation(WinCenterX, WinCenterY, 0.0f);
        Mat2DOffset = D2DMatrixTranslation(p.XTrans, p.YTrans, 0.0f);
        *PMatFinal = MatModel * MatCamera * Mat2DOffset;
    }

    static void SetTrackingVisualRect(IDCompositionVisual* PTrackingVisual, IDCompositionMatrixTransform3D* PTrackingTransform, const RECT& HostRect, const RECT& InitialRcFrame, const RECT& RcNow, const THUMB_OVERSCAN& Overscan) {
        if (!PTrackingVisual || !PTrackingTransform) return;
        D3DMATRIX Mat = {{{0}}}; Mat._11 = 1.0f; Mat._22 = 1.0f; Mat._33 = 1.0f; Mat._44 = 1.0f;
        PTrackingTransform->SetMatrix(Mat);
        PTrackingVisual->SetOffsetX((float)(RcNow.left - HostRect.left - Overscan.Left));
        PTrackingVisual->SetOffsetY((float)(RcNow.top - HostRect.top - Overscan.Top));
    }

    static IDCompositionAnimation* CreateSteppedMatrixAnimation(const std::vector<SAMPLE_POINT>& Samples, int Row, int Col) {
        if (!GPDCompDevice || Samples.size() < 2) return nullptr;
        IDCompositionAnimation* Anim = nullptr;
        if (FAILED(GPDCompDevice->CreateAnimation(&Anim)) || !Anim) return nullptr;

        for (size_t I = 0; I + 1 < Samples.size(); ++I) {
            double T0 = Samples[I].OffsetSec, T1 = Samples[I + 1].OffsetSec; float V0 = Samples[I].Mat.M[Row][Col], V1 = Samples[I + 1].Mat.M[Row][Col];
            double Dt = T1 - T0; if (Dt <= 0.0) continue;
            double Slope = ((double)V1 - (double)V0) / Dt;
            if (FAILED(Anim->AddCubic(T0, V0, Slope, 0.0, 0.0))) { Anim->Release(); return nullptr; }
        }
        if (FAILED(Anim->End(Samples.back().OffsetSec, Samples.back().Mat.M[Row][Col]))) { Anim->Release(); return nullptr; }
        return Anim;
    }

    static IDCompositionAnimation* CreateSteppedOpacityAnimation(const std::vector<SAMPLE_POINT>& Samples) {
        if (!GPDCompDevice || Samples.size() < 2) return nullptr;
        IDCompositionAnimation* Anim = nullptr;
        if (FAILED(GPDCompDevice->CreateAnimation(&Anim)) || !Anim) return nullptr;

        for (size_t I = 0; I + 1 < Samples.size(); ++I) {
            double T0 = Samples[I].OffsetSec, T1 = Samples[I + 1].OffsetSec; float V0 = Samples[I].Opacity, V1 = Samples[I+1].Opacity;
            double Dt = T1 - T0; if (Dt <= 0.0) continue;
            double Slope = ((double)V1 - (double)V0) / Dt;
            if (FAILED(Anim->AddCubic(T0, V0, Slope, 0.0, 0.0))) { Anim->Release(); return nullptr; }
        }
        if (FAILED(Anim->End(Samples.back().OffsetSec, Samples.back().Opacity))) { Anim->Release(); return nullptr; }
        return Anim;
    }

    static IDCompositionAnimation* CreateSteppedBlurAnimation(const std::vector<SAMPLE_POINT>& Samples) {
        if (!GPDCompDevice || Samples.size() < 2) return nullptr;
        IDCompositionAnimation* Anim = nullptr;
        if (FAILED(GPDCompDevice->CreateAnimation(&Anim)) || !Anim) return nullptr;

        for (size_t I = 0; I + 1 < Samples.size(); ++I) {
            double T0 = Samples[I].OffsetSec, T1 = Samples[I + 1].OffsetSec; float V0 = Samples[I].Blur, V1 = Samples[I+1].Blur;
            double Dt = T1 - T0; if (Dt <= 0.0) continue;
            double Slope = ((double)V1 - (double)V0) / Dt;
            if (FAILED(Anim->AddCubic(T0, V0, Slope, 0.0, 0.0))) { Anim->Release(); return nullptr; }
        }
        if (FAILED(Anim->End(Samples.back().OffsetSec, Samples.back().Blur))) { Anim->Release(); return nullptr; }
        return Anim;
    }

    static void ReleaseAnimationResources(ACTIVE_ANIM& Anim) {
        std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
        if (Anim.PRootVisual && Anim.PTrackingVisual) Anim.PRootVisual->RemoveVisual(Anim.PTrackingVisual);
        for (auto* A : Anim.ScalarAnimations) if (A) A->Release();
        Anim.ScalarAnimations.clear();

        if (Anim.PTrackingTransform) Anim.PTrackingTransform->Release(); if (Anim.PTrackingEffectGroup) Anim.PTrackingEffectGroup->Release();
        if (Anim.PBlurEffect) Anim.PBlurEffect->Release(); if (Anim.PBlurVisual) Anim.PBlurVisual->Release();
        if (Anim.PTrackingVisual) Anim.PTrackingVisual->Release(); if (Anim.PTransform) Anim.PTransform->Release();
        if (Anim.PEffectGroup) Anim.PEffectGroup->Release();

        if (Anim.PVisual) Anim.PVisual->Release();
        if (Anim.HThumbnail && PDwmUnregisterThumbnail) PDwmUnregisterThumbnail(Anim.HThumbnail);

        if (Anim.HwndHost) ReturnPooledHostWindow(Anim.HwndHost);
    }

    static void ClearFastTeardown(HWND Hwnd) {
        AcquireSRWLockExclusive(&GTeardownLock);
        GFastTeardownMap.erase(Hwnd);
        ReleaseSRWLockExclusive(&GTeardownLock);
    }

    static bool BuildAnimation(IDCompositionMatrixTransform3D* PTransform, IDCompositionEffectGroup* PEffectGroup, IDCompositionGaussianBlurEffect* PBlurEffect, int AnimType, DWORD MasterDuration, RECT RcFrame, RECT RcTaskbar, const THUMB_OVERSCAN& Overscan, std::vector<IDCompositionAnimation*>& AnimRefs, bool IsInterruption, const ANIM_TRANSFORM_PARAMS& OldParams, const MOD_SETTINGS& Settings) {
        if (AnimType == ANIM_TYPE_DRAG || AnimType == ANIM_TYPE_DRAG_END) {
            IDCompositionAnimation* DummyOpacityAnim = nullptr;
            if (GPDCompDevice && SUCCEEDED(GPDCompDevice->CreateAnimation(&DummyOpacityAnim)) && DummyOpacityAnim) {
                DummyOpacityAnim->AddCubic(0.0, 1.0f, 0.0f, 0.0f, 0.0f);
                DummyOpacityAnim->End(1000000.0, 1.0f);
                PEffectGroup->SetOpacity(DummyOpacityAnim);
                AnimRefs.push_back(DummyOpacityAnim);
            }
            return true;
        }
        const int SampleCount = GetAnimationSampleCount(MasterDuration, Settings); const double MasterDurationSec = MsToSeconds(MasterDuration);
        
        std::vector<SAMPLE_POINT> Samples; Samples.reserve(SampleCount + 1);
        double InverseSampleCount = 1.0 / (double)SampleCount;

        ANIM_TRANSFORM_PARAMS NewBaseParams = {0};
        ANIM_TRANSFORM_PARAMS DeltaParams = {0};
        if (IsInterruption) {
            ComputeTransformParams(&NewBaseParams, AnimType, 0.0, 0.0f, RcFrame, RcTaskbar, Overscan, Settings);
            DeltaParams.Pitch = OldParams.Pitch - NewBaseParams.Pitch;
            DeltaParams.Yaw = OldParams.Yaw - NewBaseParams.Yaw;
            DeltaParams.Roll = OldParams.Roll - NewBaseParams.Roll;
            DeltaParams.ZTrans = OldParams.ZTrans - NewBaseParams.ZTrans;
            DeltaParams.XTrans = OldParams.XTrans - NewBaseParams.XTrans;
            DeltaParams.YTrans = OldParams.YTrans - NewBaseParams.YTrans;
            DeltaParams.ScaleX = OldParams.ScaleX - NewBaseParams.ScaleX;
            DeltaParams.ScaleY = OldParams.ScaleY - NewBaseParams.ScaleY;
            DeltaParams.Opacity = OldParams.Opacity - NewBaseParams.Opacity;
            DeltaParams.Blur = OldParams.Blur - NewBaseParams.Blur;
            DeltaParams.CurCenterX = OldParams.CurCenterX - NewBaseParams.CurCenterX;
            DeltaParams.CurCenterY = OldParams.CurCenterY - NewBaseParams.CurCenterY;
        }

        float W = FastMax((float)(RcFrame.right - RcFrame.left), 1.0f);
        float H = FastMax((float)(RcFrame.bottom - RcFrame.top), 1.0f);

        for (int I = 0; I <= SampleCount; ++I) {
            double Progress = (double)I * InverseSampleCount; 
            double T_sec = MasterDurationSec * Progress;
            
            float GlobalEasedProgress = EvaluateAnimationProgress(AnimType, T_sec, MasterDuration, Settings);

            ANIM_TRANSFORM_PARAMS PtParams;
            ComputeTransformParams(&PtParams, AnimType, T_sec, GlobalEasedProgress, RcFrame, RcTaskbar, Overscan, Settings);

            if (IsInterruption) {
                float DecayTrans = 1.0f - PtParams.eTrans;
                float DecayPitch = 1.0f - PtParams.eP;
                float DecayYaw = 1.0f - PtParams.eY;
                float DecayRoll = 1.0f - PtParams.eR;
                float DecayScale = 1.0f - PtParams.eS;
                float DecayOpacity = 1.0f - PtParams.eO;
                float DecayBlur = 1.0f - PtParams.eB;

                PtParams.Pitch += DeltaParams.Pitch * DecayPitch;
                PtParams.Yaw += DeltaParams.Yaw * DecayYaw;
                PtParams.Roll += DeltaParams.Roll * DecayRoll;
                PtParams.ZTrans += DeltaParams.ZTrans * DecayTrans;
                PtParams.XTrans += DeltaParams.XTrans * DecayTrans;
                PtParams.YTrans += DeltaParams.YTrans * DecayTrans;
                PtParams.ScaleX += DeltaParams.ScaleX * DecayScale;
                PtParams.ScaleY += DeltaParams.ScaleY * DecayScale;
                PtParams.Opacity += DeltaParams.Opacity * DecayOpacity;
                PtParams.Blur += DeltaParams.Blur * DecayBlur;
                PtParams.CurCenterX += DeltaParams.CurCenterX * DecayTrans;
                PtParams.CurCenterY += DeltaParams.CurCenterY * DecayTrans;
            }

            PtParams.ScaleX = FastMax(PtParams.ScaleX, 0.001f);
            PtParams.ScaleY = FastMax(PtParams.ScaleY, 0.001f);
            PtParams.Opacity = FastMax(0.0f, FastMin(1.0f, PtParams.Opacity));
            PtParams.Blur = FastMax(0.0f, PtParams.Blur);
            PtParams.ZTrans = FastMax(PtParams.ZTrans, -(H * 0.8f) + 1.0f);

            SAMPLE_POINT Pt = {}; Pt.OffsetSec = T_sec;
            Pt.Opacity = PtParams.Opacity;
            Pt.Blur = PtParams.Blur;
            BuildMatrixFromParams(&Pt.Mat, PtParams, AnimType, W, H, Overscan);
            Samples.push_back(Pt);
        }

        D3DMATRIX Base = {}; memcpy(&Base, &Samples[0].Mat, sizeof(Base));
        
        for (int r = 0; r < 4; ++r) {
            for (int c = 0; c < 4; ++c) {
                PTransform->SetMatrixElement(r, c, Base.m[r][c]);
            }
        }
        
        if (FAILED(PTransform->SetMatrix(Base))) return false;

        for (int Row = 0; Row < 4; ++Row) {
            for (int Col = 0; Col < 4; ++Col) {
                float First = Samples[0].Mat.M[Row][Col]; bool Changed = false;
                for (size_t I = 1; I < Samples.size(); ++I) { if (!NearlyEqual(First, Samples[I].Mat.M[Row][Col])) { Changed = true; break; } }
                if (!Changed) continue;
                IDCompositionAnimation* Anim = CreateSteppedMatrixAnimation(Samples, Row, Col);
                if (!Anim) return false;
                if (FAILED(PTransform->SetMatrixElement(Row, Col, Anim))) { Anim->Release(); return false; }
                AnimRefs.push_back(Anim);
            }
        }

        float BaseOpacity = Samples[0].Opacity; bool OpacityChanged = false;
        for (size_t I = 1; I < Samples.size(); ++I) { if (!NearlyEqual(BaseOpacity, Samples[I].Opacity)) { OpacityChanged = true; break; } }
        
        if (OpacityChanged) {
            IDCompositionAnimation* OpacityAnim = CreateSteppedOpacityAnimation(Samples);
            if (!OpacityAnim) return false;
            if (FAILED(PEffectGroup->SetOpacity(OpacityAnim))) { OpacityAnim->Release(); return false; }
            AnimRefs.push_back(OpacityAnim);
        } 

        if (PBlurEffect) {
            float BaseBlur = Samples[0].Blur; bool BlurChanged = false;
            for (size_t I = 1; I < Samples.size(); ++I) { if (!NearlyEqual(BaseBlur, Samples[I].Blur)) { BlurChanged = true; break; } }

            if (BlurChanged) {
                IDCompositionAnimation* BlurAnim = CreateSteppedBlurAnimation(Samples);
                if (!BlurAnim) return false;
                if (FAILED(PBlurEffect->SetStandardDeviation(BlurAnim))) { BlurAnim->Release(); return false; }
                AnimRefs.push_back(BlurAnim);
            }
        }
        return true;
    }

    void UpdateScene3D(ANIM_PARAMS* PParams) {
        UpdateMetricsCache();
        
        HWND HWnd = PParams->HwndOriginal; int AnimType = PParams->AnimType; DWORD MasterDuration = PParams->MasterDuration;
        RECT RcFrame = PParams->RcFrame; RECT RcTaskbar = PParams->RcTaskbar; THUMB_OVERSCAN Overscan = PParams->Overscan;
        void* PWindowData = PParams->PWindowData;

        if (!GPDCompDevice || !PDwmpCreateSharedThumbnailVisual) return;

        bool IsInterruption = false;
        ANIM_TRANSFORM_PARAMS OldParams = {0};
        ACTIVE_ANIM ExistingAnim = {};
        MOD_SETTINGS Settings = GetSafeSettings();

        {
            std::lock_guard<std::mutex> lock(GAnimationsMutex);
            for (auto it = GAnimations.begin(); it != GAnimations.end(); ++it) {
                if (it->HwndOriginal == HWnd) {
                    for (auto* A : it->ScalarAnimations) if (A) A->Release();
                    it->ScalarAnimations.clear();
                    ExistingAnim = std::move(*it);
                    IsInterruption = true;
                    GAnimations.erase(it);
                    break;
                }
            }
        }

        double NowSec = QueryTimeSeconds();
        RECT RcHost = { 0 }; 

        if (IsInterruption) {
            double OldT_sec = FastMax(0.0, NowSec - ExistingAnim.CreationTimeSec);
            float OldProgress = EvaluateAnimationProgress(ExistingAnim.AnimType, OldT_sec, ExistingAnim.MasterDuration, Settings);
            ComputeTransformParams(&OldParams, ExistingAnim.AnimType, OldT_sec, OldProgress, ExistingAnim.InitialRcFrame, ExistingAnim.RcTaskbar, ExistingAnim.Overscan, Settings);
            
            float OldH = FastMax((float)(ExistingAnim.InitialRcFrame.bottom - ExistingAnim.InitialRcFrame.top), 1.0f);
            OldParams.ScaleX = FastMax(OldParams.ScaleX, 0.001f);
            OldParams.ScaleY = FastMax(OldParams.ScaleY, 0.001f);
            OldParams.Opacity = FastMax(0.0f, FastMin(1.0f, OldParams.Opacity));
            OldParams.Blur = FastMax(0.0f, OldParams.Blur);
            OldParams.ZTrans = FastMax(OldParams.ZTrans, -(OldH * 0.8f) + 1.0f);
        }

        HWND HwndHost = NULL;
        IDCompositionTarget* PTarget = nullptr; IDCompositionVisual* PRootVisual = nullptr;
        IDCompositionVisual* PAnimVisual = nullptr; HTHUMBNAIL HThumbnail = NULL;
        IDCompositionVisual* PTrackingVisual = nullptr; IDCompositionEffectGroup* PTrackingEffectGroup = nullptr;
        IDCompositionVisual* PBlurVisual = nullptr; IDCompositionGaussianBlurEffect* PBlurEffect = nullptr;
        IDCompositionMatrixTransform3D* PTrackingTransform = nullptr; IDCompositionEffectGroup* PEffectGroup = nullptr;
        IDCompositionMatrixTransform3D* PTransform = nullptr;
        std::vector<IDCompositionAnimation*> AnimRefs;
        std::shared_ptr<FAST_TEARDOWN> teardown;

        auto cleanup = [&]() {
            ClearFastTeardown(HWnd);
            for (auto* A : AnimRefs) if (A) A->Release();
            if (PTransform) PTransform->Release(); if (PEffectGroup) PEffectGroup->Release();
            if (PBlurEffect) PBlurEffect->Release(); if (PBlurVisual) PBlurVisual->Release();
            if (PTrackingTransform) PTrackingTransform->Release(); if (PTrackingEffectGroup) PTrackingEffectGroup->Release();
            if (PTrackingVisual) PTrackingVisual->Release(); if (PAnimVisual) PAnimVisual->Release();
            if (HThumbnail && PDwmUnregisterThumbnail) PDwmUnregisterThumbnail(HThumbnail);
            if (HwndHost) ReturnPooledHostWindow(HwndHost);
        };

        std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);

        if (IsInterruption) {
            HwndHost = ExistingAnim.HwndHost;
            PTarget = ExistingAnim.PTarget;
            PRootVisual = ExistingAnim.PRootVisual;
            PAnimVisual = ExistingAnim.PVisual;
            HThumbnail = ExistingAnim.HThumbnail;
            PTrackingVisual = ExistingAnim.PTrackingVisual;
            PTrackingEffectGroup = ExistingAnim.PTrackingEffectGroup;
            PBlurVisual = ExistingAnim.PBlurVisual;
            PBlurEffect = ExistingAnim.PBlurEffect;
            PTrackingTransform = ExistingAnim.PTrackingTransform;
            PEffectGroup = ExistingAnim.PEffectGroup;
            PTransform = ExistingAnim.PTransform;
            teardown = ExistingAnim.TeardownPtr;
            
            if (teardown) teardown->Signaled.store(false);

            for (auto* A : ExistingAnim.ScalarAnimations) if (A) A->Release();
            ExistingAnim.ScalarAnimations.clear();

            int Width = FastMax((int)(RcFrame.right - RcFrame.left), 1);
            int Height = FastMax((int)(RcFrame.bottom - RcFrame.top), 1);
            int PaddedWidth = Width + Overscan.Left + Overscan.Right; int PaddedHeight = Height + Overscan.Top + Overscan.Bottom;
            DWM_THUMBNAIL_PROPERTIES Thumb = { 0 };
            Thumb.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_RECTSOURCE | DWM_TNP_OPACITY | DWM_TNP_ENABLE3D;
            Thumb.opacity = 255; Thumb.fVisible = TRUE;
            Thumb.rcDestination = { 0, 0, PaddedWidth, PaddedHeight };
            Thumb.rcSource = { -Overscan.Left, -Overscan.Top, Width + Overscan.Right, Height + Overscan.Bottom };
            if (PDwmUpdateThumbnailProperties && HThumbnail) PDwmUpdateThumbnailProperties(HThumbnail, &Thumb);

            PositionAnimationHostWindow(HwndHost, HWnd, AnimType, &RcHost);
            SetTrackingVisualRect(PTrackingVisual, PTrackingTransform, RcHost, RcFrame, RcFrame, Overscan);

            if (PRootVisual && PTrackingVisual) {
                PRootVisual->RemoveAllVisuals();
                PRootVisual->AddVisual(PTrackingVisual, TRUE, nullptr);
            }

        } else {
            if (!GetPooledHostWindow(HWnd, AnimType, &RcHost, HwndHost, PTarget, PRootVisual)) { cleanup(); return; }

            int Width = RcFrame.right - RcFrame.left; int Height = RcFrame.bottom - RcFrame.top;
            if (Width <= 0 || Height <= 0) { cleanup(); return; }

            int PaddedWidth = Width + Overscan.Left + Overscan.Right; int PaddedHeight = Height + Overscan.Top + Overscan.Bottom;
            DWM_THUMBNAIL_PROPERTIES Thumb = { 0 };
            Thumb.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_RECTSOURCE | DWM_TNP_OPACITY | DWM_TNP_ENABLE3D;
            Thumb.opacity = 255; Thumb.fVisible = TRUE;
            Thumb.rcDestination = { 0, 0, PaddedWidth, PaddedHeight };
            Thumb.rcSource = { -Overscan.Left, -Overscan.Top, Width + Overscan.Right, Height + Overscan.Bottom };

            VOID* PAPIContext = GPDCompDesktopDevice ? (VOID*)GPDCompDesktopDevice : (VOID*)GPDCompDevice;
            if (PAPIContext) PDwmpCreateSharedThumbnailVisual(HwndHost, HWnd, 2, &Thumb, PAPIContext, (void**)&PAnimVisual, &HThumbnail);

            if (!PAnimVisual) { cleanup(); return; }
            if (PDwmUpdateThumbnailProperties && HThumbnail) PDwmUpdateThumbnailProperties(HThumbnail, &Thumb);

            bool WantsBlur = false;
            if (AnimType == ANIM_TYPE_OPEN) WantsBlur = Settings.open_blur > 0.0f; else if (AnimType == ANIM_TYPE_CLOSE) WantsBlur = Settings.close_blur > 0.0f;
            else if (AnimType == ANIM_TYPE_MINIMIZE) WantsBlur = Settings.min_blur > 0.0f; else if (AnimType == ANIM_TYPE_RESTORE) WantsBlur = Settings.res_blur > 0.0f;

            if (WantsBlur && GPDCompDevice3) {
                if (FAILED(GPDCompDevice->CreateVisual(&PBlurVisual)) || FAILED(GPDCompDevice3->CreateGaussianBlurEffect(&PBlurEffect))) {
                    if (PBlurVisual) { PBlurVisual->Release(); PBlurVisual = nullptr; }
                    if (PBlurEffect) { PBlurEffect->Release(); PBlurEffect = nullptr; }
                }
            }

            if (FAILED(GPDCompDevice->CreateVisual(&PTrackingVisual)) || FAILED(GPDCompDevice->CreateEffectGroup(&PTrackingEffectGroup)) ||
                FAILED(GPDCompDevice->CreateMatrixTransform3D(&PTrackingTransform)) || FAILED(GPDCompDevice->CreateEffectGroup(&PEffectGroup)) ||
                FAILED(GPDCompDevice->CreateMatrixTransform3D(&PTransform))) { cleanup(); return; }

            SetTrackingVisualRect(PTrackingVisual, PTrackingTransform, RcHost, RcFrame, RcFrame, Overscan);
            PTrackingEffectGroup->SetTransform3D(PTrackingTransform); PTrackingVisual->SetEffect(PTrackingEffectGroup);

            ANIM_TRANSFORM_PARAMS InitParams;
            ComputeTransformParams(&InitParams, AnimType, 0.0f, 0.0f, RcFrame, RcTaskbar, Overscan, Settings);
            
            float InitH = FastMax((float)(RcFrame.bottom - RcFrame.top), 1.0f);
            InitParams.ScaleX = FastMax(InitParams.ScaleX, 0.001f);
            InitParams.ScaleY = FastMax(InitParams.ScaleY, 0.001f);
            InitParams.Opacity = FastMax(0.0f, FastMin(1.0f, InitParams.Opacity));
            InitParams.Blur = FastMax(0.0f, InitParams.Blur);
            InitParams.ZTrans = FastMax(InitParams.ZTrans, -(InitH * 0.8f) + 1.0f);

            D2DMatrix InitMat; BuildMatrixFromParams(&InitMat, InitParams, AnimType, FastMax((float)(RcFrame.right - RcFrame.left), 1.0f), InitH, Overscan);
            float InitOpacity = InitParams.Opacity; float InitBlur = InitParams.Blur;
            D3DMATRIX InitBase = {}; memcpy(&InitBase, &InitMat, sizeof(InitBase));
            PTransform->SetMatrix(InitBase); PEffectGroup->SetOpacity(InitOpacity);
            if (PBlurEffect) PBlurEffect->SetStandardDeviation(FastMax(InitBlur, 0.001f));

            PEffectGroup->SetTransform3D(PTransform); 
            if (WantsBlur && PBlurVisual && PBlurEffect) {
                PBlurVisual->SetEffect(PEffectGroup); PAnimVisual->SetEffect(PBlurEffect);
                PTrackingVisual->AddVisual(PBlurVisual, TRUE, nullptr); PBlurVisual->AddVisual(PAnimVisual, TRUE, nullptr);
            } else {
                PAnimVisual->SetEffect(PEffectGroup); PTrackingVisual->AddVisual(PAnimVisual, TRUE, nullptr);
            }

            // Original window remains visible during drag unless naturally cloaked.
            // We use a native animation spoofing trick to force DWM to natively hide the real window.

            PRootVisual->AddVisual(PTrackingVisual, TRUE, nullptr);
        }
        
        if (AnimType == ANIM_TYPE_OPEN || AnimType == ANIM_TYPE_RESTORE) {
            if (!teardown) {
                teardown = std::make_shared<FAST_TEARDOWN>();
                teardown->PRootVisual = PRootVisual;
                PRootVisual->AddRef();
                teardown->Signaled = false;
                {
                    AcquireSRWLockExclusive(&GTeardownLock);
                    GFastTeardownMap[HWnd] = teardown;
                    ReleaseSRWLockExclusive(&GTeardownLock);
                }
            }
        } else {
            if (teardown) {
                ClearFastTeardown(HWnd);
                teardown.reset();
            }
        }

        if (!BuildAnimation(PTransform, PEffectGroup, PBlurEffect, AnimType, MasterDuration, RcFrame, RcTaskbar, Overscan, AnimRefs, IsInterruption, OldParams, Settings)) {
            cleanup(); 
            return; 
        }

        PositionAnimationHostWindow(HwndHost, HWnd, AnimType);
        if (IsSafeToDComp()) {
            GPDCompDevice->Commit();
            DwmFlush();
        }

        NowSec = QueryTimeSeconds();

        ACTIVE_ANIM Anim = {
            HwndHost, PTarget, PRootVisual, RcHost, PTrackingVisual, PTrackingEffectGroup, PBlurVisual, PBlurEffect, PAnimVisual, PEffectGroup, PTransform, PTrackingTransform, HThumbnail,
            NowSec + MsToSeconds(MasterDuration), NowSec + MsToSeconds(MasterDuration + GetFailSafeMs(AnimType)), MasterDuration, AnimType, HWnd, RcFrame, RcFrame, RcTaskbar, Overscan,
            FastMax((float)(RcFrame.right - RcFrame.left), 1.0f), FastMax((float)(RcFrame.bottom - RcFrame.top), 1.0f), std::move(AnimRefs), PWindowData, teardown, NowSec,
            ExistingAnim.CurrentPitch, ExistingAnim.CurrentYaw, ExistingAnim.TargetPitch, ExistingAnim.TargetYaw, ExistingAnim.LastCursorPos, ExistingAnim.LastCursorTime
        };

        dcompLock.unlock();

        {
            std::lock_guard<std::mutex> lock(GAnimationsMutex);
            if (AnimType == ANIM_TYPE_DRAG) {
                static UINT s_MsgCloak = RegisterWindowMessageW(L"WindowAnimationCloakTrigger");
                SendNotifyMessageW(HWnd, s_MsgCloak, 1, 0);
            }
            GAnimations.push_back(std::move(Anim));
            if (GAnimations.size() == 1) {
                timeBeginPeriod(1); 
                GIsTimerActive = true;
                SetTimer(GHwndAnimController, 1, 16, NULL);
            }
        }
    }
}

namespace CDesktopManager {
    static bool GIsDCompInitialized = false;
    bool InitializeDComp();
    void EnsureDCompInitialized() {
        if (GIsDCompInitialized) return;
        InitializeDComp(); UpdateMetricsCache();
        std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
        std::lock_guard<std::mutex> lock(GHostPoolMutex);
        for (int i = 0; i < MAX_HOST_POOL; ++i) {
            DWORD ExStyle = WS_EX_NOREDIRECTIONBITMAP | WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_NOACTIVATE;
            HWND h = CreateWindowExW(ExStyle, L"AnimationHostClass", NULL, WS_POPUP, -20000, -20000, 1, 1, NULL, NULL, GHinst, NULL);
            ShowWindow(h, SW_SHOWNOACTIVATE);
            IDCompositionTarget* target = nullptr;
            IDCompositionVisual* root = nullptr;
            if (GPDCompDevice && SUCCEEDED(GPDCompDevice->CreateTargetForHwnd(h, TRUE, &target)) && SUCCEEDED(GPDCompDevice->CreateVisual(&root))) {
                target->SetRoot(root);
                GHostPool[i] = { h, target, root, false };
            } else {
                if (target) target->Release();
                DestroyWindow(h);
            }
        }
        GIsDCompInitialized = true;
    }

    bool InitializeDComp() {
        if (GPDCompDevice) return true;
        HRESULT Hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, nullptr, 0, D3D11_SDK_VERSION, &GPD3DDevice, nullptr, &GPD3DContext);
        if (FAILED(Hr)) return false;

        IDXGIDevice* PDXGIDevice = nullptr; GPD3DDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&PDXGIDevice);
        
        HMODULE HDcomp = LoadLibraryW(L"dcomp.dll");
        if (HDcomp) {
            auto PDCompCreate3 = (HRESULT(WINAPI*)(IUnknown*, REFIID, void**))GetProcAddress(HDcomp, "DCompositionCreateDevice3");
            if (PDCompCreate3) {
                static const GUID IID_DesktopDevice = { 0x5f4633fe, 0x1e08, 0x4cb8, { 0x8c, 0x75, 0xce, 0x24, 0x33, 0x3f, 0x56, 0x02 } };
                Hr = PDCompCreate3((IUnknown*)PDXGIDevice, IID_DesktopDevice, (void**)&GPDCompDesktopDevice);
                if (SUCCEEDED(Hr) && GPDCompDesktopDevice) {
                    Hr = GPDCompDesktopDevice->QueryInterface(__uuidof(IDCompositionDevice), (void**)&GPDCompDevice);
                    GPDCompDesktopDevice->QueryInterface(__uuidof(IDCompositionDevice3), (void**)&GPDCompDevice3);
                }
            }
        }

        if (!GPDCompDevice) {
            if (PDXGIDevice) {
                Hr = DCompositionCreateDevice(PDXGIDevice, __uuidof(IDCompositionDevice), (void**)&GPDCompDevice);
            }
        }
        
        if (SUCCEEDED(Hr) && GPDCompDevice) {
            std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
            if (!GCommitHooked) {
                void** vtable = *(void***)GPDCompDevice;
                Wh_SetFunctionHook(vtable[3], (void*)HookedDCompCommit, (void**)&OrigDCompCommit);
                GCommitHooked = true;
            }
        }

        if (PDXGIDevice) PDXGIDevice->Release();
        return SUCCEEDED(Hr) && GPDCompDevice;
    }
    
    RECT GetRefinedTaskbarRect(HWND hwndOriginal, RECT approxRect, bool enableCursorTrack) {
        int w = approxRect.right - approxRect.left;
        if (w <= 0 || approxRect.left <= -20000 || w > 400) { 
            w = 160; 
            if (approxRect.left > -20000 && approxRect.right > -20000) {
                int cx = approxRect.left + (approxRect.right - approxRect.left) / 2;
                approxRect.left = cx - w / 2;
                approxRect.right = cx + w / 2;
            } else {
                int sw = GetSystemMetrics(SM_CXSCREEN);
                approxRect.left = sw / 2 - w / 2; 
                approxRect.right = sw / 2 + w / 2; 
            }
        }
        
        if (!enableCursorTrack) return approxRect;
        
        POINT pt;
        if (GetCursorPos(&pt)) {
            HWND hTray = FindWindowW(L"Shell_TrayWnd", NULL);
            if (hTray) {
                RECT trayRect;
                if (GetWindowRect(hTray, &trayRect)) {
                    if (PtInRect(&trayRect, pt)) {
                        approxRect.left = pt.x - w / 2;
                        approxRect.right = pt.x + w / 2;
                        approxRect.top = trayRect.top;
                        approxRect.bottom = trayRect.bottom;
                    }
                }
            }
        }
        return approxRect;
    }

    LRESULT CALLBACK DesktopWindowProc(HWND Hwnd, UINT UMsg, WPARAM WParam, LPARAM LParam) {
        if (UMsg == WM_NCHITTEST) return HTTRANSPARENT;
        if (UMsg == WM_CLOSE) { if (g_ModUnloading.load()) DestroyWindow(Hwnd); return 0; }
        if (UMsg == WM_DESTROY) { PostQuitMessage(0); return 0; }

        if (UMsg == GUMsgInstantTeardown && UMsg != 0) {
            HWND HwndTarget = (HWND)LParam;
            bool isInterrupted = false;
            MSG peekMsg;
            if (PeekMessageW(&peekMsg, Hwnd, GUMsgAnimateWindow, GUMsgAnimateWindow, PM_NOREMOVE)) {
                ANIM_PARAMS* p = (ANIM_PARAMS*)peekMsg.lParam;
                if (p && p->HwndOriginal == HwndTarget) isInterrupted = true;
            }
            if (!isInterrupted) {
                std::lock_guard<std::mutex> lock(GPendingMutex);
                for (auto* p : GPendingAnimations) {
                    if (p->HwndOriginal == HwndTarget) { isInterrupted = true; break; }
                }
            }

            if (!isInterrupted) {
                std::shared_ptr<FAST_TEARDOWN> targetTeardown;
                {
                    AcquireSRWLockShared(&GTeardownLock);
                    auto it = GFastTeardownMap.find(HwndTarget);
                    if (it != GFastTeardownMap.end()) targetTeardown = it->second;
                    ReleaseSRWLockShared(&GTeardownLock);
                }
                if (targetTeardown && targetTeardown->PRootVisual && targetTeardown->Signaled.load()) {
                    std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
                    targetTeardown->PRootVisual->RemoveAllVisuals();
                    if (GPDCompDevice && IsSafeToDComp()) GPDCompDevice->Commit();
                }
            }
            return 0;
        }

        if (UMsg == GUMsgAnimateWindow && UMsg != 0) {
            EnsureDCompInitialized();
            ANIM_PARAMS* PParams = (ANIM_PARAMS*)LParam;

            if (PParams->HwndOriginal && IsWindow(PParams->HwndOriginal)) {
                if (PParams->AnimType == ANIM_TYPE_OPEN || PParams->AnimType == ANIM_TYPE_RESTORE) {
                    RECT RealRect;
                    if (GetWindowRect(PParams->HwndOriginal, &RealRect) && RealRect.left > -20000 && RealRect.top > -20000) {
                        PParams->RcFrame = RealRect;
                    }
                }
            }
            PParams->Overscan = ComputeOverscan(PParams->RcFrame);

            if (PParams->RcFrame.left <= -20000 || PParams->RcFrame.top <= -20000 || (PParams->RcFrame.right - PParams->RcFrame.left) <= 0 || (PParams->RcFrame.bottom - PParams->RcFrame.top) <= 0) {
                delete PParams; return 0;
            }
            
            if (PParams->AnimType == ANIM_TYPE_MINIMIZE || PParams->AnimType == ANIM_TYPE_RESTORE) {
                bool doTrack = false;
                AcquireSRWLockShared(&GSettingsLock);
                if (PParams->AnimType == ANIM_TYPE_MINIMIZE) doTrack = GlobalSettings.min_track_taskbar;
                if (PParams->AnimType == ANIM_TYPE_RESTORE) doTrack = GlobalSettings.res_track_taskbar;
                ReleaseSRWLockShared(&GSettingsLock);
                PParams->RcTaskbar = GetRefinedTaskbarRect(PParams->HwndOriginal, PParams->RcTaskbar, doTrack);
            }
            
            bool isInterruption = false;
            {
                std::lock_guard<std::mutex> lock(GAnimationsMutex);
                for (const auto& anim : GAnimations) {
                    if (anim.HwndOriginal == PParams->HwndOriginal) { isInterruption = true; break; }
                }
            }

            if (PParams->AnimType == ANIM_TYPE_CLOSE || PParams->AnimType == ANIM_TYPE_MINIMIZE || PParams->AnimType == ANIM_TYPE_DRAG || isInterruption) {
                CTopLevelWindow4D::UpdateScene3D(PParams);
                delete PParams;
            } else {
                std::lock_guard<std::mutex> lock(GPendingMutex);
                for (size_t i = 0; i < GPendingAnimations.size(); ) {
                    if (GPendingAnimations[i]->HwndOriginal == PParams->HwndOriginal) {
                        delete GPendingAnimations[i];
                        GPendingAnimations[i] = GPendingAnimations.back();
                        GPendingAnimations.pop_back();
                    } else {
                        ++i;
                    }
                }
                GPendingAnimations.push_back(PParams);
                SetTimer(Hwnd, 2, 16, NULL);
            }
            return 0;
        }

        if (UMsg == WM_TIMER && WParam == 2) {
            double NowSec = QueryTimeSeconds();
            std::vector<ANIM_PARAMS*> ReadyAnims;
            {
                std::lock_guard<std::mutex> lock(GPendingMutex);
                for (size_t i = 0; i < GPendingAnimations.size(); ) {
                    auto* PParams = GPendingAnimations[i];
                    bool isReady = true;
                    if (PParams->AnimType == ANIM_TYPE_RESTORE || PParams->AnimType == ANIM_TYPE_OPEN) {
                        isReady = IsWindowReadyForReveal(PParams->PWindowData) || (NowSec - PParams->CreationTimeSec >= 0.500);
                    }
                    if (isReady && NowSec - PParams->CreationTimeSec >= 0.050) {
                        ReadyAnims.push_back(PParams);
                        GPendingAnimations[i] = GPendingAnimations.back();
                        GPendingAnimations.pop_back();
                    } else { ++i; }
                }
                if (GPendingAnimations.empty()) KillTimer(Hwnd, 2);
            }
            for (auto* PParams : ReadyAnims) {
                CTopLevelWindow4D::UpdateScene3D(PParams);
                delete PParams;
            }
            return 0;
        }

        if (UMsg == WM_DISPLAYCHANGE || UMsg == WM_SETTINGCHANGE || UMsg == 0x02E0 /* WM_DPICHANGED */) {
            UpdateMetricsCache(); UpdateRefreshRateCache(); bool NeedsCommit = false;
            std::vector<DEFERRED_WINPOS_UPDATE> WinUpdates;
            
            { 
                std::lock_guard<std::mutex> lock(GAnimationsMutex);
                std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
                for (auto& Anim : GAnimations) {
                    if (Anim.AnimType != ANIM_TYPE_MINIMIZE) PositionAnimationHostWindow(Anim.HwndHost, Anim.HwndOriginal, Anim.AnimType, &Anim.HostRect, &WinUpdates);
                    CTopLevelWindow4D::SetTrackingVisualRect(Anim.PTrackingVisual, Anim.PTrackingTransform, Anim.HostRect, Anim.InitialRcFrame, Anim.LastRcFrame, Anim.Overscan);
                    NeedsCommit = true;
                }
            } 
            
            for (const auto& wu : WinUpdates) {
                SetWindowPos(wu.hwnd, wu.hwndInsertAfter, wu.x, wu.y, wu.cx, wu.cy, wu.flags);
            }
            if (NeedsCommit && GPDCompDevice && IsSafeToDComp()) {
                std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
                GPDCompDevice->Commit();
            }
            return 0;
        }

        if (UMsg == WM_TIMER && WParam == 1) {
            double NowSec = QueryTimeSeconds(); 
            bool NeedsCommit = false;
            bool IsEmpty = false;

            std::vector<ACTIVE_ANIM> ToDestroy;
            std::vector<DEFERRED_THUMB_UPDATE> ThumbUpdates;
            std::vector<DEFERRED_WINPOS_UPDATE> WinUpdates;

            { 
                std::lock_guard<std::mutex> lock(GAnimationsMutex);
                std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);

                for (size_t i = 0; i < GAnimations.size(); ) {
                    auto& Anim = GAnimations[i];

                    if (CTopLevelWindow4D::ShouldTrackLiveWindowRect(Anim.AnimType)) {
                        RECT RcNow = Anim.LastRcFrame;
                        if (GetWindowRect(Anim.HwndOriginal, &RcNow) && !EqualRect(&RcNow, &Anim.LastRcFrame)) {
                            bool SizeChanged = (RcNow.right - RcNow.left) != (Anim.LastRcFrame.right - Anim.LastRcFrame.left) || 
                                               (RcNow.bottom - RcNow.top) != (Anim.LastRcFrame.bottom - Anim.LastRcFrame.top);
                            Anim.LastRcFrame = RcNow;
                            
                            PositionAnimationHostWindow(Anim.HwndHost, Anim.HwndOriginal, Anim.AnimType, &Anim.HostRect, &WinUpdates);
                            CTopLevelWindow4D::SetTrackingVisualRect(Anim.PTrackingVisual, Anim.PTrackingTransform, Anim.HostRect, Anim.InitialRcFrame, RcNow, Anim.Overscan);

                            if (SizeChanged && PDwmUpdateThumbnailProperties) {
                                int Width = FastMax((int)(RcNow.right - RcNow.left), 1);
                                int Height = FastMax((int)(RcNow.bottom - RcNow.top), 1);
                                int PaddedWidth = Width + Anim.Overscan.Left + Anim.Overscan.Right;
                                int PaddedHeight = Height + Anim.Overscan.Top + Anim.Overscan.Bottom;

                                DWM_THUMBNAIL_PROPERTIES Thumb = { 0 };
                                Thumb.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTSOURCE | DWM_TNP_RECTDESTINATION | DWM_TNP_OPACITY | DWM_TNP_ENABLE3D;
                                Thumb.opacity = 255; Thumb.fVisible = TRUE;
                                Thumb.rcDestination = { 0, 0, PaddedWidth, PaddedHeight };
                                Thumb.rcSource = { -Anim.Overscan.Left, -Anim.Overscan.Top, Width + Anim.Overscan.Right, Height + Anim.Overscan.Bottom };
                                ThumbUpdates.push_back({ Anim.HThumbnail, Thumb });
                            }
                            NeedsCommit = true;
                        }
                    } else if (Anim.AnimType == ANIM_TYPE_CLOSE) {
                        WinUpdates.push_back({ Anim.HwndHost, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE });
                    }

                    if (Anim.AnimType == ANIM_TYPE_DRAG || Anim.AnimType == ANIM_TYPE_DRAG_END) {
                        WinUpdates.push_back({ Anim.HwndOriginal, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER });
                        
                        POINT curPt; GetCursorPos(&curPt);
                        double dt = NowSec - Anim.LastCursorTime;
                        if (dt <= 0.0) dt = 0.016;

                        if (Anim.AnimType == ANIM_TYPE_DRAG) {
                            if ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0) {
                                Anim.AnimType = ANIM_TYPE_DRAG_END;
                                Anim.EndTimeSec = NowSec + 0.3; 
                            } else if (Anim.LastCursorTime > 0.0 && dt < 0.1) {
                                MOD_SETTINGS Settings = GetSafeSettings();
                                double vx = (curPt.x - Anim.LastCursorPos.x) / dt;
                                double vy = (curPt.y - Anim.LastCursorPos.y) / dt;
                                double intensity = Settings.drag_intensity * 0.005; 
                                Anim.TargetPitch = -vy * intensity;
                                Anim.TargetYaw = vx * intensity;
                                Anim.TargetPitch = FastMax(-45.0, FastMin(45.0, Anim.TargetPitch));
                                Anim.TargetYaw = FastMax(-45.0, FastMin(45.0, Anim.TargetYaw));
                            }
                            Anim.LastCursorPos = curPt;
                            Anim.LastCursorTime = NowSec;
                        } else {
                            Anim.TargetPitch = 0.0;
                            Anim.TargetYaw = 0.0;
                            if (abs(Anim.CurrentPitch) < 0.1 && abs(Anim.CurrentYaw) < 0.1) {
                                Anim.EndTimeSec = NowSec - 1.0; // force cleanup
                            }
                        }

                        MOD_SETTINGS Settings = GetSafeSettings();
                        double smoothing = Settings.drag_smoothing;
                        if (smoothing <= 0.0) smoothing = 1.0;
                        double lerpFactor = 1.0 - exp(-smoothing * dt);
                        Anim.CurrentPitch += (Anim.TargetPitch - Anim.CurrentPitch) * lerpFactor;
                        Anim.CurrentYaw += (Anim.TargetYaw - Anim.CurrentYaw) * lerpFactor;

                        if (Anim.PTransform) {
                            float W = FastMax((float)(Anim.LastRcFrame.right - Anim.LastRcFrame.left), 1.0f);
                            float H = FastMax((float)(Anim.LastRcFrame.bottom - Anim.LastRcFrame.top), 1.0f);
                            float cx = W * 0.5f + Anim.Overscan.Left;
                            float cy = H * 0.5f + Anim.Overscan.Top;
                            CTopLevelWindow4D::ANIM_TRANSFORM_PARAMS PtParams = {};
                            PtParams.Pitch = (float)Anim.CurrentPitch;
                            PtParams.Yaw = (float)Anim.CurrentYaw;
                            PtParams.ScaleX = 1.0f;
                            PtParams.ScaleY = 1.0f;
                            PtParams.Opacity = 1.0f;
                            PtParams.CurCenterX = cx;
                            PtParams.CurCenterY = cy;
                            D2DMatrix Mat;
                            CTopLevelWindow4D::BuildMatrixFromParams(&Mat, PtParams, Anim.AnimType, W, H, Anim.Overscan);
                            D3DMATRIX BaseMat; memcpy(&BaseMat, &Mat, sizeof(BaseMat));
                            Anim.PTransform->SetMatrix(BaseMat);
                            Anim.PEffectGroup->SetTransform3D(Anim.PTransform);
                            Anim.PVisual->SetEffect(Anim.PEffectGroup);
                        }
                        NeedsCommit = true;
                    }

                    bool TimeDone = NowSec >= Anim.EndTimeSec;
                    
                    if (TimeDone && (Anim.AnimType == ANIM_TYPE_MINIMIZE || Anim.AnimType == ANIM_TYPE_CLOSE)) {
                        bool HasPendingRestore = false;
                        {
                            std::lock_guard<std::mutex> lockPending(GPendingMutex);
                            for (auto* pending : GPendingAnimations) {
                                if (pending->HwndOriginal == Anim.HwndOriginal && (pending->AnimType == ANIM_TYPE_RESTORE || pending->AnimType == ANIM_TYPE_OPEN)) {
                                    HasPendingRestore = true;
                                    break;
                                }
                            }
                        }
                        if (HasPendingRestore) TimeDone = false;
                    }

                    bool RevealReady = (Anim.AnimType == ANIM_TYPE_OPEN || Anim.AnimType == ANIM_TYPE_RESTORE) ? (IsWindowReadyForReveal(Anim.PWindowData) || NowSec >= Anim.RevealWaitDeadlineSec) : true;
                    
                    bool TeardownSignaled = false;
                    if (Anim.TeardownPtr) TeardownSignaled = Anim.TeardownPtr->Signaled.load();

                    if (TeardownSignaled || (TimeDone && RevealReady)) {
                        ToDestroy.push_back(std::move(GAnimations[i])); 
                        if (i != GAnimations.size() - 1) {
                            GAnimations[i] = std::move(GAnimations.back());
                        }
                        GAnimations.pop_back(); 
                        NeedsCommit = true;
                    } else { 
                        ++i; 
                    }
                }
                IsEmpty = GAnimations.empty();
            } 
            
            for (const auto& wu : WinUpdates) {
                SetWindowPos(wu.hwnd, wu.hwndInsertAfter, wu.x, wu.y, wu.cx, wu.cy, wu.flags);
            }
            for (const auto& tu : ThumbUpdates) {
                PDwmUpdateThumbnailProperties(tu.h, &tu.props);
            }
            for (auto& deadAnim : ToDestroy) {
                if (deadAnim.AnimType == ANIM_TYPE_DRAG || deadAnim.AnimType == ANIM_TYPE_DRAG_END) {
                    static UINT s_MsgCloak = RegisterWindowMessageW(L"WindowAnimationCloakTrigger");
                    SendNotifyMessageW(deadAnim.HwndOriginal, s_MsgCloak, 0, 0);
                    SetWindowPos(deadAnim.HwndOriginal, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
                }
                CTopLevelWindow4D::ClearFastTeardown(deadAnim.HwndOriginal);
                CTopLevelWindow4D::ReleaseAnimationResources(deadAnim);
            }
            if (NeedsCommit && IsSafeToDComp() && GPDCompDevice) {
                std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
                GPDCompDevice->Commit();
            }
            if (IsEmpty) {
                KillTimer(Hwnd, 1);
                timeEndPeriod(1);
                GIsTimerActive = false;
            }
            return 0;
        }
        return DefWindowProc(Hwnd, UMsg, WParam, LParam);
    }

    // Removed GHwndToTargetClass

    HWINEVENTHOOK GLocationChangeHook = NULL;

    void CALLBACK WinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) {
        if (idObject != OBJID_WINDOW || idChild != CHILDID_SELF) return;
        if (event == EVENT_OBJECT_LOCATIONCHANGE) {
            if (!GetSafeSettings().enable_drag) return;
            if ((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0) return;
            if (!hwnd || !IsWindowVisible(hwnd)) return;
            
            LONG_PTR style = GetWindowLongPtrW(hwnd, GWL_STYLE);
            if ((style & WS_CHILD) != 0) return;

            bool isAlreadyDragging = false;
            {
                std::lock_guard<std::mutex> lock(GAnimationsMutex);
                for (const auto& anim : GAnimations) {
                    if (anim.HwndOriginal == hwnd && anim.AnimType == ANIM_TYPE_DRAG) {
                        isAlreadyDragging = true;
                        break;
                    }
                }
            }
            if (!isAlreadyDragging && GHwndAnimController) {
                RECT rect; GetWindowRect(hwnd, &rect);
                ANIM_PARAMS* PParams = new ANIM_PARAMS{ hwnd, ANIM_TYPE_DRAG, 0xFFFFFFFF, rect, {0}, ComputeOverscan(rect), nullptr, QueryTimeSeconds() };
                PostMessageW(GHwndAnimController, GUMsgAnimateWindow, 0, (LPARAM)PParams);
            }
        }
    }

    DWORD CALLBACK DesktopThreadProc(HANDLE HEvent) {
        CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

        WNDCLASSW Wc = { 0 }; Wc.lpfnWndProc = DesktopWindowProc; Wc.hInstance = GHinst; Wc.lpszClassName = L"AnimationControllerClass";
        RegisterClassW(&Wc);
        WNDCLASSW HostWc = { 0 }; HostWc.lpfnWndProc = HostWindowProc; HostWc.hInstance = GHinst; HostWc.lpszClassName = L"AnimationHostClass";
        RegisterClassW(&HostWc);

        GHwndAnimController = CreateWindowExW(0, L"AnimationControllerClass", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GHinst, NULL);
        GLocationChangeHook = SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, NULL, WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);

        if (HEvent) SetEvent(HEvent);

        MSG Msg;
        while (GetMessageW(&Msg, NULL, 0, 0)) { TranslateMessage(&Msg); DispatchMessageW(&Msg);
        }
        
        if (GLocationChangeHook) UnhookWinEvent(GLocationChangeHook);

        while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) { if (Msg.message == GUMsgAnimateWindow && Msg.lParam) delete (ANIM_PARAMS*)Msg.lParam;
        }



        {
            std::lock_guard<std::mutex> lock(GPendingMutex);
            for (auto* PParams : GPendingAnimations) delete PParams;
            GPendingAnimations.clear();
        }

        std::vector<ACTIVE_ANIM> ToDestroy;
        {
            std::lock_guard<std::mutex> lock(GAnimationsMutex);
            ToDestroy = std::move(GAnimations);
        }
        
        if (GIsTimerActive) {
            timeEndPeriod(1);
            GIsTimerActive = false;
        }
        
        for (auto& Anim : ToDestroy) {
            CTopLevelWindow4D::ClearFastTeardown(Anim.HwndOriginal);
            CTopLevelWindow4D::ReleaseAnimationResources(Anim);
        }

        {
            AcquireSRWLockExclusive(&GTeardownLock);
            GFastTeardownMap.clear();
            ReleaseSRWLockExclusive(&GTeardownLock);
        }

        {
            std::unique_lock<std::recursive_mutex> dcompLock(GDCompTreeMutex);
            std::lock_guard<std::mutex> lock(GHostPoolMutex);
            for (int i = 0; i < MAX_HOST_POOL; ++i) {
                if (GHostPool[i].RootVisual) GHostPool[i].RootVisual->Release();
                if (GHostPool[i].Target) GHostPool[i].Target->Release();
                if (GHostPool[i].Hwnd) DestroyWindow(GHostPool[i].Hwnd);
                GHostPool[i] = {0};
            }
        }
        
        if (GPDCompDevice3) { GPDCompDevice3->Release(); GPDCompDevice3 = nullptr; }
        if (GPDCompDevice) { GPDCompDevice->Release(); GPDCompDevice = nullptr; }
        if (GPDCompDesktopDevice) { GPDCompDesktopDevice->Release(); GPDCompDesktopDevice = nullptr; }
        if (GPD3DContext) { GPD3DContext->Release(); GPD3DContext = nullptr; }
        if (GPD3DDevice) { GPD3DDevice->Release(); GPD3DDevice = nullptr; }
        if (GHwndAnimController && ::IsWindow(GHwndAnimController)) DestroyWindow(GHwndAnimController);

        UnregisterClassW(L"AnimationHostClass", GHinst);
        UnregisterClassW(L"AnimationControllerClass", GHinst); CoUninitialize();
        return 0;
    }
}

typedef HRESULT(WINAPI* GetThemeAnimationProperty_t)(HTHEME, int, int, int, VOID*, DWORD, DWORD*);
GetThemeAnimationProperty_t PGetThemeAnimationPropertyOrig = nullptr;
HRESULT WINAPI GetThemeAnimationProperty_Hook(HTHEME HTheme, int IStoryboardId, int ITargetId, int EProperty, VOID* PvProperty, DWORD CbSize, DWORD* PcbSizeOut) {
    if (GCustomAnimDuration > 0) {
        if (EProperty == 5 && PvProperty && CbSize >= sizeof(DWORD)) { *(DWORD*)PvProperty = GCustomAnimDuration; if (PcbSizeOut) *PcbSizeOut = sizeof(DWORD); return S_OK; }
        if (EProperty == 2 && PvProperty && CbSize >= sizeof(DWORD)) {
            *(DWORD*)PvProperty = 0; if (PcbSizeOut) *PcbSizeOut = sizeof(DWORD); return S_OK;
        }
        if (EProperty == 6 && PvProperty && CbSize >= sizeof(DWORD)) { *(DWORD*)PvProperty = 0; if (PcbSizeOut) *PcbSizeOut = sizeof(DWORD); return S_OK; }
    }
    return PGetThemeAnimationPropertyOrig(HTheme, IStoryboardId, ITargetId, EProperty, PvProperty, CbSize, PcbSizeOut);
}

typedef HRESULT(WINAPI* GetThemeAnimationTransform_t)(HTHEME, int, int, DWORD, VOID*, DWORD, DWORD*);
GetThemeAnimationTransform_t PGetThemeAnimationTransformOrig = nullptr;
HRESULT WINAPI GetThemeAnimationTransform_Hook(HTHEME HTheme, int IStoryboardId, int ITargetId, DWORD DwTransformIndex, VOID* PTransform, DWORD CbSize, DWORD* PcbSizeOut) {
    HRESULT Hr = PGetThemeAnimationTransformOrig(HTheme, IStoryboardId, ITargetId, DwTransformIndex, PTransform, CbSize, PcbSizeOut);
    if (SUCCEEDED(Hr) && GCustomAnimDuration > 0 && PTransform && CbSize >= 20) {
        DWORD ETransformType = *(DWORD*)PTransform; 
        DWORD* PDuration = (DWORD*)((BYTE*)PTransform + 12);

        if (ETransformType == 2 && CbSize >= 28) {
            float* ROpacity = (float*)((BYTE*)PTransform + 20); float* RInitialOpacity = (float*)((BYTE*)PTransform + 24);
            *ROpacity = 0.0f; *RInitialOpacity = 0.0f; *PDuration = GCustomAnimDuration; 
        } else if (ETransformType == 1 && CbSize >= 36) {
            float* RX = (float*)((BYTE*)PTransform + 20); float* RY = (float*)((BYTE*)PTransform + 24);
            float* RInitialX = (float*)((BYTE*)PTransform + 28); float* RInitialY = (float*)((BYTE*)PTransform + 32);
            *RX = 0.0f; *RY = 0.0f; *RInitialX = 0.0f; *RInitialY = 0.0f; *PDuration = GCustomAnimDuration;
        } else if (ETransformType == 0 && CbSize >= 36) {
            float* RX = (float*)((BYTE*)PTransform + 20); float* RY = (float*)((BYTE*)PTransform + 24);
            float* RInitialX = (float*)((BYTE*)PTransform + 28); float* RInitialY = (float*)((BYTE*)PTransform + 32);
            *RX = 1.0f; *RY = 1.0f; *RInitialX = 1.0f; *RInitialY = 1.0f; *PDuration = GCustomAnimDuration;
        }
    }
    return Hr;
}

void FindWindowHandleOffset_Impl(void* Self) {
    BYTE Buffer[0x1A0 + sizeof(void*)] = {0}; SIZE_T BytesRead = 0;
    if (ReadProcessMemory(GetCurrentProcess(), Self, Buffer, sizeof(Buffer), &BytesRead)) {
        for (DWORD Offset = 0x100; Offset <= 0x1A0; Offset += 8) {
            void* PossibleClass = *(void**)(Buffer + Offset);
            if (PossibleClass && (ULONG_PTR)PossibleClass > 0x10000) {
                HWND PossibleHwnd = nullptr;
                if (ReadProcessMemory(GetCurrentProcess(), (char*)PossibleClass + 0x28, &PossibleHwnd, sizeof(HWND), &BytesRead) && BytesRead == sizeof(HWND)) {
                    if (PossibleHwnd && IsWindow(PossibleHwnd) && GetAncestor(PossibleHwnd, GA_ROOT) == PossibleHwnd) {
                        if (GetWindowThreadProcessId(PossibleHwnd, NULL) != 0) { GClassHwndOffset = Offset; return; }
                    }
                }
            }
        }
    }
}

// --- Hook Definitions ---

typedef HRESULT(__fastcall* CTopLevelWindow3D_StartAnimation_t)(void* Self, unsigned int AnimType);
typedef HRESULT(__fastcall* CTopLevelWindow3D_StopAnimation_t)(void* Self);
CTopLevelWindow3D_StartAnimation_t CTopLevelWindow3D_StartAnimation_Orig = nullptr;
CTopLevelWindow3D_StopAnimation_t CTopLevelWindow3D_StopAnimation_Orig = nullptr;

HRESULT __fastcall CTopLevelWindow3D_StopAnimation_Hook(void* Self) {
    HWND Hwnd = nullptr;

    if (Self != nullptr && GClassHwndOffset != 0) {
        void* TargetClass = nullptr;
        if (ReadProcessMemory(GetCurrentProcess(), (char*)Self + GClassHwndOffset, &TargetClass, sizeof(void*), nullptr) && TargetClass) {
            if (!ReadProcessMemory(GetCurrentProcess(), (char*)TargetClass + 40, &Hwnd, sizeof(HWND), nullptr)) Hwnd = nullptr;
        }
    }

    if (Hwnd && IsWindow(Hwnd)) {
        std::shared_ptr<FAST_TEARDOWN> targetTeardown;
        {
            AcquireSRWLockShared(&GTeardownLock);
            auto it = GFastTeardownMap.find(Hwnd);
            if (it != GFastTeardownMap.end()) targetTeardown = it->second;
            ReleaseSRWLockShared(&GTeardownLock);
        }

        if (targetTeardown) {
            bool expected = false;
            if (targetTeardown->Signaled.compare_exchange_strong(expected, true)) {
                if (GHwndAnimController) PostMessageW(GHwndAnimController, GUMsgInstantTeardown, 0, (LPARAM)Hwnd);
            }
        }
    }
    return CTopLevelWindow3D_StopAnimation_Orig(Self);
}

static DWORD GetMaxAnimationDuration(DWORD BaseDur, const AdvAnimSettings& Adv) {
    DWORD MaxD = BaseDur;
    if (Adv.opacity.enabled && Adv.opacity.duration + Adv.opacity.delay > MaxD) MaxD = Adv.opacity.duration + Adv.opacity.delay;
    if (Adv.blur.enabled && Adv.blur.duration + Adv.blur.delay > MaxD) MaxD = Adv.blur.duration + Adv.blur.delay;
    if (Adv.scale.enabled && Adv.scale.duration + Adv.scale.delay > MaxD) MaxD = Adv.scale.duration + Adv.scale.delay;
    if (Adv.pitch.enabled && Adv.pitch.duration + Adv.pitch.delay > MaxD) MaxD = Adv.pitch.duration + Adv.pitch.delay;
    if (Adv.yaw.enabled && Adv.yaw.duration + Adv.yaw.delay > MaxD) MaxD = Adv.yaw.duration + Adv.yaw.delay;
    if (Adv.roll.enabled && Adv.roll.duration + Adv.roll.delay > MaxD) MaxD = Adv.roll.duration + Adv.roll.delay;
    return MaxD;
}

HRESULT __fastcall CTopLevelWindow3D_StartAnimation_Hook(void* Self, unsigned int AnimType) {
    bool WasHandled = false; int CustomAnimType = -1;
    HWND Hwnd = nullptr;
    RECT RcFrame = { 0 }; void* TargetClass = nullptr;

    if (Self != nullptr) {
        if (GClassHwndOffset == 0 && !g_ScannerRan) { FindWindowHandleOffset_Impl(Self); g_ScannerRan = true; }
        if (GClassHwndOffset != 0) {
            if (ReadProcessMemory(GetCurrentProcess(), (char*)Self + GClassHwndOffset, &TargetClass, sizeof(void*), nullptr) && TargetClass) {
                if (!ReadProcessMemory(GetCurrentProcess(), (char*)TargetClass + 40, &Hwnd, sizeof(HWND), nullptr)) Hwnd = nullptr;
                ReadProcessMemory(GetCurrentProcess(), (char*)TargetClass + 48, &RcFrame.left, sizeof(int), nullptr);
                ReadProcessMemory(GetCurrentProcess(), (char*)TargetClass + 52, &RcFrame.top, sizeof(int), nullptr);
                ReadProcessMemory(GetCurrentProcess(), (char*)TargetClass + 56, &RcFrame.right, sizeof(int), nullptr);
                ReadProcessMemory(GetCurrentProcess(), (char*)TargetClass + 60, &RcFrame.bottom, sizeof(int), nullptr);
                if (!IsWindow(Hwnd)) Hwnd = nullptr;
            }
        }
    }

    if (Hwnd) {
        if (AnimType == 1) CustomAnimType = ANIM_TYPE_OPEN;
        else if (AnimType == 3) CustomAnimType = ANIM_TYPE_MINIMIZE;
        else if (AnimType == 5) CustomAnimType = ANIM_TYPE_RESTORE;
        else if (AnimType == 6) CustomAnimType = ANIM_TYPE_CLOSE;

        if (CustomAnimType != -1) {
            MOD_SETTINGS Settings = GetSafeSettings();
            DWORD BaseDuration = 250; DWORD MasterDuration = 250;
            
            if (CustomAnimType == ANIM_TYPE_OPEN) {
                if (!Settings.enable_open) CustomAnimType = -1;
                else { BaseDuration = Settings.duration_open; MasterDuration = GetMaxAnimationDuration(BaseDuration, Settings.open_adv); }
            } else if (CustomAnimType == ANIM_TYPE_CLOSE) {
                if (!Settings.enable_close) CustomAnimType = -1;
                else { BaseDuration = Settings.duration_close; MasterDuration = GetMaxAnimationDuration(BaseDuration, Settings.close_adv); }
            } else if (CustomAnimType == ANIM_TYPE_MINIMIZE) {
                if (!Settings.enable_minimize) CustomAnimType = -1;
                else { BaseDuration = Settings.duration_minimize; MasterDuration = GetMaxAnimationDuration(BaseDuration, Settings.min_adv); }
            } else if (CustomAnimType == ANIM_TYPE_RESTORE) {
                if (!Settings.enable_restore) CustomAnimType = -1;
                else { BaseDuration = Settings.duration_restore; MasterDuration = GetMaxAnimationDuration(BaseDuration, Settings.res_adv); }
            }

            if (CustomAnimType != -1) {
                if (GAnimationsShiftKeyEnabled && (GetAsyncKeyState(VK_SHIFT) & 0x8000)) MasterDuration *= 20;
                RECT RcTaskbar = { 0 };
                if (CustomAnimType == ANIM_TYPE_MINIMIZE || CustomAnimType == ANIM_TYPE_RESTORE) {
                    if (PNtUserGetWindowMinimizeRect) PNtUserGetWindowMinimizeRect(Hwnd, &RcTaskbar);
                    if (IsRectEmpty(&RcTaskbar) || RcTaskbar.left <= -20000 || RcTaskbar.top <= -20000) {
                        HWND hTray = FindWindowW(L"Shell_TrayWnd", NULL);
                        if (hTray && GetWindowRect(hTray, &RcTaskbar)) {
                            // Valid taskbar rect
                        } else {
                            int Sw = GetSystemMetrics(SM_CXSCREEN);
                            int Sh = GetSystemMetrics(SM_CYSCREEN);
                            RcTaskbar = { Sw / 2 - 50, Sh - 40, Sw / 2 + 50, Sh };
                        }
                    }
                }

                THUMB_OVERSCAN Overscan = ComputeOverscan(RcFrame);

                if (GHwndAnimController) {
                    ANIM_PARAMS* PParams = new ANIM_PARAMS{ Hwnd, CustomAnimType, MasterDuration, RcFrame, RcTaskbar, Overscan, TargetClass, QueryTimeSeconds() };
                    if (PostMessageW(GHwndAnimController, GUMsgAnimateWindow, 0, (LPARAM)PParams)) { 
                        WasHandled = true;
                        GCustomAnimDuration = MasterDuration; GCurrentCustomAnimType = CustomAnimType;
                    } else { 
                        delete PParams;
                    }
                }
            }
        }
    }
    
    struct ScopedDurationReset {
        bool& handled;
        ~ScopedDurationReset() { if (handled) { GCustomAnimDuration = 0; GCurrentCustomAnimType = -1; } }
    } resetter{ WasHandled };

    return CTopLevelWindow3D_StartAnimation_Orig(Self, AnimType);
}

typedef LRESULT(WINAPI* DefWindowProcW_t)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
DefWindowProcW_t DefWindowProcW_Orig = nullptr;
LRESULT WINAPI DefWindowProcW_Hook(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    static UINT s_MsgCloak = RegisterWindowMessageW(L"WindowAnimationCloakTrigger");
    if (Msg == s_MsgCloak) {
        int cloak = wParam ? 1 : 0;
        DwmSetWindowAttribute(hWnd, 13, &cloak, sizeof(cloak));
        return 0;
    }
    return DefWindowProcW_Orig ? DefWindowProcW_Orig(hWnd, Msg, wParam, lParam) : 0;
}

typedef LRESULT(WINAPI* DefWindowProcA_t)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
DefWindowProcA_t DefWindowProcA_Orig = nullptr;
LRESULT WINAPI DefWindowProcA_Hook(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    static UINT s_MsgCloak = RegisterWindowMessageW(L"WindowAnimationCloakTrigger");
    if (Msg == s_MsgCloak) {
        int cloak = wParam ? 1 : 0;
        DwmSetWindowAttribute(hWnd, 13, &cloak, sizeof(cloak));
        return 0;
    }
    return DefWindowProcA_Orig ? DefWindowProcA_Orig(hWnd, Msg, wParam, lParam) : 0;
}

BOOL Wh_ModInit(void) {
    if (!CheckCrashLoopFailsafe()) return FALSE;

    WCHAR processName[MAX_PATH];
    GetModuleFileNameW(NULL, processName, MAX_PATH);
    if (!wcsstr(processName, L"dwm.exe")) {
        HMODULE hUser32 = GetModuleHandleW(L"user32.dll");
        if (hUser32) {
            void* pDefWindowProcW = (void*)GetProcAddress(hUser32, "DefWindowProcW");
            if (pDefWindowProcW) Wh_SetFunctionHook(pDefWindowProcW, (void*)DefWindowProcW_Hook, (void**)&DefWindowProcW_Orig);
            void* pDefWindowProcA = (void*)GetProcAddress(hUser32, "DefWindowProcA");
            if (pDefWindowProcA) Wh_SetFunctionHook(pDefWindowProcA, (void*)DefWindowProcA_Hook, (void**)&DefWindowProcA_Orig);
        }
        return TRUE; 
    }

    LoadModSettings(); GHinst = GetModuleHandle(NULL);
    GUMsgAnimateWindow = RegisterWindowMessageW(L"WindowAnimationTrigger");
    GUMsgInstantTeardown = RegisterWindowMessageW(L"WindowAnimationInstantTeardown");
    GRevealOffsetInfo = { 0, 0 };

    if (!GHAnimThread) {
        HANDLE HEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
        GHAnimThread = CreateThread(NULL, 0, CDesktopManager::DesktopThreadProc, HEvent, 0, &GHAnimThreadId);
        if (HEvent) { WaitForSingleObject(HEvent, 5000); CloseHandle(HEvent); }
    }

    HMODULE HDwmApi = LoadLibraryW(L"dwmapi.dll");
    HMODULE HWin32u = LoadLibraryW(L"win32u.dll");
    HMODULE HUser32 = LoadLibraryW(L"user32.dll");
    HMODULE HUxtheme = LoadLibraryW(L"uxtheme.dll");

    if (HDwmApi) {
        PDwmpCreateSharedThumbnailVisual = (DwmpCreateSharedThumbnailVisual_t)GetProcAddress(HDwmApi, (LPCSTR)147);
        if (!PDwmpCreateSharedThumbnailVisual) PDwmpCreateSharedThumbnailVisual = (DwmpCreateSharedThumbnailVisual_t)GetProcAddress(HDwmApi, (LPCSTR)163);
        PDwmUnregisterThumbnail = (DwmUnregisterThumbnail_t)GetProcAddress(HDwmApi, "DwmUnregisterThumbnail");
        PDwmUpdateThumbnailProperties = (DwmUpdateThumbnailProperties_t)GetProcAddress(HDwmApi, "DwmUpdateThumbnailProperties");
    }

    if (HWin32u) PNtUserGetWindowMinimizeRect = (NtUserGetWindowMinimizeRect_t)GetProcAddress(HWin32u, "NtUserGetWindowMinimizeRect");
    if (HUser32) PCreateWindowInBand = (CreateWindowInBand_t)GetProcAddress(HUser32, "CreateWindowInBand");
    if (!PNtUserGetWindowMinimizeRect && HUser32) PNtUserGetWindowMinimizeRect = (NtUserGetWindowMinimizeRect_t)GetProcAddress(HUser32, "GetWindowMinimizeRect");

    HKEY HKey;
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\Dwm", 0, KEY_READ, &HKey) == ERROR_SUCCESS) {
        DWORD Val = 0; DWORD Size = sizeof(Val);
        if (RegQueryValueExW(HKey, L"AnimationsShiftKey", NULL, NULL, (LPBYTE)&Val, &Size) == ERROR_SUCCESS) GAnimationsShiftKeyEnabled = (Val != 0);
        RegCloseKey(HKey);
    }

    if (HUxtheme) {
        void* PGetThemeAnimationProperty = (void*)GetProcAddress(HUxtheme, "GetThemeAnimationProperty");
        if (PGetThemeAnimationProperty) Wh_SetFunctionHook(PGetThemeAnimationProperty, (void*)GetThemeAnimationProperty_Hook, (void**)&PGetThemeAnimationPropertyOrig);
        void* PGetThemeAnimationTransform = (void*)GetProcAddress(HUxtheme, "GetThemeAnimationTransform");
        if (PGetThemeAnimationTransform) Wh_SetFunctionHook(PGetThemeAnimationTransform, (void*)GetThemeAnimationTransform_Hook, (void**)&PGetThemeAnimationTransformOrig);
    }

    HMODULE uDWM = LoadLibraryW(L"uDWM.dll");
    WindhawkUtils::SYMBOL_HOOK uDWMHooks[] = {
        { { L"private: long __cdecl CTopLevelWindow3D::StartAnimation(enum CTopLevelWindow3D::WindowAnimationType)", L"public: long __cdecl CTopLevelWindow3D::StartAnimation(enum CTopLevelWindow3D::WindowAnimationType)" }, (void**)&CTopLevelWindow3D_StartAnimation_Orig, (void*)CTopLevelWindow3D_StartAnimation_Hook, false },
        { { L"public: long __cdecl CTopLevelWindow3D::StopAnimation(void)", L"private: long __cdecl CTopLevelWindow3D::StopAnimation(void)" }, (void**)&CTopLevelWindow3D_StopAnimation_Orig, (void*)CTopLevelWindow3D_StopAnimation_Hook, false }
    };

    return WindhawkUtils::HookSymbols(uDWM, uDWMHooks, ARRAYSIZE(uDWMHooks)) ? TRUE : FALSE;
}

void Wh_ModUninit(void) {
    g_ModUnloading.store(true);
    g_ScannerRan = false;

    GCommitHooked = false;
                
    
    HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
    if (hNtdll) {
        auto pRtlDllShutdownInProgress = (BOOLEAN (NTAPI *)())GetProcAddress(hNtdll, "RtlDllShutdownInProgress");
        if (pRtlDllShutdownInProgress && pRtlDllShutdownInProgress()) {
            if (GHAnimThread) CloseHandle(GHAnimThread);
            return;
        }
    }
    
    if (GHAnimThread) {
        PostThreadMessageW(GHAnimThreadId, WM_QUIT, 0, 0);
        if (GHwndAnimController && ::IsWindow(GHwndAnimController)) {
            PostMessageW(GHwndAnimController, WM_CLOSE, 0, 0);
        }
        
        ULONGLONG WaitStart = GetTickCount64();
        while (true) {
            ULONGLONG Elapsed = GetTickCount64() - WaitStart;
            if (Elapsed >= 3000) break;
            
            DWORD WaitResult = MsgWaitForMultipleObjects(1, &GHAnimThread, FALSE, (DWORD)(3000 - Elapsed), QS_ALLINPUT);
            if (WaitResult == WAIT_OBJECT_0) {
                break;
            } else if (WaitResult == WAIT_OBJECT_0 + 1) {
                MSG Msg;
                while (PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) {
                    TranslateMessage(&Msg);
                    DispatchMessageW(&Msg);
                }
            } else {
                break;
            }
        }
        
        CloseHandle(GHAnimThread);
        GHAnimThread = NULL;
    }
}