diff --git a/Servers/WindowServer/WSMenu.cpp b/Servers/WindowServer/WSMenu.cpp index 3d0ee4c5c8..cfcc88a42d 100644 --- a/Servers/WindowServer/WSMenu.cpp +++ b/Servers/WindowServer/WSMenu.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2020, Shannon Booth * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,6 +38,7 @@ #include #include #include +#include #include #include @@ -279,7 +281,23 @@ void WSMenu::event(CEvent& event) { if (event.type() == WSEvent::MouseMove) { ASSERT(menu_window()); - int index = item_index_at(static_cast(event).position()); + auto mouse_event = static_cast(event); + + if (hovered_item() && hovered_item()->is_submenu()) { + + auto item = *hovered_item(); + auto submenu_top_left = item.rect().location() + Point { item.rect().width(), 0 }; + auto submenu_bottom_left = submenu_top_left + Point { 0, item.submenu()->height() }; + + auto safe_hover_triangle = Triangle { m_last_position_in_hover, submenu_top_left, submenu_bottom_left }; + m_last_position_in_hover = mouse_event.position(); + + // Don't update the hovered item if mouse is moving towards a submenu + if (safe_hover_triangle.contains(mouse_event.position())) + return; + } + + int index = item_index_at(mouse_event.position()); if (m_hovered_item_index == index) return; m_hovered_item_index = index; diff --git a/Servers/WindowServer/WSMenu.h b/Servers/WindowServer/WSMenu.h index 2ecb4bccb6..8aea486501 100644 --- a/Servers/WindowServer/WSMenu.h +++ b/Servers/WindowServer/WSMenu.h @@ -133,7 +133,7 @@ private: WeakPtr m_window_menu_of; bool m_is_window_menu_open = { false }; - + Point m_last_position_in_hover; int m_theme_index_at_last_paint { -1 }; int m_hovered_item_index { -1 }; bool m_in_submenu { false };