Fixed title bar hittest and changing cursor

This commit is contained in:
Simon Lübeß
2024-11-03 19:09:18 +01:00
parent 4a18d3150f
commit 80048951f8
3 changed files with 86 additions and 24 deletions
@@ -31,9 +31,39 @@ class UltralightMainWindow : UltralightWindow
_hoveringNonClientArea = JSValueToBoolean(context, arguments[0]); _hoveringNonClientArea = JSValueToBoolean(context, arguments[0]);
_window.[Friend]_hoveredOverTitleBar = _hoveringNonClientArea;
Log.ClientLogger.Info($"_hoveringNonClientArea: {_hoveringNonClientArea}"); Log.ClientLogger.Info($"_hoveringNonClientArea: {_hoveringNonClientArea}");
} }
void HandleHoverMaximizeWindow(JSContextRef context, JSObjectRef thisObject, Span<JSValueRef> 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) private void RegisterBeefFunction(JSContextRef context, JSObjectRef object, StringView functionName, JSCallback callback)
{ {
JSObjectRef func = UltralightHelper.CreateJsFunctionFromDelegate(context, callback); JSObjectRef func = UltralightHelper.CreateJsFunctionFromDelegate(context, callback);
@@ -68,6 +98,7 @@ class UltralightMainWindow : UltralightWindow
StdAllocator stdAlloc = StdAllocator(); StdAllocator stdAlloc = StdAllocator();
RegisterBeefFunction(context, scriptGlue, "setHoverNonClientArea", new:stdAlloc => HandleHoverNonClientArea); 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) protected override void OnDOMReady(C_View* caller, uint64 frame_id, bool is_main_frame, C_String* url)
@@ -224,14 +224,12 @@ abstract class UltralightWindow
ulDestroyMouseEvent(evt); ulDestroyMouseEvent(evt);
_cursorPosition = .(e.PositionX, e.PositionY); _cursorPosition = .(e.PositionX, e.PositionY);
Log.EngineLogger.Warning($"{_cursorPosition.X} {_cursorPosition.Y}");
return true; return true;
} }
private bool MousePressed(MouseButtonEvent e, bool press) private bool MousePressed(MouseButtonEvent e, bool press)
{ {
Log.ClientLogger.Warning($"{e.MouseButton} {press}");
ULMouseButton button = .kMouseButton_None; ULMouseButton button = .kMouseButton_None;
@@ -43,16 +43,18 @@ namespace GlitchyEngine.UI
private WindowStyle _windowStyle; private WindowStyle _windowStyle;
enum TitleBarButton public enum TitleBarButton
{ {
None,
Minimize, Minimize,
Maximize, Maximize,
Close, Close
None
} }
private TitleBarButton _hoveredTitleBarButton; private TitleBarButton _hoveredTitleBarButton;
private bool _hoveredOverTitleBar;
public override int32 MinWidth public override int32 MinWidth
{ {
get => _minMaxInfo.MinimumTrackingSize.x; 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) switch (uMsg)
{ {
@@ -498,8 +501,8 @@ namespace GlitchyEngine.UI
var event = scope MouseButtonPressedEvent(.LeftButton); var event = scope MouseButtonPressedEvent(.LeftButton);
window._eventCallback(event); window._eventCallback(event);
// if hovering a button if (window._hoveredTitleBarButton != .None)
return 0; return 0;
} }
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
{ {
@@ -513,8 +516,8 @@ namespace GlitchyEngine.UI
var event = scope MouseButtonReleasedEvent(.LeftButton); var event = scope MouseButtonReleasedEvent(.LeftButton);
window._eventCallback(event); window._eventCallback(event);
// if hovering a button if (window._hoveredTitleBarButton != .None)
return 0; return 0;
} }
case WM_LBUTTONUP: case WM_LBUTTONUP:
{ {
@@ -595,14 +598,15 @@ namespace GlitchyEngine.UI
DirectX.Math.Rectangle title_bar_rect = win32_titlebar_rect(hwnd); DirectX.Math.Rectangle title_bar_rect = win32_titlebar_rect(hwnd);
// You could do tighter invalidation here but probably doesn't matter // You could do tighter invalidation here but probably doesn't matter
InvalidateRect(hwnd, title_bar_rect, false); 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); 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); var event = scope MouseMovedEvent(p.x, p.y);
window._eventCallback(event); window._eventCallback(event);
@@ -735,8 +739,13 @@ namespace GlitchyEngine.UI
} }
// Check if hover button is on maximize to support SnapLayout on Windows 11 // Check if hover button is on maximize to support SnapLayout on Windows 11
if (window._hoveredTitleBarButton == .Maximize) { if (window._hoveredTitleBarButton == .Maximize)
return 9 /* HTMAXBUTTON */; {
return 9 /* HTMAXBUTTON */;
}
else if (window._hoveredTitleBarButton == .Minimize)
{
return 8 /* HTMINBUTTON */;
} }
// Looks like adjustment happening in NCCALCSIZE is messing with the detection // Looks like adjustment happening in NCCALCSIZE is messing with the detection
@@ -746,15 +755,18 @@ namespace GlitchyEngine.UI
int padding = GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi); int padding = GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
POINT cursor_point = .(); 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); ScreenToClient(hwnd, &cursor_point);
if (cursor_point.y > 0 && cursor_point.y < frame_y + padding) { if (cursor_point.y > 0 && cursor_point.y < frame_y + padding)
return 12 /* HTTOP */; {
return 12 /* HTTOP */;
} }
// Since we are drawing our own caption, this needs to be a custom test // Since we are drawing our own caption, this needs to be a custom test
if (cursor_point.y < win32_titlebar_rect(hwnd).Bottom) { if (window._hoveredTitleBarButton == .None && window._hoveredOverTitleBar)
return 2 /* HTCAPTION */; {
return 2 /* HTCAPTION */;
} }
return 1 /* HTCLIENT */; return 1 /* HTCLIENT */;
@@ -763,6 +775,24 @@ namespace GlitchyEngine.UI
return DefWindowProcW(hwnd, uMsg, wParam, lParam); 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) static bool win32_window_is_maximized(HWND handle)
{ {
WINDOWPLACEMENT placement = .(); WINDOWPLACEMENT placement = .();
@@ -1067,8 +1097,11 @@ namespace GlitchyEngine.UI
hCursor = Winuser.LoadCursorW((.)0, cursor); hCursor = Winuser.LoadCursorW((.)0, cursor);
} }
_cursor = hCursor; if (_cursor != hCursor)
Winuser.SetCursor(hCursor); {
_cursor = hCursor;
Winuser.SetCursor(hCursor);
}
return .Ok; return .Ok;
} }