diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp index 9e5fc7930a..b45a1f2d86 100644 --- a/Servers/WindowServer/WSEventLoop.cpp +++ b/Servers/WindowServer/WSEventLoop.cpp @@ -89,11 +89,9 @@ WSEventLoop::~WSEventLoop() void WSEventLoop::drain_mouse() { auto& screen = WSScreen::the(); - unsigned prev_buttons = screen.mouse_button_state(); - int dx = 0; - int dy = 0; - int dz = 0; - unsigned buttons = prev_buttons; + MousePacket state; + state.buttons = screen.mouse_button_state(); + unsigned buttons = state.buttons; for (;;) { MousePacket packet; ssize_t nread = read(m_mouse_fd, &packet, sizeof(MousePacket)); @@ -102,19 +100,26 @@ void WSEventLoop::drain_mouse() ASSERT(nread == sizeof(packet)); buttons = packet.buttons; - dx += packet.dx; - dy += -packet.dy; - dz += packet.dz; - if (buttons != prev_buttons) { - screen.on_receive_mouse_data(dx, dy, dz, buttons); - dx = 0; - dy = 0; - dz = 0; - prev_buttons = buttons; + if (packet.is_relative) { + state.x += packet.x; + state.y -= packet.y; + state.z += packet.z; + } else { + state.x = packet.x; + state.y = packet.y; + state.z += packet.z; + } + + if (buttons != state.buttons) { + state.buttons = buttons; + screen.on_receive_mouse_data(state); + state.x = 0; + state.y = 0; + state.z = 0; } } - if (dx || dy || dz) - screen.on_receive_mouse_data(dx, dy, dz, buttons); + if (state.is_relative && (state.x || state.y || state.z)) + screen.on_receive_mouse_data(state); } void WSEventLoop::drain_keyboard() diff --git a/Servers/WindowServer/WSScreen.cpp b/Servers/WindowServer/WSScreen.cpp index 6e9f9f6bea..20875e962e 100644 --- a/Servers/WindowServer/WSScreen.cpp +++ b/Servers/WindowServer/WSScreen.cpp @@ -30,6 +30,7 @@ #include "WSEventLoop.h" #include "WSWindowManager.h" #include +#include #include #include #include @@ -101,11 +102,16 @@ void WSScreen::set_buffer(int index) ASSERT(rc == 0); } -void WSScreen::on_receive_mouse_data(int dx, int dy, int dz, unsigned buttons) +void WSScreen::on_receive_mouse_data(const MousePacket& packet) { auto prev_location = m_cursor_location; - m_cursor_location.move_by(dx, dy); + if (packet.is_relative) + m_cursor_location.move_by(packet.x, packet.y); + else + m_cursor_location = { packet.x * m_width / 0xffff, packet.y * m_height / 0xffff }; m_cursor_location.constrain(rect()); + + unsigned buttons = packet.buttons; unsigned prev_buttons = m_mouse_button_state; m_mouse_button_state = buttons; unsigned changed_buttons = prev_buttons ^ buttons; @@ -123,8 +129,8 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, int dz, unsigned buttons) Core::EventLoop::current().post_event(WSWindowManager::the(), move(message)); } - if (dz) { - auto message = make(WSEvent::MouseWheel, m_cursor_location, buttons, MouseButton::None, m_modifiers, dz); + if (packet.z) { + auto message = make(WSEvent::MouseWheel, m_cursor_location, buttons, MouseButton::None, m_modifiers, packet.z); Core::EventLoop::current().post_event(WSWindowManager::the(), move(message)); } diff --git a/Servers/WindowServer/WSScreen.h b/Servers/WindowServer/WSScreen.h index d7728c09a0..c62d8964c5 100644 --- a/Servers/WindowServer/WSScreen.h +++ b/Servers/WindowServer/WSScreen.h @@ -31,6 +31,8 @@ #include #include +struct MousePacket; + class WSScreen { public: WSScreen(unsigned width, unsigned height); @@ -53,7 +55,7 @@ public: Point cursor_location() const { return m_cursor_location; } unsigned mouse_button_state() const { return m_mouse_button_state; } - void on_receive_mouse_data(int dx, int dy, int dz, unsigned buttons); + void on_receive_mouse_data(const MousePacket&); void on_receive_keyboard_data(KeyEvent); private: