mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 10:27:35 +00:00
LibGUI: Implement enter/leave events (with WindowServer support.)
Windows now learn when the mouse cursor leaves or enters them. Use this to implement GWidget::{enter,leave}_event() and use that to implement the CoolBar button effect. :^)
This commit is contained in:
parent
af7eb5c89c
commit
bf30502560
14 changed files with 103 additions and 5 deletions
|
@ -62,6 +62,8 @@ struct WSAPI_ServerMessage {
|
|||
MouseMove,
|
||||
MouseDown,
|
||||
MouseUp,
|
||||
WindowEntered,
|
||||
WindowLeft,
|
||||
KeyDown,
|
||||
KeyUp,
|
||||
WindowActivated,
|
||||
|
|
|
@ -14,6 +14,8 @@ public:
|
|||
MouseMove,
|
||||
MouseDown,
|
||||
MouseUp,
|
||||
WindowEntered,
|
||||
WindowLeft,
|
||||
KeyDown,
|
||||
KeyUp,
|
||||
WindowActivated,
|
||||
|
|
|
@ -94,6 +94,12 @@ void WSWindow::on_message(WSMessage& message)
|
|||
server_message.mouse.button = to_api(static_cast<WSMouseEvent&>(message).button());
|
||||
server_message.mouse.buttons = static_cast<WSMouseEvent&>(message).buttons();
|
||||
break;
|
||||
case WSMessage::WindowEntered:
|
||||
server_message.type = WSAPI_ServerMessage::Type::WindowEntered;
|
||||
break;
|
||||
case WSMessage::WindowLeft:
|
||||
server_message.type = WSAPI_ServerMessage::Type::WindowLeft;
|
||||
break;
|
||||
case WSMessage::KeyDown:
|
||||
server_message.type = WSAPI_ServerMessage::Type::KeyDown;
|
||||
server_message.key.character = static_cast<WSKeyEvent&>(message).character();
|
||||
|
|
|
@ -488,8 +488,10 @@ void WSWindowManager::handle_close_button_mouse_event(WSWindow& window, WSMouseE
|
|||
}
|
||||
}
|
||||
|
||||
void WSWindowManager::process_mouse_event(WSMouseEvent& event)
|
||||
void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& event_window)
|
||||
{
|
||||
event_window = nullptr;
|
||||
|
||||
if (event.type() == WSMessage::MouseUp && event.button() == MouseButton::Left) {
|
||||
if (m_drag_window) {
|
||||
#ifdef DRAG_DEBUG
|
||||
|
@ -561,6 +563,7 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event)
|
|||
move_to_front(window);
|
||||
set_active_window(&window);
|
||||
}
|
||||
event_window = &window;
|
||||
// FIXME: Should we just alter the coordinates of the existing MouseEvent and pass it through?
|
||||
Point position { event.x() - window.rect().x(), event.y() - window.rect().y() };
|
||||
auto local_event = make<WSMouseEvent>(event.type(), position, event.buttons(), event.button());
|
||||
|
@ -753,8 +756,12 @@ void WSWindowManager::draw_cursor()
|
|||
|
||||
void WSWindowManager::on_message(WSMessage& message)
|
||||
{
|
||||
if (message.is_mouse_event())
|
||||
return process_mouse_event(static_cast<WSMouseEvent&>(message));
|
||||
if (message.is_mouse_event()) {
|
||||
WSWindow* event_window = nullptr;
|
||||
process_mouse_event(static_cast<WSMouseEvent&>(message), event_window);
|
||||
set_hovered_window(event_window);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.is_key_event()) {
|
||||
// FIXME: This is a good place to hook key events globally. :)
|
||||
|
@ -795,6 +802,20 @@ void WSWindowManager::set_active_window(WSWindow* window)
|
|||
}
|
||||
}
|
||||
|
||||
void WSWindowManager::set_hovered_window(WSWindow* window)
|
||||
{
|
||||
if (m_hovered_window.ptr() == window)
|
||||
return;
|
||||
|
||||
if (m_hovered_window)
|
||||
WSMessageLoop::the().post_message(m_hovered_window.ptr(), make<WSMessage>(WSMessage::WindowLeft));
|
||||
|
||||
m_hovered_window = window ? window->make_weak_ptr() : nullptr;
|
||||
|
||||
if (m_hovered_window)
|
||||
WSMessageLoop::the().post_message(m_hovered_window.ptr(), make<WSMessage>(WSMessage::WindowEntered));
|
||||
}
|
||||
|
||||
void WSWindowManager::invalidate()
|
||||
{
|
||||
m_dirty_rects.clear_with_capacity();
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
void set_resolution(int width, int height);
|
||||
|
||||
private:
|
||||
void process_mouse_event(WSMouseEvent&);
|
||||
void process_mouse_event(WSMouseEvent&, WSWindow*& event_window);
|
||||
void handle_menu_mouse_event(WSMenu&, WSMouseEvent&);
|
||||
void handle_menubar_mouse_event(WSMouseEvent&);
|
||||
void handle_titlebar_mouse_event(WSWindow&, WSMouseEvent&);
|
||||
|
@ -79,6 +79,7 @@ private:
|
|||
void handle_client_request(WSAPIClientRequest&);
|
||||
|
||||
void set_active_window(WSWindow*);
|
||||
void set_hovered_window(WSWindow*);
|
||||
template<typename Callback> IterationDecision for_each_visible_window_of_type_from_back_to_front(WSWindowType, Callback);
|
||||
template<typename Callback> IterationDecision for_each_visible_window_of_type_from_front_to_back(WSWindowType, Callback);
|
||||
template<typename Callback> IterationDecision for_each_visible_window_from_front_to_back(Callback);
|
||||
|
@ -111,7 +112,7 @@ private:
|
|||
InlineLinkedList<WSWindow> m_windows_in_order;
|
||||
|
||||
WeakPtr<WSWindow> m_active_window;
|
||||
|
||||
WeakPtr<WSWindow> m_hovered_window;
|
||||
WeakPtr<WSWindow> m_drag_window;
|
||||
|
||||
Point m_drag_origin;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue