From 80048951f81e82ec9b72a4669b342851be097d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sun, 3 Nov 2024 19:08:30 +0100 Subject: [PATCH] Fixed title bar hittest and changing cursor --- .../src/Ultralight/UltralightMainWindow.bf | 31 ++++++++ .../src/Ultralight/UltralightWindow.bf | 2 - .../src/Platform/Windows/WindowsWindow.bf | 77 +++++++++++++------ 3 files changed, 86 insertions(+), 24 deletions(-) diff --git a/GlitchyEditor/src/Ultralight/UltralightMainWindow.bf b/GlitchyEditor/src/Ultralight/UltralightMainWindow.bf index 23bed40..2f09319 100644 --- a/GlitchyEditor/src/Ultralight/UltralightMainWindow.bf +++ b/GlitchyEditor/src/Ultralight/UltralightMainWindow.bf @@ -31,9 +31,39 @@ class UltralightMainWindow : UltralightWindow _hoveringNonClientArea = JSValueToBoolean(context, arguments[0]); + _window.[Friend]_hoveredOverTitleBar = _hoveringNonClientArea; Log.ClientLogger.Info($"_hoveringNonClientArea: {_hoveringNonClientArea}"); } + void HandleHoverMaximizeWindow(JSContextRef context, JSObjectRef thisObject, Span arguments, JSValueRef* exception = null) + { + Log.EngineLogger.Info("HandleHoverMaximizeWindow"); + + if (arguments.Length != 1) + { + Log.EngineLogger.Error("EngineGlue.HandleHoverMaximizeWindow: called with wrong number of arguments."); + return; + } + + if (!JSValueIsBoolean(context, arguments[0])) + { + Log.EngineLogger.Error($"EngineGlue.HandleHoverMaximizeWindow: expected boolean, but received {JSValueGetType(context, arguments[0])} instead."); + return; + } + + if (JSValueToBoolean(context, arguments[0])) + _window.[Friend]_hoveredTitleBarButton = .Maximize; + else + { + _window.[Friend]_hoveredTitleBarButton = .None; + Log.ClientLogger.Info($"esar ogsdflkg aerwufg"); + } + + EditorLayer.HoveredTitleBarButton = _window.[Friend]_hoveredTitleBarButton; + + Log.ClientLogger.Info($"_hoveredTitleBarButton: {_window.[Friend]_hoveredTitleBarButton}"); + } + private void RegisterBeefFunction(JSContextRef context, JSObjectRef object, StringView functionName, JSCallback callback) { JSObjectRef func = UltralightHelper.CreateJsFunctionFromDelegate(context, callback); @@ -68,6 +98,7 @@ class UltralightMainWindow : UltralightWindow StdAllocator stdAlloc = StdAllocator(); RegisterBeefFunction(context, scriptGlue, "setHoverNonClientArea", new:stdAlloc => HandleHoverNonClientArea); + RegisterBeefFunction(context, scriptGlue, "setHoverMaximizeWindow", new:stdAlloc => HandleHoverMaximizeWindow); } protected override void OnDOMReady(C_View* caller, uint64 frame_id, bool is_main_frame, C_String* url) diff --git a/GlitchyEditor/src/Ultralight/UltralightWindow.bf b/GlitchyEditor/src/Ultralight/UltralightWindow.bf index 8566d93..42680eb 100644 --- a/GlitchyEditor/src/Ultralight/UltralightWindow.bf +++ b/GlitchyEditor/src/Ultralight/UltralightWindow.bf @@ -224,14 +224,12 @@ abstract class UltralightWindow ulDestroyMouseEvent(evt); _cursorPosition = .(e.PositionX, e.PositionY); - Log.EngineLogger.Warning($"{_cursorPosition.X} {_cursorPosition.Y}"); return true; } private bool MousePressed(MouseButtonEvent e, bool press) { - Log.ClientLogger.Warning($"{e.MouseButton} {press}"); ULMouseButton button = .kMouseButton_None; diff --git a/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf b/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf index bd9b121..b4cdcbd 100644 --- a/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf +++ b/GlitchyEngine/src/Platform/Windows/WindowsWindow.bf @@ -43,16 +43,18 @@ namespace GlitchyEngine.UI private WindowStyle _windowStyle; - enum TitleBarButton + public enum TitleBarButton { + None, Minimize, Maximize, - Close, - None + Close } private TitleBarButton _hoveredTitleBarButton; + private bool _hoveredOverTitleBar; + public override int32 MinWidth { get => _minMaxInfo.MinimumTrackingSize.x; @@ -377,7 +379,8 @@ namespace GlitchyEngine.UI } } - ImGui.ImGuiImplWin32.WndProcHandler(hwnd, uMsg, wParam, lParam); + if (Application.Instance.MainWindow == window) + ImGui.ImGuiImplWin32.WndProcHandler(hwnd, uMsg, wParam, lParam); switch (uMsg) { @@ -498,8 +501,8 @@ namespace GlitchyEngine.UI var event = scope MouseButtonPressedEvent(.LeftButton); window._eventCallback(event); - // if hovering a button - return 0; + if (window._hoveredTitleBarButton != .None) + return 0; } case WM_LBUTTONDOWN: { @@ -512,9 +515,9 @@ namespace GlitchyEngine.UI { var event = scope MouseButtonReleasedEvent(.LeftButton); window._eventCallback(event); - - // if hovering a button - return 0; + + if (window._hoveredTitleBarButton != .None) + return 0; } case WM_LBUTTONUP: { @@ -595,14 +598,15 @@ namespace GlitchyEngine.UI DirectX.Math.Rectangle title_bar_rect = win32_titlebar_rect(hwnd); // You could do tighter invalidation here but probably doesn't matter InvalidateRect(hwnd, title_bar_rect, false); - window._hoveredTitleBarButton = .None; + //window._hoveredTitleBarButton = .None; } - SplitHighAndLowOrder!(lParam, let x, let y); + SplitXAndY(lParam, let x, let y); DirectX.Windows.POINT p = .(x, y); - ScreenToClient(hwnd, &p); + if (uMsg == 0x00A0 /*WM_NCMOUSEMOVE*/) + ScreenToClient(hwnd, &p); var event = scope MouseMovedEvent(p.x, p.y); window._eventCallback(event); @@ -733,10 +737,15 @@ namespace GlitchyEngine.UI 17 /* HTBOTTOMRIGHT */: return hit; } - + // Check if hover button is on maximize to support SnapLayout on Windows 11 - if (window._hoveredTitleBarButton == .Maximize) { - return 9 /* HTMAXBUTTON */; + if (window._hoveredTitleBarButton == .Maximize) + { + return 9 /* HTMAXBUTTON */; + } + else if (window._hoveredTitleBarButton == .Minimize) + { + return 8 /* HTMINBUTTON */; } // Looks like adjustment happening in NCCALCSIZE is messing with the detection @@ -746,15 +755,18 @@ namespace GlitchyEngine.UI int padding = GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); POINT cursor_point = .(); - SplitHighAndLowOrder(lParam, out cursor_point.x, out cursor_point.y); + cursor_point.x = GetXParam(lParam); + cursor_point.y = GetYParam(lParam); ScreenToClient(hwnd, &cursor_point); - if (cursor_point.y > 0 && cursor_point.y < frame_y + padding) { - return 12 /* HTTOP */; + if (cursor_point.y > 0 && cursor_point.y < frame_y + padding) + { + return 12 /* HTTOP */; } // Since we are drawing our own caption, this needs to be a custom test - if (cursor_point.y < win32_titlebar_rect(hwnd).Bottom) { - return 2 /* HTCAPTION */; + if (window._hoveredTitleBarButton == .None && window._hoveredOverTitleBar) + { + return 2 /* HTCAPTION */; } return 1 /* HTCLIENT */; @@ -763,6 +775,24 @@ namespace GlitchyEngine.UI return DefWindowProcW(hwnd, uMsg, wParam, lParam); } + public static void SplitXAndY(int64 input, out int32 x, out int32 y) + { + x = GetXParam(input); + y = GetYParam(input); + } + + [Inline] + public static int32 GetXParam(int64 input) + { + return ((int32)(int16)GetLowOrder(input)); + } + + [Inline] + public static int32 GetYParam(int64 input) + { + return ((int32)(int16)GetHighOrder(input)); + } + static bool win32_window_is_maximized(HWND handle) { WINDOWPLACEMENT placement = .(); @@ -1067,8 +1097,11 @@ namespace GlitchyEngine.UI hCursor = Winuser.LoadCursorW((.)0, cursor); } - _cursor = hCursor; - Winuser.SetCursor(hCursor); + if (_cursor != hCursor) + { + _cursor = hCursor; + Winuser.SetCursor(hCursor); + } return .Ok; }