WindowServer: Support absolute position mouse

This commit is contained in:
Bananymous 2025-07-19 18:01:23 +03:00
parent 2c65590134
commit aa0249fadb
3 changed files with 76 additions and 29 deletions

View File

@ -613,36 +613,9 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
} }
} }
void WindowServer::on_mouse_move(LibInput::MouseMoveEvent event) void WindowServer::on_mouse_move_impl(int32_t new_x, int32_t new_y)
{ {
if (m_is_mouse_captured) LibInput::MouseMoveEvent event;
{
ASSERT(m_focused_window);
LibGUI::EventPacket::MouseMoveEvent packet;
packet.event.x = event.rel_x;
packet.event.y = -event.rel_y;
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
dwarnln("could not send mouse move event: {}", ret.error());
return;
}
const auto [new_x, new_y] =
[&]() -> Position
{
const int32_t new_x = m_cursor.x + event.rel_x;
const int32_t new_y = m_cursor.y - event.rel_y;
return (m_state == State::Fullscreen)
? Position {
.x = BAN::Math::clamp(new_x, m_focused_window->client_x(), m_focused_window->client_x() + m_focused_window->client_width()),
.y = BAN::Math::clamp(new_y, m_focused_window->client_y(), m_focused_window->client_y() + m_focused_window->client_height())
}
: Position {
.x = BAN::Math::clamp(new_x, 0, m_framebuffer.width),
.y = BAN::Math::clamp(new_y, 0, m_framebuffer.height)
};
}();
event.rel_x = new_x - m_cursor.x; event.rel_x = new_x - m_cursor.x;
event.rel_y = new_y - m_cursor.y; event.rel_y = new_y - m_cursor.y;
if (event.rel_x == 0 && event.rel_y == 0) if (event.rel_x == 0 && event.rel_y == 0)
@ -706,6 +679,74 @@ void WindowServer::on_mouse_move(LibInput::MouseMoveEvent event)
} }
} }
void WindowServer::on_mouse_move(LibInput::MouseMoveEvent event)
{
if (m_is_mouse_captured)
{
ASSERT(m_focused_window);
LibGUI::EventPacket::MouseMoveEvent packet;
packet.event.x = event.rel_x;
packet.event.y = -event.rel_y;
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
dwarnln("could not send mouse move event: {}", ret.error());
return;
}
int32_t min_x, max_x;
int32_t min_y, max_y;
if (m_state == State::Fullscreen)
{
min_x = m_focused_window->client_x();
min_y = m_focused_window->client_y();
max_x = m_focused_window->client_x() + m_focused_window->client_width();
max_y = m_focused_window->client_y() + m_focused_window->client_height();
}
else
{
min_x = 0;
min_y = 0;
max_x = m_framebuffer.width;
max_y = m_framebuffer.height;
}
const int32_t new_x = BAN::Math::clamp(m_cursor.x + event.rel_x, min_x, max_x);
const int32_t new_y = BAN::Math::clamp(m_cursor.y + event.rel_y, min_y, max_y);
return on_mouse_move_impl(new_x, new_y);
}
void WindowServer::on_mouse_move_abs(LibInput::MouseMoveAbsEvent event)
{
constexpr auto map =
[](int32_t val, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max) -> int32_t
{
return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
};
int32_t out_min_x, out_max_x;
int32_t out_min_y, out_max_y;
if (m_state == State::Fullscreen)
{
out_min_x = m_focused_window->client_x();
out_min_y = m_focused_window->client_y();
out_max_x = m_focused_window->client_x() + m_focused_window->client_width();
out_max_y = m_focused_window->client_y() + m_focused_window->client_height();
}
else
{
out_min_x = 0;
out_min_y = 0;
out_max_x = m_framebuffer.width;
out_max_y = m_framebuffer.height;
}
const int32_t new_x = map(event.abs_x, event.min_x, event.max_x, out_min_x, out_max_x);
const int32_t new_y = map(event.abs_y, event.min_y, event.max_y, out_min_y, out_max_y);
return on_mouse_move_impl(new_x, new_y);
}
void WindowServer::on_mouse_scroll(LibInput::MouseScrollEvent event) void WindowServer::on_mouse_scroll(LibInput::MouseScrollEvent event)
{ {
if (m_focused_window) if (m_focused_window)

View File

@ -46,6 +46,7 @@ public:
void on_key_event(LibInput::KeyEvent event); void on_key_event(LibInput::KeyEvent event);
void on_mouse_button(LibInput::MouseButtonEvent event); void on_mouse_button(LibInput::MouseButtonEvent event);
void on_mouse_move(LibInput::MouseMoveEvent event); void on_mouse_move(LibInput::MouseMoveEvent event);
void on_mouse_move_abs(LibInput::MouseMoveAbsEvent event);
void on_mouse_scroll(LibInput::MouseScrollEvent event); void on_mouse_scroll(LibInput::MouseScrollEvent event);
void set_focused_window(BAN::RefPtr<Window> window); void set_focused_window(BAN::RefPtr<Window> window);
@ -63,6 +64,8 @@ public:
bool is_stopped() const { return m_is_stopped; } bool is_stopped() const { return m_is_stopped; }
private: private:
void on_mouse_move_impl(int32_t new_x, int32_t new_y);
void mark_pending_sync(Rectangle area); void mark_pending_sync(Rectangle area);
bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height) const; bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height) const;

View File

@ -290,6 +290,9 @@ int main()
case LibInput::MouseEventType::MouseMoveEvent: case LibInput::MouseEventType::MouseMoveEvent:
window_server.on_mouse_move(event.move_event); window_server.on_mouse_move(event.move_event);
break; break;
case LibInput::MouseEventType::MouseMoveAbsEvent:
window_server.on_mouse_move_abs(event.move_abs_event);
break;
case LibInput::MouseEventType::MouseScrollEvent: case LibInput::MouseEventType::MouseScrollEvent:
window_server.on_mouse_scroll(event.scroll_event); window_server.on_mouse_scroll(event.scroll_event);
break; break;