From 2e80f0674e8fe514c31f844f99858734a7e1717a Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 05:43:32 -0300 Subject: [PATCH 01/22] fix(macos): proper delta handling, no force warp --- src/platform/macos/input.cpp | 116 +++++++++++++++++++++-------------- 1 file changed, 70 insertions(+), 46 deletions(-) diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index 11c6d228421..7683422e72b 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -316,84 +316,107 @@ const KeyCodeMap kKeyCodesMap[] = { // returns current mouse location: inline CGPoint - get_mouse_loc(input_t &input) { - return CGEventGetLocation(((macos_input_t *) input.get())->mouse_event); + get_mouse_loc(const macos_input_t &input) { + // Creating a new event every time to avoid any reuse risk + const auto snapshot_event = CGEventCreate(input.source); + const auto current = CGEventGetLocation(snapshot_event); + CFRelease(snapshot_event); + return current; } void - post_mouse(input_t &input, CGMouseButton button, CGEventType type, CGPoint location, int click_count) { - BOOST_LOG(debug) << "mouse_event: "sv << button << ", type: "sv << type << ", location:"sv << location.x << ":"sv << location.y << " click_count: "sv << click_count; - - auto macos_input = (macos_input_t *) input.get(); - auto display = macos_input->display; - auto event = macos_input->mouse_event; + post_mouse( + input_t &input, + const CGMouseButton button, + const CGEventType type, + const CGPoint raw_location, + const CGPoint previous_location, + const int click_count + ) { + BOOST_LOG(debug) << "mouse_event: "sv << button << ", type: "sv << type << ", location:"sv << raw_location.x << ":"sv << raw_location.y << " click_count: "sv << click_count; + + const auto macos_input = static_cast(input.get()); + const auto display = macos_input->display; + const auto event = macos_input->mouse_event; // get display bounds for current display - CGRect display_bounds = CGDisplayBounds(display); + const CGRect display_bounds = CGDisplayBounds(display); // limit mouse to current display bounds - location.x = std::clamp(location.x, display_bounds.origin.x, display_bounds.origin.x + display_bounds.size.width - 1); - location.y = std::clamp(location.y, display_bounds.origin.y, display_bounds.origin.y + display_bounds.size.height - 1); + const auto location = CGPoint { + std::clamp(raw_location.x, display_bounds.origin.x, display_bounds.origin.x + display_bounds.size.width - 1), + std::clamp(raw_location.y, display_bounds.origin.y, display_bounds.origin.y + display_bounds.size.height - 1) + }; CGEventSetType(event, type); CGEventSetLocation(event, location); CGEventSetIntegerValueField(event, kCGMouseEventButtonNumber, button); CGEventSetIntegerValueField(event, kCGMouseEventClickState, click_count); - CGEventPost(kCGHIDEventTap, event); + // Include deltas so some 3D applications can consume changes (game cameras, etc) + const double deltaX = raw_location.x - previous_location.x; + const double deltaY = raw_location.y - previous_location.y; + CGEventSetDoubleValueField(event, kCGMouseEventDeltaX, deltaX); + CGEventSetDoubleValueField(event, kCGMouseEventDeltaY, deltaY); - // For why this is here, see: - // https://stackoverflow.com/questions/15194409/simulated-mouseevent-not-working-properly-osx - CGWarpMouseCursorPosition(location); + CGEventPost(kCGHIDEventTap, event); } inline CGEventType event_type_mouse(input_t &input) { - auto macos_input = ((macos_input_t *) input.get()); + const auto macos_input = static_cast(input.get()); if (macos_input->mouse_down[0]) { return kCGEventLeftMouseDragged; } - else if (macos_input->mouse_down[1]) { + if (macos_input->mouse_down[1]) { return kCGEventOtherMouseDragged; } - else if (macos_input->mouse_down[2]) { + if (macos_input->mouse_down[2]) { return kCGEventRightMouseDragged; } - else { - return kCGEventMouseMoved; - } + return kCGEventMouseMoved; } void - move_mouse(input_t &input, int deltaX, int deltaY) { - auto current = get_mouse_loc(input); - - CGPoint location = CGPointMake(current.x + deltaX, current.y + deltaY); - - post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, 0); + move_mouse( + input_t &input, + const int deltaX, + const int deltaY + ) { + const auto macos_input = static_cast(input.get()); + const auto current = get_mouse_loc(*macos_input); + + const CGPoint location = CGPointMake(current.x + deltaX, current.y + deltaY); + post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, current, 0); } void - abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { - auto macos_input = static_cast(input.get()); - auto scaling = macos_input->displayScaling; - auto display = macos_input->display; + abs_mouse( + input_t &input, + const touch_port_t &touch_port, + const float x, + const float y + ) { + const auto macos_input = static_cast(input.get()); + const auto scaling = macos_input->displayScaling; + const auto display = macos_input->display; CGPoint location = CGPointMake(x * scaling, y * scaling); CGRect display_bounds = CGDisplayBounds(display); // in order to get the correct mouse location for capturing display , we need to add the display bounds to the location location.x += display_bounds.origin.x; location.y += display_bounds.origin.y; - post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, 0); + + post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, get_mouse_loc(*macos_input), 0); } void - button_mouse(input_t &input, int button, bool release) { + button_mouse(input_t &input, const int button, const bool release) { CGMouseButton mac_button; CGEventType event; - auto mouse = ((macos_input_t *) input.get()); + const auto macos_input = static_cast(input.get()); switch (button) { case 1: @@ -413,22 +436,23 @@ const KeyCodeMap kKeyCodesMap[] = { return; } - mouse->mouse_down[mac_button] = !release; + macos_input->mouse_down[mac_button] = !release; // if the last mouse down was less than MULTICLICK_DELAY_MS, we send a double click event - auto now = std::chrono::steady_clock::now(); - if (now < mouse->last_mouse_event[mac_button][release] + MULTICLICK_DELAY_MS) { - post_mouse(input, mac_button, event, get_mouse_loc(input), 2); - } - else { - post_mouse(input, mac_button, event, get_mouse_loc(input), 1); + const auto now = std::chrono::steady_clock::now(); + const auto mouse_position = get_mouse_loc(*macos_input); + + if (now < macos_input->last_mouse_event[mac_button][release] + MULTICLICK_DELAY_MS) { + post_mouse(input, mac_button, event, mouse_position, mouse_position, 2); + } else { + post_mouse(input, mac_button, event, mouse_position, mouse_position, 1); } - mouse->last_mouse_event[mac_button][release] = now; + macos_input->last_mouse_event[mac_button][release] = now; } void - scroll(input_t &input, int high_res_distance) { + scroll(input_t &input, const int high_res_distance) { CGEventRef upEvent = CGEventCreateScrollWheelEvent( nullptr, kCGScrollEventUnitLine, @@ -509,7 +533,7 @@ const KeyCodeMap kKeyCodesMap[] = { input() { input_t result { new macos_input_t() }; - auto macos_input = (macos_input_t *) result.get(); + const auto macos_input = static_cast(result.get()); // Default to main display macos_input->display = CGMainDisplayID(); @@ -534,7 +558,7 @@ const KeyCodeMap kKeyCodesMap[] = { } // Input coordinates are based on the virtual resolution not the physical, so we need the scaling factor - CGDisplayModeRef mode = CGDisplayCopyDisplayMode(macos_input->display); + const CGDisplayModeRef mode = CGDisplayCopyDisplayMode(macos_input->display); macos_input->displayScaling = ((CGFloat) CGDisplayPixelsWide(macos_input->display)) / ((CGFloat) CGDisplayModeGetPixelWidth(mode)); CFRelease(mode); @@ -555,7 +579,7 @@ const KeyCodeMap kKeyCodesMap[] = { void freeInput(void *p) { - auto *input = (macos_input_t *) p; + const auto *input = static_cast(p); CFRelease(input->source); CFRelease(input->kb_event); From e3afb4b6091dfc6e6938ca8e9c90c73d84c591dd Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 08:01:26 -0300 Subject: [PATCH 02/22] chore(macos): make mouse tests pass --- src/platform/common.h | 12 ++++++++ src/platform/macos/input.cpp | 29 ++++++++++-------- src/utility.h | 5 ++++ tests/unit/test_input.cpp | 58 ++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 12 deletions(-) create mode 100644 tests/unit/test_input.cpp diff --git a/src/platform/common.h b/src/platform/common.h index 007f7ece61b..1960d829878 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -672,6 +672,18 @@ namespace platf { input_t input(); + /** + * @brief Gets the current mouse position on screen + * @param input The input_t instance to use. + * @return util::point_t (x, y) + * + * EXAMPLES: + * ```cpp + * auto [x, y] = get_mouse_loc(input); + * ``` + */ + util::point_t + get_mouse_loc(input_t &input); void move_mouse(input_t &input, int deltaX, int deltaY); void diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index 7683422e72b..b7151cee927 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -2,6 +2,8 @@ * @file src/platform/macos/input.cpp * @brief todo */ +#include "src/input.h" + #import #include #include @@ -315,13 +317,17 @@ const KeyCodeMap kKeyCodesMap[] = { } // returns current mouse location: - inline CGPoint - get_mouse_loc(const macos_input_t &input) { + inline util::point_t + get_mouse_loc(input_t &input) { // Creating a new event every time to avoid any reuse risk - const auto snapshot_event = CGEventCreate(input.source); + const auto macos_input = static_cast(input.get()); + const auto snapshot_event = CGEventCreate(macos_input->source); const auto current = CGEventGetLocation(snapshot_event); CFRelease(snapshot_event); - return current; + return util::point_t { + current.x, + current.y + }; } void @@ -329,8 +335,8 @@ const KeyCodeMap kKeyCodesMap[] = { input_t &input, const CGMouseButton button, const CGEventType type, - const CGPoint raw_location, - const CGPoint previous_location, + const util::point_t raw_location, + const util::point_t previous_location, const int click_count ) { BOOST_LOG(debug) << "mouse_event: "sv << button << ", type: "sv << type << ", location:"sv << raw_location.x << ":"sv << raw_location.y << " click_count: "sv << click_count; @@ -384,10 +390,9 @@ const KeyCodeMap kKeyCodesMap[] = { const int deltaX, const int deltaY ) { - const auto macos_input = static_cast(input.get()); - const auto current = get_mouse_loc(*macos_input); + const auto current = get_mouse_loc(input); - const CGPoint location = CGPointMake(current.x + deltaX, current.y + deltaY); + const auto location = util::point_t { current.x + deltaX, current.y + deltaY }; post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, current, 0); } @@ -402,13 +407,13 @@ const KeyCodeMap kKeyCodesMap[] = { const auto scaling = macos_input->displayScaling; const auto display = macos_input->display; - CGPoint location = CGPointMake(x * scaling, y * scaling); + auto location = util::point_t { x * scaling, y * scaling }; CGRect display_bounds = CGDisplayBounds(display); // in order to get the correct mouse location for capturing display , we need to add the display bounds to the location location.x += display_bounds.origin.x; location.y += display_bounds.origin.y; - post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, get_mouse_loc(*macos_input), 0); + post_mouse(input, kCGMouseButtonLeft, event_type_mouse(input), location, get_mouse_loc(input), 0); } void @@ -440,7 +445,7 @@ const KeyCodeMap kKeyCodesMap[] = { // if the last mouse down was less than MULTICLICK_DELAY_MS, we send a double click event const auto now = std::chrono::steady_clock::now(); - const auto mouse_position = get_mouse_loc(*macos_input); + const auto mouse_position = get_mouse_loc(input); if (now < macos_input->last_mouse_event[mac_button][release] + MULTICLICK_DELAY_MS) { post_mouse(input, mac_button, event, mouse_position, mouse_position, 2); diff --git a/src/utility.h b/src/utility.h index 3ed321203c2..d0b08a103f2 100644 --- a/src/utility.h +++ b/src/utility.h @@ -940,6 +940,11 @@ namespace util { return std::string_view((const char *) &data, sizeof(T)); } + struct point_t { + double x; + double y; + }; + namespace endian { template struct endianness { diff --git a/tests/unit/test_input.cpp b/tests/unit/test_input.cpp new file mode 100644 index 00000000000..43f848dd6f9 --- /dev/null +++ b/tests/unit/test_input.cpp @@ -0,0 +1,58 @@ +/** + * @file tests/test_input.cpp + * @brief Test src/input.*. + */ +#include +#include + +#include + +TEST(InputTest, MoveInputTest) { + platf::input_t input = platf::input(); + + auto old_loc = platf::get_mouse_loc(input); + + platf::move_mouse(input, 40, 40); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + auto new_loc = platf::get_mouse_loc(input); + + bool has_input_moved = old_loc.x != new_loc.x && old_loc.y != new_loc.y; + + if (!has_input_moved) { + std::cout << "InputTest:: haven't moved" << std::endl; + } else { + std::cout << "InputTest:: moved" << std::endl; + } + + EXPECT_TRUE(has_input_moved); + + // Verify we moved as much as we requested + EXPECT_TRUE(new_loc.x - old_loc.x == 40); + EXPECT_TRUE(new_loc.y - old_loc.y == 40); +} + +TEST(InputTest, AbsMoveInputTest) { + platf::input_t input = platf::input(); + + auto old_loc = platf::get_mouse_loc(input); + + platf::abs_mouse(input, platf::touch_port_t {}, 40, 40); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + auto new_loc = platf::get_mouse_loc(input); + + bool has_input_moved = old_loc.x != new_loc.x && old_loc.y != new_loc.y; + + if (!has_input_moved) { + std::cout << "InputTest:: haven't moved" << std::endl; + } else { + std::cout << "InputTest:: moved" << std::endl; + } + + EXPECT_TRUE(has_input_moved); + + // Verify we moved to the absolute coordinate + EXPECT_TRUE(new_loc.x == 40); + EXPECT_TRUE(new_loc.y == 40); +} \ No newline at end of file From 89cc08ada4888a57b085f0538b598b18eeebc5fe Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 08:02:09 -0300 Subject: [PATCH 03/22] feat: implements windows and linux get_mouse_loc --- src/platform/linux/input.cpp | 29 ++++++++++++ src/platform/windows/input.cpp | 17 +++++++ tests/unit/test_input.cpp | 58 ------------------------ tests/unit/test_mouse.cpp | 83 ++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 58 deletions(-) delete mode 100644 tests/unit/test_input.cpp create mode 100644 tests/unit/test_mouse.cpp diff --git a/src/platform/linux/input.cpp b/src/platform/linux/input.cpp index 14ee50fe70b..181fe1e8e99 100644 --- a/src/platform/linux/input.cpp +++ b/src/platform/linux/input.cpp @@ -1098,6 +1098,35 @@ namespace platf { #endif } + util::point_t + get_mouse_loc(input_t &input) { +#ifdef SUNSHINE_BUILD_X11 + Display *xdisplay = ((input_raw_t *) input.get())->display; + if (!xdisplay) { + return util::point_t { }; + } + Window root, root_return, child_return; + root = DefaultRootWindow(display); + int root_x, root_y; + int win_x, win_y; + unsigned int mask_return; + + if (XQueryPointer(display, root, &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask_return)) { + BOOST_LOG(debug) + << "Pointer is at:"sv << std::endl + << " x: " << root_x << std::endl + << " y: " << root_y << std::endl; + + return util::point_t { (double)root_x, (double)root_y }; + } else { + BOOST_LOG(debug) << "Unable to query x11 pointer"sv << std::endl; + } +#else + BOOST_LOG(debug) << "Unable to query wayland pointer"sv << std::endl; +#endif + return util::point_t { }; + } + /** * @brief Absolute mouse move. * @param input The input_t instance to use. diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index dfc9852f586..15c22fc1d00 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -542,6 +542,23 @@ namespace platf { send_input(i); } + inline util::point_t + get_mouse_loc(input_t &input) { + INPUT i {}; + + i.type = INPUT_MOUSE; + auto &mi = i.mi; + mi.dwFlags = + MOUSEEVENTF_ABSOLUTE | + + // MOUSEEVENTF_VIRTUALDESK maps to the entirety of the desktop rather than the primary desktop + MOUSEEVENTF_VIRTUALDESK; + return util::point_t { + mi.dx, + mi.dy + }; + } + void button_mouse(input_t &input, int button, bool release) { INPUT i {}; diff --git a/tests/unit/test_input.cpp b/tests/unit/test_input.cpp deleted file mode 100644 index 43f848dd6f9..00000000000 --- a/tests/unit/test_input.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file tests/test_input.cpp - * @brief Test src/input.*. - */ -#include -#include - -#include - -TEST(InputTest, MoveInputTest) { - platf::input_t input = platf::input(); - - auto old_loc = platf::get_mouse_loc(input); - - platf::move_mouse(input, 40, 40); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - - auto new_loc = platf::get_mouse_loc(input); - - bool has_input_moved = old_loc.x != new_loc.x && old_loc.y != new_loc.y; - - if (!has_input_moved) { - std::cout << "InputTest:: haven't moved" << std::endl; - } else { - std::cout << "InputTest:: moved" << std::endl; - } - - EXPECT_TRUE(has_input_moved); - - // Verify we moved as much as we requested - EXPECT_TRUE(new_loc.x - old_loc.x == 40); - EXPECT_TRUE(new_loc.y - old_loc.y == 40); -} - -TEST(InputTest, AbsMoveInputTest) { - platf::input_t input = platf::input(); - - auto old_loc = platf::get_mouse_loc(input); - - platf::abs_mouse(input, platf::touch_port_t {}, 40, 40); - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - - auto new_loc = platf::get_mouse_loc(input); - - bool has_input_moved = old_loc.x != new_loc.x && old_loc.y != new_loc.y; - - if (!has_input_moved) { - std::cout << "InputTest:: haven't moved" << std::endl; - } else { - std::cout << "InputTest:: moved" << std::endl; - } - - EXPECT_TRUE(has_input_moved); - - // Verify we moved to the absolute coordinate - EXPECT_TRUE(new_loc.x == 40); - EXPECT_TRUE(new_loc.y == 40); -} \ No newline at end of file diff --git a/tests/unit/test_mouse.cpp b/tests/unit/test_mouse.cpp new file mode 100644 index 00000000000..5f86ebe5ecf --- /dev/null +++ b/tests/unit/test_mouse.cpp @@ -0,0 +1,83 @@ +/** + * @file tests/test_mouse.cpp + * @brief Test src/input.*. + */ +#include +#include + +#include + +class MouseTest: public virtual BaseTest, public ::testing::WithParamInterface { +protected: + void + SetUp() override { + BaseTest::SetUp(); + } + + void + TearDown() override { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + BaseTest::TearDown(); + } +}; +INSTANTIATE_TEST_SUITE_P( + MouseInputs, + MouseTest, + ::testing::Values( + util::point_t { 40, 40 }, + util::point_t { 70, 150 } + )); + +TEST_P(MouseTest, MoveInputTest) { + util::point_t mouse_delta = GetParam(); + + platf::input_t input = platf::input(); + + auto old_loc = platf::get_mouse_loc(input); + + platf::move_mouse(input, mouse_delta.x, mouse_delta.y); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + auto new_loc = platf::get_mouse_loc(input); + + bool has_input_moved = old_loc.x != new_loc.x && old_loc.y != new_loc.y; + + if (!has_input_moved) { + std::cout << "MouseTest:: haven't moved" << std::endl; + } else { + std::cout << "MouseTest:: moved" << std::endl; + } + + EXPECT_TRUE(has_input_moved); + + // Verify we moved as much as we requested + EXPECT_EQ(new_loc.x - old_loc.x, mouse_delta.x); + EXPECT_EQ(new_loc.y - old_loc.y, mouse_delta.y); +} + +TEST_P(MouseTest, AbsMoveInputTest) { + util::point_t mouse_pos = GetParam(); + + platf::input_t input = platf::input(); + + auto old_loc = platf::get_mouse_loc(input); + + platf::abs_mouse(input, platf::touch_port_t {}, mouse_pos.x, mouse_pos.y); + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + + auto new_loc = platf::get_mouse_loc(input); + + bool has_input_moved = old_loc.x != new_loc.x || old_loc.y != new_loc.y; + + if (!has_input_moved) { + std::cout << "MouseTest:: haven't moved" << std::endl; + } else { + std::cout << "MouseTest:: moved" << std::endl; + } + + EXPECT_TRUE(has_input_moved); + + // Verify we moved to the absolute coordinate + EXPECT_EQ(new_loc.x, mouse_pos.x); + EXPECT_EQ(new_loc.y, mouse_pos.y); +} \ No newline at end of file From d1c09d154c57e284663b519a684079e4e97c12d0 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 09:15:05 -0300 Subject: [PATCH 04/22] chore: improve test readability --- src/utility.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/utility.h b/src/utility.h index d0b08a103f2..1fd99b8cd25 100644 --- a/src/utility.h +++ b/src/utility.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -943,6 +944,10 @@ namespace util { struct point_t { double x; double y; + + friend std::ostream& operator << (std::ostream &os, const point_t &p) { + return (os << "Point(x: " << p.x << ", y: " << p.y << ")"); + } }; namespace endian { From b34bc26dc8c7725224770847bc4820d4016e19f5 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 09:18:31 -0300 Subject: [PATCH 05/22] fix: tests now correct, except for windows --- src/platform/linux/input.cpp | 4 ++-- src/platform/macos/input.cpp | 2 +- src/platform/windows/input.cpp | 18 +++++++----------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/platform/linux/input.cpp b/src/platform/linux/input.cpp index 181fe1e8e99..0536bed7286 100644 --- a/src/platform/linux/input.cpp +++ b/src/platform/linux/input.cpp @@ -1106,12 +1106,12 @@ namespace platf { return util::point_t { }; } Window root, root_return, child_return; - root = DefaultRootWindow(display); + root = DefaultRootWindow(xdisplay); int root_x, root_y; int win_x, win_y; unsigned int mask_return; - if (XQueryPointer(display, root, &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask_return)) { + if (XQueryPointer(xdisplay, root, &root_return, &child_return, &root_x, &root_y, &win_x, &win_y, &mask_return)) { BOOST_LOG(debug) << "Pointer is at:"sv << std::endl << " x: " << root_x << std::endl diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index b7151cee927..10cff080361 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -317,7 +317,7 @@ const KeyCodeMap kKeyCodesMap[] = { } // returns current mouse location: - inline util::point_t + util::point_t get_mouse_loc(input_t &input) { // Creating a new event every time to avoid any reuse risk const auto macos_input = static_cast(input.get()); diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 15c22fc1d00..3a1e39b8140 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -542,20 +542,16 @@ namespace platf { send_input(i); } - inline util::point_t + util::point_t get_mouse_loc(input_t &input) { - INPUT i {}; - - i.type = INPUT_MOUSE; - auto &mi = i.mi; - mi.dwFlags = - MOUSEEVENTF_ABSOLUTE | + POINT p; + if (!GetCursorPos(&p)) { + return util::point_t { 0.0, 0.0 }; + } - // MOUSEEVENTF_VIRTUALDESK maps to the entirety of the desktop rather than the primary desktop - MOUSEEVENTF_VIRTUALDESK; return util::point_t { - mi.dx, - mi.dy + (double) p.x, + (double) p.y }; } From 64acda3b508df93ac7d41105a13685626a993fe1 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 13:01:00 -0300 Subject: [PATCH 06/22] chore: test alternative abs_mouse method --- src/platform/windows/input.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 3a1e39b8140..3311264f06b 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -506,7 +506,7 @@ namespace platf { } void - abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { + abs_mouse2(input_t &input, const touch_port_t &touch_port, float x, float y) { INPUT i {}; i.type = INPUT_MOUSE; @@ -528,6 +528,17 @@ namespace platf { send_input(i); } + void + abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { + INPUT i {}; + i.type = INPUT_MOUSE; + auto &mi = i.mi; + mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + mi.dx = (x * 65535) / GetSystemMetrics(SM_CXSCREEN); + mi.dy = (y * 65535) / GetSystemMetrics(SM_CYSCREEN); + send_input(i); + } + void move_mouse(input_t &input, int deltaX, int deltaY) { INPUT i {}; @@ -535,7 +546,7 @@ namespace platf { i.type = INPUT_MOUSE; auto &mi = i.mi; - mi.dwFlags = MOUSEEVENTF_MOVE; + mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; mi.dx = deltaX; mi.dy = deltaY; @@ -544,6 +555,7 @@ namespace platf { util::point_t get_mouse_loc(input_t &input) { + syncThreadDesktop(); POINT p; if (!GetCursorPos(&p)) { return util::point_t { 0.0, 0.0 }; From 8a980818f5267e62d45472f73bced8fb3cfbdea9 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 14:44:55 -0300 Subject: [PATCH 07/22] chore: back to original abs_mouse method --- src/platform/windows/input.cpp | 4 +++- tests/unit/test_mouse.cpp | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 3311264f06b..c1c25a649a0 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -506,7 +506,7 @@ namespace platf { } void - abs_mouse2(input_t &input, const touch_port_t &touch_port, float x, float y) { + abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { INPUT i {}; i.type = INPUT_MOUSE; @@ -528,6 +528,7 @@ namespace platf { send_input(i); } +/** void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { INPUT i {}; @@ -538,6 +539,7 @@ namespace platf { mi.dy = (y * 65535) / GetSystemMetrics(SM_CYSCREEN); send_input(i); } + */ void move_mouse(input_t &input, int deltaX, int deltaY) { diff --git a/tests/unit/test_mouse.cpp b/tests/unit/test_mouse.cpp index 5f86ebe5ecf..8ad06bbcaef 100644 --- a/tests/unit/test_mouse.cpp +++ b/tests/unit/test_mouse.cpp @@ -62,7 +62,20 @@ TEST_P(MouseTest, AbsMoveInputTest) { auto old_loc = platf::get_mouse_loc(input); - platf::abs_mouse(input, platf::touch_port_t {}, mouse_pos.x, mouse_pos.y); + #ifdef _WIN32 + platf::touch_port_t abs_port { + 0, 0, + 65535, 65535 + }; + #elif __linux__ + platf::touch_port_t abs_port { + 0, 0, + 19200, 12000 + }; + #else + platf::touch_port_t abs_port { }; + #endif + platf::abs_mouse(input, abs_port, mouse_pos.x, mouse_pos.y); std::this_thread::sleep_for(std::chrono::milliseconds(200)); auto new_loc = platf::get_mouse_loc(input); From 06967a9e97d02ba82ffa0d4c7dfbf6080651eb4f Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 21 May 2024 15:28:49 -0300 Subject: [PATCH 08/22] build: skip mouse test windows --- src/platform/windows/input.cpp | 8 ++++++-- tests/unit/test_mouse.cpp | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index c1c25a649a0..b99ab463daa 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -529,6 +529,8 @@ namespace platf { } /** +* // TODO: This method seems to work better during tests, + but it doesn't seem to cover the same features as the original method void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { INPUT i {}; @@ -548,7 +550,8 @@ namespace platf { i.type = INPUT_MOUSE; auto &mi = i.mi; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; + // mi.dwFlags = MOUSEEVENTF_MOVE; + mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; // TODO: Not sure if needed mi.dx = deltaX; mi.dy = deltaY; @@ -557,7 +560,8 @@ namespace platf { util::point_t get_mouse_loc(input_t &input) { - syncThreadDesktop(); + // TODO: Tests are failing, something wrong here? + // syncThreadDesktop(); POINT p; if (!GetCursorPos(&p)) { return util::point_t { 0.0, 0.0 }; diff --git a/tests/unit/test_mouse.cpp b/tests/unit/test_mouse.cpp index 8ad06bbcaef..6a4925e35fb 100644 --- a/tests/unit/test_mouse.cpp +++ b/tests/unit/test_mouse.cpp @@ -12,6 +12,12 @@ class MouseTest: public virtual BaseTest, public ::testing::WithParamInterface Date: Tue, 21 May 2024 16:05:44 -0300 Subject: [PATCH 09/22] build: fix platform call in tests --- tests/unit/test_mouse.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_mouse.cpp b/tests/unit/test_mouse.cpp index 6a4925e35fb..d6238648d32 100644 --- a/tests/unit/test_mouse.cpp +++ b/tests/unit/test_mouse.cpp @@ -7,22 +7,24 @@ #include -class MouseTest: public virtual BaseTest, public ::testing::WithParamInterface { +class MouseTest: public virtual BaseTest, public PlatformInitBase, public ::testing::WithParamInterface { protected: void SetUp() override { BaseTest::SetUp(); + PlatformInitBase::SetUp(); #ifdef _WIN32 // TODO: Windows tests are failing, `get_mouse_loc` seems broken and `platf::abs_mouse` too // the alternative `platf::abs_mouse` method seem to work better during tests, // but I'm not sure about real work - GTEST_SKIP_((std::string("MouseTest:: skipped for now. TODO Windows").c_str()); + GTEST_SKIP_("MouseTest:: skipped for now. TODO Windows"); #endif } void TearDown() override { std::this_thread::sleep_for(std::chrono::milliseconds(200)); + PlatformInitBase::TearDown(); BaseTest::TearDown(); } }; @@ -31,9 +33,8 @@ INSTANTIATE_TEST_SUITE_P( MouseTest, ::testing::Values( util::point_t { 40, 40 }, - util::point_t { 70, 150 } + util::point_t { 70, 150 })); // todo: add tests for hitting screen edges - )); TEST_P(MouseTest, MoveInputTest) { util::point_t mouse_delta = GetParam(); From 25c528296e58f1228d809cc7e42fcf9c26d147c2 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Wed, 22 May 2024 13:14:06 -0300 Subject: [PATCH 10/22] ci: accessibility permission --- .github/workflows/CI.yml | 60 ++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5681797cb76..1560061b303 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -733,40 +733,52 @@ jobs: name: sunshine-macports path: artifacts/ - - name: Fix screen capture permissions - if: ${{ matrix.os_version != 12 }} # macOS-12 is okay - # can be removed if the following is fixed in the runner image - # https://github.com/actions/runner-images/issues/9529 - # https://github.com/actions/runner-images/pull/9530 + - name: Fix permissions run: | # https://apple.stackexchange.com/questions/362865/macos-list-apps-authorized-for-full-disk-access - - # permissions for screen capture - values="'kTCCServiceScreenCapture','/opt/off/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159" + # https://github.com/actions/runner-images/issues/9529 + # https://github.com/actions/runner-images/pull/9530 + + # function to execute sql query for each value + function execute_sql_query { + local value=$1 + local dbPath=$2 + + echo "Executing SQL query for value: $value" + sudo sqlite3 "$dbPath" "INSERT OR IGNORE INTO access VALUES($value);" + } + + # permissions + declare -a values=( + "'kTCCServiceAccessibility','/opt/off/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,NULL,1592919552" + "'kTCCServiceScreenCapture','/opt/off/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159" + ) if [[ "${{ matrix.os_version }}" == "14" ]]; then # TCC access table in Sonoma has extra 4 columns: pid, pid_version, boot_uuid, last_reminded - values="${values},NULL,NULL,'UNUSED',${values##*,}" + for i in "${!values[@]}"; do + values[$i]="${values[$i]},NULL,NULL,'UNUSED',${values[$i]##*,}" + done fi - + # system and user databases dbPaths=( "/Library/Application Support/com.apple.TCC/TCC.db" "$HOME/Library/Application Support/com.apple.TCC/TCC.db" ) - - sqlQuery="INSERT OR IGNORE INTO access VALUES($values);" - - for dbPath in "${dbPaths[@]}"; do - echo "Column names for $dbPath" - echo "-------------------" - sudo sqlite3 "$dbPath" "PRAGMA table_info(access);" - echo "Current permissions for $dbPath" - echo "-------------------" - sudo sqlite3 "$dbPath" "SELECT * FROM access WHERE service='kTCCServiceScreenCapture';" - sudo sqlite3 "$dbPath" "$sqlQuery" - echo "Updated permissions for $dbPath" - echo "-------------------" - sudo sqlite3 "$dbPath" "SELECT * FROM access WHERE service='kTCCServiceScreenCapture';" + + for value in "${values[@]}"; do + for dbPath in "${dbPaths[@]}"; do + echo "Column names for $dbPath" + echo "-------------------" + sudo sqlite3 "$dbPath" "PRAGMA table_info(access);" + echo "Current permissions for $dbPath" + echo "-------------------" + sudo sqlite3 "$dbPath" "SELECT * FROM access WHERE service='kTCCServiceScreenCapture';" + execute_sql_query "$value" "$dbPath" + echo "Updated permissions for $dbPath" + echo "-------------------" + sudo sqlite3 "$dbPath" "SELECT * FROM access WHERE service='kTCCServiceScreenCapture';" + done done - name: Run tests From 787e74ab2e1775c24bdf38983a0acdc975064c5f Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Wed, 22 May 2024 13:24:48 -0300 Subject: [PATCH 11/22] ci: lint remove trailing spaces --- .github/workflows/CI.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1560061b303..de6de79b181 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -738,16 +738,16 @@ jobs: # https://apple.stackexchange.com/questions/362865/macos-list-apps-authorized-for-full-disk-access # https://github.com/actions/runner-images/issues/9529 # https://github.com/actions/runner-images/pull/9530 - + # function to execute sql query for each value function execute_sql_query { local value=$1 local dbPath=$2 - + echo "Executing SQL query for value: $value" sudo sqlite3 "$dbPath" "INSERT OR IGNORE INTO access VALUES($value);" } - + # permissions declare -a values=( "'kTCCServiceAccessibility','/opt/off/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,NULL,1592919552" @@ -759,13 +759,13 @@ jobs: values[$i]="${values[$i]},NULL,NULL,'UNUSED',${values[$i]##*,}" done fi - + # system and user databases dbPaths=( "/Library/Application Support/com.apple.TCC/TCC.db" "$HOME/Library/Application Support/com.apple.TCC/TCC.db" ) - + for value in "${values[@]}"; do for dbPath in "${dbPaths[@]}"; do echo "Column names for $dbPath" From 4f4a040b91a2971a32d875881a723c50d45328ac Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Wed, 22 May 2024 14:52:59 -0300 Subject: [PATCH 12/22] chore: improve test logs --- src/platform/macos/input.cpp | 9 ++++++++- tests/unit/test_mouse.cpp | 34 +++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index 10cff080361..21956c42829 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -12,6 +12,13 @@ #include "src/platform/common.h" #include "src/utility.h" +#include +#include +#include +#include +#include +#include + /** * @brief Delay for a double click, in milliseconds. * @todo Make this configurable. @@ -350,7 +357,7 @@ const KeyCodeMap kKeyCodesMap[] = { // limit mouse to current display bounds const auto location = CGPoint { - std::clamp(raw_location.x, display_bounds.origin.x, display_bounds.origin.x + display_bounds.size.width - 1), + std::clamp(raw_location.x, display_bounds.origin.x, display_bounds.origin.x + display_bounds.size.width - 1), std::clamp(raw_location.y, display_bounds.origin.y, display_bounds.origin.y + display_bounds.size.height - 1) }; diff --git a/tests/unit/test_mouse.cpp b/tests/unit/test_mouse.cpp index d6238648d32..f60f3ffc5b8 100644 --- a/tests/unit/test_mouse.cpp +++ b/tests/unit/test_mouse.cpp @@ -7,7 +7,7 @@ #include -class MouseTest: public virtual BaseTest, public PlatformInitBase, public ::testing::WithParamInterface { +class MouseHIDTest: public virtual BaseTest, public PlatformInitBase, public ::testing::WithParamInterface { protected: void SetUp() override { @@ -30,30 +30,38 @@ class MouseTest: public virtual BaseTest, public PlatformInitBase, public ::test }; INSTANTIATE_TEST_SUITE_P( MouseInputs, - MouseTest, + MouseHIDTest, ::testing::Values( util::point_t { 40, 40 }, util::point_t { 70, 150 })); // todo: add tests for hitting screen edges -TEST_P(MouseTest, MoveInputTest) { +TEST_P(MouseHIDTest, MoveInputTest) { util::point_t mouse_delta = GetParam(); + std::cout << "MoveInputTest:: got param: " << mouse_delta << std::endl; platf::input_t input = platf::input(); + std::cout << "MoveInputTest:: init input" << std::endl; + std::cout << "MoveInputTest:: get current mouse loc" << std::endl; auto old_loc = platf::get_mouse_loc(input); + std::cout << "MoveInputTest:: got current mouse loc: " << old_loc << std::endl; + std::cout << "MoveInputTest:: move: " << mouse_delta << std::endl; platf::move_mouse(input, mouse_delta.x, mouse_delta.y); std::this_thread::sleep_for(std::chrono::milliseconds(200)); + std::cout << "MoveInputTest:: moved: " << mouse_delta << std::endl; + std::cout << "MoveInputTest:: get updated mouse loc" << std::endl; auto new_loc = platf::get_mouse_loc(input); + std::cout << "MoveInputTest:: got updated mouse loc: " << new_loc << std::endl; bool has_input_moved = old_loc.x != new_loc.x && old_loc.y != new_loc.y; if (!has_input_moved) { - std::cout << "MouseTest:: haven't moved" << std::endl; + std::cout << "MoveInputTest:: haven't moved" << std::endl; } else { - std::cout << "MouseTest:: moved" << std::endl; + std::cout << "MoveInputTest:: moved" << std::endl; } EXPECT_TRUE(has_input_moved); @@ -63,12 +71,16 @@ TEST_P(MouseTest, MoveInputTest) { EXPECT_EQ(new_loc.y - old_loc.y, mouse_delta.y); } -TEST_P(MouseTest, AbsMoveInputTest) { +TEST_P(MouseHIDTest, AbsMoveInputTest) { util::point_t mouse_pos = GetParam(); + std::cout << "AbsMoveInputTest:: got param: " << mouse_pos << std::endl; platf::input_t input = platf::input(); + std::cout << "AbsMoveInputTest:: init input" << std::endl; + std::cout << "AbsMoveInputTest:: get current mouse loc" << std::endl; auto old_loc = platf::get_mouse_loc(input); + std::cout << "AbsMoveInputTest:: got current mouse loc: " << old_loc << std::endl; #ifdef _WIN32 platf::touch_port_t abs_port { @@ -83,17 +95,21 @@ TEST_P(MouseTest, AbsMoveInputTest) { #else platf::touch_port_t abs_port { }; #endif + std::cout << "AbsMoveInputTest:: move: " << mouse_pos << std::endl; platf::abs_mouse(input, abs_port, mouse_pos.x, mouse_pos.y); std::this_thread::sleep_for(std::chrono::milliseconds(200)); + std::cout << "AbsMoveInputTest:: moved: " << mouse_pos << std::endl; + std::cout << "AbsMoveInputTest:: get updated mouse loc" << std::endl; auto new_loc = platf::get_mouse_loc(input); + std::cout << "AbsMoveInputTest:: got updated mouse loc: " << new_loc << std::endl; bool has_input_moved = old_loc.x != new_loc.x || old_loc.y != new_loc.y; if (!has_input_moved) { - std::cout << "MouseTest:: haven't moved" << std::endl; + std::cout << "AbsMoveInputTest:: haven't moved" << std::endl; } else { - std::cout << "MouseTest:: moved" << std::endl; + std::cout << "AbsMoveInputTest:: moved" << std::endl; } EXPECT_TRUE(has_input_moved); @@ -101,4 +117,4 @@ TEST_P(MouseTest, AbsMoveInputTest) { // Verify we moved to the absolute coordinate EXPECT_EQ(new_loc.x, mouse_pos.x); EXPECT_EQ(new_loc.y, mouse_pos.y); -} \ No newline at end of file +} From 89a32ec9290edeb843221d32d0d221afcd1d043d Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Thu, 23 May 2024 03:32:08 -0300 Subject: [PATCH 13/22] fix(ci): skip tests that can block macports thread --- packaging/macos/Portfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/macos/Portfile b/packaging/macos/Portfile index e0cc9ef34f6..baf59b36be9 100644 --- a/packaging/macos/Portfile +++ b/packaging/macos/Portfile @@ -77,4 +77,4 @@ test.run yes test.dir ${build.dir}/tests test.target "" test.cmd ./test_sunshine -test.args --gtest_color=yes +test.args --gtest_color=yes --gtest_filter=-*HIDTest.*:-*DeathTest.* From e422d7c7060a70d05db6719734cdbb0a173d37bb Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Thu, 23 May 2024 04:15:31 -0300 Subject: [PATCH 14/22] fix(ci): tests running directly on macports --- .github/workflows/CI.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index de6de79b181..b023d2453a6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -781,16 +781,20 @@ jobs: done done - - name: Run tests + - name: Run tests directly id: test timeout-minutes: 10 + working-directory: + /opt/local/var/macports/build/_Users_runner_work_Sunshine_Sunshine_ports_multimedia_Sunshine/Sunshine/work/build/tests run: | - sudo port test "Sunshine" + sudo port install doxygen + sudo port install graphviz + sudo ./test_sunshine --gtest_color=yes - name: Test Logs if: always() run: | - logfile="/opt/local/var/macports/logs/_Users_runner_work_Sunshine_Sunshine_ports_multimedia_Sunshine/Sunshine/main.log" + logfile="/opt/local/var/macports/build/_Users_runner_work_Sunshine_Sunshine_ports_multimedia_Sunshine/Sunshine/work/build/tests/test.log" cat "$logfile" - name: Generate gcov report From 36e6bc218b0bfeaa56075689f1510f34aaa6f998 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Thu, 23 May 2024 06:43:20 -0300 Subject: [PATCH 15/22] chore: lint fixes --- src/platform/linux/input.cpp | 9 +++++---- src/platform/macos/input.cpp | 18 +++++++----------- src/platform/windows/input.cpp | 6 +++--- src/utility.h | 3 ++- tests/unit/test_mouse.cpp | 18 ++++++++++-------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/platform/linux/input.cpp b/src/platform/linux/input.cpp index 0536bed7286..4af7c568eee 100644 --- a/src/platform/linux/input.cpp +++ b/src/platform/linux/input.cpp @@ -1103,7 +1103,7 @@ namespace platf { #ifdef SUNSHINE_BUILD_X11 Display *xdisplay = ((input_raw_t *) input.get())->display; if (!xdisplay) { - return util::point_t { }; + return util::point_t {}; } Window root, root_return, child_return; root = DefaultRootWindow(xdisplay); @@ -1117,14 +1117,15 @@ namespace platf { << " x: " << root_x << std::endl << " y: " << root_y << std::endl; - return util::point_t { (double)root_x, (double)root_y }; - } else { + return util::point_t { (double) root_x, (double) root_y }; + } + else { BOOST_LOG(debug) << "Unable to query x11 pointer"sv << std::endl; } #else BOOST_LOG(debug) << "Unable to query wayland pointer"sv << std::endl; #endif - return util::point_t { }; + return util::point_t {}; } /** diff --git a/src/platform/macos/input.cpp b/src/platform/macos/input.cpp index 21956c42829..ec2822ad356 100644 --- a/src/platform/macos/input.cpp +++ b/src/platform/macos/input.cpp @@ -12,12 +12,10 @@ #include "src/platform/common.h" #include "src/utility.h" +#include +#include #include #include -#include -#include -#include -#include /** * @brief Delay for a double click, in milliseconds. @@ -344,8 +342,7 @@ const KeyCodeMap kKeyCodesMap[] = { const CGEventType type, const util::point_t raw_location, const util::point_t previous_location, - const int click_count - ) { + const int click_count) { BOOST_LOG(debug) << "mouse_event: "sv << button << ", type: "sv << type << ", location:"sv << raw_location.x << ":"sv << raw_location.y << " click_count: "sv << click_count; const auto macos_input = static_cast(input.get()); @@ -395,8 +392,7 @@ const KeyCodeMap kKeyCodesMap[] = { move_mouse( input_t &input, const int deltaX, - const int deltaY - ) { + const int deltaY) { const auto current = get_mouse_loc(input); const auto location = util::point_t { current.x + deltaX, current.y + deltaY }; @@ -408,8 +404,7 @@ const KeyCodeMap kKeyCodesMap[] = { input_t &input, const touch_port_t &touch_port, const float x, - const float y - ) { + const float y) { const auto macos_input = static_cast(input.get()); const auto scaling = macos_input->displayScaling; const auto display = macos_input->display; @@ -456,7 +451,8 @@ const KeyCodeMap kKeyCodesMap[] = { if (now < macos_input->last_mouse_event[mac_button][release] + MULTICLICK_DELAY_MS) { post_mouse(input, mac_button, event, mouse_position, mouse_position, 2); - } else { + } + else { post_mouse(input, mac_button, event, mouse_position, mouse_position, 1); } diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index b99ab463daa..c919674963b 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -528,8 +528,8 @@ namespace platf { send_input(i); } -/** -* // TODO: This method seems to work better during tests, + /** + * // TODO: This method seems to work better during tests, but it doesn't seem to cover the same features as the original method void abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { @@ -551,7 +551,7 @@ namespace platf { auto &mi = i.mi; // mi.dwFlags = MOUSEEVENTF_MOVE; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; // TODO: Not sure if needed + mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; // TODO: Not sure if needed mi.dx = deltaX; mi.dy = deltaY; diff --git a/src/utility.h b/src/utility.h index 1fd99b8cd25..723986c24d8 100644 --- a/src/utility.h +++ b/src/utility.h @@ -945,7 +945,8 @@ namespace util { double x; double y; - friend std::ostream& operator << (std::ostream &os, const point_t &p) { + friend std::ostream & + operator<<(std::ostream &os, const point_t &p) { return (os << "Point(x: " << p.x << ", y: " << p.y << ")"); } }; diff --git a/tests/unit/test_mouse.cpp b/tests/unit/test_mouse.cpp index f60f3ffc5b8..21a3dd428f9 100644 --- a/tests/unit/test_mouse.cpp +++ b/tests/unit/test_mouse.cpp @@ -34,7 +34,7 @@ INSTANTIATE_TEST_SUITE_P( ::testing::Values( util::point_t { 40, 40 }, util::point_t { 70, 150 })); - // todo: add tests for hitting screen edges +// todo: add tests for hitting screen edges TEST_P(MouseHIDTest, MoveInputTest) { util::point_t mouse_delta = GetParam(); @@ -60,7 +60,8 @@ TEST_P(MouseHIDTest, MoveInputTest) { if (!has_input_moved) { std::cout << "MoveInputTest:: haven't moved" << std::endl; - } else { + } + else { std::cout << "MoveInputTest:: moved" << std::endl; } @@ -82,19 +83,19 @@ TEST_P(MouseHIDTest, AbsMoveInputTest) { auto old_loc = platf::get_mouse_loc(input); std::cout << "AbsMoveInputTest:: got current mouse loc: " << old_loc << std::endl; - #ifdef _WIN32 +#ifdef _WIN32 platf::touch_port_t abs_port { 0, 0, 65535, 65535 }; - #elif __linux__ +#elif __linux__ platf::touch_port_t abs_port { 0, 0, 19200, 12000 }; - #else - platf::touch_port_t abs_port { }; - #endif +#else + platf::touch_port_t abs_port {}; +#endif std::cout << "AbsMoveInputTest:: move: " << mouse_pos << std::endl; platf::abs_mouse(input, abs_port, mouse_pos.x, mouse_pos.y); std::this_thread::sleep_for(std::chrono::milliseconds(200)); @@ -108,7 +109,8 @@ TEST_P(MouseHIDTest, AbsMoveInputTest) { if (!has_input_moved) { std::cout << "AbsMoveInputTest:: haven't moved" << std::endl; - } else { + } + else { std::cout << "AbsMoveInputTest:: moved" << std::endl; } From 2a5b93277cbcdc8f8a19c98cdc38ee2abad0adf8 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Thu, 23 May 2024 11:37:45 -0300 Subject: [PATCH 16/22] chore: rename test task --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b023d2453a6..25b54c73c59 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -781,7 +781,7 @@ jobs: done done - - name: Run tests directly + - name: Run tests id: test timeout-minutes: 10 working-directory: From 5d525d7b687505067329322b88c8f6e59e631c28 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Mon, 3 Jun 2024 20:39:35 -0300 Subject: [PATCH 17/22] chore: throw error if get_mouse_loc is used on windows before we fix it --- src/platform/windows/input.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index c919674963b..10cd30529df 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -560,6 +560,7 @@ namespace platf { util::point_t get_mouse_loc(input_t &input) { + throw std::exception(); // TODO "not implemented" // TODO: Tests are failing, something wrong here? // syncThreadDesktop(); POINT p; From 772ac92f2cc344b333fa67fab0a8f155f4703781 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Mon, 3 Jun 2024 20:43:34 -0300 Subject: [PATCH 18/22] chore: revert original behavior --- src/platform/windows/input.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 10cd30529df..754b8574728 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -550,8 +550,8 @@ namespace platf { i.type = INPUT_MOUSE; auto &mi = i.mi; - // mi.dwFlags = MOUSEEVENTF_MOVE; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; // TODO: Not sure if needed + mi.dwFlags = MOUSEEVENTF_MOVE; + // mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; // TODO: Not sure if needed mi.dx = deltaX; mi.dy = deltaY; From de53f365cd66510e6b1c8180589961f709c79616 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 4 Jun 2024 23:50:03 -0300 Subject: [PATCH 19/22] chore: change exception type to be more clear --- src/platform/windows/input.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 754b8574728..41ca189024b 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -560,7 +560,7 @@ namespace platf { util::point_t get_mouse_loc(input_t &input) { - throw std::exception(); // TODO "not implemented" + throw std::runtime_error("not implemented"); // TODO: Tests are failing, something wrong here? // syncThreadDesktop(); POINT p; From 922eb4d2e1d37a1a28d44f5803c96358b6d89beb Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 11 Jun 2024 21:01:16 -0300 Subject: [PATCH 20/22] chore: remove unnecessary comments --- src/platform/windows/input.cpp | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/platform/windows/input.cpp b/src/platform/windows/input.cpp index 41ca189024b..74aba6e09ef 100644 --- a/src/platform/windows/input.cpp +++ b/src/platform/windows/input.cpp @@ -528,21 +528,6 @@ namespace platf { send_input(i); } - /** - * // TODO: This method seems to work better during tests, - but it doesn't seem to cover the same features as the original method - void - abs_mouse(input_t &input, const touch_port_t &touch_port, float x, float y) { - INPUT i {}; - i.type = INPUT_MOUSE; - auto &mi = i.mi; - mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - mi.dx = (x * 65535) / GetSystemMetrics(SM_CXSCREEN); - mi.dy = (y * 65535) / GetSystemMetrics(SM_CYSCREEN); - send_input(i); - } - */ - void move_mouse(input_t &input, int deltaX, int deltaY) { INPUT i {}; @@ -551,7 +536,6 @@ namespace platf { auto &mi = i.mi; mi.dwFlags = MOUSEEVENTF_MOVE; - // mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_MOVE_NOCOALESCE; // TODO: Not sure if needed mi.dx = deltaX; mi.dy = deltaY; @@ -560,9 +544,8 @@ namespace platf { util::point_t get_mouse_loc(input_t &input) { - throw std::runtime_error("not implemented"); + throw std::runtime_error("not implemented yet, has to pass tests"); // TODO: Tests are failing, something wrong here? - // syncThreadDesktop(); POINT p; if (!GetCursorPos(&p)) { return util::point_t { 0.0, 0.0 }; From b90d5ba391873f7e664dfbb1b563a93f37e6df00 Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 11 Jun 2024 21:06:30 -0300 Subject: [PATCH 21/22] ci: remove test logs --- .github/workflows/CI.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 25b54c73c59..4941f744cf8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -791,12 +791,6 @@ jobs: sudo port install graphviz sudo ./test_sunshine --gtest_color=yes - - name: Test Logs - if: always() - run: | - logfile="/opt/local/var/macports/build/_Users_runner_work_Sunshine_Sunshine_ports_multimedia_Sunshine/Sunshine/work/build/tests/test.log" - cat "$logfile" - - name: Generate gcov report # any except canceled or skipped if: always() && (steps.test.outcome == 'success' || steps.test.outcome == 'failure') From 84183af51814b92532623c8993c28271a689586e Mon Sep 17 00:00:00 2001 From: Vithorio Polten Date: Tue, 11 Jun 2024 21:07:18 -0300 Subject: [PATCH 22/22] ci: cleanup port install Co-authored-by: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> --- .github/workflows/CI.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4941f744cf8..ec32e6cc630 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -787,8 +787,9 @@ jobs: working-directory: /opt/local/var/macports/build/_Users_runner_work_Sunshine_Sunshine_ports_multimedia_Sunshine/Sunshine/work/build/tests run: | - sudo port install doxygen - sudo port install graphviz + sudo port install \ + doxygen \ + graphviz sudo ./test_sunshine --gtest_color=yes - name: Generate gcov report