mirror of
https://github.com/RGBCube/serenity
synced 2025-07-23 09:17:36 +00:00
WindowServer: Make automatic menu dismissal feel more "natural."
This commit is contained in:
parent
43d9994d93
commit
3c863e0ffa
4 changed files with 29 additions and 12 deletions
|
@ -3,6 +3,7 @@
|
||||||
#include "WSWindow.h"
|
#include "WSWindow.h"
|
||||||
#include "WSMessage.h"
|
#include "WSMessage.h"
|
||||||
#include "WSMessageLoop.h"
|
#include "WSMessageLoop.h"
|
||||||
|
#include "WSWindowManager.h"
|
||||||
#include <SharedGraphics/Painter.h>
|
#include <SharedGraphics/Painter.h>
|
||||||
#include <SharedGraphics/Font.h>
|
#include <SharedGraphics/Font.h>
|
||||||
|
|
||||||
|
@ -131,6 +132,7 @@ void WSMenu::did_activate(WSMenuItem& item)
|
||||||
{
|
{
|
||||||
if (on_item_activation)
|
if (on_item_activation)
|
||||||
on_item_activation(item);
|
on_item_activation(item);
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
WSMenuItem* WSMenu::item_at(const Point& position)
|
WSMenuItem* WSMenu::item_at(const Point& position)
|
||||||
|
@ -142,3 +144,8 @@ WSMenuItem* WSMenu::item_at(const Point& position)
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WSMenu::close()
|
||||||
|
{
|
||||||
|
WSWindowManager::the().close_menu(*this);
|
||||||
|
};
|
||||||
|
|
|
@ -62,6 +62,8 @@ public:
|
||||||
|
|
||||||
Function<void(WSMenuItem&)> on_item_activation;
|
Function<void(WSMenuItem&)> on_item_activation;
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void did_activate(WSMenuItem&);
|
void did_activate(WSMenuItem&);
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ WSWindowManager::WSWindowManager()
|
||||||
menubar->add_menu(move(menu));
|
menubar->add_menu(move(menu));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto menu = make<WSMenu>("Application");
|
auto menu = make<WSMenu>("Terminal");
|
||||||
menu->add_item(make<WSMenuItem>(5, "Foo."));
|
menu->add_item(make<WSMenuItem>(5, "Foo."));
|
||||||
menu->add_item(make<WSMenuItem>(6, "Bar?"));
|
menu->add_item(make<WSMenuItem>(6, "Bar?"));
|
||||||
menu->add_item(make<WSMenuItem>(7, "Baz!"));
|
menu->add_item(make<WSMenuItem>(7, "Baz!"));
|
||||||
|
@ -380,8 +380,9 @@ void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect
|
||||||
|
|
||||||
void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, WSMouseEvent& event)
|
void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, WSMouseEvent& event)
|
||||||
{
|
{
|
||||||
bool should_open_menu = (event.type() == WSMouseEvent::MouseMove && event.buttons() & (unsigned)MouseButton::Left)
|
bool is_hover_with_any_menu_open = event.type() == WSMouseEvent::MouseMove && m_current_menu;
|
||||||
|| (event.type() == WSMouseEvent::MouseDown && event.button() == MouseButton::Left);
|
bool is_mousedown_with_left_button = event.type() == WSMouseEvent::MouseDown && event.button() == MouseButton::Left;
|
||||||
|
bool should_open_menu = &menu != m_current_menu && (is_hover_with_any_menu_open || is_mousedown_with_left_button);
|
||||||
|
|
||||||
if (should_open_menu) {
|
if (should_open_menu) {
|
||||||
if (m_current_menu == &menu)
|
if (m_current_menu == &menu)
|
||||||
|
@ -393,7 +394,7 @@ void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, WSMouseEvent& event)
|
||||||
m_current_menu = &menu;
|
m_current_menu = &menu;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event.type() == WSMouseEvent::MouseUp && event.button() == MouseButton::Left) {
|
if (event.type() == WSMouseEvent::MouseDown && event.button() == MouseButton::Left) {
|
||||||
close_current_menu();
|
close_current_menu();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -486,16 +487,16 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_current_menu && m_current_menu->hovered_item() && !m_current_menu->menu_window()->rect().contains(event.position())) {
|
if (m_current_menu) {
|
||||||
m_current_menu->clear_hovered_item();
|
bool event_is_inside_current_menu = m_current_menu->menu_window()->rect().contains(event.position());
|
||||||
|
if (!event_is_inside_current_menu) {
|
||||||
|
if (m_current_menu->hovered_item())
|
||||||
|
m_current_menu->clear_hovered_item();
|
||||||
|
if (event.type() == WSMessage::MouseDown || event.type() == WSMessage::MouseUp)
|
||||||
|
close_current_menu();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Figure out an automatic menu dismissal logic that feels right.
|
|
||||||
#if 0
|
|
||||||
if (m_current_menu && event.type() == WSMouseEvent::MouseUp && event.button() == MouseButton::Left)
|
|
||||||
close_current_menu();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
|
for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
|
||||||
if (!window->is_visible())
|
if (!window->is_visible())
|
||||||
continue;
|
continue;
|
||||||
|
@ -764,3 +765,8 @@ void WSWindowManager::flush(const Rect& a_rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WSWindowManager::close_menu(WSMenu& menu)
|
||||||
|
{
|
||||||
|
ASSERT(m_current_menu == &menu);
|
||||||
|
close_current_menu();
|
||||||
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ public:
|
||||||
Font& font() { return *m_font; }
|
Font& font() { return *m_font; }
|
||||||
const Font& font() const { return *m_font; }
|
const Font& font() const { return *m_font; }
|
||||||
|
|
||||||
|
void close_menu(WSMenu&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WSWindowManager();
|
WSWindowManager();
|
||||||
virtual ~WSWindowManager() override;
|
virtual ~WSWindowManager() override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue