Mir

Merge lp:~alan-griffiths/mir/drag-and-drop into lp:mir

Proposed by Alan Griffiths
Status: Merged
Merged at revision: 4100
Proposed branch: lp:~alan-griffiths/mir/drag-and-drop
Merge into: lp:mir
Diff against target: 2159 lines (+1040/-26)
77 files modified
examples/server_example_basic_window_manager.cpp (+8/-0)
examples/server_example_basic_window_manager.h (+5/-0)
include/client/mir/events/event_builders.h (+2/-0)
include/client/mir_toolkit/extensions/drag_and_drop.h (+68/-0)
include/core/mir_toolkit/common.h (+2/-0)
include/server/mir/scene/null_surface_observer.h (+1/-0)
include/server/mir/scene/surface.h (+1/-0)
include/server/mir/scene/surface_observer.h (+2/-0)
include/server/mir/shell/abstract_shell.h (+8/-0)
include/server/mir/shell/focus_controller.h (+5/-0)
include/server/mir/shell/input_targeter.h (+5/-0)
include/server/mir/shell/shell.h (+4/-0)
include/server/mir/shell/shell_wrapper.h (+8/-0)
include/server/mir/shell/system_compositor_window_manager.h (+5/-0)
include/server/mir/shell/window_manager.h (+5/-0)
include/test/mir/test/doubles/mock_window_manager.h (+1/-0)
include/test/mir/test/doubles/stub_surface.h (+1/-0)
include/test/mir_test_framework/observant_shell.h (+8/-0)
src/capnproto/mir_event.capnp (+5/-1)
src/client/CMakeLists.txt (+2/-0)
src/client/drag_and_drop.cpp (+67/-0)
src/client/drag_and_drop.h (+32/-0)
src/client/events/event_builders.cpp (+25/-0)
src/client/mir_blob.cpp (+1/-8)
src/client/mir_connection.cpp (+4/-0)
src/client/mir_surface.cpp (+17/-0)
src/client/mir_surface.h (+1/-0)
src/client/rpc/mir_display_server.cpp (+9/-0)
src/client/rpc/mir_display_server.h (+4/-0)
src/client/symbols.map (+2/-0)
src/common/events/pointer_event.cpp (+41/-3)
src/common/events/surface_event.cpp (+39/-1)
src/common/symbols.map (+4/-0)
src/include/common/mir/events/pointer_event.h (+6/-1)
src/include/common/mir/events/surface_event.h (+6/-1)
src/include/common/mir/protobuf/display_server.h (+4/-0)
src/include/common/mir_blob.h (+32/-0)
src/include/server/mir/frontend/shell.h (+5/-0)
src/include/server/mir/scene/surface_event_source.h (+1/-0)
src/include/server/mir/scene/surface_observers.h (+1/-0)
src/include/server/mir/shell/basic_window_manager.h (+15/-0)
src/include/server/mir/shell/canonical_window_manager.h (+4/-0)
src/protobuf/mir_protobuf.proto (+5/-0)
src/protobuf/symbols.map (+26/-0)
src/server/frontend/protobuf_message_processor.cpp (+4/-0)
src/server/frontend/session_mediator.cpp (+20/-1)
src/server/frontend/session_mediator.h (+4/-0)
src/server/frontend/shell_wrapper.cpp (+8/-0)
src/server/frontend/shell_wrapper.h (+5/-0)
src/server/input/null_input_targeter.h (+3/-0)
src/server/input/surface_input_dispatcher.cpp (+32/-6)
src/server/input/surface_input_dispatcher.h (+5/-1)
src/server/scene/basic_surface.cpp (+12/-0)
src/server/scene/basic_surface.h (+1/-0)
src/server/scene/legacy_surface_change_notification.cpp (+4/-0)
src/server/scene/legacy_surface_change_notification.h (+1/-0)
src/server/scene/null_surface_observer.cpp (+1/-0)
src/server/scene/surface_event_source.cpp (+5/-0)
src/server/shell/abstract_shell.cpp (+17/-0)
src/server/shell/basic_window_manager.cpp (+21/-0)
src/server/shell/canonical_window_manager.cpp (+13/-0)
src/server/shell/frontend_shell.cpp (+10/-0)
src/server/shell/frontend_shell.h (+5/-0)
src/server/shell/shell_wrapper.cpp (+18/-0)
src/server/shell/system_compositor_window_manager.cpp (+7/-0)
src/server/symbols.map (+10/-0)
tests/acceptance-tests/CMakeLists.txt (+2/-0)
tests/acceptance-tests/drag_and_drop.cpp (+293/-0)
tests/acceptance-tests/test_client_cursor_api.cpp (+1/-0)
tests/include/mir/test/doubles/mock_input_targeter.h (+3/-0)
tests/include/mir/test/doubles/mock_shell.h (+3/-0)
tests/include/mir/test/doubles/stub_display_server.h (+4/-0)
tests/include/mir/test/doubles/stub_input_targeter.h (+3/-0)
tests/include/mir/test/doubles/stub_scene_surface.h (+1/-0)
tests/mir_test_framework/observant_shell.cpp (+21/-2)
tests/mir_test_framework/stub_surface.cpp (+4/-0)
tests/unit-tests/client/test_client_mir_surface.cpp (+2/-1)
To merge this branch: bzr merge lp:~alan-griffiths/mir/drag-and-drop
Reviewer Review Type Date Requested Status
Alan Griffiths Abstain
Mir CI Bot continuous-integration Needs Fixing
Kevin DuBois (community) Approve
Review via email: mp+319581@code.launchpad.net

Commit message

Initial support for Drag and Drop: tests (and implementation for) starting drag

Description of the change

Initial support for Drag and Drop: tests (and implementation for) starting drag

This covers the first few interactions of https://goo.gl/AfG5v2

More to come...

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :
Download full text (24.2 KiB)

LP:1613523

Oh! This one seems new...

15:13:59 [ RUN ] MirClientSurfaceTest.attributes_set_on_surface_creation
15:13:59
15:13:59 GMOCK WARNING:
15:13:59 Uninteresting mock function call - returning directly.
15:13:59 Function call: adopted_by(0x9af56b0)
15:13:59 NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
15:13:59
15:13:59 GMOCK WARNING:
15:13:59 Uninteresting mock function call - taking default action specified at:
15:13:59 /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/tests/unit-tests/client/test_client_mir_surface.cpp:271:
15:13:59 Function call: swap_interval()
15:13:59 Returns: 1
15:13:59 NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
15:13:59 ==11697== Conditional jump or move depends on uninitialised value(s)
15:13:59 ==11697== at 0x1CDDEB1: testing::AssertionResult testing::internal::CmpHelperEQ<int, int>(char const*, char const*, int const&, int const&) (gtest.h:1392)
15:13:59 ==11697== by 0x1CD3C33: testing::AssertionResult testing::internal::EqHelper<false>::Compare<int, int>(char const*, char const*, int const&, int const&) (gtest.h:1421)
15:13:59 ==11697== by 0x1E8F58F: MirClientSurfaceTest_attributes_set_on_surface_creation_Test::TestBody() (test_client_mir_surface.cpp:372)
15:13:59 ==11697== by 0x2D929FD: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (in /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/obj-x86_64-linux-gnu/bin/mir_unit_tests.bin)
15:13:59 ==11697== by 0x2D7EF8A: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (in /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/obj-x86_64-linux-gnu/bin/mir_unit_tests.bin)
15:13:59 ==11697== by 0x2D64405: testing::Test::Run() (in /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/obj-x86_64-linux-gnu/bin/mir_unit_tests.bin)
15:13:59 ==11697== by 0x2D65372: testing::TestInfo::Run() (in /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/obj-x86_64-linux-gnu/bin/mir_unit_tests.bin)
15:13:59 ==11697== by 0x2D65B7B: testing::TestCase::Run() (in /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/obj-x86_64-linux-gnu/bin/mir_unit_tests.bin)
15:13:59 ==11697== by 0x2D6DD20: testing::internal::UnitTestImpl::RunAllTests() (in /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/obj-x86_64-linux-gnu/bin/mir_unit_tests.bin)
15:13:59 ==11697== by 0x2D95F2D: bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (in /<<BUILDDIR>>/mir-0.26.0+zesty4276bzr4104/obj-x86_64-linux-gnu/bin/mir_unit_tests.bin)
15:13:59 ==11697== by 0x2D8111A: bool testin...

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> Oh! This one seems new...
>
> 15:13:59 [ RUN ] MirClientSurfaceTest.attributes_set_on_surface_creation

Fixed

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

FAILED: Continuous integration, rev:4105
https://mir-jenkins.ubuntu.com/job/mir-ci/3130/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4202/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4289
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4279
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4279
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4279
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4229
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4229/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4229
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4229/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4229
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4229/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4229/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4229/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4229
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4229/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I had almost forgotten about g++-4.9 - and I don't have a system with it to experiment on any longer.

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

PASSED: Continuous integration, rev:4106
https://mir-jenkins.ubuntu.com/job/mir-ci/3132/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4204
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4291
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4281
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4281
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4281
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4231
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4231/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4231
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4231/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4231
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4231/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/4231
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4231/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/4231
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4231/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4231
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4231/artifact/output/*zip*/output.zip

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

review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

nits:
+struct MyMirBlob : MirBlob
DnDBlob?

+ //std::copy(reader.begin(), reader.end(), back_inserter(blob->data_));
why commented out?

lgtm otherwise

review: Approve
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> nits:
> +struct MyMirBlob : MirBlob
> DnDBlob?

Is that clearer?

> + //std::copy(reader.begin(), reader.end(), back_inserter(blob->data_));
> why commented out?

Because that's what I would write if capnp would let it compile. ;)

I guess I can delete it, the code is clear enough without.

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

FAILED: Continuous integration, rev:4108
https://mir-jenkins.ubuntu.com/job/mir-ci/3141/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4215/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4302
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4292
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4292
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4292
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4242
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4242/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4242/console
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4242/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4242
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4242/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/4242
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4242/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4242
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4242/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

18:37:58 11: [ RUN ] DragAndDrop.during_drag_when_user_moves_mouse_client_receives_handle
...
18:39:30 11: /<<BUILDDIR>>/mir-0.26.0+xenial4292bzr4108/tests/acceptance-tests/drag_and_drop.cpp:191: Failure
18:39:30 11: Value of: have_cookie.wait_for(receive_event_timeout)
18:39:30 11: Expected: is equal to true
18:39:30 11: Actual: false (of type bool)
18:39:30 11: ==27856== Invalid read of size 8

The memory errors and FD leaks that follow result from following the resulting nullptr.

~~~~

18:20:22 12: [ FAILED ] ClientLatency.dropping_latency_is_closer_to_zero_than_one
18:20:22 12: [ FAILED ] ClientLatency.async_swap_dropping_latency_is_closer_to_zero_than_one

lp:1640366

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

FAILED: Continuous integration, rev:4109
https://mir-jenkins.ubuntu.com/job/mir-ci/3150/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/4229/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4316
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4306
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4306
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4306
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4256/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4256
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4256/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4256
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4256/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/4256
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4256/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/4256
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4256/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4256
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4256/artifact/output/*zip*/output.zip

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

review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK, that's a better failure mode.

I'm hoping the follow-up fixes the race that causes this, in which case I'll merge the MPs and resubmit.

11:34:50 9: [ RUN ] DragAndDrop.during_drag_when_user_moves_mouse_client_receives_handle
11:34:50 9: [2017-03-14 11:34:50.894056] mirserver: Starting
11:34:50 9: [2017-03-14 11:34:50.897709] mirserver: Selected driver: mir:stub-graphics (version 0.27.0)
11:34:50 9: [2017-03-14 11:34:50.919402] mirserver: Using software cursor
11:34:51 9: [2017-03-14 11:34:51.080386] mirserver: Selected input driver: mir:stub-input (version: 0.27.0)
11:34:51 9: [2017-03-14 11:34:51.096963] mirserver: Mir version 0.27.0
11:34:51 9: [2017-03-14 11:34:51.103497] mirserver: Initial display configuration:
11:34:51 9: [2017-03-14 11:34:51.103792] mirserver: Output 1: VGA connected, used
11:34:51 9: [2017-03-14 11:34:51.104124] mirserver: Physical size 0.0" 0x0mm
11:34:51 9: [2017-03-14 11:34:51.104267] mirserver: Power is on
11:34:51 9: [2017-03-14 11:34:51.104432] mirserver: Current mode 800x600 60.00Hz
11:34:51 9: [2017-03-14 11:34:51.104592] mirserver: Preferred mode 800x600 60.00Hz
11:34:51 9: [2017-03-14 11:34:51.104726] mirserver: Orientation normal
11:34:51 9: [2017-03-14 11:34:51.104871] mirserver: Logical size 800x600
11:34:51 9: [2017-03-14 11:34:51.105010] mirserver: Logical position +0+0
11:34:51 9: [2017-03-14 11:34:51.105154] mirserver: Scaling factor: 1.00
11:36:21 9: /<<BUILDDIR>>/mir-0.26.1+17.04.20170209.1+zesty4306bzr4109/tests/acceptance-tests/drag_and_drop.cpp:191: Failure
11:36:21 9: Value of: have_cookie.wait_for(receive_event_timeout)
11:36:21 9: Expected: is equal to true
11:36:21 9: Actual: false (of type bool)
11:36:21 9: /<<BUILDDIR>>/mir-0.26.1+17.04.20170209.1+zesty4306bzr4109/tests/acceptance-tests/drag_and_drop.cpp:286: Failure
11:36:21 9: Value of: cookie.get()
11:36:21 9: Expected: isn't NULL
11:36:21 9: Actual: NULL (of type MirCookie const*)
11:36:21 9: [2017-03-14 11:36:21.680766] mirserver: Stopping
11:36:21 9: [ FAILED ] DragAndDrop.during_drag_when_user_moves_mouse_client_receives_handle (90835 ms)

review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'examples/server_example_basic_window_manager.cpp'
2--- examples/server_example_basic_window_manager.cpp 2017-01-18 02:29:37 +0000
3+++ examples/server_example_basic_window_manager.cpp 2017-03-14 11:00:58 +0000
4@@ -136,6 +136,14 @@
5 policy->handle_raise_surface(session, surface);
6 }
7
8+void me::BasicWindowManager::handle_request_drag_and_drop(
9+ std::shared_ptr<scene::Session> const& /*session*/,
10+ std::shared_ptr<scene::Surface> const& /*surface*/,
11+ uint64_t /*timestamp*/)
12+{
13+ // Not supported in example servers
14+}
15+
16 int me::BasicWindowManager::set_surface_attribute(
17 std::shared_ptr<scene::Session> const& /*session*/,
18 std::shared_ptr<scene::Surface> const& surface,
19
20=== modified file 'examples/server_example_basic_window_manager.h'
21--- examples/server_example_basic_window_manager.h 2017-01-18 02:29:37 +0000
22+++ examples/server_example_basic_window_manager.h 2017-03-14 11:00:58 +0000
23@@ -174,6 +174,11 @@
24 std::shared_ptr<scene::Surface> const& surface,
25 uint64_t timestamp) override;
26
27+ void handle_request_drag_and_drop(
28+ std::shared_ptr<scene::Session> const& session,
29+ std::shared_ptr<scene::Surface> const& surface,
30+ uint64_t timestamp) override;
31+
32 int set_surface_attribute(
33 std::shared_ptr<scene::Session> const& /*session*/,
34 std::shared_ptr<scene::Surface> const& surface,
35
36=== modified file 'include/client/mir/events/event_builders.h'
37--- include/client/mir/events/event_builders.h 2017-02-15 13:36:35 +0000
38+++ include/client/mir/events/event_builders.h 2017-03-14 11:00:58 +0000
39@@ -161,6 +161,8 @@
40 void transform_positions(MirEvent& event, mir::geometry::Displacement const& movement);
41 void set_window_id(MirEvent& event, int window_id);
42
43+EventUPtr make_start_drag_and_drop_event(frontend::SurfaceId const& surface_id, std::vector<uint8_t> const& handle);
44+void set_drag_and_drop_handle(MirEvent& event, std::vector<uint8_t> const& handle);
45 }
46 }
47
48
49=== added file 'include/client/mir_toolkit/extensions/drag_and_drop.h'
50--- include/client/mir_toolkit/extensions/drag_and_drop.h 1970-01-01 00:00:00 +0000
51+++ include/client/mir_toolkit/extensions/drag_and_drop.h 2017-03-14 11:00:58 +0000
52@@ -0,0 +1,68 @@
53+/*
54+ * Copyright © 2017 Canonical Ltd.
55+ *
56+ * This program is free software: you can redistribute it and/or modify it
57+ * under the terms of the GNU Lesser General Public License version 3,
58+ * as published by the Free Software Foundation.
59+ *
60+ * This program is distributed in the hope that it will be useful,
61+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
62+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63+ * GNU Lesser General Public License for more details.
64+ *
65+ * You should have received a copy of the GNU Lesser General Public License
66+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
67+ *
68+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
69+ */
70+
71+#ifndef MIR_DRAG_AND_DROP_H
72+#define MIR_DRAG_AND_DROP_H
73+
74+#include "mir_toolkit/mir_extension_core.h"
75+#include "mir_toolkit/client_types.h"
76+
77+#ifdef __cplusplus
78+extern "C" {
79+#endif
80+
81+typedef struct MirDragAndDropV1
82+{
83+ /**
84+ * Request drag and drop. If the request succeeds a window event with a
85+ * "start drag" handle will be received.
86+ *
87+ * \warning An invalid cookie will terminate the client connection.
88+ *
89+ * \param [in] window The source window
90+ * \param [in] cookie A cookie instance obtained from an input event.
91+ */
92+ void (*request_drag_and_drop)(MirWindow* window, MirCookie const* cookie);
93+
94+ /**
95+ * Retrieve any "drag & drop" handle associated with the event
96+ *
97+ * \param [in] event The event
98+ * \return The associated drag handle or NULL
99+ */
100+ MirBlob* (*start_drag_and_drop)(MirWindowEvent const* event);
101+
102+ /**
103+ * Retrieve any "drag & drop" handle associated with the event.
104+ *
105+ * \param [in] event The event
106+ * \return The associated drag handle or NULL
107+ */
108+ MirBlob* (*pointer_drag_and_drop)(MirPointerEvent const* event);
109+
110+} MirDragAndDropV1;
111+
112+static inline MirDragAndDropV1 const* mir_drag_and_drop_v1(MirConnection* connection)
113+{
114+ return (MirDragAndDropV1 const*) mir_connection_request_extension(connection, "mir_drag_and_drop", 1);
115+}
116+
117+#ifdef __cplusplus
118+}
119+#endif
120+#endif //MIR_DRAG_AND_DROP_H
121\ No newline at end of file
122
123=== modified file 'include/core/mir_toolkit/common.h'
124--- include/core/mir_toolkit/common.h 2017-01-23 22:29:00 +0000
125+++ include/core/mir_toolkit/common.h 2017-03-14 11:00:58 +0000
126@@ -63,6 +63,7 @@
127 mir_surface_attrib_dpi,
128 mir_surface_attrib_visibility,
129 mir_surface_attrib_preferred_orientation,
130+ mir_surface_attrib_drag_and_drop_handle,
131 /* Must be last */
132 mir_surface_attribs
133 } MirSurfaceAttrib __attribute__ ((deprecated("use MirWindowAttrib")));
134@@ -84,6 +85,7 @@
135 mir_window_attrib_dpi,
136 mir_window_attrib_visibility,
137 mir_window_attrib_preferred_orientation,
138+ mir_window_attrib_drag_and_drop_handle,
139 /* Must be last */
140 mir_window_attribs
141 } MirWindowAttrib;
142
143=== modified file 'include/server/mir/scene/null_surface_observer.h'
144--- include/server/mir/scene/null_surface_observer.h 2017-02-15 13:36:35 +0000
145+++ include/server/mir/scene/null_surface_observer.h 2017-03-14 11:00:58 +0000
146@@ -47,6 +47,7 @@
147 void cursor_image_removed() override;
148 void placed_relative(geometry::Rectangle const& placement) override;
149 void input_consumed(MirEvent const* event) override;
150+ void start_drag_and_drop(std::vector<uint8_t> const& handle) override;
151
152 protected:
153 NullSurfaceObserver(NullSurfaceObserver const&) = delete;
154
155=== modified file 'include/server/mir/scene/surface.h'
156--- include/server/mir/scene/surface.h 2017-02-15 14:45:41 +0000
157+++ include/server/mir/scene/surface.h 2017-03-14 11:00:58 +0000
158@@ -116,6 +116,7 @@
159 virtual MirPointerConfinementState confine_pointer_state() const = 0;
160
161 virtual void placed_relative(geometry::Rectangle const& placement) = 0;
162+ virtual void start_drag_and_drop(std::vector<uint8_t> const& handle) = 0;
163 };
164 }
165 }
166
167=== modified file 'include/server/mir/scene/surface_observer.h'
168--- include/server/mir/scene/surface_observer.h 2017-02-15 13:36:35 +0000
169+++ include/server/mir/scene/surface_observer.h 2017-03-14 11:00:58 +0000
170@@ -27,6 +27,7 @@
171
172 #include <glm/glm.hpp>
173 #include <string>
174+#include <vector>
175
176 namespace mir
177 {
178@@ -62,6 +63,7 @@
179 virtual void cursor_image_removed() = 0;
180 virtual void placed_relative(geometry::Rectangle const& placement) = 0;
181 virtual void input_consumed(MirEvent const* event) = 0;
182+ virtual void start_drag_and_drop(std::vector<uint8_t> const& handle) = 0;
183
184 protected:
185 SurfaceObserver() = default;
186
187=== modified file 'include/server/mir/shell/abstract_shell.h'
188--- include/server/mir/shell/abstract_shell.h 2017-01-18 02:29:37 +0000
189+++ include/server/mir/shell/abstract_shell.h 2017-03-14 11:00:58 +0000
190@@ -82,6 +82,11 @@
191 std::shared_ptr<scene::Surface> const& surface,
192 uint64_t timestamp) override;
193
194+ void request_drag_and_drop(
195+ std::shared_ptr<scene::Session> const& session,
196+ std::shared_ptr<scene::Surface> const& surface,
197+ uint64_t timestamp) override;
198+
199 std::shared_ptr<scene::PromptSession> start_prompt_session_for(
200 std::shared_ptr<scene::Session> const& session,
201 scene::PromptSessionCreationParameters const& params) override;
202@@ -124,6 +129,9 @@
203
204 void update_focused_surface_confined_region();
205
206+ void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override;
207+ void clear_drag_and_drop_handle() override;
208+
209 protected:
210 std::shared_ptr<InputTargeter> const input_targeter;
211 std::shared_ptr<SurfaceStack> const surface_stack;
212
213=== modified file 'include/server/mir/shell/focus_controller.h'
214--- include/server/mir/shell/focus_controller.h 2016-01-29 08:18:22 +0000
215+++ include/server/mir/shell/focus_controller.h 2017-03-14 11:00:58 +0000
216@@ -19,8 +19,10 @@
217 #ifndef MIR_SHELL_FOCUS_CONTROLLER_H_
218 #define MIR_SHELL_FOCUS_CONTROLLER_H_
219
220+#include <stddef.h>
221 #include <memory>
222 #include <set>
223+#include <vector>
224
225 namespace mir
226 {
227@@ -54,6 +56,9 @@
228
229 virtual void raise(SurfaceSet const& surfaces) = 0;
230
231+ virtual void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) = 0;
232+ virtual void clear_drag_and_drop_handle() = 0;
233+
234 protected:
235 FocusController() = default;
236 FocusController(FocusController const&) = delete;
237
238=== modified file 'include/server/mir/shell/input_targeter.h'
239--- include/server/mir/shell/input_targeter.h 2015-06-18 02:46:16 +0000
240+++ include/server/mir/shell/input_targeter.h 2017-03-14 11:00:58 +0000
241@@ -19,7 +19,9 @@
242 #ifndef MIR_SHELL_INPUT_TARGETER_H_
243 #define MIR_SHELL_INPUT_TARGETER_H_
244
245+#include <stddef.h>
246 #include <memory>
247+#include <vector>
248
249 namespace mir
250 {
251@@ -40,6 +42,9 @@
252 virtual void set_focus(std::shared_ptr<input::Surface> const& focus_surface) = 0;
253 virtual void clear_focus() = 0;
254
255+ virtual void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) = 0;
256+ virtual void clear_drag_and_drop_handle() = 0;
257+
258 protected:
259 InputTargeter() = default;
260 InputTargeter(InputTargeter const&) = delete;
261
262=== modified file 'include/server/mir/shell/shell.h'
263--- include/server/mir/shell/shell.h 2017-01-19 00:27:55 +0000
264+++ include/server/mir/shell/shell.h 2017-03-14 11:00:58 +0000
265@@ -100,6 +100,10 @@
266 std::shared_ptr<scene::Surface> const& surface,
267 uint64_t timestamp) = 0;
268
269+ virtual void request_drag_and_drop(
270+ std::shared_ptr<scene::Session> const& session,
271+ std::shared_ptr<scene::Surface> const& surface,
272+ uint64_t timestamp) = 0;
273 /** @} */
274 };
275 }
276
277=== modified file 'include/server/mir/shell/shell_wrapper.h'
278--- include/server/mir/shell/shell_wrapper.h 2017-01-18 02:29:37 +0000
279+++ include/server/mir/shell/shell_wrapper.h 2017-03-14 11:00:58 +0000
280@@ -85,11 +85,19 @@
281 std::shared_ptr<scene::Surface> const& surface,
282 uint64_t timestamp) override;
283
284+ void request_drag_and_drop(
285+ std::shared_ptr<scene::Session> const& session,
286+ std::shared_ptr<scene::Surface> const& surface,
287+ uint64_t timestamp) override;
288+
289 void add_display(geometry::Rectangle const& area) override;
290 void remove_display(geometry::Rectangle const& area) override;
291
292 bool handle(MirEvent const& event) override;
293
294+ void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override;
295+ void clear_drag_and_drop_handle() override;
296+
297 protected:
298 std::shared_ptr<Shell> const wrapped;
299 };
300
301=== modified file 'include/server/mir/shell/system_compositor_window_manager.h'
302--- include/server/mir/shell/system_compositor_window_manager.h 2017-01-18 02:29:37 +0000
303+++ include/server/mir/shell/system_compositor_window_manager.h 2017-03-14 11:00:58 +0000
304@@ -95,6 +95,11 @@
305 std::shared_ptr<scene::Surface> const& surface,
306 uint64_t timestamp) override;
307
308+ void handle_request_drag_and_drop(
309+ std::shared_ptr<scene::Session> const& session,
310+ std::shared_ptr<scene::Surface> const& surface,
311+ uint64_t timestamp) override;
312+
313 int set_surface_attribute(
314 std::shared_ptr<scene::Session> const& session,
315 std::shared_ptr<scene::Surface> const& surface,
316
317=== modified file 'include/server/mir/shell/window_manager.h'
318--- include/server/mir/shell/window_manager.h 2017-01-18 02:29:37 +0000
319+++ include/server/mir/shell/window_manager.h 2017-03-14 11:00:58 +0000
320@@ -76,6 +76,11 @@
321 std::shared_ptr<scene::Surface> const& surface,
322 uint64_t timestamp) = 0;
323
324+ virtual void handle_request_drag_and_drop(
325+ std::shared_ptr<scene::Session> const& session,
326+ std::shared_ptr<scene::Surface> const& surface,
327+ uint64_t timestamp) = 0;
328+
329 virtual ~WindowManager() = default;
330 WindowManager() = default;
331 WindowManager(WindowManager const&) = delete;
332
333=== modified file 'include/test/mir/test/doubles/mock_window_manager.h'
334--- include/test/mir/test/doubles/mock_window_manager.h 2017-01-18 02:29:37 +0000
335+++ include/test/mir/test/doubles/mock_window_manager.h 2017-03-14 11:00:58 +0000
336@@ -58,6 +58,7 @@
337 MOCK_METHOD1(handle_pointer_event, bool(MirPointerEvent const*));
338
339 MOCK_METHOD3(handle_raise_surface, void(std::shared_ptr<scene::Session> const&, std::shared_ptr<scene::Surface> const&, uint64_t));
340+ MOCK_METHOD3(handle_request_drag_and_drop, void(std::shared_ptr<scene::Session> const&, std::shared_ptr<scene::Surface> const&, uint64_t));
341
342 MOCK_METHOD4(set_surface_attribute,
343 int(std::shared_ptr<scene::Session> const& session,
344
345=== modified file 'include/test/mir/test/doubles/stub_surface.h'
346--- include/test/mir/test/doubles/stub_surface.h 2017-02-15 14:45:41 +0000
347+++ include/test/mir/test/doubles/stub_surface.h 2017-03-14 11:00:58 +0000
348@@ -70,6 +70,7 @@
349 void set_confine_pointer_state(MirPointerConfinementState state) override;
350 MirPointerConfinementState confine_pointer_state() const override;
351 void placed_relative(geometry::Rectangle const& placement) override;
352+ void start_drag_and_drop(std::vector<uint8_t> const& handle) override;
353 };
354 }
355 }
356
357=== modified file 'include/test/mir_test_framework/observant_shell.h'
358--- include/test/mir_test_framework/observant_shell.h 2017-01-20 00:01:50 +0000
359+++ include/test/mir_test_framework/observant_shell.h 2017-03-14 11:00:58 +0000
360@@ -96,6 +96,14 @@
361 std::shared_ptr<mir::scene::Surface> const& window,
362 uint64_t timestamp) override;
363
364+ void request_drag_and_drop(
365+ std::shared_ptr<mir::scene::Session> const& session,
366+ std::shared_ptr<mir::scene::Surface> const& window,
367+ uint64_t timestamp) override;
368+
369+ void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override;
370+ void clear_drag_and_drop_handle() override;
371+
372 private:
373 std::shared_ptr<mir::shell::Shell> const wrapped;
374 std::shared_ptr<mir::scene::SurfaceObserver> const surface_observer;
375
376=== modified file 'src/capnproto/mir_event.capnp'
377--- src/capnproto/mir_event.capnp 2017-02-17 08:46:05 +0000
378+++ src/capnproto/mir_event.capnp 2017-03-14 11:00:58 +0000
379@@ -104,6 +104,8 @@
380
381 buttons @7 :UInt32;
382
383+ dndHandle @8 :List(UInt8);
384+
385 enum PointerAction
386 {
387 up @0;
388@@ -149,6 +151,7 @@
389 id @0 :Int32;
390 attrib @1 :Attrib;
391 value @2 :Int32;
392+ dndHandle @3 :List(UInt8);
393
394 enum Attrib
395 {
396@@ -160,8 +163,9 @@
397 dpi @4;
398 visibility @5;
399 preferredOrientation @6;
400+ startDragAndDrop @7;
401 # Must be last
402- surfaceAttrib @7;
403+ surfaceAttrib @8;
404 }
405 }
406
407
408=== modified file 'src/client/CMakeLists.txt'
409--- src/client/CMakeLists.txt 2017-01-24 13:43:12 +0000
410+++ src/client/CMakeLists.txt 2017-03-14 11:00:58 +0000
411@@ -49,6 +49,7 @@
412 add_library(mirclientobjects OBJECT
413
414 display_configuration.cpp
415+ drag_and_drop.cpp drag_and_drop.h
416 error_connections.cpp
417 event.cpp
418 event_printer.cpp
419@@ -105,6 +106,7 @@
420 ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/mir_error.h
421 mir_extension_core.cpp
422 ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/mir_extension_core.h
423+ ${CMAKE_SOURCE_DIR}/include/client/mir_toolkit/extensions/drag_and_drop.h
424 )
425
426 # Ensure protobuf C++ headers have been produced before
427
428=== added file 'src/client/drag_and_drop.cpp'
429--- src/client/drag_and_drop.cpp 1970-01-01 00:00:00 +0000
430+++ src/client/drag_and_drop.cpp 2017-03-14 11:00:58 +0000
431@@ -0,0 +1,67 @@
432+/*
433+ * Copyright © 2017 Canonical Ltd.
434+ *
435+ * This program is free software: you can redistribute it and/or modify it
436+ * under the terms of the GNU Lesser General Public License version 3,
437+ * as published by the Free Software Foundation.
438+ *
439+ * This program is distributed in the hope that it will be useful,
440+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
441+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
442+ * GNU Lesser General Public License for more details.
443+ *
444+ * You should have received a copy of the GNU Lesser General Public License
445+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
446+ *
447+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
448+ */
449+
450+#include "drag_and_drop.h"
451+#include "mir_toolkit/extensions/drag_and_drop.h"
452+
453+#include "mir/uncaught.h"
454+#include "mir/events/surface_event.h"
455+#include "mir/events/pointer_event.h"
456+
457+#include "mir_surface.h"
458+
459+namespace
460+{
461+
462+void request_drag_and_drop(MirWindow* window, MirCookie const* cookie)
463+try
464+{
465+ window->request_drag_and_drop(cookie);
466+}
467+catch (std::exception const& e)
468+{
469+ MIR_LOG_UNCAUGHT_EXCEPTION(e);
470+ abort();
471+}
472+
473+MirBlob* start_drag_and_drop(MirWindowEvent const* event)
474+try
475+{
476+ return event->dnd_handle();
477+}
478+catch (std::exception const& e)
479+{
480+ MIR_LOG_UNCAUGHT_EXCEPTION(e);
481+ abort();
482+}
483+
484+MirBlob* pointer_drag_and_drop(MirPointerEvent const* event)
485+try
486+{
487+ return event->dnd_handle();
488+}
489+catch (std::exception const& e)
490+{
491+ MIR_LOG_UNCAUGHT_EXCEPTION(e);
492+ abort();
493+}
494+
495+MirDragAndDropV1 const impl{&request_drag_and_drop, &start_drag_and_drop, &pointer_drag_and_drop};
496+}
497+
498+MirDragAndDropV1 const* const mir::drag_and_drop::v1 = &impl;
499
500=== added file 'src/client/drag_and_drop.h'
501--- src/client/drag_and_drop.h 1970-01-01 00:00:00 +0000
502+++ src/client/drag_and_drop.h 2017-03-14 11:00:58 +0000
503@@ -0,0 +1,32 @@
504+/*
505+ * Copyright © 2017 Canonical Ltd.
506+ *
507+ * This program is free software: you can redistribute it and/or modify it
508+ * under the terms of the GNU Lesser General Public License version 3,
509+ * as published by the Free Software Foundation.
510+ *
511+ * This program is distributed in the hope that it will be useful,
512+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
513+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
514+ * GNU Lesser General Public License for more details.
515+ *
516+ * You should have received a copy of the GNU Lesser General Public License
517+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
518+ *
519+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
520+ */
521+
522+#ifndef MIR_DRAG_AND_DROP_V1_H
523+#define MIR_DRAG_AND_DROP_V1_H
524+
525+typedef struct MirDragAndDropV1 MirDragAndDropV1;
526+
527+namespace mir
528+{
529+namespace drag_and_drop
530+{
531+extern MirDragAndDropV1 const* const v1;
532+}
533+}
534+
535+#endif //MIR_DRAG_AND_DROP_V1_H
536
537=== modified file 'src/client/events/event_builders.cpp'
538--- src/client/events/event_builders.cpp 2017-02-15 13:36:35 +0000
539+++ src/client/events/event_builders.cpp 2017-03-14 11:00:58 +0000
540@@ -110,6 +110,20 @@
541 return make_uptr_event(e);
542 }
543
544+auto mev::make_start_drag_and_drop_event(frontend::SurfaceId const& surface_id, std::vector<uint8_t> const& handle)
545+ -> EventUPtr
546+{
547+ auto e = new_event<MirWindowEvent>();
548+
549+ e->set_id(surface_id.as_value());
550+ e->set_attrib(mir_window_attrib_drag_and_drop_handle);
551+ e->set_value(0);
552+ e->set_dnd_handle(handle);
553+
554+ return make_uptr_event(e);
555+
556+}
557+
558 mir::EventUPtr mev::make_event(mf::SurfaceId const& surface_id)
559 {
560 auto e = new_event<MirCloseWindowEvent>();
561@@ -450,3 +464,14 @@
562 BOOST_THROW_EXCEPTION(std::invalid_argument("Event has no window id."));
563 }
564 }
565+
566+void mev::set_drag_and_drop_handle(MirEvent& event, std::vector<uint8_t> const& handle)
567+{
568+ if (event.type() == mir_event_type_input)
569+ {
570+ auto const input_event = event.to_input();
571+ if (mir_input_event_get_type(input_event) == mir_input_event_type_pointer)
572+ const_cast<MirPointerEvent*>(mir_input_event_get_pointer_event(input_event))->set_dnd_handle(handle);
573+ }
574+}
575+
576
577=== modified file 'src/client/mir_blob.cpp'
578--- src/client/mir_blob.cpp 2017-01-18 02:29:37 +0000
579+++ src/client/mir_blob.cpp 2017-03-14 11:00:58 +0000
580@@ -16,6 +16,7 @@
581 * Authored by: Alan Griffiths <alan@octopull.co.uk>
582 */
583
584+#include "mir_blob.h"
585 #include "display_configuration.h"
586
587 #include "mir_toolkit/mir_blob.h"
588@@ -25,14 +26,6 @@
589
590 namespace mp = mir::protobuf;
591
592-struct MirBlob
593-{
594- virtual size_t size() const = 0;
595- virtual void const* data() const = 0;
596-
597- virtual ~MirBlob() = default;
598-};
599-
600 namespace
601 {
602 struct MirManagedBlob : MirBlob
603
604=== modified file 'src/client/mir_connection.cpp'
605--- src/client/mir_connection.cpp 2017-03-14 04:41:33 +0000
606+++ src/client/mir_connection.cpp 2017-03-14 11:00:58 +0000
607@@ -17,6 +17,7 @@
608 */
609
610 #include "mir_connection.h"
611+#include "drag_and_drop.h"
612 #include "mir_surface.h"
613 #include "mir_prompt_session.h"
614 #include "mir_toolkit/extensions/graphics_module.h"
615@@ -1451,6 +1452,9 @@
616 if (!strcmp(name, "mir_extension_graphics_module") && (version == 1) && graphics_module_extension.is_set())
617 return &graphics_module_extension.value();
618
619+ if (!strcmp(name, "mir_drag_and_drop") && (version == 1))
620+ return const_cast<MirDragAndDropV1*>(mir::drag_and_drop::v1);
621+
622 return platform->request_interface(name, version);
623 }
624
625
626=== modified file 'src/client/mir_surface.cpp'
627--- src/client/mir_surface.cpp 2017-03-14 04:41:33 +0000
628+++ src/client/mir_surface.cpp 2017-03-14 11:00:58 +0000
629@@ -598,6 +598,23 @@
630 google::protobuf::NewCallback(google::protobuf::DoNothing));
631 }
632
633+void MirSurface::request_drag_and_drop(MirCookie const* cookie)
634+{
635+ mp::RequestAuthority authority;
636+
637+ std::unique_lock<decltype(mutex)> lock(mutex);
638+ authority.mutable_surface_id()->set_value(surface->id().value());
639+
640+ auto const event_cookie = authority.mutable_cookie();
641+
642+ event_cookie->set_cookie(cookie->cookie().data(), cookie->size());
643+
644+ server->request_drag_and_drop(
645+ &authority,
646+ void_response.get(),
647+ google::protobuf::NewCallback(google::protobuf::DoNothing));
648+}
649+
650 MirBufferStream* MirSurface::get_buffer_stream()
651 {
652 std::lock_guard<decltype(mutex)> lock(mutex);
653
654=== modified file 'src/client/mir_surface.h'
655--- src/client/mir_surface.h 2017-02-15 14:45:41 +0000
656+++ src/client/mir_surface.h 2017-03-14 11:00:58 +0000
657@@ -200,6 +200,7 @@
658 MirWaitHandle* set_preferred_orientation(MirOrientationMode mode);
659
660 void raise_surface(MirCookie const* cookie);
661+ void request_drag_and_drop(MirCookie const* cookie);
662
663 MirWaitHandle* configure_cursor(MirCursorConfiguration const* cursor);
664
665
666=== modified file 'src/client/rpc/mir_display_server.cpp'
667--- src/client/rpc/mir_display_server.cpp 2017-02-15 07:38:33 +0000
668+++ src/client/rpc/mir_display_server.cpp 2017-03-14 11:00:58 +0000
669@@ -238,6 +238,15 @@
670 {
671 channel->call_method(std::string(__func__), request, response, done);
672 }
673+
674+void mclr::DisplayServer::request_drag_and_drop(
675+ mir::protobuf::RequestAuthority const* request,
676+ mir::protobuf::Void* response,
677+ google::protobuf::Closure* done)
678+{
679+ channel->call_method(std::string(__func__), request, response, done);
680+}
681+
682 void mclr::DisplayServer::apply_input_configuration(
683 mir::protobuf::InputConfigurationRequest const* request,
684 mir::protobuf::Void* response,
685
686=== modified file 'src/client/rpc/mir_display_server.h'
687--- src/client/rpc/mir_display_server.h 2017-02-15 07:38:33 +0000
688+++ src/client/rpc/mir_display_server.h 2017-03-14 11:00:58 +0000
689@@ -155,6 +155,10 @@
690 mir::protobuf::RaiseRequest const* request,
691 mir::protobuf::Void* response,
692 google::protobuf::Closure* done) override;
693+ void request_drag_and_drop(
694+ mir::protobuf::RequestAuthority const* request,
695+ mir::protobuf::Void* response,
696+ google::protobuf::Closure* done) override;
697 void apply_input_configuration(
698 mir::protobuf::InputConfigurationRequest const* request,
699 mir::protobuf::Void* response,
700
701=== modified file 'src/client/symbols.map'
702--- src/client/symbols.map 2017-03-14 04:41:33 +0000
703+++ src/client/symbols.map 2017-03-14 11:00:58 +0000
704@@ -604,6 +604,8 @@
705 global:
706 extern "C++" {
707 mir::events::set_window_id*;
708+ mir::events::make_start_drag_and_drop_event*;
709+ mir::events::set_drag_and_drop_handle*;
710 };
711 } MIR_CLIENT_DETAIL_0.26.1;
712
713
714=== modified file 'src/common/events/pointer_event.cpp'
715--- src/common/events/pointer_event.cpp 2016-11-07 23:02:26 +0000
716+++ src/common/events/pointer_event.cpp 2017-03-14 11:00:58 +0000
717@@ -1,5 +1,5 @@
718 /*
719- * Copyright © 2016 Canonical Ltd.
720+ * Copyright © 2016-2017 Canonical Ltd.
721 *
722 * This program is free software: you can redistribute it and/or modify it
723 * under the terms of the GNU Lesser General Public License version 3,
724@@ -16,10 +16,11 @@
725 * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
726 */
727
728+#include "mir/events/pointer_event.h"
729+#include "mir_blob.h"
730+
731 #include <boost/throw_exception.hpp>
732
733-#include "mir/events/pointer_event.h"
734-
735 MirPointerEvent::MirPointerEvent()
736 {
737 event.initInput();
738@@ -132,3 +133,40 @@
739 {
740 event.getInput().getPointer().setAction(static_cast<mir::capnp::PointerEvent::PointerAction>(action));
741 }
742+
743+void MirPointerEvent::set_dnd_handle(std::vector<uint8_t> const& handle)
744+{
745+ event.getInput().getPointer().initDndHandle(handle.size());
746+ event.getInput().getPointer().setDndHandle(::kj::ArrayPtr<uint8_t const>{&*begin(handle), &*end(handle)});
747+}
748+
749+namespace
750+{
751+struct MyMirBlob : MirBlob
752+{
753+
754+ size_t size() const override { return data_.size(); }
755+ virtual void const* data() const override { return data_.data(); }
756+
757+ std::vector<uint8_t> data_;
758+};
759+}
760+
761+MirBlob* MirPointerEvent::dnd_handle() const
762+{
763+ auto const reader = event.asReader().getInput().getPointer();
764+
765+ if (!reader.hasDndHandle())
766+ return nullptr;
767+
768+ auto const dnd_handle = reader.getDndHandle();
769+
770+ auto blob = std::make_unique<MyMirBlob>();
771+ blob->data_.reserve(dnd_handle.size());
772+
773+ //std::copy(dnd_handle.begin(), dnd_handle.end(), back_inserter(blob->data_));
774+ for (auto p = dnd_handle.begin(); p != dnd_handle.end(); ++p)
775+ blob->data_.push_back(*p);
776+
777+ return blob.release();
778+}
779
780=== modified file 'src/common/events/surface_event.cpp'
781--- src/common/events/surface_event.cpp 2017-01-23 03:38:33 +0000
782+++ src/common/events/surface_event.cpp 2017-03-14 11:00:58 +0000
783@@ -1,5 +1,5 @@
784 /*
785- * Copyright © 2016 Canonical Ltd.
786+ * Copyright © 2016-2017 Canonical Ltd.
787 *
788 * This program is free software: you can redistribute it and/or modify it
789 * under the terms of the GNU Lesser General Public License version 3,
790@@ -17,6 +17,7 @@
791 */
792
793 #include "mir/events/surface_event.h"
794+#include "mir_blob.h"
795
796 // MirSurfaceEvent is a deprecated type, but we need to implement it
797 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
798@@ -55,3 +56,40 @@
799 {
800 event.getSurface().setValue(value);
801 }
802+
803+void MirSurfaceEvent::set_dnd_handle(std::vector<uint8_t> const& handle)
804+{
805+ event.getSurface().initDndHandle(handle.size());
806+ event.getSurface().setDndHandle(::kj::ArrayPtr<uint8_t const>{&*begin(handle), &*end(handle)});
807+}
808+
809+namespace
810+{
811+struct MyMirBlob : MirBlob
812+{
813+
814+ size_t size() const override { return data_.size(); }
815+ virtual void const* data() const override { return data_.data(); }
816+
817+ std::vector<uint8_t> data_;
818+};
819+}
820+
821+MirBlob* MirSurfaceEvent::dnd_handle() const
822+{
823+ if (!event.asReader().getSurface().hasDndHandle())
824+ return nullptr;
825+
826+ auto blob = std::make_unique<MyMirBlob>();
827+
828+ auto reader = event.asReader().getSurface().getDndHandle();
829+
830+ blob->data_.reserve(reader.size());
831+
832+ // Can't use std::copy() as the CapnP iterators don't provide an iterator category
833+ for (auto p = reader.begin(); p != reader.end(); ++p)
834+ blob->data_.push_back(*p);
835+
836+ return blob.release();
837+}
838+
839
840=== modified file 'src/common/symbols.map'
841--- src/common/symbols.map 2017-02-28 08:53:57 +0000
842+++ src/common/symbols.map 2017-03-14 11:00:58 +0000
843@@ -432,5 +432,9 @@
844 MirInputEvent::window_id*;
845 MirKeyboardEvent::set_text*;
846 MirKeyboardEvent::text*;
847+ MirPointerEvent::dnd_handle*;
848+ MirPointerEvent::set_dnd_handle*;
849+ MirSurfaceEvent::dnd_handle*;
850+ MirSurfaceEvent::set_dnd_handle*;
851 };
852 } MIR_COMMON_0.26;
853
854=== modified file 'src/include/common/mir/events/pointer_event.h'
855--- src/include/common/mir/events/pointer_event.h 2016-09-22 19:21:34 +0000
856+++ src/include/common/mir/events/pointer_event.h 2017-03-14 11:00:58 +0000
857@@ -1,5 +1,5 @@
858 /*
859- * Copyright © 2016 Canonical Ltd.
860+ * Copyright © 2016-2017 Canonical Ltd.
861 *
862 * This program is free software: you can redistribute it and/or modify it
863 * under the terms of the GNU Lesser General Public License version 3,
864@@ -21,6 +21,8 @@
865
866 #include "mir/events/input_event.h"
867
868+typedef struct MirBlob MirBlob;
869+
870 struct MirPointerEvent : MirInputEvent
871 {
872 MirPointerEvent();
873@@ -60,6 +62,9 @@
874
875 MirPointerButtons buttons() const;
876 void set_buttons(MirPointerButtons buttons);
877+
878+ void set_dnd_handle(std::vector<uint8_t> const& handle);
879+ MirBlob* dnd_handle() const;
880 private:
881 };
882
883
884=== modified file 'src/include/common/mir/events/surface_event.h'
885--- src/include/common/mir/events/surface_event.h 2017-01-18 02:29:37 +0000
886+++ src/include/common/mir/events/surface_event.h 2017-03-14 11:00:58 +0000
887@@ -1,5 +1,5 @@
888 /*
889- * Copyright © 2016 Canonical Ltd.
890+ * Copyright © 2016-2017 Canonical Ltd.
891 *
892 * This program is free software: you can redistribute it and/or modify it
893 * under the terms of the GNU Lesser General Public License version 3,
894@@ -21,6 +21,8 @@
895
896 #include "mir/events/event.h"
897
898+typedef struct MirBlob MirBlob;
899+
900 struct MirSurfaceEvent : MirEvent
901 {
902 MirSurfaceEvent();
903@@ -33,6 +35,9 @@
904
905 int value() const;
906 void set_value(int value);
907+
908+ void set_dnd_handle(std::vector<uint8_t> const& handle);
909+ MirBlob* dnd_handle() const;
910 };
911
912 #endif /* MIR_COMMON_SURFACE_EVENT_H_ */
913
914=== modified file 'src/include/common/mir/protobuf/display_server.h'
915--- src/include/common/mir/protobuf/display_server.h 2017-02-15 07:38:33 +0000
916+++ src/include/common/mir/protobuf/display_server.h 2017-03-14 11:00:58 +0000
917@@ -151,6 +151,10 @@
918 mir::protobuf::RaiseRequest const* request,
919 mir::protobuf::Void* response,
920 google::protobuf::Closure* done) = 0;
921+ virtual void request_drag_and_drop(
922+ mir::protobuf::RequestAuthority const* request,
923+ mir::protobuf::Void* response,
924+ google::protobuf::Closure* done) = 0;
925 virtual void apply_input_configuration(
926 mir::protobuf::InputConfigurationRequest const* request,
927 mir::protobuf::Void* response,
928
929=== added file 'src/include/common/mir_blob.h'
930--- src/include/common/mir_blob.h 1970-01-01 00:00:00 +0000
931+++ src/include/common/mir_blob.h 2017-03-14 11:00:58 +0000
932@@ -0,0 +1,32 @@
933+/*
934+ * Copyright © 2017 Canonical Ltd.
935+ *
936+ * This program is free software: you can redistribute it and/or modify
937+ * it under the terms of the GNU Lesser General Public License version 3 as
938+ * published by the Free Software Foundation.
939+ *
940+ * This program is distributed in the hope that it will be useful,
941+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
942+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
943+ * GNU Lesser General Public License for more details.
944+ *
945+ * You should have received a copy of the GNU Lesser General Public License
946+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
947+ *
948+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
949+ */
950+
951+#ifndef MIR_MIR_BLOB_H_H
952+#define MIR_MIR_BLOB_H_H
953+
954+#include <stddef.h>
955+
956+struct MirBlob
957+{
958+ virtual size_t size() const = 0;
959+ virtual void const* data() const = 0;
960+
961+ virtual ~MirBlob() = default;
962+};
963+
964+#endif //MIR_MIR_BLOB_H_H
965
966=== modified file 'src/include/server/mir/frontend/shell.h'
967--- src/include/server/mir/frontend/shell.h 2017-01-18 02:29:37 +0000
968+++ src/include/server/mir/frontend/shell.h 2017-03-14 11:00:58 +0000
969@@ -87,6 +87,11 @@
970 SurfaceId surface_id,
971 uint64_t timestamp) = 0;
972
973+ virtual void request_drag_and_drop(
974+ std::shared_ptr<Session> const& session,
975+ SurfaceId surface_id,
976+ uint64_t timestamp) = 0;
977+
978 protected:
979 Shell() = default;
980 Shell(const Shell&) = delete;
981
982=== modified file 'src/include/server/mir/scene/surface_event_source.h'
983--- src/include/server/mir/scene/surface_event_source.h 2017-02-15 13:36:35 +0000
984+++ src/include/server/mir/scene/surface_event_source.h 2017-03-14 11:00:58 +0000
985@@ -51,6 +51,7 @@
986 std::string const& variant, std::string const& options) override;
987 void placed_relative(geometry::Rectangle const& placement) override;
988 void input_consumed(MirEvent const* event) override;
989+ void start_drag_and_drop(std::vector<uint8_t> const& handle) override;
990
991 private:
992 frontend::SurfaceId const id;
993
994=== modified file 'src/include/server/mir/scene/surface_observers.h'
995--- src/include/server/mir/scene/surface_observers.h 2017-02-15 13:36:35 +0000
996+++ src/include/server/mir/scene/surface_observers.h 2017-03-14 11:00:58 +0000
997@@ -51,6 +51,7 @@
998 void cursor_image_removed() override;
999 void placed_relative(geometry::Rectangle const& placement) override;
1000 void input_consumed(MirEvent const* event) override;
1001+ void start_drag_and_drop(std::vector<uint8_t> const& handle) override;
1002 };
1003
1004 }
1005
1006=== modified file 'src/include/server/mir/shell/basic_window_manager.h'
1007--- src/include/server/mir/shell/basic_window_manager.h 2017-01-18 02:29:37 +0000
1008+++ src/include/server/mir/shell/basic_window_manager.h 2017-03-14 11:00:58 +0000
1009@@ -65,6 +65,9 @@
1010
1011 virtual void raise_tree(std::shared_ptr<scene::Surface> const& root) = 0;
1012
1013+ virtual void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) = 0;
1014+ virtual void clear_drag_and_drop_handle() = 0;
1015+
1016 virtual ~WindowManagerTools() = default;
1017 WindowManagerTools() = default;
1018 WindowManagerTools(WindowManagerTools const&) = delete;
1019@@ -107,6 +110,10 @@
1020 std::shared_ptr<scene::Session> const& session,
1021 std::shared_ptr<scene::Surface> const& surface) = 0;
1022
1023+ virtual void handle_request_drag_and_drop(
1024+ std::shared_ptr<scene::Session> const& session,
1025+ std::shared_ptr<scene::Surface> const& surface) = 0;
1026+
1027 virtual ~WindowManagementPolicy() = default;
1028 WindowManagementPolicy() = default;
1029 WindowManagementPolicy(WindowManagementPolicy const&) = delete;
1030@@ -163,6 +170,11 @@
1031 std::shared_ptr<scene::Surface> const& surface,
1032 uint64_t timestamp) override;
1033
1034+ void handle_request_drag_and_drop(
1035+ std::shared_ptr<scene::Session> const& session,
1036+ std::shared_ptr<scene::Surface> const& surface,
1037+ uint64_t timestamp) override;
1038+
1039 int set_surface_attribute(
1040 std::shared_ptr<scene::Session> const& /*session*/,
1041 std::shared_ptr<scene::Surface> const& surface,
1042@@ -192,6 +204,9 @@
1043
1044 void raise_tree(std::shared_ptr<scene::Surface> const& root) override;
1045
1046+ void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override;
1047+ void clear_drag_and_drop_handle() override;
1048+
1049 private:
1050 shell::FocusController* const focus_controller;
1051 std::unique_ptr<WindowManagementPolicy> const policy;
1052
1053=== modified file 'src/include/server/mir/shell/canonical_window_manager.h'
1054--- src/include/server/mir/shell/canonical_window_manager.h 2017-01-18 02:29:37 +0000
1055+++ src/include/server/mir/shell/canonical_window_manager.h 2017-03-14 11:00:58 +0000
1056@@ -75,6 +75,10 @@
1057 std::shared_ptr<scene::Session> const& session,
1058 std::shared_ptr<scene::Surface> const& surface) override;
1059
1060+ void handle_request_drag_and_drop(
1061+ std::shared_ptr<scene::Session> const& session,
1062+ std::shared_ptr<scene::Surface> const& surface) override;
1063+
1064 private:
1065 static const int modifier_mask =
1066 mir_input_event_modifier_alt |
1067
1068=== modified file 'src/protobuf/mir_protobuf.proto'
1069--- src/protobuf/mir_protobuf.proto 2017-03-14 04:41:33 +0000
1070+++ src/protobuf/mir_protobuf.proto 2017-03-14 11:00:58 +0000
1071@@ -444,6 +444,11 @@
1072 required SurfaceId surface_id = 2;
1073 }
1074
1075+message RequestAuthority {
1076+ required Cookie cookie = 1;
1077+ required SurfaceId surface_id = 2;
1078+}
1079+
1080 message InputDevices {
1081 repeated InputDeviceInfo device_info = 1;
1082 }
1083
1084=== modified file 'src/protobuf/symbols.map'
1085--- src/protobuf/symbols.map 2017-02-15 07:38:33 +0000
1086+++ src/protobuf/symbols.map 2017-03-14 11:00:58 +0000
1087@@ -1112,3 +1112,29 @@
1088 vtable?for?mir::protobuf::PromptSession;
1089 };
1090 } MIR_PROTOBUF_0.22;
1091+
1092+MIR_PROTOBUF_0.27 {
1093+ global:
1094+ extern "C++" {
1095+ mir::protobuf::RequestAuthority::ByteSize*;
1096+ mir::protobuf::RequestAuthority::CheckTypeAndMergeFrom*;
1097+ mir::protobuf::RequestAuthority::Clear*;
1098+ mir::protobuf::RequestAuthority::CopyFrom*;
1099+ mir::protobuf::RequestAuthority::default_instance*;
1100+ mir::protobuf::RequestAuthority::DiscardUnknownFields*;
1101+ mir::protobuf::RequestAuthority::GetTypeName*;
1102+ mir::protobuf::RequestAuthority::IsInitialized*;
1103+ mir::protobuf::RequestAuthority::kCookieFieldNumber*;
1104+ mir::protobuf::RequestAuthority::kSurfaceIdFieldNumber*;
1105+ mir::protobuf::RequestAuthority::MergeFrom*;
1106+ mir::protobuf::RequestAuthority::MergePartialFromCodedStream*;
1107+ mir::protobuf::RequestAuthority::New*;
1108+ mir::protobuf::RequestAuthority::?RequestAuthority*;
1109+ mir::protobuf::RequestAuthority::RequestAuthority*;
1110+ mir::protobuf::RequestAuthority::SerializeWithCachedSizes*;
1111+ mir::protobuf::RequestAuthority::Swap*;
1112+ non-virtual?thunk?to?mir::protobuf::RequestAuthority::?RequestAuthority*;
1113+ typeinfo?for?mir::protobuf::RequestAuthority;
1114+ vtable?for?mir::protobuf::RequestAuthority;
1115+ };
1116+} MIR_PROTOBUF_0.26;
1117
1118=== modified file 'src/server/frontend/protobuf_message_processor.cpp'
1119--- src/server/frontend/protobuf_message_processor.cpp 2017-02-15 07:38:33 +0000
1120+++ src/server/frontend/protobuf_message_processor.cpp 2017-03-14 11:00:58 +0000
1121@@ -305,6 +305,10 @@
1122 {
1123 invoke(this, display_server.get(), &protobuf::DisplayServer::stop_prompt_session, invocation);
1124 }
1125+ else if ("request_drag_and_drop" == invocation.method_name())
1126+ {
1127+ invoke(this, display_server.get(), &protobuf::DisplayServer::request_drag_and_drop, invocation);
1128+ }
1129 else if ("disconnect" == invocation.method_name())
1130 {
1131 invoke(this, display_server.get(), &DisplayServer::disconnect, invocation);
1132
1133=== modified file 'src/server/frontend/session_mediator.cpp'
1134--- src/server/frontend/session_mediator.cpp 2017-03-14 04:41:33 +0000
1135+++ src/server/frontend/session_mediator.cpp 2017-03-14 11:00:58 +0000
1136@@ -1175,6 +1175,26 @@
1137 done->Run();
1138 }
1139
1140+void mir::frontend::SessionMediator::request_drag_and_drop(mir::protobuf::RequestAuthority const* request,
1141+ mir::protobuf::Void*, google::protobuf::Closure* done)
1142+{
1143+ auto const session = weak_session.lock();
1144+ if (!session)
1145+ BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session"));
1146+
1147+ auto const cookie = request->cookie();
1148+ auto const surface_id = request->surface_id();
1149+
1150+ auto cookie_string = cookie.cookie();
1151+
1152+ std::vector<uint8_t> cookie_bytes(cookie_string.begin(), cookie_string.end());
1153+ auto const cookie_ptr = cookie_authority->make_cookie(cookie_bytes);
1154+
1155+ shell->request_drag_and_drop(session, mf::SurfaceId{surface_id.value()}, cookie_ptr->timestamp());
1156+
1157+ done->Run();
1158+}
1159+
1160 void mf::SessionMediator::apply_input_configuration(
1161 mir::protobuf::InputConfigurationRequest const* request,
1162 mir::protobuf::Void*,
1163@@ -1254,7 +1274,6 @@
1164 screencast_buffer_tracker.remove_session(id);
1165 }
1166
1167-
1168 auto mf::detail::PromptSessionStore::insert(std::shared_ptr<PromptSession> const& session) -> PromptSessionId
1169 {
1170 std::lock_guard<decltype(mutex)> lock{mutex};
1171
1172=== modified file 'src/server/frontend/session_mediator.h'
1173--- src/server/frontend/session_mediator.h 2017-03-14 02:26:28 +0000
1174+++ src/server/frontend/session_mediator.h 2017-03-14 11:00:58 +0000
1175@@ -249,6 +249,10 @@
1176 mir::protobuf::RaiseRequest const* request,
1177 mir::protobuf::Void*,
1178 google::protobuf::Closure* done) override;
1179+ void request_drag_and_drop(
1180+ mir::protobuf::RequestAuthority const* request,
1181+ mir::protobuf::Void*,
1182+ google::protobuf::Closure* done) override;
1183 void apply_input_configuration(
1184 mir::protobuf::InputConfigurationRequest const* request,
1185 mir::protobuf::Void* response,
1186
1187=== modified file 'src/server/frontend/shell_wrapper.cpp'
1188--- src/server/frontend/shell_wrapper.cpp 2017-01-18 02:29:37 +0000
1189+++ src/server/frontend/shell_wrapper.cpp 2017-03-14 11:00:58 +0000
1190@@ -106,3 +106,11 @@
1191 {
1192 wrapped->raise_surface(session, surface_id, timestamp);
1193 }
1194+
1195+void mf::ShellWrapper::request_drag_and_drop(
1196+ std::shared_ptr<Session> const& session,
1197+ SurfaceId surface_id,
1198+ uint64_t timestamp)
1199+{
1200+ wrapped->request_drag_and_drop(session, surface_id, timestamp);
1201+}
1202
1203=== modified file 'src/server/frontend/shell_wrapper.h'
1204--- src/server/frontend/shell_wrapper.h 2017-01-18 02:29:37 +0000
1205+++ src/server/frontend/shell_wrapper.h 2017-03-14 11:00:58 +0000
1206@@ -80,6 +80,11 @@
1207 SurfaceId surface_id,
1208 uint64_t timestamp) override;
1209
1210+ void request_drag_and_drop(
1211+ std::shared_ptr<Session> const& session,
1212+ SurfaceId surface_id,
1213+ uint64_t timestamp) override;
1214+
1215 protected:
1216 std::shared_ptr<Shell> const wrapped;
1217 };
1218
1219=== modified file 'src/server/input/null_input_targeter.h'
1220--- src/server/input/null_input_targeter.h 2017-02-15 14:45:41 +0000
1221+++ src/server/input/null_input_targeter.h 2017-03-14 11:00:58 +0000
1222@@ -38,6 +38,9 @@
1223 void clear_focus() override
1224 {
1225 }
1226+
1227+ void set_drag_and_drop_handle(std::vector<uint8_t> const&) override {}
1228+ void clear_drag_and_drop_handle() override {}
1229 };
1230
1231 }
1232
1233=== modified file 'src/server/input/surface_input_dispatcher.cpp'
1234--- src/server/input/surface_input_dispatcher.cpp 2017-01-18 02:29:37 +0000
1235+++ src/server/input/surface_input_dispatcher.cpp 2017-03-14 11:00:58 +0000
1236@@ -70,7 +70,10 @@
1237 std::function<void(ms::Surface*)> const on_removed;
1238 };
1239
1240-void deliver_without_relative_motion(std::shared_ptr<mi::Surface> const& surface, MirEvent const* ev)
1241+void deliver_without_relative_motion(
1242+ std::shared_ptr<mi::Surface> const& surface,
1243+ MirEvent const* ev,
1244+ std::vector<uint8_t> const& drag_and_drop_handle)
1245 {
1246 auto const* input_ev = mir_event_get_input_event(ev);
1247 auto const* pev = mir_input_event_get_pointer_event(input_ev);
1248@@ -98,12 +101,21 @@
1249 0.0f);
1250
1251 mev::transform_positions(*to_deliver, geom::Displacement{bounds.top_left.x.as_int(), bounds.top_left.y.as_int()});
1252+ if (!drag_and_drop_handle.empty())
1253+ mev::set_drag_and_drop_handle(*to_deliver, drag_and_drop_handle);
1254 surface->consume(to_deliver.get());
1255 }
1256
1257-void deliver(std::shared_ptr<mi::Surface> const& surface, MirEvent const* ev)
1258+void deliver(
1259+ std::shared_ptr<mi::Surface> const& surface,
1260+ MirEvent const* ev,
1261+ std::vector<uint8_t> const& drag_and_drop_handle)
1262 {
1263 auto to_deliver = mev::clone_event(*ev);
1264+
1265+ if (!drag_and_drop_handle.empty())
1266+ mev::set_drag_and_drop_handle(*to_deliver, drag_and_drop_handle);
1267+
1268 auto const& bounds = surface->input_bounds();
1269 mev::transform_positions(*to_deliver, geom::Displacement{bounds.top_left.x.as_int(), bounds.top_left.y.as_int()});
1270 surface->consume(to_deliver.get());
1271@@ -243,6 +255,8 @@
1272 mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_x),
1273 mir_pointer_event_axis_value(pev, mir_pointer_axis_relative_y));
1274
1275+ if (!drag_and_drop_handle.empty())
1276+ mev::set_drag_and_drop_handle(*event, drag_and_drop_handle);
1277 surface->consume(event.get());
1278 }
1279
1280@@ -270,7 +284,7 @@
1281
1282 if (pointer_state.gesture_owner)
1283 {
1284- deliver(pointer_state.gesture_owner, ev);
1285+ deliver(pointer_state.gesture_owner, ev, drag_and_drop_handle);
1286
1287 if (is_gesture_terminator(pev))
1288 {
1289@@ -323,11 +337,11 @@
1290 if (sent_ev)
1291 {
1292 if (action != mir_pointer_action_motion)
1293- deliver_without_relative_motion(target, ev);
1294+ deliver_without_relative_motion(target, ev, drag_and_drop_handle);
1295 }
1296 else
1297 {
1298- deliver(target, ev);
1299+ deliver(target, ev, drag_and_drop_handle);
1300 }
1301 return true;
1302 }
1303@@ -383,7 +397,7 @@
1304
1305 if (gesture_owner)
1306 {
1307- deliver(gesture_owner, ev);
1308+ deliver(gesture_owner, ev, drag_and_drop_handle);
1309
1310 if (is_gesture_end(tev))
1311 gesture_owner.reset();
1312@@ -450,3 +464,15 @@
1313 set_focus_locked(lg, nullptr);
1314 }
1315
1316+void mir::input::SurfaceInputDispatcher::set_drag_and_drop_handle(std::vector<uint8_t> const& handle)
1317+{
1318+ std::lock_guard<std::mutex> lg(dispatcher_mutex);
1319+ drag_and_drop_handle = handle;
1320+}
1321+
1322+void mir::input::SurfaceInputDispatcher::clear_drag_and_drop_handle()
1323+{
1324+ std::lock_guard<std::mutex> lg(dispatcher_mutex);
1325+ drag_and_drop_handle.clear();
1326+}
1327+
1328
1329=== modified file 'src/server/input/surface_input_dispatcher.h'
1330--- src/server/input/surface_input_dispatcher.h 2016-10-05 13:18:38 +0000
1331+++ src/server/input/surface_input_dispatcher.h 2017-03-14 11:00:58 +0000
1332@@ -54,7 +54,10 @@
1333 // InputTargeter
1334 void set_focus(std::shared_ptr<input::Surface> const& target) override;
1335 void clear_focus() override;
1336-
1337+
1338+ void set_drag_and_drop_handle(std::vector<uint8_t> const& handle) override;
1339+ void clear_drag_and_drop_handle() override;
1340+
1341 private:
1342 void device_reset(MirInputDeviceId reset_device_id, std::chrono::nanoseconds when);
1343 bool dispatch_key(MirEvent const* kev);
1344@@ -92,6 +95,7 @@
1345
1346 std::mutex dispatcher_mutex;
1347 std::weak_ptr<input::Surface> focus_surface;
1348+ std::vector<uint8_t> drag_and_drop_handle;
1349 bool started;
1350 };
1351
1352
1353=== modified file 'src/server/scene/basic_surface.cpp'
1354--- src/server/scene/basic_surface.cpp 2017-02-15 14:45:41 +0000
1355+++ src/server/scene/basic_surface.cpp 2017-03-14 11:00:58 +0000
1356@@ -144,6 +144,12 @@
1357 { observer->input_consumed(event); });
1358 }
1359
1360+void ms::SurfaceObservers::start_drag_and_drop(std::vector<uint8_t> const& handle)
1361+{
1362+ for_each([&](std::shared_ptr<SurfaceObserver> const& observer)
1363+ { observer->start_drag_and_drop(handle); });
1364+}
1365+
1366
1367 struct ms::CursorStreamImageAdapter
1368 {
1369@@ -590,6 +596,7 @@
1370 case mir_window_attrib_dpi: return dpi_;
1371 case mir_window_attrib_visibility: return visibility_;
1372 case mir_window_attrib_preferred_orientation: return pref_orientation_mode;
1373+ case mir_window_attrib_drag_and_drop_handle: return 0;
1374 default: BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface "
1375 "attribute."));
1376 }
1377@@ -923,3 +930,8 @@
1378 {
1379 observers.placed_relative(placement);
1380 }
1381+
1382+void mir::scene::BasicSurface::start_drag_and_drop(std::vector<uint8_t> const& handle)
1383+{
1384+ observers.start_drag_and_drop(handle);
1385+}
1386
1387=== modified file 'src/server/scene/basic_surface.h'
1388--- src/server/scene/basic_surface.h 2017-02-15 14:45:41 +0000
1389+++ src/server/scene/basic_surface.h 2017-03-14 11:00:58 +0000
1390@@ -139,6 +139,7 @@
1391 void set_confine_pointer_state(MirPointerConfinementState state) override;
1392 MirPointerConfinementState confine_pointer_state() const override;
1393 void placed_relative(geometry::Rectangle const& placement) override;
1394+ void start_drag_and_drop(std::vector<uint8_t> const& handle) override;
1395
1396 private:
1397 bool visible(std::unique_lock<std::mutex>&) const;
1398
1399=== modified file 'src/server/scene/legacy_surface_change_notification.cpp'
1400--- src/server/scene/legacy_surface_change_notification.cpp 2017-02-15 13:36:35 +0000
1401+++ src/server/scene/legacy_surface_change_notification.cpp 2017-03-14 11:00:58 +0000
1402@@ -108,3 +108,7 @@
1403 void ms::LegacySurfaceChangeNotification::input_consumed(MirEvent const*)
1404 {
1405 }
1406+
1407+void ms::LegacySurfaceChangeNotification::start_drag_and_drop(std::vector<uint8_t> const& /*handle*/)
1408+{
1409+}
1410\ No newline at end of file
1411
1412=== modified file 'src/server/scene/legacy_surface_change_notification.h'
1413--- src/server/scene/legacy_surface_change_notification.h 2017-02-15 13:36:35 +0000
1414+++ src/server/scene/legacy_surface_change_notification.h 2017-03-14 11:00:58 +0000
1415@@ -51,6 +51,7 @@
1416 void cursor_image_removed() override;
1417 void placed_relative(geometry::Rectangle const& placement) override;
1418 void input_consumed(MirEvent const* event) override;
1419+ void start_drag_and_drop(std::vector<uint8_t> const& handle) override;
1420
1421 private:
1422 std::function<void()> const notify_scene_change;
1423
1424=== modified file 'src/server/scene/null_surface_observer.cpp'
1425--- src/server/scene/null_surface_observer.cpp 2017-02-15 13:36:35 +0000
1426+++ src/server/scene/null_surface_observer.cpp 2017-03-14 11:00:58 +0000
1427@@ -41,3 +41,4 @@
1428 void ms::NullSurfaceObserver::cursor_image_removed() {}
1429 void ms::NullSurfaceObserver::placed_relative(geometry::Rectangle const& /*placement*/) {}
1430 void ms::NullSurfaceObserver::input_consumed(MirEvent const* /*event*/) {}
1431+void ms::NullSurfaceObserver::start_drag_and_drop(std::vector<uint8_t> const& /*handle*/) {}
1432
1433=== modified file 'src/server/scene/surface_event_source.cpp'
1434--- src/server/scene/surface_event_source.cpp 2017-02-15 13:36:35 +0000
1435+++ src/server/scene/surface_event_source.cpp 2017-03-14 11:00:58 +0000
1436@@ -101,3 +101,8 @@
1437 mev::set_window_id(*ev, id.as_value());
1438 event_sink->handle_event(*ev);
1439 }
1440+
1441+void ms::SurfaceEventSource::start_drag_and_drop(std::vector<uint8_t> const& handle)
1442+{
1443+ event_sink->handle_event(*mev::make_start_drag_and_drop_event(id, handle));
1444+}
1445
1446=== modified file 'src/server/shell/abstract_shell.cpp'
1447--- src/server/shell/abstract_shell.cpp 2017-03-10 19:47:57 +0000
1448+++ src/server/shell/abstract_shell.cpp 2017-03-14 11:00:58 +0000
1449@@ -251,6 +251,14 @@
1450 window_manager->handle_raise_surface(session, surface, timestamp);
1451 }
1452
1453+void msh::AbstractShell::request_drag_and_drop(
1454+ std::shared_ptr<scene::Session> const& session,
1455+ std::shared_ptr<scene::Surface> const& surface,
1456+ uint64_t timestamp)
1457+{
1458+ window_manager->handle_request_drag_and_drop(session, surface, timestamp);
1459+}
1460+
1461 void msh::AbstractShell::focus_next_session()
1462 {
1463 std::unique_lock<std::mutex> lock(focus_mutex);
1464@@ -401,3 +409,12 @@
1465 report->surfaces_raised(surfaces);
1466 }
1467
1468+void msh::AbstractShell::set_drag_and_drop_handle(std::vector<uint8_t> const& handle)
1469+{
1470+ input_targeter->set_drag_and_drop_handle(handle);
1471+}
1472+
1473+void msh::AbstractShell::clear_drag_and_drop_handle()
1474+{
1475+ input_targeter->clear_drag_and_drop_handle();
1476+}
1477
1478=== modified file 'src/server/shell/basic_window_manager.cpp'
1479--- src/server/shell/basic_window_manager.cpp 2017-01-18 02:29:37 +0000
1480+++ src/server/shell/basic_window_manager.cpp 2017-03-14 11:00:58 +0000
1481@@ -135,6 +135,16 @@
1482 policy->handle_raise_surface(session, surface);
1483 }
1484
1485+void msh::BasicWindowManager::handle_request_drag_and_drop(
1486+ std::shared_ptr<scene::Session> const& session,
1487+ std::shared_ptr<scene::Surface> const& surface,
1488+ uint64_t timestamp)
1489+{
1490+ std::lock_guard<decltype(mutex)> lock(mutex);
1491+ if (timestamp >= last_input_event_timestamp)
1492+ policy->handle_request_drag_and_drop(session, surface);
1493+}
1494+
1495 int msh::BasicWindowManager::set_surface_attribute(
1496 std::shared_ptr<scene::Session> const& /*session*/,
1497 std::shared_ptr<scene::Surface> const& surface,
1498@@ -309,3 +319,14 @@
1499 }
1500 }
1501 }
1502+
1503+void mir::shell::BasicWindowManager::set_drag_and_drop_handle(std::vector<uint8_t> const& handle)
1504+{
1505+ focus_controller->set_drag_and_drop_handle(handle);
1506+}
1507+
1508+void mir::shell::BasicWindowManager::clear_drag_and_drop_handle()
1509+{
1510+ focus_controller->clear_drag_and_drop_handle();
1511+}
1512+
1513
1514=== modified file 'src/server/shell/canonical_window_manager.cpp'
1515--- src/server/shell/canonical_window_manager.cpp 2017-03-10 19:47:57 +0000
1516+++ src/server/shell/canonical_window_manager.cpp 2017-03-14 11:00:58 +0000
1517@@ -24,6 +24,7 @@
1518 #include "mir/shell/surface_ready_observer.h"
1519 #include "mir/shell/display_layout.h"
1520
1521+#include <uuid/uuid.h>
1522 #include <linux/input.h>
1523 #include <csignal>
1524
1525@@ -583,6 +584,18 @@
1526 select_active_surface(surface);
1527 }
1528
1529+void msh::CanonicalWindowManagerPolicy::handle_request_drag_and_drop(
1530+ std::shared_ptr<ms::Session> const& /*session*/,
1531+ std::shared_ptr<ms::Surface> const& surface)
1532+{
1533+ uuid_t uuid;
1534+ uuid_generate(uuid);
1535+ std::vector<uint8_t> const handle{std::begin(uuid), std::end(uuid)};
1536+
1537+ surface->start_drag_and_drop(handle);
1538+ tools->set_drag_and_drop_handle(handle);
1539+}
1540+
1541 bool msh::CanonicalWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
1542 {
1543 auto const action = mir_keyboard_event_action(event);
1544
1545=== modified file 'src/server/shell/frontend_shell.cpp'
1546--- src/server/shell/frontend_shell.cpp 2017-01-18 02:29:37 +0000
1547+++ src/server/shell/frontend_shell.cpp 2017-03-14 11:00:58 +0000
1548@@ -157,3 +157,13 @@
1549 auto const surface = scene_session->surface(surface_id);
1550 wrapped->raise_surface(scene_session, surface, timestamp);
1551 }
1552+
1553+void msh::FrontendShell::request_drag_and_drop(
1554+ std::shared_ptr<mf::Session> const& session,
1555+ mf::SurfaceId surface_id,
1556+ uint64_t timestamp)
1557+{
1558+ auto const scene_session = std::dynamic_pointer_cast<ms::Session>(session);
1559+ auto const surface = scene_session->surface(surface_id);
1560+ wrapped->request_drag_and_drop(scene_session, surface, timestamp);
1561+}
1562
1563=== modified file 'src/server/shell/frontend_shell.h'
1564--- src/server/shell/frontend_shell.h 2017-01-18 02:29:37 +0000
1565+++ src/server/shell/frontend_shell.h 2017-03-14 11:00:58 +0000
1566@@ -91,6 +91,11 @@
1567 std::shared_ptr<mf::Session> const& session,
1568 mf::SurfaceId surface_id,
1569 uint64_t timestamp) override;
1570+
1571+ void request_drag_and_drop(
1572+ std::shared_ptr<mf::Session> const& session,
1573+ mf::SurfaceId surface_id,
1574+ uint64_t timestamp) override;
1575 };
1576 }
1577 }
1578
1579=== modified file 'src/server/shell/shell_wrapper.cpp'
1580--- src/server/shell/shell_wrapper.cpp 2017-01-18 02:29:37 +0000
1581+++ src/server/shell/shell_wrapper.cpp 2017-03-14 11:00:58 +0000
1582@@ -120,6 +120,14 @@
1583 wrapped->raise_surface(session, surface, timestamp);
1584 }
1585
1586+void msh::ShellWrapper::request_drag_and_drop(
1587+ std::shared_ptr<ms::Session> const& session,
1588+ std::shared_ptr<ms::Surface> const& surface,
1589+ uint64_t timestamp)
1590+{
1591+ wrapped->request_drag_and_drop(session, surface, timestamp);
1592+}
1593+
1594 void msh::ShellWrapper::add_display(geometry::Rectangle const& area)
1595 {
1596 wrapped->add_display(area);
1597@@ -149,3 +157,13 @@
1598 {
1599 return wrapped->raise(surfaces);
1600 }
1601+
1602+void msh::ShellWrapper::set_drag_and_drop_handle(std::vector<uint8_t> const& handle)
1603+{
1604+ wrapped->set_drag_and_drop_handle(handle);
1605+}
1606+
1607+void msh::ShellWrapper::clear_drag_and_drop_handle()
1608+{
1609+ wrapped->clear_drag_and_drop_handle();
1610+}
1611
1612=== modified file 'src/server/shell/system_compositor_window_manager.cpp'
1613--- src/server/shell/system_compositor_window_manager.cpp 2017-01-18 02:29:37 +0000
1614+++ src/server/shell/system_compositor_window_manager.cpp 2017-03-14 11:00:58 +0000
1615@@ -201,3 +201,10 @@
1616 uint64_t /*timestamp*/)
1617 {
1618 }
1619+
1620+void msh::SystemCompositorWindowManager::handle_request_drag_and_drop(
1621+ std::shared_ptr<ms::Session> const& /*session*/,
1622+ std::shared_ptr<ms::Surface> const& /*surface*/,
1623+ uint64_t /*timestamp*/)
1624+{
1625+}
1626
1627=== modified file 'src/server/symbols.map'
1628--- src/server/symbols.map 2017-03-13 08:12:52 +0000
1629+++ src/server/symbols.map 2017-03-14 11:00:58 +0000
1630@@ -130,6 +130,7 @@
1631 mir::scene::NullSurfaceObserver::reception_mode_set_to*;
1632 mir::scene::NullSurfaceObserver::renamed*;
1633 mir::scene::NullSurfaceObserver::resized_to*;
1634+ mir::scene::NullSurfaceObserver::start_drag_and_drop*;
1635 mir::scene::NullSurfaceObserver::transformation_set_to*;
1636 mir::scene::Observer::?Observer*;
1637 mir::scene::Observer::Observer*;
1638@@ -294,6 +295,7 @@
1639 mir::shell::ShellReport::ShellReport*;
1640 mir::shell::ShellWrapper::add_display*;
1641 mir::shell::ShellWrapper::add_prompt_provider_for*;
1642+ mir::shell::ShellWrapper::clear_drag_and_drop_handle*;
1643 mir::shell::ShellWrapper::close_session*;
1644 mir::shell::ShellWrapper::create_surface*;
1645 mir::shell::ShellWrapper::destroy_surface*;
1646@@ -307,9 +309,11 @@
1647 mir::shell::ShellWrapper::raise*;
1648 mir::shell::ShellWrapper::raise_surface*;
1649 mir::shell::ShellWrapper::remove_display*;
1650+ mir::shell::ShellWrapper::request_drag_and_drop*;
1651 mir::shell::ShellWrapper::set_focus_to*;
1652 mir::shell::ShellWrapper::set_surface_attribute*;
1653 mir::shell::ShellWrapper::ShellWrapper*;
1654+ mir::shell::ShellWrapper::set_drag_and_drop_handle*;
1655 mir::shell::ShellWrapper::start_prompt_session_for*;
1656 mir::shell::ShellWrapper::stop_prompt_session*;
1657 mir::shell::ShellWrapper::surface_at*;
1658@@ -339,6 +343,7 @@
1659 mir::shell::SystemCompositorWindowManager::remove_display*;
1660 mir::shell::SystemCompositorWindowManager::remove_session*;
1661 mir::shell::SystemCompositorWindowManager::remove_surface*;
1662+ mir::shell::SystemCompositorWindowManager::handle_request_drag_and_drop*;
1663 mir::shell::SystemCompositorWindowManager::set_surface_attribute*;
1664 mir::shell::SystemCompositorWindowManager::SystemCompositorWindowManager*;
1665 mir::shell::WindowManager::operator*;
1666@@ -696,6 +701,7 @@
1667 mir::shell::CanonicalWindowManagerPolicy::handle_touch_event*;
1668 mir::shell::CanonicalWindowManagerPolicy::handle_pointer_event*;
1669 mir::shell::CanonicalWindowManagerPolicy::handle_raise_surface*;
1670+ mir::shell::CanonicalWindowManagerPolicy::handle_request_drag_and_drop*;
1671 typeinfo?for?mir::shell::CanonicalWindowManagerPolicy;
1672 vtable?for?mir::shell::CanonicalWindowManagerPolicy;
1673 VTT?for?mir::shell::CanonicalWindowManagerPolicy;
1674@@ -832,6 +838,7 @@
1675 mir::shell::BasicWindowManager::add_session*;
1676 mir::shell::BasicWindowManager::add_surface*;
1677 mir::shell::BasicWindowManager::BasicWindowManager*;
1678+ mir::shell::BasicWindowManager::clear_drag_and_drop_handle*;
1679 mir::shell::BasicWindowManager::find_session*;
1680 mir::shell::BasicWindowManager::focused_session*;
1681 mir::shell::BasicWindowManager::focused_surface*;
1682@@ -840,6 +847,7 @@
1683 mir::shell::BasicWindowManager::handle_keyboard_event*;
1684 mir::shell::BasicWindowManager::handle_pointer_event*;
1685 mir::shell::BasicWindowManager::handle_raise_surface*;
1686+ mir::shell::BasicWindowManager::handle_request_drag_and_drop*;
1687 mir::shell::BasicWindowManager::handle_touch_event*;
1688 mir::shell::BasicWindowManager::info_for*;
1689 mir::shell::BasicWindowManager::modify_surface*;
1690@@ -847,6 +855,7 @@
1691 mir::shell::BasicWindowManager::remove_display*;
1692 mir::shell::BasicWindowManager::remove_session*;
1693 mir::shell::BasicWindowManager::remove_surface*;
1694+ mir::shell::BasicWindowManager::set_drag_and_drop_handle*;
1695 mir::shell::BasicWindowManager::set_focus_to*;
1696 mir::shell::BasicWindowManager::set_surface_attribute*;
1697 mir::shell::BasicWindowManager::surface_at*;
1698@@ -857,6 +866,7 @@
1699 virtual?thunk?to?mir::shell::BasicWindowManager::handle_keyboard_event*;
1700 virtual?thunk?to?mir::shell::BasicWindowManager::handle_pointer_event*;
1701 virtual?thunk?to?mir::shell::BasicWindowManager::handle_raise_surface*;
1702+ virtual?thunk?to?mir::shell::BasicWindowManager::handle_request_drag_and_drop*;
1703 virtual?thunk?to?mir::shell::BasicWindowManager::handle_touch_event*;
1704 virtual?thunk?to?mir::shell::BasicWindowManager::modify_surface*;
1705 virtual?thunk?to?mir::shell::BasicWindowManager::remove_display*;
1706
1707=== modified file 'tests/acceptance-tests/CMakeLists.txt'
1708--- tests/acceptance-tests/CMakeLists.txt 2017-03-10 19:47:57 +0000
1709+++ tests/acceptance-tests/CMakeLists.txt 2017-03-14 11:00:58 +0000
1710@@ -3,6 +3,8 @@
1711 set(
1712 SOURCES
1713
1714+ drag_and_drop.cpp
1715+
1716 # Catch double-free bugs by wrapping close() and abort()ing on EBADF
1717 strict_close.cpp
1718
1719
1720=== added file 'tests/acceptance-tests/drag_and_drop.cpp'
1721--- tests/acceptance-tests/drag_and_drop.cpp 1970-01-01 00:00:00 +0000
1722+++ tests/acceptance-tests/drag_and_drop.cpp 2017-03-14 11:00:58 +0000
1723@@ -0,0 +1,293 @@
1724+/*
1725+ * Copyright © 2017 Canonical Ltd.
1726+ *
1727+ * This program is free software: you can redistribute it and/or modify it
1728+ * under the terms of the GNU General Public License version 3,
1729+ * as published by the Free Software Foundation.
1730+ *
1731+ * This program is distributed in the hope that it will be useful,
1732+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1733+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1734+ * GNU General Public License for more details.
1735+ *
1736+ * You should have received a copy of the GNU General Public License
1737+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1738+ *
1739+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
1740+ */
1741+
1742+#include <mir_toolkit/extensions/drag_and_drop.h>
1743+#include <mir_toolkit/mir_blob.h>
1744+
1745+#include <mir/geometry/displacement.h>
1746+#include <mir/input/input_device_info.h>
1747+#include <mir/input/device_capability.h>
1748+#include <mir/shell/shell.h>
1749+
1750+#include <mir_test_framework/connected_client_with_a_window.h>
1751+#include <mir_test_framework/fake_input_device.h>
1752+#include <mir_test_framework/stub_server_platform_factory.h>
1753+#include <mir/test/event_factory.h>
1754+#include <mir/test/signal.h>
1755+
1756+#include <gmock/gmock.h>
1757+#include <gtest/gtest.h>
1758+
1759+#include <linux/input.h>
1760+
1761+#include <boost/throw_exception.hpp>
1762+
1763+using namespace std::chrono_literals;
1764+using namespace mir::geometry;
1765+using namespace testing;
1766+using mir::test::Signal;
1767+
1768+namespace
1769+{
1770+class Cookie
1771+{
1772+public:
1773+ Cookie() = default;
1774+ explicit Cookie(MirCookie const* cookie) : self{cookie, deleter} {}
1775+
1776+ operator MirCookie const*() const { return self.get(); }
1777+ auto get() const -> MirCookie const* { return self.get(); }
1778+
1779+ void reset() { self.reset(); }
1780+ void reset(MirCookie const* cookie) { self.reset(cookie, deleter); }
1781+
1782+private:
1783+ static void deleter(MirCookie const* cookie) { mir_cookie_release(cookie); }
1784+ std::shared_ptr<MirCookie const> self;
1785+};
1786+
1787+void mir_cookie_release(Cookie const&) = delete;
1788+
1789+class Blob
1790+{
1791+public:
1792+ Blob() = default;
1793+ explicit Blob(MirBlob* blob) : self{blob, deleter} {}
1794+
1795+ operator MirBlob*() const { return self.get(); }
1796+ auto get() const -> MirBlob* { return self.get(); }
1797+
1798+ void reset() { self.reset(); }
1799+ void reset(MirBlob* blob) { self.reset(blob, deleter); }
1800+
1801+private:
1802+ static void deleter(MirBlob* blob) { mir_blob_release(blob); }
1803+ std::shared_ptr<MirBlob> self;
1804+};
1805+
1806+void mir_blob_release(Blob const&) = delete;
1807+
1808+struct MouseMoverAndFaker
1809+{
1810+ void start_dragging_mouse()
1811+ {
1812+ using namespace mir::input::synthesis;
1813+ fake_mouse->emit_event(a_button_down_event().of_button(BTN_LEFT));
1814+ }
1815+
1816+ void move_mouse(Displacement const& displacement)
1817+ {
1818+ using mir::input::synthesis::a_pointer_event;
1819+ fake_mouse->emit_event(a_pointer_event().with_movement(displacement.dx.as_int(), displacement.dy.as_int()));
1820+ }
1821+
1822+private:
1823+ std::unique_ptr<mir_test_framework::FakeInputDevice> fake_mouse{
1824+ mir_test_framework::add_fake_input_device(
1825+ mir::input::InputDeviceInfo{"mouse", "mouse-uid", mir::input::DeviceCapability::pointer})};
1826+};
1827+
1828+Rectangle const screen_geometry{{0,0}, {800,600}};
1829+auto const receive_event_timeout = 90s;
1830+
1831+struct DragAndDrop : mir_test_framework::ConnectedClientWithAWindow,
1832+ MouseMoverAndFaker
1833+{
1834+ MirDragAndDropV1 const* dnd = nullptr;
1835+
1836+ void SetUp() override
1837+ {
1838+ initial_display_layout({screen_geometry});
1839+ mir_test_framework::ConnectedClientWithAWindow::SetUp();
1840+
1841+ dnd = mir_drag_and_drop_v1(connection);
1842+
1843+ paint_window();
1844+ mir_window_set_event_handler(window, &window_event_handler, this);
1845+
1846+ center_mouse();
1847+ }
1848+
1849+ void TearDown() override
1850+ {
1851+ set_window_event_handler([&](MirWindow*, MirEvent const*) {});
1852+ mir_test_framework::ConnectedClientWithAWindow::TearDown();
1853+ }
1854+
1855+ auto user_initiates_drag() -> Cookie;
1856+ auto client_requests_drag(Cookie const& cookie) -> Blob;
1857+ auto handle_from_mouse_move() -> Blob;
1858+
1859+private:
1860+ void center_mouse() { move_mouse(0.5 * as_displacement(screen_geometry.size)); }
1861+ void paint_window() const { mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window)); }
1862+ void set_window_event_handler(std::function<void(MirWindow* window, MirEvent const* event)> const& handler);
1863+
1864+ void invoke_window_event_handler(MirWindow* window, MirEvent const* event)
1865+ {
1866+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
1867+ window_event_handler_(window, event);
1868+ }
1869+
1870+ std::mutex window_event_handler_mutex;
1871+ std::function<void(MirWindow* window, MirEvent const* event)> window_event_handler_ =
1872+ [](MirWindow*, MirEvent const*) {};
1873+
1874+ static void window_event_handler(MirWindow* window, MirEvent const* event, void* context);
1875+};
1876+
1877+void DragAndDrop::set_window_event_handler(std::function<void(MirWindow* window, MirEvent const* event)> const& handler)
1878+{
1879+ std::lock_guard<decltype(window_event_handler_mutex)> lock{window_event_handler_mutex};
1880+ window_event_handler_ = handler;
1881+}
1882+
1883+void DragAndDrop::window_event_handler(MirWindow* window, MirEvent const* event, void* context)
1884+{
1885+ static_cast<DragAndDrop*>(context)->invoke_window_event_handler(window, event);
1886+}
1887+
1888+auto DragAndDrop::user_initiates_drag() -> Cookie
1889+{
1890+ Cookie cookie;
1891+ Signal have_cookie;
1892+
1893+ set_window_event_handler([&](MirWindow*, MirEvent const* event)
1894+ {
1895+ if (mir_event_get_type(event) != mir_event_type_input)
1896+ return;
1897+
1898+ auto const input_event = mir_event_get_input_event(event);
1899+
1900+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
1901+ return;
1902+
1903+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
1904+
1905+ if (mir_pointer_event_action(pointer_event) != mir_pointer_action_button_down)
1906+ return;
1907+
1908+ cookie = Cookie{mir_input_event_get_cookie(input_event)};
1909+ have_cookie.raise();
1910+ });
1911+
1912+ start_dragging_mouse();
1913+
1914+ EXPECT_THAT(have_cookie.wait_for(receive_event_timeout), Eq(true));
1915+
1916+ return cookie;
1917+}
1918+
1919+auto DragAndDrop::client_requests_drag(Cookie const& cookie) -> Blob
1920+{
1921+ Blob blob;
1922+ Signal initiated;
1923+
1924+ set_window_event_handler([&](MirWindow*, MirEvent const* event)
1925+ {
1926+ if (mir_event_get_type(event) != mir_event_type_window)
1927+ return;
1928+
1929+ if (!dnd) return;
1930+
1931+ blob.reset(dnd->start_drag_and_drop(mir_event_get_window_event(event)));
1932+
1933+ if (blob)
1934+ initiated.raise();
1935+ });
1936+
1937+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
1938+
1939+ if (dnd)
1940+ dnd->request_drag_and_drop(window, cookie);
1941+
1942+ EXPECT_TRUE(initiated.wait_for(receive_event_timeout));
1943+
1944+ return blob;
1945+}
1946+
1947+auto DragAndDrop::handle_from_mouse_move() -> Blob
1948+{
1949+ Blob blob;
1950+ Signal have_blob;
1951+
1952+ set_window_event_handler([&](MirWindow*, MirEvent const* event)
1953+ {
1954+ if (mir_event_get_type(event) != mir_event_type_input)
1955+ return;
1956+
1957+ auto const input_event = mir_event_get_input_event(event);
1958+
1959+ if (mir_input_event_get_type(input_event) != mir_input_event_type_pointer)
1960+ return;
1961+
1962+ auto const pointer_event = mir_input_event_get_pointer_event(input_event);
1963+
1964+ EXPECT_THAT(dnd, Ne(nullptr)) << "No Drag and Drop extension";
1965+
1966+ if (dnd)
1967+ blob.reset(dnd->pointer_drag_and_drop(pointer_event));
1968+
1969+ if (blob)
1970+ have_blob.raise();
1971+ });
1972+
1973+ move_mouse({1,1});
1974+
1975+ EXPECT_TRUE(have_blob.wait_for(receive_event_timeout));
1976+ return blob;
1977+}
1978+
1979+MATCHER_P(BlobContentEq, p, "")
1980+{
1981+ if (!arg || !p)
1982+ return false;
1983+ if (mir_blob_size(arg) != mir_blob_size(p))
1984+ return false;
1985+ return !memcmp(mir_blob_data(arg), mir_blob_data(p), mir_blob_size(p));
1986+}
1987+}
1988+
1989+TEST_F(DragAndDrop, when_user_initiates_drag_client_receives_cookie)
1990+{
1991+ auto const cookie = user_initiates_drag();
1992+
1993+ EXPECT_THAT(cookie.get(), NotNull());
1994+}
1995+
1996+TEST_F(DragAndDrop, when_client_requests_drags_it_receives_handle)
1997+{
1998+ auto const cookie = user_initiates_drag();
1999+ ASSERT_THAT(cookie.get(), NotNull());
2000+
2001+ auto const handle = client_requests_drag(cookie);
2002+
2003+ EXPECT_THAT(handle.get(), NotNull());
2004+}
2005+
2006+TEST_F(DragAndDrop, during_drag_when_user_moves_mouse_client_receives_handle)
2007+{
2008+ auto const cookie = user_initiates_drag();
2009+ ASSERT_THAT(cookie.get(), NotNull());
2010+ auto const handle_from_request = client_requests_drag(cookie);
2011+
2012+ auto const handle = handle_from_mouse_move();
2013+
2014+ EXPECT_THAT(handle.get(), NotNull());
2015+ EXPECT_THAT(handle.get(), BlobContentEq(handle_from_request.get()));
2016+}
2017
2018=== modified file 'tests/acceptance-tests/test_client_cursor_api.cpp'
2019--- tests/acceptance-tests/test_client_cursor_api.cpp 2017-02-28 08:53:57 +0000
2020+++ tests/acceptance-tests/test_client_cursor_api.cpp 2017-03-14 11:00:58 +0000
2021@@ -82,6 +82,7 @@
2022 MOCK_METHOD0(cursor_image_removed, void());
2023 MOCK_METHOD1(placed_relative, void(geom::Rectangle const& placement));
2024 MOCK_METHOD1(input_consumed, void(MirEvent const*));
2025+ MOCK_METHOD1(start_drag_and_drop, void(std::vector<uint8_t> const& handle));
2026 };
2027
2028
2029
2030=== modified file 'tests/include/mir/test/doubles/mock_input_targeter.h'
2031--- tests/include/mir/test/doubles/mock_input_targeter.h 2015-06-18 02:46:16 +0000
2032+++ tests/include/mir/test/doubles/mock_input_targeter.h 2017-03-14 11:00:58 +0000
2033@@ -35,6 +35,9 @@
2034 virtual ~MockInputTargeter() noexcept(true) {}
2035 MOCK_METHOD1(set_focus, void(std::shared_ptr<input::Surface> const&));
2036 MOCK_METHOD0(clear_focus, void());
2037+
2038+ void set_drag_and_drop_handle(std::vector<uint8_t> const&) override {}
2039+ void clear_drag_and_drop_handle() override {}
2040 };
2041
2042 }
2043
2044=== modified file 'tests/include/mir/test/doubles/mock_shell.h'
2045--- tests/include/mir/test/doubles/mock_shell.h 2017-01-18 02:29:37 +0000
2046+++ tests/include/mir/test/doubles/mock_shell.h 2017-03-14 11:00:58 +0000
2047@@ -72,6 +72,9 @@
2048
2049 MOCK_METHOD3(raise_surface, void(std::shared_ptr<frontend::Session> const& session,
2050 frontend::SurfaceId surface_id, uint64_t timestamp));
2051+
2052+ MOCK_METHOD3(request_drag_and_drop, void(std::shared_ptr<frontend::Session> const& session,
2053+ frontend::SurfaceId surface_id, uint64_t timestamp));
2054 };
2055
2056 }
2057
2058=== modified file 'tests/include/mir/test/doubles/stub_display_server.h'
2059--- tests/include/mir/test/doubles/stub_display_server.h 2017-02-15 07:38:33 +0000
2060+++ tests/include/mir/test/doubles/stub_display_server.h 2017-03-14 11:00:58 +0000
2061@@ -158,6 +158,10 @@
2062 mir::protobuf::RaiseRequest const* /*request*/,
2063 mir::protobuf::Void* /*response*/,
2064 google::protobuf::Closure* /*done*/) {}
2065+ void request_drag_and_drop(
2066+ mir::protobuf::RequestAuthority const* /*request*/,
2067+ mir::protobuf::Void* /*response*/,
2068+ google::protobuf::Closure* /*done*/) {}
2069 void apply_input_configuration(
2070 mir::protobuf::InputConfigurationRequest const* /*request*/,
2071 mir::protobuf::Void* /*response*/,
2072
2073=== modified file 'tests/include/mir/test/doubles/stub_input_targeter.h'
2074--- tests/include/mir/test/doubles/stub_input_targeter.h 2015-06-18 02:46:16 +0000
2075+++ tests/include/mir/test/doubles/stub_input_targeter.h 2017-03-14 11:00:58 +0000
2076@@ -36,6 +36,9 @@
2077 void clear_focus()
2078 {
2079 }
2080+
2081+ void set_drag_and_drop_handle(std::vector<uint8_t> const&) override {}
2082+ void clear_drag_and_drop_handle() override {}
2083 };
2084
2085 }
2086
2087=== modified file 'tests/include/mir/test/doubles/stub_scene_surface.h'
2088--- tests/include/mir/test/doubles/stub_scene_surface.h 2017-02-15 14:45:41 +0000
2089+++ tests/include/mir/test/doubles/stub_scene_surface.h 2017-03-14 11:00:58 +0000
2090@@ -94,6 +94,7 @@
2091 void set_confine_pointer_state(MirPointerConfinementState /*state*/) override {}
2092 MirPointerConfinementState confine_pointer_state() const override { return {}; }
2093 void placed_relative(geometry::Rectangle const& /*placement*/) override {}
2094+ void start_drag_and_drop(std::vector<uint8_t> const& /*handle*/) override {}
2095 };
2096
2097 }
2098
2099=== modified file 'tests/mir_test_framework/observant_shell.cpp'
2100--- tests/mir_test_framework/observant_shell.cpp 2017-01-20 00:01:50 +0000
2101+++ tests/mir_test_framework/observant_shell.cpp 2017-03-14 11:00:58 +0000
2102@@ -155,7 +155,26 @@
2103 void mtf::ObservantShell::raise_surface(
2104 std::shared_ptr<msc::Session> const& session,
2105 std::shared_ptr<msc::Surface> const& window,
2106+ uint64_t timestamp)
2107+{
2108+ return wrapped->raise_surface(session, window, timestamp);
2109+}
2110+
2111+void mtf::ObservantShell::request_drag_and_drop(
2112+ std::shared_ptr<msc::Session> const& session,
2113+ std::shared_ptr<msc::Surface> const& window,
2114 uint64_t timestamp)
2115 {
2116- return wrapped->raise_surface(session, window, timestamp);
2117-}
2118+ return wrapped->request_drag_and_drop(session, window, timestamp);
2119+}
2120+
2121+void mtf::ObservantShell::set_drag_and_drop_handle(std::vector<uint8_t> const& handle)
2122+{
2123+ wrapped->set_drag_and_drop_handle(handle);
2124+}
2125+
2126+void mtf::ObservantShell::clear_drag_and_drop_handle()
2127+{
2128+ wrapped->clear_drag_and_drop_handle();
2129+}
2130+
2131
2132=== modified file 'tests/mir_test_framework/stub_surface.cpp'
2133--- tests/mir_test_framework/stub_surface.cpp 2017-02-15 14:45:41 +0000
2134+++ tests/mir_test_framework/stub_surface.cpp 2017-03-14 11:00:58 +0000
2135@@ -198,6 +198,10 @@
2136 {
2137 }
2138
2139+void mtd::StubSurface::start_drag_and_drop(std::vector<uint8_t> const& /*handle*/)
2140+{
2141+}
2142+
2143 namespace
2144 {
2145 // Ensure we don't accidentally have an abstract class
2146
2147=== modified file 'tests/unit-tests/client/test_client_mir_surface.cpp'
2148--- tests/unit-tests/client/test_client_mir_surface.cpp 2017-03-10 19:47:57 +0000
2149+++ tests/unit-tests/client/test_client_mir_surface.cpp 2017-03-14 11:00:58 +0000
2150@@ -215,7 +215,8 @@
2151 { mir_window_attrib_focus, mir_window_focus_state_focused },
2152 { mir_window_attrib_dpi, 19 },
2153 { mir_window_attrib_visibility, mir_window_visibility_exposed },
2154- { mir_window_attrib_preferred_orientation, mir_orientation_mode_any }
2155+ { mir_window_attrib_preferred_orientation, mir_orientation_mode_any },
2156+ { mir_window_attrib_drag_and_drop_handle, 0 }
2157 };
2158
2159 class TestConnectionConfiguration : public mcl::DefaultConnectionConfiguration

Subscribers

People subscribed via source and target branches