blob: ab4c499c24313f15359b739919bd5e6d0b67f22d [file] [log] [blame] [edit]
/*
* Copyright © 2018 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: William Wold <william.wold@canonical.com>
*/
#include "helpers.h"
#include "in_process_server.h"
#include "xdg_shell_stable.h"
#include "surface_builder.h"
#include <gmock/gmock.h>
#include <vector>
#include <memory>
using namespace testing;
class TouchTest:
public wlcs::InProcessServer,
public testing::WithParamInterface<std::shared_ptr<wlcs::SurfaceBuilder>>
{
};
TEST_P(TouchTest, touch_on_surface_seen)
{
int const window_width = 300, window_height = 300;
int const window_top_left_x = 64, window_top_left_y = 7;
wlcs::Client client{the_server()};
auto const surface = GetParam()->build(
the_server(), client, {window_top_left_x, window_top_left_y}, {window_width, window_height});
auto const wl_surface = static_cast<struct wl_surface*>(*surface);
auto touch = the_server().create_touch();
int touch_x = window_top_left_x + 27;
int touch_y = window_top_left_y + 8;
touch.down_at(touch_x, touch_y);
client.roundtrip();
ASSERT_THAT(client.touched_window(), Eq(wl_surface)) << "touch did not register on surface";
ASSERT_THAT(client.touch_position(),
Eq(std::make_pair(
wl_fixed_from_int(touch_x - window_top_left_x),
wl_fixed_from_int(touch_y - window_top_left_y)))) << "touch came down in the wrong place";
touch.up();
client.roundtrip();
}
TEST_P(TouchTest, touch_and_drag_on_surface_seen)
{
int const window_width = 300, window_height = 300;
int const window_top_left_x = 64, window_top_left_y = 12;
int const touch_x = window_top_left_x + 27, touch_y = window_top_left_y + 140;
int const dx = 37, dy = -52;
wlcs::Client client{the_server()};
auto const surface = GetParam()->build(
the_server(), client, {window_top_left_x, window_top_left_y}, {window_width, window_height});
auto const wl_surface = static_cast<struct wl_surface*>(*surface);
auto touch = the_server().create_touch();
touch.down_at(touch_x, touch_y);
client.roundtrip();
ASSERT_THAT(client.touched_window(), Eq(wl_surface)) << "touch did not register on surface";
ASSERT_THAT(client.touch_position(),
Eq(std::make_pair(
wl_fixed_from_int(touch_x - window_top_left_x),
wl_fixed_from_int(touch_y - window_top_left_y)))) << "touch came down in the wrong place";
touch.move_to(touch_x + dx, touch_y + dy);
client.roundtrip();
ASSERT_THAT(client.touched_window(), Eq(wl_surface)) << "surface was unfocused when it shouldn't have been";
ASSERT_THAT(client.touch_position(),
Ne(std::make_pair(
wl_fixed_from_int(touch_x - window_top_left_x),
wl_fixed_from_int(touch_y - window_top_left_y)))) << "touch did not move";
ASSERT_THAT(client.touch_position(),
Eq(std::make_pair(
wl_fixed_from_int(touch_x - window_top_left_x + dx),
wl_fixed_from_int(touch_y - window_top_left_y + dy)))) << "touch did not end up in the right place";
touch.up();
client.roundtrip();
}
TEST_P(TouchTest, touch_drag_outside_of_surface_and_back_not_lost)
{
int const window_width = 300, window_height = 300;
int const window_top_left_x = 64, window_top_left_y = 12;
int const touch_a_x = window_top_left_x + 27, touch_a_y = window_top_left_y + 12;
int const touch_b_x = window_top_left_x - 6, touch_b_y = window_top_left_y + window_width + 8;
wlcs::Client client{the_server()};
auto const surface = GetParam()->build(
the_server(), client, {window_top_left_x, window_top_left_y}, {window_width, window_height});
auto const wl_surface = static_cast<struct wl_surface*>(*surface);
auto touch = the_server().create_touch();
touch.down_at(touch_a_x, touch_a_y);
client.roundtrip();
ASSERT_THAT(client.touched_window(), Eq(wl_surface)) << "touch did not register on surface";
ASSERT_THAT(client.touch_position(),
Eq(std::make_pair(
wl_fixed_from_int(touch_a_x - window_top_left_x),
wl_fixed_from_int(touch_a_y - window_top_left_y)))) << "touch came down in the wrong place";
touch.move_to(touch_b_x, touch_b_y);
client.roundtrip();
EXPECT_THAT(client.touched_window(), Eq(wl_surface)) << "touch was lost when it moved out of the surface";
if (client.touched_window() == wl_surface)
{
EXPECT_THAT(client.touch_position(),
Eq(std::make_pair(
wl_fixed_from_int(touch_b_x - window_top_left_x),
wl_fixed_from_int(touch_b_y - window_top_left_y)))) << "touch did not end up in the right place outside of the surface";
}
touch.move_to(touch_a_x, touch_a_y);
client.roundtrip();
EXPECT_THAT(client.touched_window(), Eq(wl_surface)) << "touch did not come back onto surface";
EXPECT_THAT(client.touch_position(),
Eq(std::make_pair(
wl_fixed_from_int(touch_a_x - window_top_left_x),
wl_fixed_from_int(touch_a_y - window_top_left_y)))) << "touch came back in the wrong place";
touch.up();
client.roundtrip();
}
TEST_P(TouchTest, sends_touch_up_on_surface_destroy)
{
int const window_width = 300, window_height = 300;
int const window_top_left_x = 64, window_top_left_y = 7;
wlcs::Client client{the_server()};
auto surface = GetParam()->build(
the_server(), client, {window_top_left_x, window_top_left_y}, {window_width, window_height});
auto touch = the_server().create_touch();
int touch_x = window_top_left_x + 27;
int touch_y = window_top_left_y + 8;
touch.down_at(touch_x, touch_y);
client.roundtrip();
surface.reset();
client.roundtrip();
ASSERT_THAT(client.touched_window(), Eq(nullptr)) << "Touch did not leave surface when surface was destroyed";
}
INSTANTIATE_TEST_SUITE_P(
AllSurfaceTypes,
TouchTest,
ValuesIn(wlcs::SurfaceBuilder::all_surface_types()));