diff --git a/WindowServer/WSMessageLoop.cpp b/WindowServer/WSMessageLoop.cpp index d7c940c251..bc240f0b63 100644 --- a/WindowServer/WSMessageLoop.cpp +++ b/WindowServer/WSMessageLoop.cpp @@ -199,38 +199,29 @@ void WSMessageLoop::wait_for_message() void WSMessageLoop::drain_mouse() { auto& screen = WSScreen::the(); - bool prev_left_button = screen.left_mouse_button_pressed(); - bool prev_right_button = screen.right_mouse_button_pressed(); - bool prev_middle_button = screen.middle_mouse_button_pressed(); + unsigned prev_buttons = screen.mouse_button_state(); int dx = 0; int dy = 0; - bool left_button = prev_left_button; - bool right_button = prev_right_button; - bool middle_button = prev_middle_button; + unsigned buttons = prev_buttons; for (;;) { MousePacket packet; ssize_t nread = read(m_mouse_fd, &packet, sizeof(MousePacket)); if (nread == 0) break; ASSERT(nread == sizeof(packet)); - left_button = packet.buttons & 1; - right_button = packet.buttons & 2; - middle_button = packet.buttons & 4; + buttons = packet.buttons; dx += packet.dx; dy += -packet.dy; - if (left_button != prev_left_button || right_button != prev_right_button || middle_button != prev_middle_button) { - prev_left_button = left_button; - prev_right_button = right_button; - prev_middle_button = middle_button; - screen.on_receive_mouse_data(dx, dy, left_button, right_button, middle_button); + if (buttons != prev_buttons) { + screen.on_receive_mouse_data(dx, dy, buttons); dx = 0; dy = 0; + prev_buttons = buttons; } } - if (dx || dy) { - screen.on_receive_mouse_data(dx, dy, left_button, right_button, middle_button); - } + if (dx || dy) + screen.on_receive_mouse_data(dx, dy, buttons); } void WSMessageLoop::drain_keyboard() diff --git a/WindowServer/WSScreen.cpp b/WindowServer/WSScreen.cpp index d3d25d498e..6148df8864 100644 --- a/WindowServer/WSScreen.cpp +++ b/WindowServer/WSScreen.cpp @@ -58,42 +58,29 @@ void WSScreen::set_resolution(int width, int height) m_cursor_location.constrain(rect()); } -void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool right_button, bool middle_button) +void WSScreen::on_receive_mouse_data(int dx, int dy, unsigned buttons) { auto prev_location = m_cursor_location; m_cursor_location.move_by(dx, dy); m_cursor_location.constrain(rect()); - unsigned buttons = 0; - if (left_button) - buttons |= (unsigned)MouseButton::Left; - if (right_button) - buttons |= (unsigned)MouseButton::Right; - if (middle_button) - buttons |= (unsigned)MouseButton::Middle; - bool prev_left_button = m_left_mouse_button_pressed; - bool prev_right_button = m_right_mouse_button_pressed; - bool prev_middle_button = m_middle_mouse_button_pressed; - m_left_mouse_button_pressed = left_button; - m_right_mouse_button_pressed = right_button; - m_middle_mouse_button_pressed = middle_button; - if (prev_left_button != left_button) { - auto message = make(left_button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, MouseButton::Left); + unsigned prev_buttons = m_mouse_button_state; + m_mouse_button_state = buttons; + unsigned changed_buttons = prev_buttons ^ buttons; + auto post_mousedown_or_mouseup_if_needed = [&] (MouseButton button) { + if (!(changed_buttons & (unsigned)button)) + return; + auto message = make(buttons & (unsigned)button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, button); WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); - } - if (prev_right_button != right_button) { - auto message = make(right_button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, MouseButton::Right); - WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); - } - if (prev_middle_button != middle_button) { - auto message = make(middle_button ? WSMessage::MouseDown : WSMessage::MouseUp, m_cursor_location, buttons, MouseButton::Middle); - WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); - } + }; + post_mousedown_or_mouseup_if_needed(MouseButton::Left); + post_mousedown_or_mouseup_if_needed(MouseButton::Right); + post_mousedown_or_mouseup_if_needed(MouseButton::Middle); if (m_cursor_location != prev_location) { auto message = make(WSMessage::MouseMove, m_cursor_location, buttons); WSMessageLoop::the().post_message(WSWindowManager::the(), move(message)); } // NOTE: Invalidate the cursor if it moved, or if the left button changed state (for the cursor color inversion.) - if (m_cursor_location != prev_location || prev_left_button != left_button) + if (m_cursor_location != prev_location || changed_buttons & (unsigned)MouseButton::Left) WSWindowManager::the().invalidate_cursor(); } diff --git a/WindowServer/WSScreen.h b/WindowServer/WSScreen.h index 654490387f..90aba3aac9 100644 --- a/WindowServer/WSScreen.h +++ b/WindowServer/WSScreen.h @@ -24,11 +24,9 @@ public: void set_y_offset(int); Point cursor_location() const { return m_cursor_location; } - bool left_mouse_button_pressed() const { return m_left_mouse_button_pressed; } - bool right_mouse_button_pressed() const { return m_right_mouse_button_pressed; } - bool middle_mouse_button_pressed() const { return m_middle_mouse_button_pressed; } + unsigned mouse_button_state() const { return m_mouse_button_state; } - void on_receive_mouse_data(int dx, int dy, bool left_button, bool right_button, bool middle_button); + void on_receive_mouse_data(int dx, int dy, unsigned buttons); void on_receive_keyboard_data(KeyEvent); private: @@ -39,9 +37,7 @@ private: int m_framebuffer_fd { -1 }; Point m_cursor_location; - bool m_left_mouse_button_pressed { false }; - bool m_right_mouse_button_pressed { false }; - bool m_middle_mouse_button_pressed { false }; + unsigned m_mouse_button_state { 0 }; }; inline RGBA32* WSScreen::scanline(int y) diff --git a/WindowServer/WSWindowManager.cpp b/WindowServer/WSWindowManager.cpp index 4fdfac62b7..8c9aead44e 100644 --- a/WindowServer/WSWindowManager.cpp +++ b/WindowServer/WSWindowManager.cpp @@ -958,7 +958,7 @@ void WSWindowManager::draw_cursor() Rect cursor_rect { cursor_location.x(), cursor_location.y(), (int)m_cursor_bitmap_inner->width(), (int)m_cursor_bitmap_inner->height() }; Color inner_color = Color::White; Color outer_color = Color::Black; - if (m_screen.left_mouse_button_pressed()) + if (m_screen.mouse_button_state() & (unsigned)MouseButton::Left) swap(inner_color, outer_color); m_back_painter->draw_bitmap(cursor_location, *m_cursor_bitmap_inner, inner_color); m_back_painter->draw_bitmap(cursor_location, *m_cursor_bitmap_outer, outer_color);