Mir

Merge lp:~robertcarr/mir/fix-input-obscurance into lp:~mir-team/mir/trunk

Proposed by Robert Carr
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 835
Proposed branch: lp:~robertcarr/mir/fix-input-obscurance
Merge into: lp:~mir-team/mir/trunk
Diff against target: 153 lines (+126/-2)
2 files modified
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+0/-2)
tests/acceptance-tests/test_client_input.cpp (+126/-0)
To merge this branch: bzr merge lp:~robertcarr/mir/fix-input-obscurance
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Kevin DuBois (community) Approve
Alan Griffiths Approve
Review via email: mp+173586@code.launchpad.net

Commit message

Fix obscurance of touch events according to stacking.

Description of the change

The refactoring of InputDispatcher to use the InputTargetEnumerator interface resulted in an error on my part breaking obscurance of touch events by surfaces. This branch introduces an acceptance test to cover the case and contains a fix.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

looks good to me too

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp'
--- 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2013-05-30 19:24:29 +0000
+++ 3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp 2013-07-08 20:03:25 +0000
@@ -1151,8 +1151,6 @@
11511151
1152 // Traverse windows from front to back to find touched window and outside targets.1152 // Traverse windows from front to back to find touched window and outside targets.
1153 mEnumerator->for_each([&](sp<InputWindowHandle> const& windowHandle){1153 mEnumerator->for_each([&](sp<InputWindowHandle> const& windowHandle){
1154 if (newTouchedWindowHandle != NULL)
1155 return;
1156 const InputWindowInfo* windowInfo = windowHandle->getInfo();1154 const InputWindowInfo* windowInfo = windowHandle->getInfo();
1157 int32_t flags = windowInfo->layoutParamsFlags;1155 int32_t flags = windowInfo->layoutParamsFlags;
11581156
11591157
=== modified file 'tests/acceptance-tests/test_client_input.cpp'
--- tests/acceptance-tests/test_client_input.cpp 2013-07-02 20:25:39 +0000
+++ tests/acceptance-tests/test_client_input.cpp 2013-07-08 20:03:25 +0000
@@ -23,6 +23,8 @@
23#include "mir/shell/placement_strategy.h"23#include "mir/shell/placement_strategy.h"
24#include "mir/shell/surface_factory.h"24#include "mir/shell/surface_factory.h"
25#include "mir/shell/surface.h"25#include "mir/shell/surface.h"
26#include "mir/surfaces/surface_controller.h"
27#include "mir/surfaces/surface_stack_model.h"
2628
27#include "src/server/input/android/android_input_manager.h"29#include "src/server/input/android/android_input_manager.h"
28#include "src/server/input/android/android_input_targeter.h"30#include "src/server/input/android/android_input_targeter.h"
@@ -643,3 +645,127 @@
643 } client_config;645 } client_config;
644 launch_client_process(client_config);646 launch_client_process(client_config);
645}647}
648
649namespace
650{
651typedef std::map<std::string, ms::DepthId> DepthList;
652
653struct StackingSurfaceController : public ms::SurfaceController
654{
655 StackingSurfaceController(std::shared_ptr<ms::SurfaceStackModel> const& surface_stack_model, DepthList const& depths)
656 : SurfaceController(surface_stack_model),
657 surface_depths_by_name(depths)
658 {
659 }
660
661 std::weak_ptr<ms::Surface> create_surface(msh::SurfaceCreationParameters const& params) override
662 {
663 return surface_stack->create_surface(params, surface_depths_by_name[params.name]);
664 }
665
666 DepthList surface_depths_by_name;
667};
668}
669
670TEST_F(TestClientInput, surfaces_obscure_motion_events_by_stacking)
671{
672 using namespace ::testing;
673
674 static std::string const test_client_name_1 = "1";
675 static std::string const test_client_name_2 = "2";
676
677 static int const screen_width = 100;
678 static int const screen_height = 100;
679
680 static geom::Rectangle const screen_geometry{geom::Point{geom::X{0}, geom::Y{0}},
681 geom::Size{geom::Width{screen_width}, geom::Height{screen_height}}};
682
683 struct ServerConiguration : mtf::InputTestingServerConfiguration
684 {
685 std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy() override
686 {
687 static GeometryList positions;
688 positions[test_client_name_1] = screen_geometry;
689
690 auto smaller_geometry = screen_geometry;
691 smaller_geometry.size.width = geom::Width{screen_width/2};
692 positions[test_client_name_2] = smaller_geometry;
693
694 return std::make_shared<StaticPlacementStrategy>(positions);
695 }
696
697 std::shared_ptr<msh::SurfaceBuilder> the_surface_builder() override
698 {
699 static DepthList depths;
700 depths[test_client_name_1] = ms::DepthId{0};
701 depths[test_client_name_2] = ms::DepthId{1};
702
703 return std::make_shared<StackingSurfaceController>(the_surface_stack_model(), depths);
704 }
705
706 void inject_input() override
707 {
708 wait_until_client_appears(test_client_name_1);
709 wait_until_client_appears(test_client_name_2);
710
711 // First we will move the cursor in to the region where client 2 obscures client 1
712 fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(1, 1));
713 fake_event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down));
714 fake_event_hub->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT));
715 // Now we move to the unobscured region of client 1
716 fake_event_hub->synthesize_event(mis::a_motion_event().with_movement(50, 0));
717 fake_event_hub->synthesize_event(mis::a_button_down_event().of_button(BTN_LEFT).with_action(mis::EventAction::Down));
718 fake_event_hub->synthesize_event(mis::a_button_up_event().of_button(BTN_LEFT));
719 }
720 } server_config;
721
722 launch_server_process(server_config);
723
724 struct ClientConfigOne : InputClient
725 {
726 ClientConfigOne()
727 : InputClient(test_client_name_1)
728 {
729 }
730
731 void expect_input(mt::WaitCondition& events_received) override
732 {
733 EXPECT_CALL(*handler, handle_input(HoverEnterEvent())).Times(AnyNumber());
734 EXPECT_CALL(*handler, handle_input(HoverExitEvent())).Times(AnyNumber());
735 EXPECT_CALL(*handler, handle_input(MovementEvent())).Times(AnyNumber());
736
737 {
738 // We should only see one button event sequence.
739 InSequence seq;
740 EXPECT_CALL(*handler, handle_input(ButtonDownEvent(51, 1))).Times(1);
741 EXPECT_CALL(*handler, handle_input(ButtonUpEvent(51, 1))).Times(1)
742 .WillOnce(mt::WakeUp(&events_received));
743 }
744 }
745 } client_config_1;
746 launch_client_process(client_config_1);
747
748 struct ClientConfigTwo : InputClient
749 {
750 ClientConfigTwo()
751 : InputClient(test_client_name_2)
752 {
753 }
754
755 void expect_input(mt::WaitCondition& events_received) override
756 {
757 EXPECT_CALL(*handler, handle_input(HoverEnterEvent())).Times(AnyNumber());
758 EXPECT_CALL(*handler, handle_input(HoverExitEvent())).Times(AnyNumber());
759 EXPECT_CALL(*handler, handle_input(MovementEvent())).Times(AnyNumber());
760
761 {
762 // Likewise we should only see one button sequence.
763 InSequence seq;
764 EXPECT_CALL(*handler, handle_input(ButtonDownEvent(1, 1))).Times(1);
765 EXPECT_CALL(*handler, handle_input(ButtonUpEvent(1, 1))).Times(1)
766 .WillOnce(mt::WakeUp(&events_received));
767 }
768 }
769 } client_config_2;
770 launch_client_process(client_config_2);
771}

Subscribers

People subscribed via source and target branches