Mir

Merge lp:~andreas-pokorny/mir/fix-1546324 into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Andreas Pokorny
Approved revision: no longer in the source branch.
Merged at revision: 3348
Proposed branch: lp:~andreas-pokorny/mir/fix-1546324
Merge into: lp:mir
Prerequisite: lp:~andreas-pokorny/mir/fix-1544878
Diff against target: 725 lines (+355/-228)
6 files modified
src/platforms/mesa/server/x11/input/input_device.cpp (+137/-1)
src/platforms/mesa/server/x11/input/input_device.h (+14/-1)
src/platforms/mesa/server/x11/input/input_platform.cpp (+165/-226)
tests/include/mir/test/doubles/mock_x11.h (+2/-0)
tests/mir_test_doubles/mock_x11.cpp (+15/-0)
tests/unit-tests/input/test_x11_platform.cpp (+22/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/fix-1546324
Reviewer Review Type Date Requested Status
Mir CI Bot continuous-integration Approve
Alexandros Frantzis (community) Approve
Cemil Azizoglu (community) Approve
PS Jenkins bot (community) continuous-integration Needs Fixing
Review via email: mp+286315@code.launchpad.net

This proposal supersedes a proposal from 2016-02-17.

Commit message

Track cursor movement when no button is pressed

Additionally some of the state tracking code and event sending was moved to mir::X::input::InputDevice. The X11 Event handling loop was changed to consume all events still in the queue before returning. Horizontal scrolling is supported now too.

Description of the change

This mainly fixes the missing cursor motion when no buttons were pressed. Other things could still be improved - i.e modifier tracking to handle press/release when the window is not touched and things like that.

To post a comment you must log in.
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Linux input also defines BTN_BACK and BTN_FORWARD, how are those mapped in X11? I have no mouse with such a button - but I found one with SIDE And EXTRA.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3322
https://mir-jenkins.ubuntu.com/job/mir-ci/330/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/120
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/132
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/128
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/128
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/125
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/125/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/125
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/125/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/125
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/125/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/125
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/125/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/330/rebuild

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

PASSED: Continuous integration, rev:3322
http://jenkins.qa.ubuntu.com/job/mir-ci/6319/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5962
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4869
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5918
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/454
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/643
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/643/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/643
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/643/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5915
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5915/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8298
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27721
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/450
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/450/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/303
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27727

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6319/rebuild

review: Approve (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

20 +MirPointerButtons to_button_state(int button)

Should be named to_mir_button(int button)
--------------------------------------------

487 + auto const up = 4, down = 5, left = 6, right = 7;

Better to use Button4 for 4, Button5 for 5 as those are standard. For 6 and 7, my understanding is that not every left/right button may be reported as 6 & 7 (though, I'm okay leaving this as you've implemented it). Is this also your understanding? That can also be said for up & down I guess.

--------------------------------------------

114 +void mix::XInputDevice::pointer_motion(std::chrono::nanoseconds event_time, mir::geometry::Point const& pos, mir::geometry::Displacement scroll)
115 +{
116 + std::cout << "pos " << pos.x.as_float() << std::endl;
117 + auto const movement = pos - pointer_pos;
118 + pointer_pos = pos;
119 + sink->handle_input(
120 + *builder->pointer_event(
121 + event_time,
122 + mir_pointer_action_motion,
123 + button_state,
124 + scroll.dx.as_float(),
125 + scroll.dy.as_float(),
126 + movement.dx.as_float(),
127 + movement.dy.as_float()
128 + )
129 + );
130 +}

button_state is not set to the proper value here. Unfortunately, this function is called at two different times; i) during scrolling, which doesn't require this setting, and ii) mouse motion, which does. So you may have to clone this function (pointer_scroll()?).

Note also that for (ii) you can't simply call to_button_state() function as it has to be extracted from, not 'button' field of the Xevent struct, but from the 'state' field. (You can look at the existing code for that case).

--------------------------------------------

Superluous lines
34 +
60 +
111 +

--------------------------------------------

Hmm, you're right implementing it this way, I think.

77 + button_state |= to_button_state(button);
96 + button_state = button_state & ~(to_button_state(button));

Though can you change the latter to
             button_state &= ~(to_button_state(button));
for consistency?

review: Needs Fixing
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

>
> 20 +MirPointerButtons to_button_state(int button)
>
> Should be named to_mir_button(int button)
> --------------------------------------------
>
> 487 + auto const up = 4, down = 5, left = 6, right = 7;
>
> Better to use Button4 for 4, Button5 for 5 as those are standard. For 6 and 7,
> my understanding is that not every left/right button may be reported as 6 & 7
> (though, I'm okay leaving this as you've implemented it). Is this also your
> understanding? That can also be said for up & down I guess.

Yeah not entirely sure - but Gtk seems to be sure about that and defines those constants
in its X11 backend. At least my mouse has about 10 buttons - but no horizontal scrolling
wheels and the additional buttons begin with 9 ...

> --------------------------------------------
>
> 114 +void mix::XInputDevice::pointer_motion(std::chrono::nanoseconds
> event_time, mir::geometry::Point const& pos, mir::geometry::Displacement
> scroll)
> 115 +{
> 116 + std::cout << "pos " << pos.x.as_float() << std::endl;
> 117 + auto const movement = pos - pointer_pos;
> 118 + pointer_pos = pos;
> 119 + sink->handle_input(
> 120 + *builder->pointer_event(
> 121 + event_time,
> 122 + mir_pointer_action_motion,
> 123 + button_state,
> 124 + scroll.dx.as_float(),
> 125 + scroll.dy.as_float(),
> 126 + movement.dx.as_float(),
> 127 + movement.dy.as_float()
> 128 + )
> 129 + );
> 130 +}
>
> button_state is not set to the proper value here. Unfortunately, this function
> is called at two different times; i) during scrolling, which doesn't require
> this setting, and ii) mouse motion, which does. So you may have to clone this
> function (pointer_scroll()?).
>
> Note also that for (ii) you can't simply call to_button_state() function as it
> has to be extracted from, not 'button' field of the Xevent struct, but from
> the 'state' field. (You can look at the existing code for that case).

Ack I should pull it from the most recent event. And remove the iostream mess..

> --------------------------------------------
>
> Superluous lines
> 34 +
> 60 +
> 111 +
>
> --------------------------------------------
>
> Hmm, you're right implementing it this way, I think.
>
> 77 + button_state |= to_button_state(button);
> 96 + button_state = button_state & ~(to_button_state(button));
>
> Though can you change the latter to
> button_state &= ~(to_button_state(button));
> for consistency?

sure..

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3323
https://mir-jenkins.ubuntu.com/job/mir-ci/350/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/142
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/155
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/151
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/151
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/147
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/147/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/147
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/147/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/147
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/147/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/147
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/147/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/350/rebuild

review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:3324
https://mir-jenkins.ubuntu.com/job/mir-ci/355/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/147/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/160
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/156
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/156
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/152
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/152/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/152
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/152/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/152
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/152/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/152/console

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/355/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3325
https://mir-jenkins.ubuntu.com/job/mir-ci/356/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/148
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/161
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/157
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/157
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/153
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/153/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/153
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/153/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/153
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/153/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/153
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/153/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/356/rebuild

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

PASSED: Continuous integration, rev:3324
http://jenkins.qa.ubuntu.com/job/mir-ci/6347/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5999
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4906
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5955
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/469
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/671
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/671/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/671
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/671/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5952
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5952/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8326
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27800
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/465
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/465/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/318
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27805

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6347/rebuild

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

PASSED: Continuous integration, rev:3325
http://jenkins.qa.ubuntu.com/job/mir-ci/6350/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/6002
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4909
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5958
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/471
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/674
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/674/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/674
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/674/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5955
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5955/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8329
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27811
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/467
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/467/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/320
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27813

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6350/rebuild

review: Approve (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3326
https://mir-jenkins.ubuntu.com/job/mir-ci/364/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/156
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/169
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/165
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/165
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/161
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/161/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/161
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/161/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/161
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/161/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/161
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/161/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/364/rebuild

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

PASSED: Continuous integration, rev:3326
http://jenkins.qa.ubuntu.com/job/mir-ci/6355/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/6007
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4914
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5963
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/474
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/679
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/679/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/679
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/679/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5960
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5960/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/8334
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27819
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/470
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/470/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/323
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/27822

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/6355/rebuild

review: Approve (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

37 +MirPointerButtons to_mir_button_state(int x_button_key_state)
38 +{
39 + // the state variable contains modifier and button state.
40 + MirPointerButtons button_state = x_button_key_state << 8;
41 + button_state = (button_state & ~(mir_pointer_button_secondary|mir_pointer_button_tertiary)) // second and middle button are swaped in X11
42 + | ((button_state & mir_pointer_button_secondary) >> 1)
43 + | ((button_state & mir_pointer_button_tertiary) << 1);
44 + return button_state;
45 +}

This is very hard to follow. It will also be difficult to change once other modifiers need to be handled here. Can we explicitly use 'ButtonNMask' as in the original code?

review: Needs Fixing
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3327
https://mir-jenkins.ubuntu.com/job/mir-ci/385/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/177
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/190
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/186
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/186
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/182
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/182/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/182
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/182/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/182
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/182/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/182
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/182/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/385/rebuild

review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

I'm happy

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

OK.

Nit/preexisting:

mix::XInputPlatform::process_input_event(s) begs to broken up into smaller functions.

review: Approve
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Autolanding.
More details in the following jenkins job:
https://mir-jenkins.ubuntu.com/job/mir-autolanding/14/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/230/console
    None: https://mir-jenkins.ubuntu.com/job/generic-land-mp/16/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/254
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/246
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/246
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=vivid+overlay/237
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=vivid+overlay/237/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/237
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial/237/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/237
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/237/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/237
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/237/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial/237/console

review: Needs Fixing (continuous-integration)
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Hm NestedServer.display_orientation_changes_are_forwarded_to_host (5514 ms) failed..

Revision history for this message
Mir CI Bot (mir-ci-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/mesa/server/x11/input/input_device.cpp'
2--- src/platforms/mesa/server/x11/input/input_device.cpp 2016-01-29 08:18:22 +0000
3+++ src/platforms/mesa/server/x11/input/input_device.cpp 2016-02-24 09:00:08 +0000
4@@ -22,10 +22,53 @@
5 #include "mir/input/touchpad_settings.h"
6 #include "mir/input/input_device_info.h"
7 #include "mir/input/device_capability.h"
8+#include "mir/input/event_builder.h"
9+#include "mir/input/input_sink.h"
10+
11+#include <X11/Xlib.h>
12+#include <iostream>
13
14 namespace mi = mir::input;
15+namespace geom = mir::geometry;
16 namespace mix = mi::X;
17
18+namespace
19+{
20+MirPointerButtons to_mir_button(int button)
21+{
22+ auto const button_side = 8;
23+ auto const button_extra = 9;
24+ if (button == Button1)
25+ return mir_pointer_button_primary;
26+ if (button == Button2) // tertiary (middle) button is Button2 in X
27+ return mir_pointer_button_tertiary;
28+ if (button == Button3)
29+ return mir_pointer_button_secondary;
30+ if (button == button_side)
31+ return mir_pointer_button_side;
32+ if (button == button_extra)
33+ return mir_pointer_button_extra;
34+ return 0;
35+}
36+
37+MirPointerButtons to_mir_button_state(int x_button_key_state)
38+{
39+ MirPointerButtons button_state = 0;
40+ if (x_button_key_state & Button1Mask)
41+ button_state |= mir_pointer_button_primary;
42+ if (x_button_key_state & Button2Mask)
43+ button_state |= mir_pointer_button_tertiary;
44+ if (x_button_key_state & Button3Mask)
45+ button_state |= mir_pointer_button_secondary;
46+ if (x_button_key_state & Button4Mask)
47+ button_state |= mir_pointer_button_back;
48+ if (x_button_key_state & Button5Mask)
49+ button_state |= mir_pointer_button_forward;
50+ return button_state;
51+}
52+
53+}
54+
55 mix::XInputDevice::XInputDevice(InputDeviceInfo const& device_info)
56 : info(device_info)
57 {
58@@ -45,6 +88,9 @@
59
60 mi::InputDeviceInfo mix::XInputDevice::get_device_info()
61 {
62+ // TODO Make use if X11-XInput2 to get raw device information
63+ // and support other devices than just the unified pointer and
64+ // keyboards.
65 return info;
66 }
67
68@@ -59,7 +105,6 @@
69
70 void mix::XInputDevice::apply_settings(PointerSettings const&)
71 {
72- // TODO Make use if X11-XInput2
73 }
74
75 mir::optional_value<mi::TouchpadSettings> mix::XInputDevice::get_touchpad_settings() const
76@@ -74,3 +119,94 @@
77 void mix::XInputDevice::apply_settings(TouchpadSettings const&)
78 {
79 }
80+
81+bool mix::XInputDevice::started() const
82+{
83+ return sink && builder;
84+}
85+
86+void mix::XInputDevice::key_press(std::chrono::nanoseconds event_time, xkb_keysym_t key_sym, int32_t key_code)
87+{
88+ sink->handle_input(
89+ *builder->key_event(
90+ event_time,
91+ mir_keyboard_action_down,
92+ key_sym,
93+ key_code
94+ )
95+ );
96+
97+}
98+
99+void mix::XInputDevice::key_release(std::chrono::nanoseconds event_time, xkb_keysym_t key_sym, int32_t key_code)
100+{
101+ sink->handle_input(
102+ *builder->key_event(
103+ event_time,
104+ mir_keyboard_action_up,
105+ key_sym,
106+ key_code
107+ )
108+ );
109+}
110+
111+void mix::XInputDevice::update_button_state(int button)
112+{
113+ button_state = to_mir_button_state(button);
114+}
115+
116+void mix::XInputDevice::pointer_press(std::chrono::nanoseconds event_time, int button, mir::geometry::Point const& pos, mir::geometry::Displacement scroll)
117+{
118+ button_state |= to_mir_button(button);
119+
120+ auto const movement = pos - pointer_pos;
121+ pointer_pos = pos;
122+ sink->handle_input(
123+ *builder->pointer_event(
124+ event_time,
125+ mir_pointer_action_button_down,
126+ button_state,
127+ scroll.dx.as_float(),
128+ scroll.dy.as_float(),
129+ movement.dx.as_float(),
130+ movement.dy.as_float()
131+ )
132+ );
133+}
134+
135+void mix::XInputDevice::pointer_release(std::chrono::nanoseconds event_time, int button, mir::geometry::Point const& pos, mir::geometry::Displacement scroll)
136+{
137+ button_state &= ~to_mir_button(button);
138+
139+ auto const movement = pos - pointer_pos;
140+ pointer_pos = pos;
141+ sink->handle_input(
142+ *builder->pointer_event(
143+ event_time,
144+ mir_pointer_action_button_up,
145+ button_state,
146+ scroll.dx.as_float(),
147+ scroll.dy.as_float(),
148+ movement.dx.as_float(),
149+ movement.dy.as_float()
150+ )
151+ );
152+
153+}
154+
155+void mix::XInputDevice::pointer_motion(std::chrono::nanoseconds event_time, mir::geometry::Point const& pos, mir::geometry::Displacement scroll)
156+{
157+ auto const movement = pos - pointer_pos;
158+ pointer_pos = pos;
159+ sink->handle_input(
160+ *builder->pointer_event(
161+ event_time,
162+ mir_pointer_action_motion,
163+ button_state,
164+ scroll.dx.as_float(),
165+ scroll.dy.as_float(),
166+ movement.dx.as_float(),
167+ movement.dy.as_float()
168+ )
169+ );
170+}
171
172=== modified file 'src/platforms/mesa/server/x11/input/input_device.h'
173--- src/platforms/mesa/server/x11/input/input_device.h 2016-01-29 08:18:22 +0000
174+++ src/platforms/mesa/server/x11/input/input_device.h 2016-02-24 09:00:08 +0000
175@@ -21,9 +21,13 @@
176
177 #include "mir/input/input_device.h"
178 #include "mir/input/input_device_info.h"
179+#include "mir_toolkit/event.h"
180 #include "mir/geometry/point.h"
181+#include "mir/geometry/displacement.h"
182 #include "mir/optional_value.h"
183
184+#include <chrono>
185+
186 namespace mir
187 {
188 namespace input
189@@ -47,10 +51,19 @@
190 optional_value<TouchpadSettings> get_touchpad_settings() const override;
191 void apply_settings(TouchpadSettings const& settings) override;
192
193+ bool started() const;
194+ void key_press(std::chrono::nanoseconds event_time, xkb_keysym_t key_sym, int32_t key_code);
195+ void key_release(std::chrono::nanoseconds event_time, xkb_keysym_t key_sym, int32_t key_code);
196+ void update_button_state(int button);
197+ void pointer_press(std::chrono::nanoseconds event_time, int button, mir::geometry::Point const& pos, mir::geometry::Displacement scroll);
198+ void pointer_release(std::chrono::nanoseconds event_time, int button, mir::geometry::Point const& pos, mir::geometry::Displacement scroll);
199+ void pointer_motion(std::chrono::nanoseconds event_time, mir::geometry::Point const& pos, mir::geometry::Displacement scroll);
200+
201+private:
202+ MirPointerButtons button_state{0};
203 InputSink* sink{nullptr};
204 EventBuilder* builder{nullptr};
205 geometry::Point pointer_pos;
206-private:
207 InputDeviceInfo info;
208 };
209
210
211=== modified file 'src/platforms/mesa/server/x11/input/input_platform.cpp'
212--- src/platforms/mesa/server/x11/input/input_platform.cpp 2016-01-29 08:18:22 +0000
213+++ src/platforms/mesa/server/x11/input/input_platform.cpp 2016-02-24 09:00:08 +0000
214@@ -21,8 +21,6 @@
215
216 #include "mir/input/input_device_registry.h"
217 #include "mir/input/input_device_info.h"
218-#include "mir/input/event_builder.h"
219-#include "mir/input/input_sink.h"
220 #include "mir/dispatch/readable_fd.h"
221
222 #define MIR_LOG_COMPONENT "x11-input"
223@@ -43,6 +41,7 @@
224 #define GRAB_KBD
225
226 namespace mi = mir::input;
227+namespace geom = mir::geometry;
228 namespace md = mir::dispatch;
229 namespace mix = mi::X;
230
231@@ -81,233 +80,173 @@
232
233 void mix::XInputPlatform::process_input_event()
234 {
235- // This code is based on :
236- // https://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html
237- XEvent xev;
238-
239- XNextEvent(x11_connection.get(), &xev);
240-
241- if (core_keyboard->sink || core_pointer->sink)
242+ do
243 {
244- switch (xev.type)
245+ // This code is based on :
246+ // https://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html
247+ XEvent xev;
248+
249+ XNextEvent(x11_connection.get(), &xev);
250+
251+ if (core_keyboard->started() && core_pointer->started())
252 {
253+ switch (xev.type)
254+ {
255 #ifdef GRAB_KBD
256- case FocusIn:
257- {
258- auto const& xfiev = (XFocusInEvent&)xev;
259- XGrabKeyboard(xfiev.display, xfiev.window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
260- break;
261- }
262-
263- case FocusOut:
264- {
265- auto const& xfoev = (XFocusOutEvent&)xev;
266- XUngrabKeyboard(xfoev.display, CurrentTime);
267- break;
268- }
269-#endif
270- case KeyPress:
271- case KeyRelease:
272- {
273- auto& xkev = (XKeyEvent&)xev;
274- static const int STRMAX = 32;
275- char str[STRMAX];
276- KeySym keysym;
277-
278-#ifdef MIR_ON_X11_INPUT_VERBOSE
279- mir::log_info("X11 key event :"
280- " type=%s, serial=%u, send_event=%d, display=%p, window=%p,"
281- " root=%p, subwindow=%p, time=%d, x=%d, y=%d, x_root=%d,"
282- " y_root=%d, state=0x%0X, keycode=%d, same_screen=%d",
283- xkev.type == KeyPress ? "down" : "up", xkev.serial,
284- xkev.send_event, xkev.display, xkev.window, xkev.root,
285- xkev.subwindow, xkev.time, xkev.x, xkev.y, xkev.x_root,
286- xkev.y_root, xkev.state, xkev.keycode, xkev.same_screen);
287- auto count =
288-#endif
289- XLookupString(&xkev, str, STRMAX, &keysym, NULL);
290-
291- auto event_time =
292- std::chrono::duration_cast<std::chrono::nanoseconds>(
293- std::chrono::milliseconds{xkev.time});
294-
295-#ifdef MIR_ON_X11_INPUT_VERBOSE
296- for (int i=0; i<count; i++)
297- mir::log_info("buffer[%d]='%c'", i, str[i]);
298- mir::log_info("Mir key event : "
299- "key_code=%d, scan_code=%d, modifiers=0x%0X, event_time=%" PRId64,
300- keysym, xkev.keycode-8, modifiers, event_time);
301-#endif
302- core_keyboard->sink->handle_input(
303- *core_keyboard->builder->key_event(
304- event_time,
305- xkev.type == KeyPress ?
306- mir_keyboard_action_down :
307- mir_keyboard_action_up,
308- keysym,
309- xkev.keycode-8
310- )
311- );
312- break;
313- }
314-
315- case ButtonPress:
316- case ButtonRelease:
317- {
318- auto const& xbev = (XButtonEvent&)xev;
319-
320-#ifdef MIR_ON_X11_INPUT_VERBOSE
321- mir::log_info("X11 button event :"
322- " type=%s, serial=%u, send_event=%d, display=%p, window=%p,"
323- " root=%p, subwindow=%p, time=%d, x=%d, y=%d, x_root=%d,"
324- " y_root=%d, state=0x%0X, button=%d, same_screen=%d",
325- xbev.type == ButtonPress ? "down" : "up", xbev.serial,
326- xbev.send_event, xbev.display, xbev.window, xbev.root,
327- xbev.subwindow, xbev.time, xbev.x, xbev.y, xbev.x_root,
328- xbev.y_root, xbev.state, xbev.button, xbev.same_screen);
329-#endif
330- if ((xbev.type == ButtonRelease) &&
331- ((xbev.button == Button4) || (xbev.button == Button5)))
332- {
333-#ifdef MIR_ON_X11_INPUT_VERBOSE
334- mir::log_info("Swallowed");
335-#endif
336- break;
337- }
338- auto event_time =
339- std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds{xbev.time});
340-
341- MirPointerButtons buttons_pressed = 0;
342- if (xbev.type == ButtonPress)
343- {
344- if (xbev.button == Button1)
345- buttons_pressed |= mir_pointer_button_primary;
346- if (xbev.button == Button2) // tertiary (middle) button is Button2 in X
347- buttons_pressed |= mir_pointer_button_tertiary;
348- if (xbev.button == Button3)
349- buttons_pressed |= mir_pointer_button_secondary;
350- if (xbev.button == Button4)
351- buttons_pressed |= mir_pointer_button_back;
352- if (xbev.button == Button5)
353- buttons_pressed |= mir_pointer_button_forward;
354- }
355-
356-#ifdef MIR_ON_X11_INPUT_VERBOSE
357- mir::log_info("Mir button event : x=%d, y=%d, "
358- "buttons_pressed=0x%0X, event_time=%" PRId64,
359- xbev.x, xbev.y, buttons_pressed, event_time);
360-#endif
361-
362- if ((xbev.button == Button4) || (xbev.button == Button5))
363- { // scroll event
364- core_pointer->sink->handle_input(
365- *core_pointer->builder->pointer_event(
366- event_time,
367- mir_pointer_action_motion,
368- 0,
369- 0.0f,
370- (xbev.button == Button4) ? 1.0f : -1.0f,
371- 0.0f,
372- 0.0f
373- )
374- );
375- }
376- else
377- {
378- auto const old_pointer_pos = core_pointer->pointer_pos;
379- core_pointer->pointer_pos = geometry::Point{xbev.x, xbev.y};
380- auto const movement = core_pointer->pointer_pos - old_pointer_pos;
381-
382- core_pointer->sink->handle_input(
383- *core_pointer->builder->pointer_event(
384- event_time,
385- xbev.type == ButtonPress ?
386- mir_pointer_action_button_down :
387- mir_pointer_action_button_up,
388- buttons_pressed,
389- 0.0f,
390- 0.0f,
391- movement.dx.as_float(),
392- movement.dy.as_float()
393- )
394- );
395- }
396- break;
397- }
398-
399- case MotionNotify:
400- {
401- auto const& xmev = (XMotionEvent&)xev;
402-
403-#ifdef MIR_ON_X11_INPUT_VERBOSE
404- mir::log_info("X11 motion event :"
405- " type=motion, serial=%u, send_event=%d, display=%p, window=%p,"
406- " root=%p, subwindow=%p, time=%d, x=%d, y=%d, x_root=%d,"
407- " y_root=%d, state=0x%0X, is_hint=%s, same_screen=%d",
408- xmev.serial, xmev.send_event, xmev.display, xmev.window,
409- xmev.root, xmev.subwindow, xmev.time, xmev.x, xmev.y, xmev.x_root,
410- xmev.y_root, xmev.state, xmev.is_hint == NotifyNormal ? "no" : "yes", xmev.same_screen);
411-#endif
412-
413- auto event_time =
414- std::chrono::duration_cast<std::chrono::nanoseconds>(
415- std::chrono::milliseconds{xmev.time});
416-
417- MirPointerButtons buttons_pressed = 0;
418- if (xmev.state & Button1Mask)
419- buttons_pressed |= mir_pointer_button_primary;
420- if (xmev.state & Button2Mask) // tertiary (middle) button is Button2 in X
421- buttons_pressed |= mir_pointer_button_tertiary;
422- if (xmev.state & Button3Mask)
423- buttons_pressed |= mir_pointer_button_secondary;
424- if (xmev.state & Button4Mask)
425- buttons_pressed |= mir_pointer_button_back;
426- if (xmev.state & Button5Mask)
427- buttons_pressed |= mir_pointer_button_forward;
428-
429-#ifdef MIR_ON_X11_INPUT_VERBOSE
430- mir::log_info("Mir pointer event : "
431- "x=%d, y=%d, buttons_pressed=0x%0X, event_time=%" PRId64,
432- xmev.x, xmev.y, buttons_pressed, event_time);
433-#endif
434- core_pointer->sink->handle_input(
435- *core_pointer->builder->pointer_event(
436- event_time,
437- mir_pointer_action_motion,
438- buttons_pressed,
439- 0.0f,
440- 0.0f,
441- 0.0f,
442- 0.0f
443- )
444- );
445- break;
446- }
447-
448- case ConfigureNotify:
449- {
450-#ifdef MIR_ON_X11_INPUT_VERBOSE
451- auto const& xcev = (XConfigureEvent&)xev;
452- mir::log_info("Window size : %dx%d", xcev.width, xcev.height);
453-#endif
454- break;
455- }
456-
457- case MappingNotify:
458-#ifdef MIR_ON_X11_INPUT_VERBOSE
459- mir::log_info("Keyboard mapping changed at server. Refreshing the cache.");
460-#endif
461- XRefreshKeyboardMapping((XMappingEvent*)&xev);
462- break;
463-
464- default:
465-#ifdef MIR_ON_X11_INPUT_VERBOSE
466- mir::log_info("Uninteresting event : %08X", xev.type);
467-#endif
468- break;
469+ case FocusIn:
470+ {
471+ auto const& xfiev = xev.xfocus;
472+ XGrabKeyboard(xfiev.display, xfiev.window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
473+ break;
474+ }
475+
476+ case FocusOut:
477+ {
478+ auto const& xfoev = xev.xfocus;
479+ XUngrabKeyboard(xfoev.display, CurrentTime);
480+ break;
481+ }
482+#endif
483+ case KeyPress:
484+ case KeyRelease:
485+ {
486+ auto & xkev = xev.xkey;
487+ static const int STRMAX = 32;
488+ char str[STRMAX];
489+ KeySym keysym;
490+
491+#ifdef MIR_ON_X11_INPUT_VERBOSE
492+ mir::log_info("X11 key event :"
493+ " type=%s, serial=%u, send_event=%d, display=%p, window=%p,"
494+ " root=%p, subwindow=%p, time=%d, x=%d, y=%d, x_root=%d,"
495+ " y_root=%d, state=0x%0X, keycode=%d, same_screen=%d",
496+ xkev.type == KeyPress ? "down" : "up", xkev.serial,
497+ xkev.send_event, xkev.display, xkev.window, xkev.root,
498+ xkev.subwindow, xkev.time, xkev.x, xkev.y, xkev.x_root,
499+ xkev.y_root, xkev.state, xkev.keycode, xkev.same_screen);
500+ auto count =
501+#endif
502+ XLookupString(&xkev, str, STRMAX, &keysym, NULL);
503+
504+ auto const event_time =
505+ std::chrono::duration_cast<std::chrono::nanoseconds>(
506+ std::chrono::milliseconds{xkev.time});
507+
508+#ifdef MIR_ON_X11_INPUT_VERBOSE
509+ for (int i=0; i<count; i++)
510+ mir::log_info("buffer[%d]='%c'", i, str[i]);
511+ mir::log_info("Mir key event : "
512+ "key_code=%d, scan_code=%d, event_time=%" PRId64,
513+ keysym, xkev.keycode-8, event_time);
514+#endif
515+
516+ if (xkev.type == KeyPress)
517+ core_keyboard->key_press(event_time, keysym, xkev.keycode - 8);
518+ else
519+ core_keyboard->key_release(event_time, keysym, xkev.keycode - 8);
520+
521+ break;
522+ }
523+
524+ case ButtonPress:
525+ case ButtonRelease:
526+ {
527+ auto const& xbev = xev.xbutton;
528+ auto const up = Button4, down = Button5, left = 6, right = 7;
529+
530+#ifdef MIR_ON_X11_INPUT_VERBOSE
531+ mir::log_info("X11 button event :"
532+ " type=%s, serial=%u, send_event=%d, display=%p, window=%p,"
533+ " root=%p, subwindow=%p, time=%d, x=%d, y=%d, x_root=%d,"
534+ " y_root=%d, state=0x%0X, button=%d, same_screen=%d",
535+ xbev.type == ButtonPress ? "down" : "up", xbev.serial,
536+ xbev.send_event, xbev.display, xbev.window, xbev.root,
537+ xbev.subwindow, xbev.time, xbev.x, xbev.y, xbev.x_root,
538+ xbev.y_root, xbev.state, xbev.button, xbev.same_screen);
539+#endif
540+ if (xbev.type == ButtonRelease && xbev.button >= up && xbev.button <= right)
541+ {
542+#ifdef MIR_ON_X11_INPUT_VERBOSE
543+ mir::log_info("Swallowed");
544+#endif
545+ break;
546+ }
547+ auto const event_time =
548+ std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::milliseconds{xbev.time});
549+ core_pointer->update_button_state(xbev.state);
550+
551+ if (xbev.button >= up && xbev.button <= right)
552+ { // scroll event
553+ core_pointer->pointer_motion(
554+ event_time,
555+ geom::Point{xbev.x, xbev.y},
556+ geom::Displacement{xbev.button == right ? 1 : xbev.button == left ? -1 : 0,
557+ xbev.button == up ? 1 : xbev.button == down ? -1 : 0});
558+ }
559+ else
560+ {
561+ if (xbev.type == ButtonPress)
562+ core_pointer->pointer_press(
563+ event_time,
564+ xbev.button,
565+ geom::Point{xbev.x, xbev.y},
566+ geom::Displacement{0, 0});
567+ else
568+ core_pointer->pointer_release(
569+ event_time,
570+ xbev.button,
571+ geom::Point{xbev.x, xbev.y},
572+ geom::Displacement{0, 0});
573+ }
574+ break;
575+ }
576+
577+ case MotionNotify:
578+ {
579+ auto const& xmev = xev.xmotion;
580+
581+#ifdef MIR_ON_X11_INPUT_VERBOSE
582+ mir::log_info("X11 motion event :"
583+ " type=motion, serial=%u, send_event=%d, display=%p, window=%p,"
584+ " root=%p, subwindow=%p, time=%d, x=%d, y=%d, x_root=%d,"
585+ " y_root=%d, state=0x%0X, is_hint=%s, same_screen=%d",
586+ xmev.serial, xmev.send_event, xmev.display, xmev.window,
587+ xmev.root, xmev.subwindow, xmev.time, xmev.x, xmev.y, xmev.x_root,
588+ xmev.y_root, xmev.state, xmev.is_hint == NotifyNormal ? "no" : "yes", xmev.same_screen);
589+#endif
590+
591+ core_pointer->update_button_state(xmev.state);
592+ core_pointer->pointer_motion(
593+ std::chrono::milliseconds{xmev.time}, geom::Point{xmev.x, xmev.y}, geom::Displacement{0, 0});
594+
595+ break;
596+ }
597+
598+ case ConfigureNotify:
599+ {
600+#ifdef MIR_ON_X11_INPUT_VERBOSE
601+ auto const& xcev = xev.xconfigure;
602+ mir::log_info("Window size : %dx%d", xcev.width, xcev.height);
603+#endif
604+ break;
605+ }
606+
607+ case MappingNotify:
608+#ifdef MIR_ON_X11_INPUT_VERBOSE
609+ mir::log_info("Keyboard mapping changed at server. Refreshing the cache.");
610+#endif
611+ XRefreshKeyboardMapping(&(xev.xmapping));
612+ break;
613+
614+ default:
615+#ifdef MIR_ON_X11_INPUT_VERBOSE
616+ mir::log_info("Uninteresting event : %08X", xev.type);
617+#endif
618+ break;
619+ }
620 }
621+ else
622+ mir::log_error("input event received with no sink to handle it");
623 }
624- else
625- mir::log_error("input event received with no sink to handle it");
626-
627+ while(XPending(x11_connection.get()));
628 }
629
630=== modified file 'tests/include/mir/test/doubles/mock_x11.h'
631--- tests/include/mir/test/doubles/mock_x11.h 2016-01-29 08:18:22 +0000
632+++ tests/include/mir/test/doubles/mock_x11.h 2016-02-24 09:00:08 +0000
633@@ -46,6 +46,7 @@
634 XEvent focus_in_event_return = { 0 };
635 XEvent focus_out_event_return = { 0 };
636 XEvent vscroll_event_return = { 0 };
637+ XEvent motion_event_return = { 0 };
638 };
639
640 class MockX11
641@@ -56,6 +57,7 @@
642
643 MOCK_METHOD1(XOpenDisplay, Display*(const char*));
644 MOCK_METHOD1(XCloseDisplay, int(Display*));
645+ MOCK_METHOD1(XPending, int(Display*));
646 MOCK_METHOD4(XGetVisualInfo, XVisualInfo*(Display*, long, XVisualInfo*, int*));
647 MOCK_METHOD4(XCreateColormap, Colormap(Display*, Window, Visual*, int));
648 /* Too long to mock, use wrapper instead.
649
650=== modified file 'tests/mir_test_doubles/mock_x11.cpp'
651--- tests/mir_test_doubles/mock_x11.cpp 2016-01-29 08:18:22 +0000
652+++ tests/mir_test_doubles/mock_x11.cpp 2016-02-24 09:00:08 +0000
653@@ -20,6 +20,8 @@
654 #include "mir/test/doubles/mock_x11.h"
655 #include <gtest/gtest.h>
656
657+#include <cstring>
658+
659 namespace mtd=mir::test::doubles;
660
661 namespace
662@@ -31,6 +33,13 @@
663 : display{reinterpret_cast<Display*>(0x12345678)},
664 window{reinterpret_cast<Window>((long unsigned int)9876543210)}
665 {
666+ std::memset(&keypress_event_return, 0, sizeof(XEvent));
667+ std::memset(&button_release_event_return, 0, sizeof(XEvent));
668+ std::memset(&expose_event_return, 0, sizeof(XEvent));
669+ std::memset(&focus_in_event_return, 0, sizeof(XEvent));
670+ std::memset(&focus_out_event_return, 0, sizeof(XEvent));
671+ std::memset(&vscroll_event_return, 0, sizeof(XEvent));
672+ std::memset(&motion_event_return, 0, sizeof(XEvent));
673 visual_info.depth = 24;
674 keypress_event_return.type = KeyPress;
675 button_release_event_return.type = ButtonRelease;
676@@ -40,6 +49,7 @@
677 vscroll_event_return.type = ButtonPress;
678 XButtonEvent& xbev = (XButtonEvent&)vscroll_event_return;
679 xbev.button = Button4;
680+ motion_event_return.type = MotionNotify;
681 }
682
683 mtd::MockX11::MockX11()
684@@ -171,3 +181,8 @@
685 {
686 return global_mock->XSetWMHints(display, window, wmhints);
687 }
688+
689+int XPending(Display* display)
690+{
691+ return global_mock->XPending(display);
692+}
693
694=== modified file 'tests/unit-tests/input/test_x11_platform.cpp'
695--- tests/unit-tests/input/test_x11_platform.cpp 2016-01-29 08:18:22 +0000
696+++ tests/unit-tests/input/test_x11_platform.cpp 2016-02-24 09:00:08 +0000
697@@ -174,6 +174,28 @@
698 process_input_event();
699 }
700
701+TEST_F(X11PlatformTest, motion_event_trigger_pointer_movement)
702+{
703+ prepare_event_processing();
704+
705+ InSequence seq;
706+ mock_x11.fake_x11.motion_event_return.xmotion.x = 20;
707+ mock_x11.fake_x11.motion_event_return.xmotion.y = 20;
708+ EXPECT_CALL(mock_x11, XNextEvent(_,_))
709+ .WillOnce(DoAll(SetArgPointee<1>(mock_x11.fake_x11.motion_event_return),
710+ Return(1)));
711+ EXPECT_CALL(mock_pointer_sink, handle_input(mt::PointerEventWithDiff(20, 20)));
712+ mock_x11.fake_x11.motion_event_return.xmotion.x = 40;
713+ mock_x11.fake_x11.motion_event_return.xmotion.y = 25;
714+ EXPECT_CALL(mock_x11, XNextEvent(_,_))
715+ .WillOnce(DoAll(SetArgPointee<1>(mock_x11.fake_x11.motion_event_return),
716+ Return(1)));
717+ EXPECT_CALL(mock_pointer_sink, handle_input(mt::PointerEventWithDiff(20, 5)));
718+
719+ process_input_event();
720+ process_input_event();
721+}
722+
723 TEST_F(X11PlatformTest, grabs_keyboard)
724 {
725 prepare_event_processing();

Subscribers

People subscribed via source and target branches