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 5385b1c337
commit a023811c26
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;
}
Result<ui::EventResult> handle_mouse_leave(ui::Point) override
Result<ui::EventResult> handle_mouse_leave() override
{
m_color = m_first_color;
return ui::EventResult::DidHandle;

View File

@ -21,7 +21,7 @@ namespace ui
void set_action(void (*action)(void));
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_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override;

View File

@ -21,7 +21,7 @@ namespace ui
void set_widget(Widget& widget);
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_up(Point position, int buttons) override;
Result<void> draw(Canvas& canvas) override;

View File

@ -85,7 +85,7 @@ namespace ui
static Result<OwnedPtr<ImageWidget>> load(const os::Path& path);
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_up(Point position, int buttons) 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);
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_up(Point position, int buttons) override;
@ -52,7 +52,7 @@ namespace ui
VerticalLayout(AdjustHeight adjust_height = AdjustHeight::Yes, AdjustWidth adjust_width = AdjustWidth::Yes);
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_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_down(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);

View File

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

View File

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

View File

@ -122,6 +122,14 @@ namespace ui
window->draw();
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!");
}
}

View File

@ -35,10 +35,10 @@ namespace ui
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;
return m_child->handle_mouse_leave(position);
return m_child->handle_mouse_leave();
}
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);
}
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)

View File

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

View File

@ -25,15 +25,15 @@ namespace ui
{
if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position));
else
TRY(widget->handle_mouse_leave(position));
TRY(widget->handle_mouse_leave());
}
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;
}
@ -114,15 +114,15 @@ namespace ui
{
if (widget->rect().contains(position)) result = TRY(widget->handle_mouse_move(position));
else
TRY(widget->handle_mouse_leave(position));
TRY(widget->handle_mouse_leave());
}
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;
}

View File

@ -101,6 +101,13 @@ namespace ui
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)
{
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;
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.buttons = packet.buttons;
os::IPC::send_async(window->client->conn, request);
new_active_window = window;
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;
ui::Point m_initial_drag_position;
Window* m_active_window = nullptr;
};