libui+wind: Handle mouse leave events when the mouse leaves a window

This commit is contained in:
apio 2023-08-29 15:26:34 +02:00
parent 1d4055411d
commit f0f1a9c46c
Signed by: apio
GPG Key ID: B8A7D06E42258954
16 changed files with 58 additions and 18 deletions

View File

@ -14,7 +14,7 @@ struct ColorWidget : public ui::Widget
return ui::EventResult::DidHandle; return ui::EventResult::DidHandle;
} }
Result<ui::EventResult> handle_mouse_leave(ui::Point) override Result<ui::EventResult> handle_mouse_leave() override
{ {
m_color = m_first_color; m_color = m_first_color;
return ui::EventResult::DidHandle; return ui::EventResult::DidHandle;

View File

@ -21,7 +21,7 @@ namespace ui
void set_action(void (*action)(void)); void set_action(void (*action)(void));
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override; Result<void> draw(Canvas& canvas) override;

View File

@ -21,7 +21,7 @@ namespace ui
void set_widget(Widget& widget); void set_widget(Widget& widget);
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override; Result<void> draw(Canvas& canvas) override;

View File

@ -85,7 +85,7 @@ namespace ui
static Result<OwnedPtr<ImageWidget>> load(const os::Path& path); static Result<OwnedPtr<ImageWidget>> load(const os::Path& path);
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override; Result<void> draw(Canvas& canvas) override;

View File

@ -31,7 +31,7 @@ namespace ui
HorizontalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes); HorizontalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes);
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;
@ -52,7 +52,7 @@ namespace ui
VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes); VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes);
Result<EventResult> handle_mouse_move(Point position) override; Result<EventResult> handle_mouse_move(Point position) override;
Result<EventResult> handle_mouse_leave(Point position) override; Result<EventResult> handle_mouse_leave() override;
Result<EventResult> handle_mouse_down(Point position, int buttons) override; Result<EventResult> handle_mouse_down(Point position, int buttons) override;
Result<EventResult> handle_mouse_up(Point position, int buttons) override; Result<EventResult> handle_mouse_up(Point position, int buttons) override;

View File

@ -29,7 +29,7 @@ namespace ui
virtual Result<EventResult> handle_mouse_move(Point position); virtual Result<EventResult> handle_mouse_move(Point position);
virtual Result<EventResult> handle_mouse_down(Point position, int buttons); virtual Result<EventResult> handle_mouse_down(Point position, int buttons);
virtual Result<EventResult> handle_mouse_up(Point position, int buttons); virtual Result<EventResult> handle_mouse_up(Point position, int buttons);
virtual Result<EventResult> handle_mouse_leave(Point position); virtual Result<EventResult> handle_mouse_leave();
virtual Result<void> draw(Canvas& canvas); virtual Result<void> draw(Canvas& canvas);

View File

@ -46,6 +46,7 @@ namespace ui
void close(); void close();
Result<void> draw(); Result<void> draw();
Result<void> handle_mouse_leave();
Result<void> handle_mouse_move(ui::Point position); Result<void> handle_mouse_move(ui::Point position);
Result<void> handle_mouse_buttons(ui::Point position, int buttons); Result<void> handle_mouse_buttons(ui::Point position, int buttons);

View File

@ -19,6 +19,7 @@ namespace ui
CREATE_WINDOW_RESPONSE_ID, CREATE_WINDOW_RESPONSE_ID,
WINDOW_CLOSE_REQUEST_ID, WINDOW_CLOSE_REQUEST_ID,
MOUSE_EVENT_REQUEST_ID, MOUSE_EVENT_REQUEST_ID,
MOUSE_LEAVE_REQUEST_ID,
GET_SCREEN_RECT_RESPONSE_ID GET_SCREEN_RECT_RESPONSE_ID
}; };
@ -46,6 +47,13 @@ namespace ui
int buttons; int buttons;
}; };
struct MouseLeaveRequest
{
static constexpr u8 ID = MOUSE_LEAVE_REQUEST_ID;
int window;
};
struct GetScreenRectResponse struct GetScreenRectResponse
{ {
static constexpr u8 ID = GET_SCREEN_RECT_RESPONSE_ID; static constexpr u8 ID = GET_SCREEN_RECT_RESPONSE_ID;

View File

@ -122,6 +122,14 @@ namespace ui
window->draw(); window->draw();
return {}; return {};
} }
case MOUSE_LEAVE_REQUEST_ID: {
MouseLeaveRequest request;
READ_MESSAGE(request);
auto* window = find_window(request.window);
window->handle_mouse_leave();
window->draw();
return {};
}
default: fail("Unexpected IPC request from server!"); default: fail("Unexpected IPC request from server!");
} }
} }

View File

@ -35,10 +35,10 @@ namespace ui
return m_child->handle_mouse_move(position); return m_child->handle_mouse_move(position);
} }
Result<EventResult> Button::handle_mouse_leave(Point position) Result<EventResult> Button::handle_mouse_leave()
{ {
m_hovered = m_clicked = false; m_hovered = m_clicked = false;
return m_child->handle_mouse_leave(position); return m_child->handle_mouse_leave();
} }
Result<EventResult> Button::handle_mouse_down(Point position, int buttons) Result<EventResult> Button::handle_mouse_down(Point position, int buttons)

View File

@ -29,9 +29,9 @@ namespace ui
return m_widget->handle_mouse_move(position); return m_widget->handle_mouse_move(position);
} }
Result<EventResult> Container::handle_mouse_leave(Point position) Result<EventResult> Container::handle_mouse_leave()
{ {
return m_widget->handle_mouse_leave(position); return m_widget->handle_mouse_leave();
} }
Result<EventResult> Container::handle_mouse_down(Point position, int buttons) Result<EventResult> Container::handle_mouse_down(Point position, int buttons)

View File

@ -45,7 +45,7 @@ namespace ui
return EventResult::DidNotHandle; return EventResult::DidNotHandle;
} }
Result<EventResult> ImageWidget::handle_mouse_leave(Point) Result<EventResult> ImageWidget::handle_mouse_leave()
{ {
return EventResult::DidNotHandle; return EventResult::DidNotHandle;
} }

View File

@ -25,15 +25,15 @@ namespace ui
{ {
if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position)); if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position));
else else
TRY(widget->handle_mouse_leave(position)); TRY(widget->handle_mouse_leave());
} }
return result; return result;
} }
Result<EventResult> HorizontalLayout::handle_mouse_leave(Point position) Result<EventResult> HorizontalLayout::handle_mouse_leave()
{ {
for (auto widget : m_widgets) TRY(widget->handle_mouse_leave(position)); for (auto widget : m_widgets) TRY(widget->handle_mouse_leave());
return ui::EventResult::DidNotHandle; return ui::EventResult::DidNotHandle;
} }
@ -114,15 +114,15 @@ namespace ui
{ {
if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position)); if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position));
else else
TRY(widget->handle_mouse_leave(position)); TRY(widget->handle_mouse_leave());
} }
return result; return result;
} }
Result<EventResult> VerticalLayout::handle_mouse_leave(Point position) Result<EventResult> VerticalLayout::handle_mouse_leave()
{ {
for (auto widget : m_widgets) TRY(widget->handle_mouse_leave(position)); for (auto widget : m_widgets) TRY(widget->handle_mouse_leave());
return ui::EventResult::DidNotHandle; return ui::EventResult::DidNotHandle;
} }

View File

@ -101,6 +101,13 @@ namespace ui
return {}; return {};
} }
Result<void> Window::handle_mouse_leave()
{
if (!m_main_widget) return {};
TRY(m_main_widget->handle_mouse_leave());
return {};
}
Result<void> Window::handle_mouse_move(ui::Point position) Result<void> Window::handle_mouse_move(ui::Point position)
{ {
if (!m_main_widget) return {}; if (!m_main_widget) return {};

View File

@ -79,6 +79,8 @@ void Mouse::update(const moon::MousePacket& packet)
} }
} }
Window* new_active_window = nullptr;
for (Window* window = g_windows.last().value_or(nullptr); window; for (Window* window = g_windows.last().value_or(nullptr); window;
window = g_windows.previous(window).value_or(nullptr)) window = g_windows.previous(window).value_or(nullptr))
{ {
@ -92,7 +94,19 @@ void Mouse::update(const moon::MousePacket& packet)
request.position = contents.relative(m_position); request.position = contents.relative(m_position);
request.buttons = packet.buttons; request.buttons = packet.buttons;
os::IPC::send_async(window->client->conn, request); os::IPC::send_async(window->client->conn, request);
new_active_window = window;
break; break;
} }
} }
if (m_active_window != new_active_window)
{
if (m_active_window)
{
ui::MouseLeaveRequest request;
request.window = m_active_window->id;
os::IPC::send_async(m_active_window->client->conn, request);
}
m_active_window = new_active_window;
}
} }

View File

@ -19,4 +19,6 @@ class Mouse
Window* m_dragging_window = nullptr; Window* m_dragging_window = nullptr;
ui::Point m_initial_drag_position; ui::Point m_initial_drag_position;
Window* m_active_window = nullptr;
}; };