summaryrefslogtreecommitdiff
diff options
-rw-r--r--CMakeLists.txt2
-rw-r--r--HACKING1
-rw-r--r--launcher/CMakeLists.txt1
-rw-r--r--launcher/GeisAdapter.cpp521
-rw-r--r--launcher/GeisAdapter.h172
-rw-r--r--launcher/Launcher.cpp89
-rw-r--r--launcher/Launcher.h10
-rw-r--r--launcher/StandaloneLauncher.cpp1
-rw-r--r--plugins/unityshell/src/GestureEngine.cpp280
-rw-r--r--plugins/unityshell/src/GestureEngine.h68
-rw-r--r--plugins/unityshell/src/UnityGestureBroker.cpp129
-rw-r--r--plugins/unityshell/src/UnityGestureBroker.h45
-rw-r--r--plugins/unityshell/src/UnityGestureTarget.cpp54
-rw-r--r--plugins/unityshell/src/UnityGestureTarget.h44
-rw-r--r--plugins/unityshell/src/WindowGestureTarget.cpp215
-rw-r--r--plugins/unityshell/src/WindowGestureTarget.h57
-rw-r--r--plugins/unityshell/src/unityshell.cpp46
-rw-r--r--plugins/unityshell/src/unityshell.h19
-rw-r--r--tests/CMakeLists.txt13
-rw-r--r--tests/test-gesture-engine/CMakeLists.txt40
-rw-r--r--tests/test-gesture-engine/GeisAdapterMock.cpp31
-rw-r--r--tests/test-gesture-engine/GeisAdapterMock.h148
-rw-r--r--tests/test-gesture-engine/test_gesture_engine.cpp251
-rw-r--r--tests/test-gestures/CMakeLists.txt71
-rw-r--r--tests/test-gestures/FakeGestureEvent.h63
-rw-r--r--tests/test-gestures/NuxMock.h19
-rw-r--r--tests/test-gestures/PluginAdapterMock.cpp (renamed from tests/test-gesture-engine/PluginAdapterMock.cpp)0
-rw-r--r--tests/test-gestures/PluginAdapterMock.h (renamed from tests/test-gesture-engine/PluginAdapterMock.h)0
-rw-r--r--tests/test-gestures/UnityGestureTargetMock.h15
-rw-r--r--tests/test-gestures/WindowGestureTargetMock.h55
-rw-r--r--tests/test-gestures/X11_mock.cpp (renamed from tests/test-gesture-engine/X11_mock.cpp)0
-rw-r--r--tests/test-gestures/X11_mock.h (renamed from tests/test-gesture-engine/X11_mock.h)0
-rw-r--r--tests/test-gestures/compiz_mock/core/core.h (renamed from tests/test-gesture-engine/compiz_mock/core/core.h)0
-rw-r--r--tests/test-gestures/compiz_mock/core/screen.h (renamed from tests/test-gesture-engine/compiz_mock/core/screen.h)35
-rw-r--r--tests/test-gestures/compiz_mock/core/window.h (renamed from tests/test-gesture-engine/compiz_mock/core/window.h)56
-rw-r--r--tests/test-gestures/sed_script_broker11
-rw-r--r--tests/test-gestures/sed_script_gesture (renamed from tests/test-gesture-engine/sed_script)8
-rw-r--r--tests/test-gestures/test_gesture_broker.cpp137
-rw-r--r--tests/test-gestures/test_gestures_main.cpp56
-rw-r--r--tests/test-gestures/test_window_gesture_target.cpp235
-rw-r--r--tests/test-gestures/ubus-server-mock.cpp (renamed from tests/test-gesture-engine/ubus-server-mock.cpp)0
-rw-r--r--tests/test-gestures/ubus-server-mock.h (renamed from tests/test-gesture-engine/ubus-server-mock.h)0
-rw-r--r--tests/test-gestures/unityshell_mock.h52
-rw-r--r--tests/test_launcher_controller.cpp1
-rw-r--r--tests/test_main.cpp2
-rw-r--r--unity-standalone/StandaloneUnity.cpp1
46 files changed, 1436 insertions, 1618 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ac6990d02..5773407de 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -133,7 +133,7 @@ endif (DISABLE_MAINTAINER_CFLAGS)
#
# Compiz Plugins
#
-set (UNITY_PLUGIN_DEPS "compiz;nux-3.0>=3.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4>=0.4.90;atk;unity-misc>=0.4.0;gconf-2.0;libutouch-geis;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;xfixes;unity-protocol-private>=5.93.1")
+set (UNITY_PLUGIN_DEPS "compiz;nux-3.0>=3.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4>=0.4.90;atk;unity-misc>=0.4.0;gconf-2.0;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;xfixes;unity-protocol-private>=5.93.1")
# FIXME: unity-protocol-private shouldn't be there, but building of unityshell is just broken
find_package (PkgConfig)
diff --git a/HACKING b/HACKING
index f01837ed5..a2ac75320 100644
--- a/HACKING
+++ b/HACKING
@@ -7,7 +7,6 @@ If you want to hack on unity you need the following packages
- gthread-2.0
- indicator
- atk
- - libutouch-geis
Or if you are on ubuntu run the command, apt-get build-dep unity
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index ceefbdb0e..3ac9e8db8 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -45,7 +45,6 @@ set (LAUNCHER_SOURCES
FavoriteStore.cpp
FavoriteStoreGSettings.cpp
FavoriteStorePrivate.cpp
- GeisAdapter.cpp
HudLauncherIcon.cpp
Launcher.cpp
LauncherController.cpp
diff --git a/launcher/GeisAdapter.cpp b/launcher/GeisAdapter.cpp
deleted file mode 100644
index d9fe220af..000000000
--- a/launcher/GeisAdapter.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
-/*
- * Copyright (C) 2010 Canonical Ltd
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authored by: Jason Smith <jason.smith@canonical.com>
- */
-
-#include <glib.h>
-#include <gdk/gdkx.h>
-#include <NuxCore/Logger.h>
-#include "GeisAdapter.h"
-
-namespace
-{
- GeisAdapter* adaptor_instance = nullptr;
- nux::logging::Logger logger("unity.geisadapter");
-}
-
-/* static */
-GeisAdapter& GeisAdapter::Instance()
-{
- if (!adaptor_instance)
- {
- LOG_ERROR(logger) << "No GeisAdapter created yet.";
- }
-
- return *adaptor_instance;
-}
-
-GeisAdapter::GeisAdapter() : _root_instance(nullptr)
-{
- if (adaptor_instance)
- {
- LOG_ERROR(logger) << "More than one GeisAdapter created.";
- }
- else
- {
- adaptor_instance = this;
- }
- RegisterRootInstance();
-}
-
-GeisAdapter::~GeisAdapter()
-{
- if (_root_instance != nullptr)
- geis_finish(_root_instance);
- if (adaptor_instance == this)
- {
- adaptor_instance = nullptr;
- }
-}
-
-void
-GeisAdapter::Run()
-{
- int fd = -1;
- GeisStatus status = GEIS_STATUS_NOT_SUPPORTED;
-
- if (_root_instance != nullptr)
- status = geis_configuration_get_value(_root_instance, GEIS_CONFIG_UNIX_FD, &fd);
-
- if (status != GEIS_STATUS_SUCCESS)
- return;
-
- _watch_id = g_io_add_watch(g_io_channel_unix_new(fd),
- G_IO_IN,
- &GeisAdapter::OnWatchIn,
- this);
-}
-
-gboolean
-GeisAdapter::OnWatchIn(GIOChannel* source, GIOCondition condition, gpointer data)
-{
- GeisAdapter* self = static_cast<GeisAdapter*>(data);
- geis_event_dispatch(self->_root_instance);
- return true;
-}
-
-void
-GeisAdapter::InputDeviceAdded(void* cookie, GeisInputDeviceId device_id, void* attrs)
-{
-}
-
-
-void
-GeisAdapter::InputDeviceChanged(void* cookie, GeisInputDeviceId device_id, void* attrs)
-{
-}
-
-
-void
-GeisAdapter::InputDeviceRemoved(void* cookie, GeisInputDeviceId device_id, void* attrs)
-{
-}
-
-void
-GeisAdapter::GestureAdded(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize count, GeisGestureAttr* attrs)
-{
-}
-
-void
-GeisAdapter::GestureRemoved(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize count, GeisGestureAttr* attrs)
-{
-}
-
-void
-GeisAdapter::GestureStart(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize count, GeisGestureAttr* attrs)
-{
- GeisAdapter* self = static_cast<GeisAdapter*>(cookie);
-
- if (gesture_type == GEIS_GESTURE_PRIMITIVE_DRAG)
- {
- GeisDragData* data = self->ProcessDragGesture(count, attrs);
- data->id = gesture_id;
- self->drag_start.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_ROTATE)
- {
- GeisRotateData* data = self->ProcessRotateGesture(count, attrs);
- data->id = gesture_id;
- self->rotate_start.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_PINCH)
- {
- GeisPinchData* data = self->ProcessPinchGesture(count, attrs);
- data->id = gesture_id;
- self->pinch_start.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_TAP)
- {
- GeisTapData* data = self->ProcessTapGesture(count, attrs);
- data->id = gesture_id;
- self->tap.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_TOUCH)
- {
- GeisTouchData* data = self->ProcessTouchGesture(count, attrs);
- data->id = gesture_id;
- self->touch_start.emit(data);
- g_free(data);
- }
-}
-
-void
-GeisAdapter::GestureUpdate(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize count, GeisGestureAttr* attrs)
-{
- GeisAdapter* self = static_cast<GeisAdapter*>(cookie);
-
- if (gesture_type == GEIS_GESTURE_PRIMITIVE_DRAG)
- {
- GeisDragData* data = self->ProcessDragGesture(count, attrs);
- data->id = gesture_id;
- self->drag_update.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_ROTATE)
- {
- GeisRotateData* data = self->ProcessRotateGesture(count, attrs);
- data->id = gesture_id;
- self->rotate_update.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_PINCH)
- {
- GeisPinchData* data = self->ProcessPinchGesture(count, attrs);
- data->id = gesture_id;
- self->pinch_update.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_TAP)
- {
- GeisTapData* data = self->ProcessTapGesture(count, attrs);
- data->id = gesture_id;
- self->tap.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_TOUCH)
- {
- GeisTouchData* data = self->ProcessTouchGesture(count, attrs);
- data->id = gesture_id;
- self->touch_update.emit(data);
- g_free(data);
- }
-}
-
-void
-GeisAdapter::GestureFinish(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize count, GeisGestureAttr* attrs)
-{
- GeisAdapter* self = static_cast<GeisAdapter*>(cookie);
-
- if (gesture_type == GEIS_GESTURE_PRIMITIVE_DRAG)
- {
- GeisDragData* data = self->ProcessDragGesture(count, attrs);
- data->id = gesture_id;
- self->drag_finish.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_ROTATE)
- {
- GeisRotateData* data = self->ProcessRotateGesture(count, attrs);
- data->id = gesture_id;
- self->rotate_finish.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_PINCH)
- {
- GeisPinchData* data = self->ProcessPinchGesture(count, attrs);
- data->id = gesture_id;
- self->pinch_finish.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_TAP)
- {
- GeisTapData* data = self->ProcessTapGesture(count, attrs);
- data->id = gesture_id;
- self->tap.emit(data);
- g_free(data);
- }
- else if (gesture_type == GEIS_GESTURE_PRIMITIVE_TOUCH)
- {
- GeisTouchData* data = self->ProcessTouchGesture(count, attrs);
- data->id = gesture_id;
- self->touch_finish.emit(data);
- g_free(data);
- }
-}
-
-GeisAdapter::GeisTapData* GeisAdapter::ProcessTapGesture(GeisSize count, GeisGestureAttr* attrs)
-{
- GeisTapData* result = (GeisTapData*) g_malloc0(sizeof(GeisTapData));
-
- int i;
- for (i = 0; i < (int) count; i++)
- {
- GeisGestureAttr attr = attrs[i];
- if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_DEVICE_ID))
- result->device_id = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID))
- result->window = (Window) attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP))
- result->timestamp = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X))
- result->focus_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y))
- result->focus_y = attr.float_val;
- else if (g_str_equal (attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES))
- result->touches = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_GESTURE_NAME))
- {
- if (!g_strcmp0(attr.string_val, GEIS_GESTURE_TYPE_TAP1))
- result->touches = 1;
- else if (!g_strcmp0(attr.string_val, GEIS_GESTURE_TYPE_TAP2))
- result->touches = 2;
- else if (!g_strcmp0(attr.string_val, GEIS_GESTURE_TYPE_TAP3))
- result->touches = 3;
- else if (!g_strcmp0(attr.string_val, GEIS_GESTURE_TYPE_TAP4))
- result->touches = 4;
- else if (!g_strcmp0(attr.string_val, GEIS_GESTURE_TYPE_TAP5))
- result->touches = 5;
- }
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TAP_TIME))
- result->tap_length_ms = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_POSITION_X))
- result->position_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_POSITION_Y))
- result->position_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1))
- result->bound_x1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1))
- result->bound_y1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2))
- result->bound_x2 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2))
- result->bound_y2 = attr.float_val;
- }
-
- return result;
-}
-
-GeisAdapter::GeisTouchData* GeisAdapter::ProcessTouchGesture(GeisSize count, GeisGestureAttr* attrs)
-{
- GeisTouchData* result = (GeisTouchData*) g_malloc0(sizeof(GeisTouchData));
-
- int i;
- for (i = 0; i < (int) count; i++)
- {
- GeisGestureAttr attr = attrs[i];
- if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_DEVICE_ID))
- result->device_id = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID))
- result->window = (Window) attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP))
- result->timestamp = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X))
- result->focus_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y))
- result->focus_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES))
- result->touches = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1))
- result->bound_x1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1))
- result->bound_y1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2))
- result->bound_x2 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2))
- result->bound_y2 = attr.float_val;
- }
-
- return result;
-}
-
-GeisAdapter::GeisDragData* GeisAdapter::ProcessDragGesture(GeisSize count, GeisGestureAttr* attrs)
-{
- GeisDragData* result = (GeisDragData*) g_malloc0(sizeof(GeisDragData));
-
- int i;
- for (i = 0; i < (int) count; i++)
- {
- GeisGestureAttr attr = attrs[i];
- if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_DEVICE_ID))
- result->device_id = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID))
- result->window = (Window) attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP))
- result->timestamp = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X))
- result->focus_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y))
- result->focus_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES))
- result->touches = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_POSITION_X))
- result->position_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_POSITION_Y))
- result->position_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_X))
- result->velocity_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_VELOCITY_Y))
- result->velocity_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_DELTA_X))
- result->delta_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_DELTA_Y))
- result->delta_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1))
- result->bound_x1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1))
- result->bound_y1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2))
- result->bound_x2 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2))
- result->bound_y2 = attr.float_val;
- }
-
- return result;
-}
-
-GeisAdapter::GeisPinchData* GeisAdapter::ProcessPinchGesture(GeisSize count, GeisGestureAttr* attrs)
-{
- GeisPinchData* result = (GeisPinchData*) g_malloc0(sizeof(GeisPinchData));
-
- int i;
- for (i = 0; i < (int) count; i++)
- {
- GeisGestureAttr attr = attrs[i];
- if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_DEVICE_ID))
- result->device_id = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID))
- result->window = (Window) attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP))
- result->timestamp = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X))
- result->focus_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y))
- result->focus_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES))
- result->touches = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_RADIUS))
- result->radius = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_RADIUS_DELTA))
- result->radius_delta = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_RADIAL_VELOCITY))
- result->radius_velocity = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1))
- result->bound_x1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1))
- result->bound_y1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2))
- result->bound_x2 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2))
- result->bound_y2 = attr.float_val;
- }
-
- return result;
-}
-
-GeisAdapter::GeisRotateData* GeisAdapter::ProcessRotateGesture(GeisSize count, GeisGestureAttr* attrs)
-{
- GeisRotateData* result = (GeisRotateData*) g_malloc0(sizeof(GeisRotateData));
-
- int i;
- for (i = 0; i < (int) count; i++)
- {
- GeisGestureAttr attr = attrs[i];
- if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_DEVICE_ID))
- result->device_id = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_CHILD_WINDOW_ID))
- result->window = (Window) attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TIMESTAMP))
- result->timestamp = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_X))
- result->focus_x = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_FOCUS_Y))
- result->focus_y = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_TOUCHES))
- result->touches = attr.integer_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_ANGLE))
- result->angle = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_ANGLE_DELTA))
- result->angle_delta = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_ANGULAR_VELOCITY))
- result->angle_velocity = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X1))
- result->bound_x1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y1))
- result->bound_y1 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_X2))
- result->bound_x2 = attr.float_val;
- else if (g_str_equal(attr.name, GEIS_GESTURE_ATTRIBUTE_BOUNDINGBOX_Y2))
- result->bound_y2 = attr.float_val;
- }
-
- return result;
-}
-
-static const char* s_gestures[] =
-{
- GEIS_GESTURE_TYPE_DRAG3, GEIS_GESTURE_TYPE_TAP3, GEIS_GESTURE_TYPE_ROTATE3, GEIS_GESTURE_TYPE_PINCH3, GEIS_GESTURE_TYPE_TOUCH3,
- GEIS_GESTURE_TYPE_DRAG4, GEIS_GESTURE_TYPE_TAP4, GEIS_GESTURE_TYPE_ROTATE4, GEIS_GESTURE_TYPE_PINCH4, GEIS_GESTURE_TYPE_TOUCH4,
- GEIS_GESTURE_TYPE_SYSTEM,
- NULL
-};
-
-void
-GeisAdapter::RegisterRootInstance()
-{
- static GeisInputFuncs input_funcs =
- {
- &GeisAdapter::InputDeviceAdded,
- &GeisAdapter::InputDeviceChanged,
- &GeisAdapter::InputDeviceRemoved
- };
-
- static GeisGestureFuncs gesture_funcs =
- {
- &GeisAdapter::GestureAdded,
- &GeisAdapter::GestureRemoved,
- &GeisAdapter::GestureStart,
- &GeisAdapter::GestureUpdate,
- &GeisAdapter::GestureFinish
- };
-
- GeisStatus status = GEIS_UNKNOWN_ERROR;
-
- GeisXcbWinInfo xcb_win_info;
- xcb_win_info.display_name = NULL,
- xcb_win_info.screenp = NULL,
- xcb_win_info.window_id = gdk_x11_get_default_root_xwindow();
-
- GeisWinInfo win_info =
- {
- GEIS_XCB_FULL_WINDOW,
- &xcb_win_info
- };
- GeisInstance instance;
-
- status = geis_init(&win_info, &instance);
- if (status != GEIS_STATUS_SUCCESS)
- {
- fprintf(stderr, "error in geis_init\n");
- return;
- }
-
- status = geis_input_devices(instance, &input_funcs, this);
- if (status != GEIS_STATUS_SUCCESS)
- {
- fprintf(stderr, "error subscribing to input devices\n");
- geis_finish(instance);
- return;
- }
-
- status = geis_subscribe(instance,
- GEIS_ALL_INPUT_DEVICES,
- s_gestures,
- &gesture_funcs,
- this);
- if (status != GEIS_STATUS_SUCCESS)
- {
- fprintf(stderr, "error subscribing to gestures\n");
- geis_finish(instance);
- return;
- }
-
- _root_instance = instance;
-}
diff --git a/launcher/GeisAdapter.h b/launcher/GeisAdapter.h
deleted file mode 100644
index f68923bed..000000000
--- a/launcher/GeisAdapter.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
-/*
- * Copyright (C) 2010 Canonical Ltd
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * aint with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authored by: Jason Smith <jason.smith@canonical.com>
- */
-
-#ifndef GEISADAPTER_H
-#define GEISADAPTER_H
-
-/* Compiz */
-#include <sigc++/sigc++.h>
-#include <geis/geis.h>
-#include <Nux/Nux.h>
-
-class GeisAdapter : public sigc::trackable
-{
-public:
- static GeisAdapter& Instance();
-
- GeisAdapter();
- ~GeisAdapter();
-
- void Run();
-
- typedef struct _GeisTapData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- int tap_length_ms;
- float position_x;
- float position_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisTapData;
-
- typedef struct _GeisDragData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float delta_x;
- float delta_y;
- float velocity_x;
- float velocity_y;
- float position_x;
- float position_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisDragData;
-
- typedef struct _GeisRotateData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float angle;
- float angle_delta;
- float angle_velocity;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisRotateData;
-
- typedef struct _GeisPinchData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float radius;
- float radius_delta;
- float radius_velocity;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisPinchData;
-
- typedef struct _GeisTouchData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisTouchData;
-
- sigc::signal<void, GeisTapData*> tap;
-
- sigc::signal<void, GeisDragData*> drag_start;
- sigc::signal<void, GeisDragData*> drag_update;
- sigc::signal<void, GeisDragData*> drag_finish;
-
- sigc::signal<void, GeisRotateData*> rotate_start;
- sigc::signal<void, GeisRotateData*> rotate_update;
- sigc::signal<void, GeisRotateData*> rotate_finish;
-
- sigc::signal<void, GeisPinchData*> pinch_start;
- sigc::signal<void, GeisPinchData*> pinch_update;
- sigc::signal<void, GeisPinchData*> pinch_finish;
-
- sigc::signal<void, GeisTouchData*> touch_start;
- sigc::signal<void, GeisTouchData*> touch_update;
- sigc::signal<void, GeisTouchData*> touch_finish;
-protected:
- static gboolean OnWatchIn(GIOChannel* source, GIOCondition condition, gpointer data);
-
- static void InputDeviceAdded(void* cookie, GeisInputDeviceId device_id, void* attrs);
- static void InputDeviceChanged(void* cookie, GeisInputDeviceId device_id, void* attrs);
- static void InputDeviceRemoved(void* cookie, GeisInputDeviceId device_id, void* attrs);
-
- static void GestureAdded(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr* attrs);
- static void GestureRemoved(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr* attrs);
-
- static void GestureStart(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr* attrs);
- static void GestureUpdate(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr* attrs);
- static void GestureFinish(void* cookie, GeisGestureType gesture_type, GeisGestureId gesture_id, GeisSize attr_count, GeisGestureAttr* attrs);
-
- GeisTapData* ProcessTapGesture(GeisSize attr_count, GeisGestureAttr* attrs);
- GeisDragData* ProcessDragGesture(GeisSize attr_count, GeisGestureAttr* attrs);
- GeisPinchData* ProcessPinchGesture(GeisSize attr_count, GeisGestureAttr* attrs);
- GeisRotateData* ProcessRotateGesture(GeisSize attr_count, GeisGestureAttr* attrs);
- GeisTouchData* ProcessTouchGesture(GeisSize attr_count, GeisGestureAttr* attrs);
-
-private:
- void RegisterRootInstance();
-
- GeisInstance _root_instance;
- guint _watch_id;
-};
-
-#endif
diff --git a/launcher/Launcher.cpp b/launcher/Launcher.cpp
index bd6ebb3c5..3c9aa84cb 100644
--- a/launcher/Launcher.cpp
+++ b/launcher/Launcher.cpp
@@ -29,6 +29,7 @@
#include <NuxCore/Logger.h>
#include <NuxGraphics/NuxGraphics.h>
+#include <NuxGraphics/GestureEvent.h>
#include <NuxGraphics/GpuDevice.h>
#include <NuxGraphics/GLTextureResourceManager.h>
@@ -136,8 +137,8 @@ Launcher::Launcher(nux::BaseWindow* parent,
, _launcher_drag_delta_min(0)
, _enter_y(0)
, _last_button_press(0)
- , _drag_out_id(0)
, _drag_out_delta_x(0.0f)
+ , _drag_gesture_ongoing(false)
, _last_reveal_progress(0.0f)
, _collection_window(collection_window)
, _selection_atom(0)
@@ -185,11 +186,6 @@ Launcher::Launcher(nux::BaseWindow* parent,
plugin_adapter.terminate_expo.connect(sigc::mem_fun(this, &Launcher::OnPluginStateChanged));
plugin_adapter.compiz_screen_viewport_switch_ended.connect(sigc::mem_fun(this, &Launcher::EnsureAnimation));
- GeisAdapter& adapter = GeisAdapter::Instance();
- adapter.drag_start.connect(sigc::mem_fun(this, &Launcher::OnDragStart));
- adapter.drag_update.connect(sigc::mem_fun(this, &Launcher::OnDragUpdate));
- adapter.drag_finish.connect(sigc::mem_fun(this, &Launcher::OnDragFinish));
-
display.changed.connect(sigc::mem_fun(this, &Launcher::OnDisplayChanged));
// 0 out timers to avoid wonky startups
@@ -233,45 +229,39 @@ void Launcher::OnDisplayChanged(Display* display)
_collection_window->display = display;
}
-void Launcher::OnDragStart(GeisAdapter::GeisDragData* data)
+void
+Launcher::OnDragStart(const nux::GestureEvent &event)
{
- if (_drag_out_id && _drag_out_id == data->id)
- return;
-
- if (data->touches == 4)
+ _drag_gesture_ongoing = true;
+ if (_hidden)
{
- _drag_out_id = data->id;
- if (_hidden)
- {
- _drag_out_delta_x = 0.0f;
- }
- else
- {
- _drag_out_delta_x = DRAG_OUT_PIXELS;
- _hide_machine.SetQuirk(LauncherHideMachine::MT_DRAG_OUT, false);
- }
+ _drag_out_delta_x = 0.0f;
+ }
+ else
+ {
+ _drag_out_delta_x = DRAG_OUT_PIXELS;
+ _hide_machine.SetQuirk(LauncherHideMachine::MT_DRAG_OUT, false);
}
}
-void Launcher::OnDragUpdate(GeisAdapter::GeisDragData* data)
+void
+Launcher::OnDragUpdate(const nux::GestureEvent &event)
{
- if (data->id == _drag_out_id)
- {
- _drag_out_delta_x = CLAMP(_drag_out_delta_x + data->delta_x, 0.0f, DRAG_OUT_PIXELS);
- EnsureAnimation();
- }
+ _drag_out_delta_x =
+ CLAMP(_drag_out_delta_x + event.GetDelta().x, 0.0f, DRAG_OUT_PIXELS);
+ EnsureAnimation();
}
-void Launcher::OnDragFinish(GeisAdapter::GeisDragData* data)
+void
+Launcher::OnDragFinish(const nux::GestureEvent &event)
{
- if (data->id == _drag_out_id)
- {
- if (_drag_out_delta_x >= DRAG_OUT_PIXELS - 90.0f)
- _hide_machine.SetQuirk(LauncherHideMachine::MT_DRAG_OUT, true);
- TimeUtil::SetTimeStruct(&_times[TIME_DRAG_OUT], &_times[TIME_DRAG_OUT], ANIM_DURATION_SHORT);
- _drag_out_id = 0;
- EnsureAnimation();
- }
+ if (_drag_out_delta_x >= DRAG_OUT_PIXELS - 90.0f)
+ _hide_machine.SetQuirk(LauncherHideMachine::MT_DRAG_OUT, true);
+ TimeUtil::SetTimeStruct(&_times[TIME_DRAG_OUT],
+ &_times[TIME_DRAG_OUT],
+ ANIM_DURATION_SHORT);
+ EnsureAnimation();
+ _drag_gesture_ongoing = false;
}
void Launcher::AddProperties(GVariantBuilder* builder)
@@ -341,9 +331,11 @@ float Launcher::DragOutProgress(struct timespec const& current) const
float timeout = CLAMP((float)(unity::TimeUtil::TimeDelta(&current, &_times[TIME_DRAG_OUT])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f);
float progress = CLAMP(_drag_out_delta_x / DRAG_OUT_PIXELS, 0.0f, 1.0f);
- if (_drag_out_id || _hide_machine.GetQuirk(LauncherHideMachine::MT_DRAG_OUT))
+ if (_drag_gesture_ongoing
+ || _hide_machine.GetQuirk(LauncherHideMachine::MT_DRAG_OUT))
return progress;
- return progress * (1.0f - timeout);
+ else
+ return progress * (1.0f - timeout);
}
float Launcher::AutohideProgress(struct timespec const& current) const
@@ -2505,7 +2497,26 @@ void Launcher::RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLaun
RestoreSystemRenderTarget();
}
-void Launcher::SetOffscreenRenderTarget(nux::ObjectPtr<nux::IOpenGLBaseTexture> texture)
+nux::GestureDeliveryRequest Launcher::GestureEvent(const nux::GestureEvent &event)
+{
+ switch(event.type)
+ {
+ case nux::EVENT_GESTURE_BEGIN:
+ OnDragStart(event);
+ break;
+ case nux::EVENT_GESTURE_UPDATE:
+ OnDragUpdate(event);
+ break;
+ default: // EVENT_GESTURE_END
+ OnDragFinish(event);
+ break;
+ }
+
+ return nux::GestureDeliveryRequest::NONE;
+}
+
+void
+Launcher::SetOffscreenRenderTarget(nux::ObjectPtr<nux::IOpenGLBaseTexture> texture)
{
int width = texture->GetWidth();
int height = texture->GetHeight();
diff --git a/launcher/Launcher.h b/launcher/Launcher.h
index 3c1c010d4..a41dfff71 100644
--- a/launcher/Launcher.h
+++ b/launcher/Launcher.h
@@ -32,7 +32,6 @@
#include "DNDCollectionWindow.h"
#include "DndData.h"
#include "EdgeBarrierController.h"
-#include "GeisAdapter.h"
#include "unity-shared/Introspectable.h"
#include "LauncherModel.h"
#include "LauncherOptions.h"
@@ -136,6 +135,7 @@ public:
void RenderIconToTexture(nux::GraphicsEngine& GfxContext, AbstractLauncherIcon::Ptr icon, nux::ObjectPtr<nux::IOpenGLBaseTexture> texture);
+ virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event);
protected:
// Introspectable methods
std::string GetName() const;
@@ -183,9 +183,9 @@ private:
void OnWindowMapped(guint32 xid);
void OnWindowUnmapped(guint32 xid);
- void OnDragStart(GeisAdapter::GeisDragData* data);
- void OnDragUpdate(GeisAdapter::GeisDragData* data);
- void OnDragFinish(GeisAdapter::GeisDragData* data);
+ void OnDragStart(const nux::GestureEvent &event);
+ void OnDragUpdate(const nux::GestureEvent &event);
+ void OnDragFinish(const nux::GestureEvent &event);
bool HandleBarrierEvent(ui::PointerBarrierWrapper* owner, ui::BarrierEvent::Ptr event);
@@ -362,8 +362,8 @@ private:
int _launcher_drag_delta_min;
int _enter_y;
int _last_button_press;
- int _drag_out_id;
float _drag_out_delta_x;
+ bool _drag_gesture_ongoing;
float _last_reveal_progress;
nux::Point2 _mouse_position;
diff --git a/launcher/StandaloneLauncher.cpp b/launcher/StandaloneLauncher.cpp
index a3e7a7752..8dba0e4f7 100644
--- a/launcher/StandaloneLauncher.cpp
+++ b/launcher/StandaloneLauncher.cpp
@@ -59,7 +59,6 @@ int main(int argc, char** argv)
nux::NuxInitialize(0);
- GeisAdapter geis_adapter;
unity::Settings settings;
panel::Style panel_style;
internal::FavoriteStoreGSettings favorite_store;
diff --git a/plugins/unityshell/src/GestureEngine.cpp b/plugins/unityshell/src/GestureEngine.cpp
deleted file mode 100644
index 9bf825b3a..000000000
--- a/plugins/unityshell/src/GestureEngine.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * GestureEngine.cpp
- * This file is part of Unity
- *
- * Copyright (C) 2011 - Canonical Ltd.
- *
- * Unity is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Unity is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Unity; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include <X11/cursorfont.h>
-
-#include "ubus-server.h"
-#include "UBusMessages.h"
-#include "GestureEngine.h"
-#include "PluginAdapter.h"
-
-GestureEngine::GestureEngine(CompScreen* screen)
-{
- _screen = screen;
-
- _drag_id = 0;
- _drag_window = 0;
- _pinch_id = 0;
- _touch_id = 0;
- _drag_grab = 0;
- _pinch_grab = 0;
- _fleur_cursor = XCreateFontCursor (screen->dpy (), XC_fleur);
-
- GeisAdapter& adapter = GeisAdapter::Instance();
-
- adapter.tap.connect(sigc::mem_fun(this, &GestureEngine::OnTap));
-
- adapter.drag_start.connect(sigc::mem_fun(this, &GestureEngine::OnDragStart));
- adapter.drag_update.connect(sigc::mem_fun(this, &GestureEngine::OnDragUpdate));
- adapter.drag_finish.connect(sigc::mem_fun(this, &GestureEngine::OnDragFinish));
-
- adapter.rotate_start.connect(sigc::mem_fun(this, &GestureEngine::OnRotateStart));
- adapter.rotate_update.connect(sigc::mem_fun(this, &GestureEngine::OnRotateUpdate));
- adapter.rotate_finish.connect(sigc::mem_fun(this, &GestureEngine::OnRotateFinish));
-
- adapter.pinch_start.connect(sigc::mem_fun(this, &GestureEngine::OnPinchStart));
- adapter.pinch_update.connect(sigc::mem_fun(this, &GestureEngine::OnPinchUpdate));
- adapter.pinch_finish.connect(sigc::mem_fun(this, &GestureEngine::OnPinchFinish));
-
- adapter.touch_start.connect(sigc::mem_fun(this, &GestureEngine::OnTouchStart));
- adapter.touch_update.connect(sigc::mem_fun(this, &GestureEngine::OnTouchUpdate));
- adapter.touch_finish.connect(sigc::mem_fun(this, &GestureEngine::OnTouchFinish));
-}
-
-GestureEngine::~GestureEngine()
-{
- if (_fleur_cursor)
- XFreeCursor (screen->dpy (), _fleur_cursor);
-}
-
-void
-GestureEngine::OnTap(GeisAdapter::GeisTapData* data)
-{
- if (data->touches == 4)
- {
- UBusServer* ubus = ubus_server_get_default();
- ubus_server_send_message(ubus, UBUS_DASH_EXTERNAL_ACTIVATION, NULL);
- }
-}
-
-CompWindow* GestureEngine::FindCompWindowAtPos(float fpos_x, float fpos_y)
-{
- const CompWindowVector& client_list_stacking = _screen->clientList(true);
-
- int pos_x = fpos_x;
- int pos_y = fpos_y;
-
- for (auto iter = client_list_stacking.rbegin(),
- end = client_list_stacking.rend();
- iter != end; ++iter)
- {
- CompWindow* window = *iter;
-
- if (pos_x >= window->x() && pos_x <= (window->width() + window->x())
- &&
- pos_y >= window->y() && pos_y <= (window->height() + window->y()))
- return window;
- }
-
- return nullptr;
-}
-
-void
-GestureEngine::OnDragStart(GeisAdapter::GeisDragData* data)
-{
- if (data->touches == 3)
- {
- _drag_window = FindCompWindowAtPos(data->focus_x, data->focus_y);
-
-
- if (!_drag_window)
- return;
-
- if (!(_drag_window->actions() & CompWindowActionMoveMask))
- {
- _drag_window = 0;
- return;
- }
-
- /* Don't allow windows to be dragged if completely maximized */
- if ((_drag_window->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE)
- {
- _drag_window = 0;
- return;
- }
-
- if (_drag_grab)
- _screen->removeGrab(_drag_grab, NULL);
- _drag_id = data->id;
- _drag_grab = _screen->pushGrab(_fleur_cursor, "unity");
- _drag_window->grabNotify (_drag_window->serverGeometry ().x (),
- _drag_window->serverGeometry ().y (),
- 0, CompWindowGrabMoveMask | CompWindowGrabButtonMask);
- }
-}
-
-/* FIXME: CompScreen::warpPointer filters out motion events which
- * other plugins may need to process, but for most cases in core
- * they should be filtered out. */
-void
-GestureEngine::OnDragUpdate(GeisAdapter::GeisDragData* data)
-{
- if (_drag_id == data->id && _drag_window)
- {
- unsigned int px = std::max (std::min (pointerX + static_cast <int> (data->delta_x), screen->width ()), 0);
- unsigned int py = std::max (std::min (pointerY + static_cast <int> (data->delta_y), screen->height ()), 0);
-
- if (_drag_window->state () & CompWindowStateMaximizedVertMask)
- py = pointerY;
- if (_drag_window->state () & CompWindowStateMaximizedHorzMask)
- px = pointerX;
-
- XWarpPointer(screen->dpy (),
- None, screen->root (),
- 0, 0, 0, 0,
- px, py);
-
- XSync(screen->dpy (), false);
- _drag_window->move(px - pointerX, py - pointerY, false);
-
- pointerX = px;
- pointerY = py;
- }
-}
-
-void
-GestureEngine::OnDragFinish(GeisAdapter::GeisDragData* data)
-{
- if (_drag_id == data->id && _drag_window)
- {
- _drag_window->ungrabNotify ();
- _drag_window->syncPosition();
- EndDrag();
- }
-}
-
-void
-GestureEngine::EndDrag()
-{
- if (_drag_window)
- {
- _screen->removeGrab(_drag_grab, NULL);
- _drag_grab = 0;
- _drag_window = 0;
- _drag_id = 0;
- }
-}
-
-void
-GestureEngine::OnRotateStart(GeisAdapter::GeisRotateData* data)
-{
-
-}
-void
-GestureEngine::OnRotateUpdate(GeisAdapter::GeisRotateData* data)
-{
-
-}
-void
-GestureEngine::OnRotateFinish(GeisAdapter::GeisRotateData* data)
-{
-
-}
-
-void
-GestureEngine::OnTouchStart(GeisAdapter::GeisTouchData* data)
-{
- if (data->touches == 3 && data->window != 0)
- {
- CompWindow* result = FindCompWindowAtPos(data->focus_x, data->focus_y);
-
- if (result)
- {
- PluginAdapter::Default()->ShowGrabHandles(result, false);
- _touch_id = data->id;
- _touch_window = result;
- }
- }
-}
-
-void
-GestureEngine::OnTouchUpdate(GeisAdapter::GeisTouchData* data)
-{
-
-}
-
-void
-GestureEngine::OnTouchFinish(GeisAdapter::GeisTouchData* data)
-{
- if (_touch_id == data->id)
- {
- if (_touch_window)
- PluginAdapter::Default()->ShowGrabHandles(_touch_window, true);
- _touch_id = 0;
- _touch_window = 0;
- }
-}
-
-void
-GestureEngine::OnPinchStart(GeisAdapter::GeisPinchData* data)
-{
- if (data->touches == 3)
- {
- _pinch_window = FindCompWindowAtPos(data->focus_x, data->focus_y);
-
- if (!_pinch_window)
- return;
-
- _pinch_id = data->id;
-
- if (_pinch_grab)
- _screen->removeGrab(_pinch_grab, NULL);
- _pinch_grab = _screen->pushGrab(_screen->invisibleCursor(), "unity");
- }
-}
-void
-GestureEngine::OnPinchUpdate(GeisAdapter::GeisPinchData* data)
-{
- if (data->id != _pinch_id)
- return;
-
- if (data->radius > 1.25)
- {
- _pinch_window->maximize(MAXIMIZE_STATE);
- EndDrag();
- }
- else if (data->radius < 0.8)
- {
- _pinch_window->maximize(0);
- EndDrag();
- }
-}
-void
-GestureEngine::OnPinchFinish(GeisAdapter::GeisPinchData* data)
-{
- if (_pinch_id == data->id && _pinch_window)
- {
- _screen->removeGrab(_pinch_grab, NULL);
- _pinch_grab = 0;
- _pinch_id = 0;
- }
-}
diff --git a/plugins/unityshell/src/GestureEngine.h b/plugins/unityshell/src/GestureEngine.h
deleted file mode 100644
index bce81628d..000000000
--- a/plugins/unityshell/src/GestureEngine.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * GestureEngine.h
- * This file is part of Unity
- *
- * Copyright (C) 2011 - Canonical Ltd.
- *
- * Unity is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Unity is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Unity; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301 USA
- */
-
-#include <core/core.h>
-
-#include <sigc++/sigc++.h>
-#include "GeisAdapter.h"
-
-class GestureEngine : public sigc::trackable
-{
-public:
- GestureEngine(CompScreen* screen);
- virtual ~GestureEngine();
-
- void OnTap(GeisAdapter::GeisTapData* data);
-
- void OnDragStart(GeisAdapter::GeisDragData* data);
- void OnDragUpdate(GeisAdapter::GeisDragData* data);
- void OnDragFinish(GeisAdapter::GeisDragData* data);
-
- void OnRotateStart(GeisAdapter::GeisRotateData* data);
- void OnRotateUpdate(GeisAdapter::GeisRotateData* data);
- void OnRotateFinish(GeisAdapter::GeisRotateData* data);
-
- void OnPinchStart(GeisAdapter::GeisPinchData* data);
- void OnPinchUpdate(GeisAdapter::GeisPinchData* data);
- void OnPinchFinish(GeisAdapter::GeisPinchData* data);
-
- void OnTouchStart(GeisAdapter::GeisTouchData* data);
- void OnTouchUpdate(GeisAdapter::GeisTouchData* data);
- void OnTouchFinish(GeisAdapter::GeisTouchData* data);
-
- void EndDrag();
-private:
- CompWindow* FindCompWindowAtPos(float pos_x, float pos_y);
-
- CompScreen* _screen;
- CompWindow* _drag_window;
- CompWindow* _pinch_window;
- CompWindow* _touch_window;
- CompScreen::GrabHandle _drag_grab;
- CompScreen::GrabHandle _pinch_grab;
-
- int _drag_id;
- int _pinch_id;
- int _touch_id;
-
- Cursor _fleur_cursor;
-};
diff --git a/plugins/unityshell/src/UnityGestureBroker.cpp b/plugins/unityshell/src/UnityGestureBroker.cpp
new file mode 100644
index 000000000..c05237f22
--- /dev/null
+++ b/plugins/unityshell/src/UnityGestureBroker.cpp
@@ -0,0 +1,129 @@
+/*
+ * UnityGestureBroker.cpp
+ * This file is part of Unity
+ *
+ * Copyright (C) 2012 - Canonical Ltd.
+ *
+ * Unity is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Unity is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Unity; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include "UnityGestureBroker.h"
+#include "UnityGestureTarget.h"
+#include "WindowGestureTarget.h"
+
+#include <X11/cursorfont.h>
+
+UnityGestureBroker::UnityGestureBroker()
+ : nux::GestureBroker()
+{
+ g_assert(WindowGestureTarget::fleur_cursor == 0);
+ WindowGestureTarget::fleur_cursor = XCreateFontCursor (screen->dpy (), XC_fleur);
+
+ unity_target.reset(new UnityGestureTarget);
+}
+
+UnityGestureBroker::~UnityGestureBroker()
+{
+ if (WindowGestureTarget::fleur_cursor)
+ {
+ XFreeCursor (screen->dpy (), WindowGestureTarget::fleur_cursor);
+ WindowGestureTarget::fleur_cursor = 0;
+ }
+}
+
+std::vector<nux::ShPtGestureTarget>
+UnityGestureBroker::FindGestureTargets(const nux::GestureEvent &event)
+{
+ std::vector<nux::ShPtGestureTarget> targets;
+ const std::vector<nux::TouchPoint> &touches = event.GetTouches();
+
+ if (touches.size() == 4)
+ {
+ targets.push_back(unity_target);
+ }
+ else if (touches.size() == 3)
+ {
+ CompWindow *window = FindWindowHitByGesture(event);
+ if (window)
+ {
+ targets.push_back(nux::ShPtGestureTarget(new WindowGestureTarget(window)));
+ }
+ }
+
+ return targets;
+}
+
+CompWindow *UnityGestureBroker::FindWindowHitByGesture(const nux::GestureEvent &event)
+{
+ if (event.IsDirectTouch())
+ {
+ /* If a direct device is being used (e.g., a touchscreen), all touch
+ points must hit the same window */
+ CompWindow *last_window = nullptr;
+ const std::vector<nux::TouchPoint> &touches = event.GetTouches();
+ for (auto touch : touches)
+ {
+ CompWindow *window = FindCompWindowAtPos(touch.x, touch.y);
+ if (last_window)
+ {
+ if (window != last_window)
+ {
+ return nullptr;
+ }
+ }
+ else
+ {
+ last_window = window;
+ }
+ }
+
+ return last_window;
+ }
+ else
+ {
+ /* If a indirect device is being used (e.g., a trackpad), the individual
+ touch points are not in screen coordinates and therefore it doesn't make
+ sense to hit-test them individually against the window tree. Instead,
+ we use just the focus point, which is the same as the cursor
+ position in this case (which is in screen coordinates). */
+ return FindCompWindowAtPos(event.GetFocus().x, event.GetFocus().y);
+ }
+}
+
+CompWindow* UnityGestureBroker::FindCompWindowAtPos(int pos_x, int pos_y)
+{
+ const CompWindowVector& client_list_stacking = screen->clientList(true);
+
+ for (auto iter = client_list_stacking.rbegin(),
+ end = client_list_stacking.rend();
+ iter != end; ++iter)
+ {
+ CompWindow* window = *iter;
+
+ if (window->minimized())
+ continue;
+
+ if (window->state() & CompWindowStateHiddenMask)
+ continue;
+
+ if (pos_x >= window->x() && pos_x <= (window->width() + window->x())
+ &&
+ pos_y >= window->y() && pos_y <= (window->height() + window->y()))
+ return window;
+ }
+
+ return nullptr;
+}
diff --git a/plugins/unityshell/src/UnityGestureBroker.h b/plugins/unityshell/src/UnityGestureBroker.h
new file mode 100644
index 000000000..d859f49a1
--- /dev/null
+++ b/plugins/unityshell/src/UnityGestureBroker.h
@@ -0,0 +1,45 @@
+/*
+ * UnityGestureBroker.h
+ * This file is part of Unity
+ *
+ * Copyright (C) 2011 - Canonical Ltd.
+ *
+ * Unity is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Unity is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Unity; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include <core/core.h>
+
+#include <Nux/GestureBroker.h>
+
+class UnityGestureBroker : public nux::GestureBroker
+{
+public:
+ UnityGestureBroker();
+ virtual ~UnityGestureBroker();
+
+private:
+ std::vector<nux::ShPtGestureTarget>
+ virtual FindGestureTargets(const nux::GestureEvent &event);
+
+ CompWindow *FindWindowHitByGesture(const nux::GestureEvent &event);
+
+ /*!
+ Returns the top-most CompWindow at the given position, if any.
+ */
+ CompWindow* FindCompWindowAtPos(int pos_x, int pos_y);
+
+ nux::ShPtGestureTarget unity_target;
+};
diff --git a/plugins/unityshell/src/UnityGestureTarget.cpp b/plugins/unityshell/src/UnityGestureTarget.cpp
new file mode 100644
index 000000000..3afe2ce26
--- /dev/null
+++ b/plugins/unityshell/src/UnityGestureTarget.cpp
@@ -0,0 +1,54 @@
+/*
+ * UnityGestureTarget.cpp
+ * This file is part of Unity
+ *
+ * Copyright (C) 2012 - Canonical Ltd.
+ *
+ * Unity is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Unity is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Unity; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include "UnityGestureTarget.h"
+
+#include <Nux/Nux.h> // otherwise unityshell.h inclusion will cause failures
+#include "unityshell.h"
+
+#include "UBusMessages.h"
+#include "ubus-server.h"
+
+using namespace nux;
+
+UnityGestureTarget::UnityGestureTarget()
+{
+ launcher = unity::UnityScreen::get(screen)->LauncherView();
+}
+
+GestureDeliveryRequest UnityGestureTarget::GestureEvent(const nux::GestureEvent &event)
+{
+ if (event.GetGestureClasses() & DRAG_GESTURE)
+ {
+ if (launcher.IsValid())
+ launcher->GestureEvent(event);
+ }
+ else if (event.GetGestureClasses() == TAP_GESTURE
+ && event.type == EVENT_GESTURE_END)
+ {
+ ubus_server_send_message(ubus_server_get_default(),
+ UBUS_DASH_EXTERNAL_ACTIVATION,
+ NULL);
+ }
+
+ return GestureDeliveryRequest::NONE;
+}
diff --git a/plugins/unityshell/src/UnityGestureTarget.h b/plugins/unityshell/src/UnityGestureTarget.h
new file mode 100644
index 000000000..f47996e63
--- /dev/null
+++ b/plugins/unityshell/src/UnityGestureTarget.h
@@ -0,0 +1,44 @@
+/*
+ * UnityGestureTarget.h
+ * This file is part of Unity
+ *
+ * Copyright (C) 2012 - Canonical Ltd.
+ *
+ * Unity is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Unity is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Unity; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef UNITY_GESTURE_TARGET_H
+#define UNITY_GESTURE_TARGET_H
+
+#include <Nux/Gesture.h>
+
+/*
+ Target for Unity-level gestures.
+ I.e., for gestures that act on Unity elements, such as
+ the dash or launcher.
+ */
+class UnityGestureTarget : public nux::GestureTarget
+{
+ public:
+ UnityGestureTarget();
+
+ virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event);
+
+ private:
+ nux::ObjectWeakPtr<nux::InputArea> launcher;
+};
+
+#endif // UNITY_GESTURE_TARGET_H
diff --git a/plugins/unityshell/src/WindowGestureTarget.cpp b/plugins/unityshell/src/WindowGestureTarget.cpp
new file mode 100644
index 000000000..37e947deb
--- /dev/null
+++ b/plugins/unityshell/src/WindowGestureTarget.cpp
@@ -0,0 +1,215 @@
+/*
+ * WindowGestureTarget.cpp
+ * This file is part of Unity
+ *
+ * Copyright (C) 2012 - Canonical Ltd.
+ *
+ * Unity is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Unity is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Unity; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#include "WindowGestureTarget.h"
+
+#include <Nux/Nux.h> // otherwise unityshell.h inclusion will cause failures
+#include "unityshell.h"
+
+#include "PluginAdapter.h"
+
+using namespace nux;
+
+Cursor WindowGestureTarget::fleur_cursor = 0;
+
+WindowGestureTarget::WindowGestureTarget(CompWindow *window)
+ : window_(window), drag_grab_(0), started_window_move_(false),
+ window_restored_by_pinch_(false)
+{
+ // A workaround for the lack of weak pointers.
+ unity::UnityWindow *unity_window = unity::UnityWindow::get(window);
+
+ connection_window_destruction =
+ unity_window->being_destroyed.connect(
+ sigc::mem_fun(this, &WindowGestureTarget::NullifyWindowPointer));
+}
+
+WindowGestureTarget::~WindowGestureTarget()
+{
+ connection_window_destruction.disconnect();
+ if (drag_grab_)
+ {
+ if (window_)
+ window_->ungrabNotify();
+ screen->removeGrab(drag_grab_, NULL);
+ }
+}
+
+void WindowGestureTarget::NullifyWindowPointer()
+{
+ window_ = nullptr;
+}
+
+GestureDeliveryRequest WindowGestureTarget::GestureEvent(const nux::GestureEvent &event)
+{
+ if (!window_)
+ return GestureDeliveryRequest::NONE;
+
+ switch (event.type)
+ {
+ case nux::EVENT_GESTURE_BEGIN:
+ PluginAdapter::Default()->ShowGrabHandles(window_, false);
+ break;
+ case EVENT_GESTURE_UPDATE:
+ if (event.GetGestureClasses() & PINCH_GESTURE)
+ MaximizeOrRestoreWindowDueToPinch(event);
+ if (event.GetGestureClasses() & DRAG_GESTURE)
+ {
+ if (WindowCanMove())
+ {
+ if (!started_window_move_)
+ {
+ StartWindowMove(event);
+ started_window_move_ = true;
+ }
+ MoveWindow(event);
+ }
+ }
+ break;
+ default: // EVENT_GESTURE_END
+ if (event.GetGestureClasses() & DRAG_GESTURE)
+ {
+ EndWindowMove(event);
+ started_window_move_ = false;
+ }
+ PluginAdapter::Default()->ShowGrabHandles(window_, true);
+ break;
+ };
+
+ return GestureDeliveryRequest::NONE;
+}
+
+bool WindowGestureTarget::WindowCanMove()
+{
+ if (!(window_->actions() & CompWindowActionMoveMask))
+ return false;
+
+ /* Don't allow windows to be dragged if completely maximized */
+ if ((window_->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE)
+ return false;
+
+ /* Don't start moving a window that has just been restored. The user is likely
+ still performing the pinch and not expecting the window to start moving */
+ if (window_restored_by_pinch_)
+ return false;
+
+ return true;
+}
+
+void WindowGestureTarget::MaximizeOrRestoreWindowDueToPinch(const nux::GestureEvent &event)
+{
+ if (event.GetRadius() > 1.25f)
+ {
+ window_->maximize(MAXIMIZE_STATE);
+ RemoveDragGrab();
+ window_restored_by_pinch_ = false;
+ }
+ else if (event.GetRadius() < 0.8f)
+ {
+ if (window_->state() & MAXIMIZE_STATE)
+ {
+ window_->maximize(0);
+ RemoveDragGrab();
+ window_restored_by_pinch_ = true;
+ }
+ }
+}
+
+void WindowGestureTarget::StartWindowMove(const nux::GestureEvent &event)
+{
+ if (!event.IsDirectTouch())
+ {
+ drag_grab_ = screen->pushGrab(fleur_cursor, "unity");
+ window_->grabNotify(window_->serverGeometry().x(),
+ window_->serverGeometry().y(),
+ 0,
+ CompWindowGrabMoveMask | CompWindowGrabButtonMask);
+ }
+}
+
+void WindowGestureTarget::MoveWindow(const nux::GestureEvent &event)
+{
+ const nux::Point2D<float> &delta = event.GetDelta();
+
+ unsigned int px = std::max(std::min(pointerX + static_cast<int>(delta.x),
+ screen->width()),
+ 0);
+
+ unsigned int py = std::max(std::min(pointerY + static_cast<int>(delta.y),
+ screen->height()),
+ 0);
+
+ if (window_->state() & CompWindowStateMaximizedVertMask)
+ py = pointerY;
+ if (window_->state() & CompWindowStateMaximizedHorzMask)
+ px = pointerX;
+
+ if (!event.IsDirectTouch())
+ {
+ /* FIXME: CompScreen::warpPointer filters out motion events which
+ other plugins may need to process, but for most cases in core
+ they should be filtered out. */
+ XWarpPointer(screen->dpy (),
+ None, screen->root (),
+ 0, 0, 0, 0,
+ px, py);
+ }
+
+ XSync(screen->dpy (), false);
+ window_->move(px - pointerX, py - pointerY, false);
+
+ pointerX = px;
+ pointerY = py;
+}
+
+void WindowGestureTarget::EndWindowMove(const nux::GestureEvent &event)
+{
+ window_->ungrabNotify();
+ RemoveDragGrab();
+ window_->syncPosition();
+}
+
+void WindowGestureTarget::RemoveDragGrab()
+{
+ if (drag_grab_)
+ {
+ screen->removeGrab(drag_grab_, NULL);
+ drag_grab_ = 0;
+ }
+}
+
+bool WindowGestureTarget::Equals(const nux::GestureTarget& other) const
+{
+ const WindowGestureTarget *window_target = dynamic_cast<const WindowGestureTarget *>(&other);
+
+ if (window_target)
+ {
+ if (window_ && window_target->window_)
+ return window_->id() == window_target->window_->id();
+ else
+ return window_ == window_target->window_;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/plugins/unityshell/src/WindowGestureTarget.h b/plugins/unityshell/src/WindowGestureTarget.h
new file mode 100644
index 000000000..e805e3948
--- /dev/null
+++ b/plugins/unityshell/src/WindowGestureTarget.h
@@ -0,0 +1,57 @@
+/*
+ * WindowGestureTarget.h
+ * This file is part of Unity
+ *
+ * Copyright (C) 2012 - Canonical Ltd.
+ *
+ * Unity is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Unity is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Unity; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef WINDOW_GESTURE_TARGET_H
+#define WINDOW_GESTURE_TARGET_H
+
+#include <Nux/Gesture.h>
+
+#include <core/core.h> // compiz stuff
+
+class WindowGestureTarget : public nux::GestureTarget
+{
+ public:
+ WindowGestureTarget(CompWindow *window);
+ virtual ~WindowGestureTarget();
+
+ virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event);
+
+ static Cursor fleur_cursor;
+
+ CompWindow *window() {return window_;}
+ private:
+ virtual bool Equals(const nux::GestureTarget& other) const;
+ void StartWindowMove(const nux::GestureEvent &event);
+ void MoveWindow(const nux::GestureEvent &event);
+ void EndWindowMove(const nux::GestureEvent &event);
+ void MaximizeOrRestoreWindowDueToPinch(const nux::GestureEvent &event);
+ bool WindowCanMove();
+ void NullifyWindowPointer();
+ void RemoveDragGrab();
+ CompWindow *window_;
+ CompScreen::GrabHandle drag_grab_;
+ bool started_window_move_;
+ bool window_restored_by_pinch_;
+ sigc::connection connection_window_destruction;
+};
+
+#endif // WINDOW_GESTURE_TARGET_H
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 5bdeed855..85b2d2f9a 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -29,7 +29,6 @@
#include "Launcher.h"
#include "LauncherIcon.h"
#include "LauncherController.h"
-#include "GeisAdapter.h"
#include "DevicesSettings.h"
#include "PluginAdapter.h"
#include "QuicklistManager.h"
@@ -38,6 +37,7 @@
#include "KeyboardUtil.h"
#include "unityshell.h"
#include "BackgroundEffectHelper.h"
+#include "UnityGestureBroker.h"
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
@@ -111,7 +111,6 @@ UnityScreen::UnityScreen(CompScreen* screen)
, gScreen(GLScreen::get(screen))
, debugger_(this)
, enable_shortcut_overlay_(true)
- , gesture_engine_(screen)
, needsRelayout(false)
, _in_paint(false)
, super_keypressed_(false)
@@ -363,7 +362,7 @@ UnityScreen::UnityScreen(CompScreen* screen)
auto init_plugins_cb = sigc::mem_fun(this, &UnityScreen::initPluginActions);
sources_.Add(std::make_shared<glib::Idle>(init_plugins_cb, glib::Source::Priority::DEFAULT));
- geis_adapter_.Run();
+ InitGesturesSupport();
CompString name(PKGDATADIR"/panel-shadow.png");
CompString pname("unityshell");
@@ -2596,6 +2595,9 @@ void UnityWindow::windowNotify(CompWindowNotify n)
window->minimizedSetEnabled (this, false);
}
break;
+ case CompWindowNotifyBeforeDestroy:
+ being_destroyed.emit();
+ break;
default:
break;
}
@@ -3042,6 +3044,18 @@ void UnityScreen::initLauncher()
ScheduleRelayout(0);
}
+nux::View *UnityScreen::LauncherView()
+{
+ nux::View *result = nullptr;
+
+ if (launcher_controller_)
+ {
+ result = &launcher_controller_->launcher();
+ }
+
+ return result;
+}
+
void UnityScreen::InitHints()
{
// TODO move category text into a vector...
@@ -3103,6 +3117,32 @@ void UnityScreen::InitHints()
hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" Drag"), _("Resize window."), shortcut::COMPIZ_MOUSE_OPTION, "resize", "initiate_button"));
}
+void UnityScreen::InitGesturesSupport()
+{
+ std::unique_ptr<nux::GestureBroker> gesture_broker(new UnityGestureBroker);
+ wt->GetWindowCompositor().SetGestureBroker(std::move(gesture_broker));
+
+ gestures_sub_launcher_.reset(new nux::GesturesSubscription);
+ gestures_sub_launcher_->SetGestureClasses(nux::DRAG_GESTURE);
+ gestures_sub_launcher_->SetNumTouches(4);
+ gestures_sub_launcher_->SetWindowId(GDK_ROOT_WINDOW());
+ gestures_sub_launcher_->Activate();
+
+ gestures_sub_dash_.reset(new nux::GesturesSubscription);
+ gestures_sub_dash_->SetGestureClasses(nux::TAP_GESTURE);
+ gestures_sub_dash_->SetNumTouches(4);
+ gestures_sub_dash_->SetWindowId(GDK_ROOT_WINDOW());
+ gestures_sub_dash_->Activate();
+
+ gestures_sub_windows_.reset(new nux::GesturesSubscription);
+ gestures_sub_windows_->SetGestureClasses(nux::TOUCH_GESTURE
+ | nux::DRAG_GESTURE
+ | nux::PINCH_GESTURE);
+ gestures_sub_windows_->SetNumTouches(3);
+ gestures_sub_windows_->SetWindowId(GDK_ROOT_WINDOW());
+ gestures_sub_windows_->Activate();
+}
+
/* Window init */
UnityWindow::UnityWindow(CompWindow* window)
: BaseSwitchWindow (dynamic_cast<BaseSwitchScreen *> (UnityScreen::get (screen)), window)
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index 34e29975e..765ad980b 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -22,6 +22,7 @@
#ifndef UNITYSHELL_H
#define UNITYSHELL_H
+#include <Nux/GesturesSubscription.h>
#include <Nux/WindowThread.h>
#include <NuxCore/Property.h>
#include <sigc++/sigc++.h>
@@ -46,7 +47,6 @@
#include "PanelController.h"
#include "PanelStyle.h"
#include "UScreen.h"
-#include "GestureEngine.h"
#include "DebugDBusInterface.h"
#include "SwitcherController.h"
#include "UBusWrapper.h"
@@ -190,6 +190,8 @@ public:
bool forcePaintOnTop ();
+ nux::View *LauncherView();
+
protected:
std::string GetName() const;
void AddProperties(GVariantBuilder* builder);
@@ -239,11 +241,12 @@ private:
void OnPanelStyleChanged();
+ void InitGesturesSupport();
+
Settings dash_settings_;
dash::Style dash_style_;
panel::Style panel_style_;
FontSettings font_settings_;
- GeisAdapter geis_adapter_;
internal::FavoriteStoreGSettings favorite_store_;
/* The window thread should be the last thing removed, as c++ does it in reverse order */
@@ -261,7 +264,15 @@ private:
std::list<shortcut::AbstractHint::Ptr> hints_;
bool enable_shortcut_overlay_;
- GestureEngine gesture_engine_;
+ /* Subscription for gestures that manipulate Unity launcher */
+ std::unique_ptr<nux::GesturesSubscription> gestures_sub_launcher_;
+
+ /* Subscription for gestures that manipulate Unity dash */
+ std::unique_ptr<nux::GesturesSubscription> gestures_sub_dash_;
+
+ /* Subscription for gestures that manipulate windows. */
+ std::unique_ptr<nux::GesturesSubscription> gestures_sub_windows_;
+
bool needsRelayout;
bool _in_paint;
bool super_keypressed_;
@@ -398,6 +409,8 @@ public:
ShowdesktopHandler *mShowdesktopHandler;
+ //! Emited when CompWindowNotifyBeforeDestroy is received
+ sigc::signal<void> being_destroyed;
private:
void DoEnableFocus ();
void DoDisableFocus ();
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 01fe6993d..184e6cf97 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -253,7 +253,6 @@ if (GTEST_SRC_DIR AND
${CMAKE_SOURCE_DIR}/launcher/FavoriteStore.cpp
${CMAKE_SOURCE_DIR}/launcher/FavoriteStoreGSettings.cpp
${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp
- ${CMAKE_SOURCE_DIR}/launcher/GeisAdapter.cpp
${CMAKE_SOURCE_DIR}/launcher/HudLauncherIcon.cpp
${CMAKE_SOURCE_DIR}/launcher/Launcher.cpp
${CMAKE_SOURCE_DIR}/launcher/LauncherController.cpp
@@ -321,7 +320,7 @@ endif (GTEST_SRC_DIR AND
GMOCK_LIB AND
GMOCK_MAIN_LIB)
-add_subdirectory (test-gesture-engine)
+add_subdirectory (test-gestures)
#
# check target
@@ -332,25 +331,25 @@ set (TEST_RESULT_HTML ${TEST_RESULT_DIR}/test-results.html)
set (GTEST_TEST_COMMAND ./test-gtest)
set (GTEST_TEST_COMMAND_XLESS ./test-gtest-xless)
set (GTEST_TEST_COMMAND_DBUS dbus-test-runner --task ./test-gtest-service --task ./test-gtest-dbus)
-set (GTEST_TEST_COMMAND_GESTURE_ENGINE ./test-gesture-engine/test-gesture-engine)
+set (GTEST_TEST_COMMAND_GESTURES ./test-gestures/test-gestures)
set (TEST_COMMAND
gtester --verbose -k --g-fatal-warnings -o=${TEST_RESULT_XML} ./test-unit
&& ${GTEST_TEST_COMMAND} --gtest_output=xml:./
&& ${GTEST_TEST_COMMAND_XLESS} --gtest_output=xml:./
- && ${GTEST_TEST_COMMAND_GESTURE_ENGINE} --gtest_output=xml:./
+ && ${GTEST_TEST_COMMAND_GESTURES} --gtest_output=xml:./
&& ${GTEST_TEST_COMMAND_DBUS} --gtest_output=xml:./
)
set (TEST_COMMAND_HEADLESS
${GTEST_TEST_COMMAND_XLESS} --gtest_output=xml:./
- && ${GTEST_TEST_COMMAND_GESTURE_ENGINE} --gtest_output=xml:./
+ && ${GTEST_TEST_COMMAND_GESTURES} --gtest_output=xml:./
#&& ${GTEST_TEST_COMMAND_DBUS} --gtest_output=xml:./
&& echo "Warning, DBus test cases are disabled!!")
if (GTEST_SRC_DIR)
- add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-xless test-gtest-dbus test-gesture-engine)
- add_custom_target (check-headless COMMAND ${TEST_COMMAND_HEADLESS} DEPENDS test-gtest-xless test-gtest-dbus test-gesture-engine)
+ add_custom_target (check COMMAND ${TEST_COMMAND} DEPENDS test-unit test-gtest test-gtest-xless test-gtest-dbus test-gestures)
+ add_custom_target (check-headless COMMAND ${TEST_COMMAND_HEADLESS} DEPENDS test-gtest-xless test-gtest-dbus test-gestures)
add_custom_target (check-report COMMAND ${TEST_UNIT_COMMAND} && gtester-report ${TEST_RESULT_XML} > ${TEST_RESULT_HTML})
add_custom_target (gcheck COMMAND ${DBUS_TEST_COMMAND} DEPENDS test-gtest test-gtest-xless)
else (GTEST_SRC_DIR)
diff --git a/tests/test-gesture-engine/CMakeLists.txt b/tests/test-gesture-engine/CMakeLists.txt
deleted file mode 100644
index 49596e152..000000000
--- a/tests/test-gesture-engine/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-if (GTEST_SRC_DIR)
- set(UNITY_SRC ${CMAKE_SOURCE_DIR}/plugins/unityshell/src)
-
- add_custom_command(OUTPUT GestureEngine.cpp GestureEngine.h UBusMessages.h
- COMMAND cp ${UNITY_SRC}/GestureEngine.cpp ${UNITY_SRC}/GestureEngine.h ${CMAKE_SOURCE_DIR}/unity-shared//UBusMessages.h ${CMAKE_CURRENT_BINARY_DIR}
- COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script ${UNITY_SRC}/GestureEngine.cpp > ${CMAKE_CURRENT_BINARY_DIR}/GestureEngine.cpp
- COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script ${UNITY_SRC}/GestureEngine.h > ${CMAKE_CURRENT_BINARY_DIR}/GestureEngine.h
- DEPENDS ${UNITY_SRC}/GestureEngine.cpp ${UNITY_SRC}/GestureEngine.h ${CMAKE_SOURCE_DIR}/unity-shared/UBusMessages.h
- COMMENT "Copying GestureEngine source.")
-
- # Clean-up includes and definitions made in ../CmakeLists.txt
- remove_definitions(${CFLAGS})
- set_directory_properties(PROPERTY INCLUDE_DIRECTORIES "")
- # And make our own
- pkg_check_modules (TEST_GESTURE_ENGINE_DEPS REQUIRED QUIET "${UNITY_PLUGIN_DEPS}")
- set(TEST_GESTURE_ENGINE_CFLAGS
- "-g"
- "-I${CMAKE_CURRENT_SOURCE_DIR}"
- "-I${CMAKE_CURRENT_BINARY_DIR}"
- ${TEST_GESTURE_ENGINE_DEPS_CFLAGS}
- )
- add_definitions(${TEST_GESTURE_ENGINE_CFLAGS})
-
- pkg_check_modules (COMPIZ REQUIRED QUIET compiz)
- link_directories (${COMPIZ_LIBDIR})
-
- add_executable(test-gesture-engine
- test_gesture_engine.cpp
- X11_mock.cpp
- GestureEngine.cpp
- PluginAdapterMock.cpp
- GeisAdapterMock.cpp
- ubus-server-mock.cpp
- )
- target_link_libraries(test-gesture-engine gtest ${TEST_GESTURE_ENGINE_DEPS_LIBRARIES} -lcompiz_core)
- add_test(UnityGTestGestureEngine test-gesture-engine)
- add_dependencies(test-gesture-engine gtest unity-core-${UNITY_API_VERSION})
-
- add_custom_target (check-gesture-engine COMMAND ./test-gesture-engine DEPENDS test-gesture-engine)
-endif (GTEST_SRC_DIR)
diff --git a/tests/test-gesture-engine/GeisAdapterMock.cpp b/tests/test-gesture-engine/GeisAdapterMock.cpp
deleted file mode 100644
index 2d4355a21..000000000
--- a/tests/test-gesture-engine/GeisAdapterMock.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3, as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranties of
- * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 3 along with this program. If not, see
- * <http://www.gnu.org/licenses/>
- *
- * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
- *
- */
-
-#include "GeisAdapterMock.h"
-
-GeisAdapterMock *GeisAdapterMock::_default = nullptr;
-
-GeisAdapterMock& GeisAdapterMock::Instance() {
- if (!_default)
- {
- _default = new GeisAdapterMock;
- }
- return *_default;
-}
diff --git a/tests/test-gesture-engine/GeisAdapterMock.h b/tests/test-gesture-engine/GeisAdapterMock.h
deleted file mode 100644
index c4237a0a8..000000000
--- a/tests/test-gesture-engine/GeisAdapterMock.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3, as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranties of
- * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 3 along with this program. If not, see
- * <http://www.gnu.org/licenses/>
- *
- * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
- *
- */
-
-#ifndef GEISADAPTER_MOCK_H
-#define GEISADAPTER_MOCK_H
-
-#include <sigc++/sigc++.h>
-#include <X11/Xlib.h>
-
-class GeisAdapterMock : public sigc::trackable
-{
-public:
- static GeisAdapterMock& Instance();
-
- ~GeisAdapterMock() {}
-
- typedef struct _GeisTapData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- int tap_length_ms;
- float position_x;
- float position_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisTapData;
-
- typedef struct _GeisDragData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float delta_x;
- float delta_y;
- float velocity_x;
- float velocity_y;
- float position_x;
- float position_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisDragData;
-
- typedef struct _GeisRotateData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float angle;
- float angle_delta;
- float angle_velocity;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisRotateData;
-
- typedef struct _GeisPinchData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float radius;
- float radius_delta;
- float radius_velocity;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisPinchData;
-
- typedef struct _GeisTouchData
- {
- int id;
- int device_id;
- Window window;
- int touches;
- int timestamp;
- float focus_x;
- float focus_y;
- float bound_x1;
- float bound_y1;
- float bound_x2;
- float bound_y2;
- } GeisTouchData;
-
- sigc::signal<void, GeisTapData*> tap;
-
- sigc::signal<void, GeisDragData*> drag_start;
- sigc::signal<void, GeisDragData*> drag_update;
- sigc::signal<void, GeisDragData*> drag_finish;
-
- sigc::signal<void, GeisRotateData*> rotate_start;
- sigc::signal<void, GeisRotateData*> rotate_update;
- sigc::signal<void, GeisRotateData*> rotate_finish;
-
- sigc::signal<void, GeisPinchData*> pinch_start;
- sigc::signal<void, GeisPinchData*> pinch_update;
- sigc::signal<void, GeisPinchData*> pinch_finish;
-
- sigc::signal<void, GeisTouchData*> touch_start;
- sigc::signal<void, GeisTouchData*> touch_update;
- sigc::signal<void, GeisTouchData*> touch_finish;
-
-private:
- GeisAdapterMock() {}
-
- static GeisAdapterMock* _default;
-
-};
-#endif
diff --git a/tests/test-gesture-engine/test_gesture_engine.cpp b/tests/test-gesture-engine/test_gesture_engine.cpp
deleted file mode 100644
index 1c009bd55..000000000
--- a/tests/test-gesture-engine/test_gesture_engine.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 3, as published
- * by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranties of
- * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 3 along with this program. If not, see
- * <http://www.gnu.org/licenses/>
- *
- * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
- *
- */
-
-#include <gtest/gtest.h>
-#include <compiz_mock/core/core.h>
-#include "GestureEngine.h"
-
-CompScreenMock concrete_screen_mock;
-CompScreenMock *screen_mock = &concrete_screen_mock;
-int pointerX_mock = 0;
-int pointerY_mock = 0;
-
-class GestureEngineTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- screen_mock->_width = 1280;
- screen_mock->_height = 1024;
-
- GenerateWindows();
- }
-
- void PerformPinch(GestureEngine &gesture_engine, float peak_radius) {
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- GeisAdapterMock::GeisTouchData touch_data;
- touch_data.id = 1;
- touch_data.touches = 3;
- touch_data.window = 123;
- touch_data.focus_x = 100; /* hits the middle window */
- touch_data.focus_y = 100;
- gesture_engine.OnTouchStart(&touch_data);
-
- GeisAdapterMock::GeisPinchData pinch_data;
- pinch_data.id = 1;
- pinch_data.touches = 3;
- pinch_data.window = 123;
- pinch_data.focus_x = 100; /* hits the middle window */
- pinch_data.focus_y = 100;
- pinch_data.radius = 1.0;
- gesture_engine.OnPinchStart(&pinch_data);
-
- touch_data.focus_x += 10;
- touch_data.focus_y += 20;
- gesture_engine.OnTouchUpdate(&touch_data);
-
- pinch_data.focus_x += 10;
- pinch_data.focus_y += 20;
- pinch_data.radius = peak_radius;
- gesture_engine.OnPinchUpdate(&pinch_data);
-
- gesture_engine.OnTouchFinish(&touch_data);
- gesture_engine.OnPinchFinish(&pinch_data);
- }
-
- private:
- void GenerateWindows() {
- /* remove windows from previous test */
- for (auto window : screen_mock->_client_list_stacking) {
- delete window;
- }
- screen_mock->_client_list_stacking.clear();
-
- /* and generate new ones */
- CompWindowMock *window;
-
- /* the root window */
- window = new CompWindowMock;
- /* x, y, width, height, border */
- window->_geometry.set(0, 0, screen_mock->width(), screen_mock->height(), 0);
- window->_serverGeometry = window->_geometry;
- window->_actions = 0;
- window->_state = 0;
- screen_mock->_client_list_stacking.push_back(window);
-
- /* middle window */
- window = new CompWindowMock;
- window->_geometry.set(10, 10, 400, 400, 0);
- window->_serverGeometry = window->_geometry;
- window->_actions = CompWindowActionMoveMask;
- window->_state = 0;
- screen_mock->_client_list_stacking.push_back(window);
-
- /* top-level window */
- window = new CompWindowMock;
- window->_geometry.set(500, 500, 410, 410, 0);
- window->_serverGeometry = window->_geometry;
- window->_actions = CompWindowActionMoveMask;
- window->_state = 0;
- screen_mock->_client_list_stacking.push_back(window);
-
- screen_mock->_client_list = screen_mock->_client_list_stacking;
- std::reverse(screen_mock->_client_list.begin(),
- screen_mock->_client_list.end());
- }
-};
-
-TEST_F(GestureEngineTest, ThreeFingersDragMovesWindow)
-{
- GestureEngine gestureEngine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- GeisAdapterMock::GeisTouchData touch_data;
- touch_data.id = 1;
- touch_data.touches = 3;
- touch_data.window = 123;
- touch_data.focus_x = 100; /* hits the middle window */
- touch_data.focus_y = 100;
- gestureEngine.OnTouchStart(&touch_data);
-
- GeisAdapterMock::GeisDragData drag_data;
- drag_data.id = 1;
- drag_data.touches = 3;
- drag_data.window = 123;
- drag_data.focus_x = 100; /* hits the middle window */
- drag_data.focus_y = 100;
- gestureEngine.OnDragStart(&drag_data);
-
- ASSERT_FALSE(middle_window->_moved);
-
- touch_data.focus_x += 10;
- touch_data.focus_y += 20;
- gestureEngine.OnTouchUpdate(&touch_data);
-
- drag_data.delta_x = 10;
- drag_data.delta_y = 20;
- drag_data.focus_x += drag_data.delta_x;
- drag_data.focus_y += drag_data.delta_x;
- gestureEngine.OnDragUpdate(&drag_data);
-
- ASSERT_TRUE(middle_window->_moved);
- ASSERT_EQ(drag_data.delta_x, middle_window->_movement_x);
- ASSERT_EQ(drag_data.delta_y, middle_window->_movement_y);
-}
-
-TEST_F(GestureEngineTest, ThreeFingersDragDoesntMoveStaticWindow)
-{
- GestureEngine gestureEngine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- /* can't be moved */
- middle_window->_actions = 0;
-
- GeisAdapterMock::GeisTouchData touch_data;
- touch_data.id = 1;
- touch_data.touches = 3;
- touch_data.window = 123;
- touch_data.focus_x = 100; /* hits the middle window */
- touch_data.focus_y = 100;
- gestureEngine.OnTouchStart(&touch_data);
-
- GeisAdapterMock::GeisDragData drag_data;
- drag_data.id = 1;
- drag_data.touches = 3;
- drag_data.window = 123;
- drag_data.focus_x = 100; /* hits the middle window */
- drag_data.focus_y = 100;
- gestureEngine.OnDragStart(&drag_data);
-
- ASSERT_FALSE(middle_window->_moved);
-
- touch_data.focus_x += 10;
- touch_data.focus_y += 20;
- gestureEngine.OnTouchUpdate(&touch_data);
-
- drag_data.delta_x = 10;
- drag_data.delta_y = 20;
- drag_data.focus_x += drag_data.delta_x;
- drag_data.focus_y += drag_data.delta_x;
- gestureEngine.OnDragUpdate(&drag_data);
-
- ASSERT_FALSE(middle_window->_moved);
-}
-
-TEST_F(GestureEngineTest, ThreeFingersPinchMaximizesWindow)
-{
- GestureEngine gesture_engine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- PerformPinch(gesture_engine, 2.0);
-
- ASSERT_EQ(1, middle_window->_maximize_count);
- ASSERT_EQ(MAXIMIZE_STATE, middle_window->_maximize_state);
-}
-
-TEST_F(GestureEngineTest, ThreeFingersPinchRestoresWindow)
-{
- GestureEngine gesture_engine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- PerformPinch(gesture_engine, 0.3);
-
- ASSERT_EQ(1, middle_window->_maximize_count);
- ASSERT_EQ(0, middle_window->_maximize_state);
-}
-
-TEST_F(GestureEngineTest, MinimalThreeFingersPinchDoesNothing)
-{
- GestureEngine gesture_engine(screen_mock);
- CompWindowMock *middle_window = screen_mock->_client_list_stacking[1];
-
- PerformPinch(gesture_engine, 1.1);
-
- ASSERT_EQ(0, middle_window->_maximize_count);
-}
-
-/* Regression test for lp:979418, where the grab is not removed if the gesture
- * id is 0. */
-TEST_F(GestureEngineTest, DragGrabCheck)
-{
- screen_mock->_grab_count = 0;
-
- GestureEngine gesture_engine(screen_mock);
-
- GeisAdapterMock::GeisDragData drag_data;
- drag_data.id = 0;
- drag_data.touches = 3;
- drag_data.window = 123;
- drag_data.focus_x = 100; /* hits the middle window */
- drag_data.focus_y = 100;
- gesture_engine.OnDragStart(&drag_data);
-
- gesture_engine.OnDragFinish(&drag_data);
-
- ASSERT_EQ(0, screen_mock->_grab_count);
-}
-
-int main(int argc, char** argv)
-{
- ::testing::InitGoogleTest(&argc, argv);
-
- int ret = RUN_ALL_TESTS();
-
- return ret;
-}
diff --git a/tests/test-gestures/CMakeLists.txt b/tests/test-gestures/CMakeLists.txt
new file mode 100644
index 000000000..8d85541f7
--- /dev/null
+++ b/tests/test-gestures/CMakeLists.txt
@@ -0,0 +1,71 @@
+if (GTEST_SRC_DIR)
+ set(UNITY_SRC ${CMAKE_SOURCE_DIR}/plugins/unityshell/src)
+
+ add_custom_command(OUTPUT UnityGestureBroker.cpp
+ UnityGestureBroker.h
+ UBusMessages.h
+ WindowGestureTarget.h
+ WindowGestureTarget.cpp
+
+ COMMAND cp ${UNITY_SRC}/UnityGestureBroker.cpp
+ ${UNITY_SRC}/UnityGestureBroker.h
+ ${CMAKE_SOURCE_DIR}/unity-shared//UBusMessages.h
+ ${UNITY_SRC}/WindowGestureTarget.h
+ ${UNITY_SRC}/WindowGestureTarget.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}
+
+ COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_broker
+ ${UNITY_SRC}/UnityGestureBroker.cpp > ${CMAKE_CURRENT_BINARY_DIR}/UnityGestureBroker.cpp
+
+ COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_broker
+ ${UNITY_SRC}/UnityGestureBroker.h > ${CMAKE_CURRENT_BINARY_DIR}/UnityGestureBroker.h
+
+ COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_gesture
+ ${UNITY_SRC}/WindowGestureTarget.h > ${CMAKE_CURRENT_BINARY_DIR}/WindowGestureTarget.h
+
+ COMMAND sed -f ${CMAKE_CURRENT_SOURCE_DIR}/sed_script_gesture
+ ${UNITY_SRC}/WindowGestureTarget.cpp > ${CMAKE_CURRENT_BINARY_DIR}/WindowGestureTarget.cpp
+
+ DEPENDS ${UNITY_SRC}/UnityGestureBroker.cpp
+ ${UNITY_SRC}/UnityGestureBroker.h
+ ${CMAKE_SOURCE_DIR}/unity-shared/UBusMessages.h
+ ${UNITY_SRC}/WindowGestureTarget.h
+ ${UNITY_SRC}/WindowGestureTarget.cpp
+ sed_script_broker
+ sed_script_gesture
+
+ COMMENT "Copying and modifying sources under test.")
+
+ # Clean-up includes and definitions made in ../CmakeLists.txt
+ remove_definitions(${CFLAGS})
+ set_directory_properties(PROPERTY INCLUDE_DIRECTORIES "")
+ # And make our own
+ pkg_check_modules (TEST_GESTURES_DEPS REQUIRED QUIET "${UNITY_PLUGIN_DEPS}")
+ set(TEST_GESTURES_CFLAGS
+ "-g"
+ "-I${CMAKE_CURRENT_SOURCE_DIR}"
+ "-I${CMAKE_CURRENT_BINARY_DIR}"
+ ${TEST_GESTURES_DEPS_CFLAGS}
+ )
+ add_definitions(${TEST_GESTURES_CFLAGS})
+
+ pkg_check_modules (COMPIZ REQUIRED QUIET compiz)
+ link_directories (${COMPIZ_LIBDIR})
+
+ add_executable(test-gestures
+ test_gestures_main.cpp
+ test_gesture_broker.cpp
+ test_window_gesture_target.cpp
+ X11_mock.cpp
+ UnityGestureBroker.cpp
+ WindowGestureTarget.cpp
+ PluginAdapterMock.cpp
+ ubus-server-mock.cpp
+ UnityGestureTargetMock.h
+ )
+ target_link_libraries(test-gestures gtest ${TEST_GESTURES_DEPS_LIBRARIES} -lcompiz_core)
+ add_test(UnityGTestGestures test-gestures)
+ add_dependencies(test-gestures gtest unity-core-${UNITY_API_VERSION})
+
+ add_custom_target (check-gestures COMMAND ./test-gestures DEPENDS test-gestures)
+endif (GTEST_SRC_DIR)
diff --git a/tests/test-gestures/FakeGestureEvent.h b/tests/test-gestures/FakeGestureEvent.h
new file mode 100644
index 000000000..9cc13aa76
--- /dev/null
+++ b/tests/test-gestures/FakeGestureEvent.h
@@ -0,0 +1,63 @@
+#ifndef FAKE_GESTURE_EVENT_H
+#define FAKE_GESTURE_EVENT_H
+
+#include <NuxGraphics/GestureEvent.h>
+#include <map>
+
+namespace nux {
+class FakeGestureEvent
+{
+ public:
+ nux::EventType type;
+
+ int gesture_id;
+ int gesture_classes;
+ bool is_direct_touch;
+ int timestamp;
+ nux::Point2D<float> focus;
+ nux::Point2D<float> delta;
+ float angle;
+ float angle_delta;
+ float angular_velocity;
+ int tap_duration;
+ nux::Point2D<float> velocity;
+ float radius;
+ float radius_delta;
+ float radial_velocity;
+ std::vector<nux::TouchPoint> touches;
+ bool is_construction_finished;
+
+ nux::GestureEvent &ToGestureEvent()
+ {
+ event_.type = type;
+
+ event_.gesture_id_ = gesture_id;
+ event_.gesture_classes_ = gesture_classes;
+ event_.is_direct_touch_ = is_direct_touch;
+ event_.timestamp_ = timestamp;
+ event_.focus_ = focus;
+ event_.delta_ = delta;
+ event_.angle_ = angle;
+ event_.angle_delta_ = angle_delta;
+ event_.angular_velocity_ = angular_velocity;
+ event_.tap_duration_ = tap_duration;
+ event_.velocity_ = velocity;
+ event_.radius_ = radius;
+ event_.radius_delta_ = radius_delta;
+ event_.radial_velocity_ = radial_velocity;
+ event_.touches_ = touches;
+ event_.is_construction_finished_ = is_construction_finished;
+
+ return event_;
+ }
+
+ private:
+ nux::GestureEvent event_;
+};
+} // namespace nux
+
+// maps a gesture id to its acceptance
+extern std::map<int, int> g_gesture_event_accept_count;
+extern std::map<int, int> g_gesture_event_reject_count;
+
+#endif // FAKE_GESTURE_EVENT_H
diff --git a/tests/test-gestures/NuxMock.h b/tests/test-gestures/NuxMock.h
new file mode 100644
index 000000000..28dfe7bf8
--- /dev/null
+++ b/tests/test-gestures/NuxMock.h
@@ -0,0 +1,19 @@
+#ifndef NUX_MOCK_H
+#define NUX_MOCK_H
+
+#include <Nux/Nux.h>
+
+namespace nux
+{
+
+class InputAreaMock : public Object
+{
+ public:
+ void GestureEvent(const GestureEvent &event)
+ {
+ }
+};
+
+} // namespace nux
+
+#endif // NUX_MOCK_H
diff --git a/tests/test-gesture-engine/PluginAdapterMock.cpp b/tests/test-gestures/PluginAdapterMock.cpp
index a71af2421..a71af2421 100644
--- a/tests/test-gesture-engine/PluginAdapterMock.cpp
+++ b/tests/test-gestures/PluginAdapterMock.cpp
diff --git a/tests/test-gesture-engine/PluginAdapterMock.h b/tests/test-gestures/PluginAdapterMock.h
index 2b111a68b..2b111a68b 100644
--- a/tests/test-gesture-engine/PluginAdapterMock.h
+++ b/tests/test-gestures/PluginAdapterMock.h
diff --git a/tests/test-gestures/UnityGestureTargetMock.h b/tests/test-gestures/UnityGestureTargetMock.h
new file mode 100644
index 000000000..9fd621fb8
--- /dev/null
+++ b/tests/test-gestures/UnityGestureTargetMock.h
@@ -0,0 +1,15 @@
+#ifndef UNITY_GESTURE_TARGET_MOCK_H
+#define UNITY_GESTURE_TARGET_MOCK_H
+
+#include <Nux/Gesture.h>
+
+class UnityGestureTargetMock : public nux::GestureTarget
+{
+ public:
+ virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event)
+ {
+ return nux::GestureDeliveryRequest::NONE;
+ }
+};
+
+#endif // UNITY_GESTURE_TARGET_MOCK_H
diff --git a/tests/test-gestures/WindowGestureTargetMock.h b/tests/test-gestures/WindowGestureTargetMock.h
new file mode 100644
index 000000000..e43bad80c
--- /dev/null
+++ b/tests/test-gestures/WindowGestureTargetMock.h
@@ -0,0 +1,55 @@
+#ifndef WINDOW_GESTURE_TARGET_MOCK_H
+#define WINDOW_GESTURE_TARGET_MOCK_H
+
+#include <Nux/Gesture.h>
+
+#include <set>
+
+class CompWindowMock;
+class WindowGestureTargetMock;
+
+extern std::set<WindowGestureTargetMock*> g_window_target_mocks;
+
+class WindowGestureTargetMock : public nux::GestureTarget
+{
+ public:
+ WindowGestureTargetMock(CompWindowMock *window) : window(window)
+ {
+ g_window_target_mocks.insert(this);
+ }
+
+ virtual ~WindowGestureTargetMock()
+ {
+ g_window_target_mocks.erase(this);
+ }
+
+ virtual nux::GestureDeliveryRequest GestureEvent(const nux::GestureEvent &event)
+ {
+ events_received.push_back(event);
+ return nux::GestureDeliveryRequest::NONE;
+ }
+
+ CompWindowMock *window;
+ std::list<nux::GestureEvent> events_received;
+
+ static Cursor fleur_cursor;
+ private:
+ virtual bool Equals(const nux::GestureTarget& other) const
+ {
+ const WindowGestureTargetMock *window_target = dynamic_cast<const WindowGestureTargetMock *>(&other);
+
+ if (window_target)
+ {
+ if (window && window_target->window)
+ return window->id() == window_target->window->id();
+ else
+ return window == window_target->window;
+ }
+ else
+ {
+ return false;
+ }
+ }
+};
+
+#endif // WINDOW_GESTURE_TARGET_MOCK_H
diff --git a/tests/test-gesture-engine/X11_mock.cpp b/tests/test-gestures/X11_mock.cpp
index 5560aa9ac..5560aa9ac 100644
--- a/tests/test-gesture-engine/X11_mock.cpp
+++ b/tests/test-gestures/X11_mock.cpp
diff --git a/tests/test-gesture-engine/X11_mock.h b/tests/test-gestures/X11_mock.h
index f98e028be..f98e028be 100644
--- a/tests/test-gesture-engine/X11_mock.h
+++ b/tests/test-gestures/X11_mock.h
diff --git a/tests/test-gesture-engine/compiz_mock/core/core.h b/tests/test-gestures/compiz_mock/core/core.h
index f1c358fbf..f1c358fbf 100644
--- a/tests/test-gesture-engine/compiz_mock/core/core.h
+++ b/tests/test-gestures/compiz_mock/core/core.h
diff --git a/tests/test-gesture-engine/compiz_mock/core/screen.h b/tests/test-gestures/compiz_mock/core/screen.h
index 38795db15..225d41c65 100644
--- a/tests/test-gesture-engine/compiz_mock/core/screen.h
+++ b/tests/test-gestures/compiz_mock/core/screen.h
@@ -31,41 +31,42 @@ typedef std::vector<CompWindowMock*> CompWindowMockVector;
class CompScreenMock {
public:
- CompScreenMock() : _grab_count(0) {}
+ CompScreenMock() : grab_count_(0), next_grab_handle_(1) {}
typedef int GrabHandle;
- int width() const {return _width;}
- int height() const {return _height;}
+ int width() const {return width_;}
+ int height() const {return height_;}
- Display *dpy() {return _dpy;}
+ Display *dpy() {return dpy_;}
const CompWindowMockVector & clientList(bool stackingOrder = true) {
if (stackingOrder)
- return _client_list_stacking;
+ return client_list_stacking_;
else
- return _client_list;
+ return client_list_;
}
- Window root() {return _root;}
+ Window root() {return root_;}
GrabHandle pushGrab(Cursor cursor, const char *name) {
- _grab_count++;
- return 0;
+ grab_count_++;
+ return next_grab_handle_++;
}
void removeGrab(GrabHandle handle, CompPoint *restorePointer) {
- _grab_count--;
+ grab_count_--;
}
Cursor invisibleCursor() {return 1;}
- int _width;
- int _height;
- Display *_dpy;
- CompWindowMockVector _client_list;
- CompWindowMockVector _client_list_stacking;
- Window _root;
- int _grab_count;
+ int width_;
+ int height_;
+ Display *dpy_;
+ CompWindowMockVector client_list_;
+ CompWindowMockVector client_list_stacking_;
+ Window root_;
+ int grab_count_;
+ int next_grab_handle_;
};
extern CompScreenMock *screen_mock;
diff --git a/tests/test-gesture-engine/compiz_mock/core/window.h b/tests/test-gestures/compiz_mock/core/window.h
index d65524b7d..f5e930107 100644
--- a/tests/test-gesture-engine/compiz_mock/core/window.h
+++ b/tests/test-gestures/compiz_mock/core/window.h
@@ -24,46 +24,56 @@
/* The real CompWindow */
#include <core/window.h>
-class CompWindowMock {
+class CompWindowMock
+{
public:
- CompWindowMock() : _moved(false), _maximize_count(0), _maximize_state(0) {}
+ CompWindowMock() : moved_(false), maximize_count_(0), maximize_state_(0),
+ minimized_(false) {}
- int x() const {return _geometry.x();}
- int y() const {return _geometry.y();}
- int width() const {return _geometry.width() + (_geometry.border()*2);}
- int height() const {return _geometry.height() + (_geometry.border()*2);}
+ int x() const {return geometry_.x();}
+ int y() const {return geometry_.y();}
+ int width() const {return geometry_.width() + (geometry_.border()*2);}
+ int height() const {return geometry_.height() + (geometry_.border()*2);}
+ int id() { return id_; }
- void move(int dx, int dy, bool immediate = true) {
- _moved = true;
- _movement_x = dx;
- _movement_y = dy;
+ void move(int dx, int dy, bool immediate = true)
+ {
+ moved_ = true;
+ movement_x_ = dx;
+ movement_y_ = dy;
}
- unsigned int actions () {return _actions;}
+ unsigned int actions () {return actions_;}
- void maximize(int state) {++_maximize_count; _maximize_state = state;}
+ bool minimized() { return minimized_; }
+
+ void maximize(int state) {++maximize_count_; maximize_state_ = state;}
/* OBS: I wonder why it returns a reference */
- unsigned int &state() {return _state;}
+ unsigned int &state() {return state_;}
void grabNotify(int x, int y, unsigned int state, unsigned int mask) {}
void ungrabNotify() {}
void syncPosition() {}
- compiz::window::Geometry &serverGeometry() {return _serverGeometry;}
+ compiz::window::Geometry &serverGeometry() {return server_geometry_;}
+
+ unsigned int actions_;
+ unsigned int state_;
+ compiz::window::Geometry server_geometry_;
+ compiz::window::Geometry geometry_;
+
+ bool moved_;
+ int movement_x_;
+ int movement_y_;
- unsigned int _actions;
- unsigned int _state;
- compiz::window::Geometry _serverGeometry;
- compiz::window::Geometry _geometry;
+ int maximize_count_;
+ int maximize_state_;
- bool _moved;
- int _movement_x;
- int _movement_y;
+ int id_;
- int _maximize_count;
- int _maximize_state;
+ bool minimized_;
};
#endif
diff --git a/tests/test-gestures/sed_script_broker b/tests/test-gestures/sed_script_broker
new file mode 100644
index 000000000..3f256b0f6
--- /dev/null
+++ b/tests/test-gestures/sed_script_broker
@@ -0,0 +1,11 @@
+s|<core/core.h>|<compiz_mock/core/core.h>|
+s|\<CompScreen\>|CompScreenMock|g
+s|\<CompWindow\>|CompWindowMock|g
+s|\<CompWindowVector\>|CompWindowMockVector|g
+s|\<screen\>|screen_mock|g
+s|\<pointerX\>|pointerX_mock|g
+s|\<pointerY\>|pointerY_mock|g
+s|\<XFreeCursor\>|XFreeCursorMock|g
+s|\<XCreateFontCursor\>|XCreateFontCursorMock|g
+s|\<WindowGestureTarget\>|WindowGestureTargetMock|g
+s|\<UnityGestureTarget\>|UnityGestureTargetMock|g
diff --git a/tests/test-gesture-engine/sed_script b/tests/test-gestures/sed_script_gesture
index 94fb691f6..c2e3ffa48 100644
--- a/tests/test-gesture-engine/sed_script
+++ b/tests/test-gestures/sed_script_gesture
@@ -9,6 +9,10 @@ s|\<XSync\>|XSyncMock|g
s|\<XWarpPointer\>|XWarpPointerMock|g
s|\<XFreeCursor\>|XFreeCursorMock|g
s|\<XCreateFontCursor\>|XCreateFontCursorMock|g
-s|\<GeisAdapter\>|GeisAdapterMock|g
-s|\<PluginAdapter\>|PluginAdapterMock|g
s|\<ubus-server.h\>|ubus-server-mock.h|g
+s|\<unityshell.h\>|unityshell_mock.h|g
+s|\<PluginAdapter\>|PluginAdapterMock|g
+s|\<UnityWindow\>|UnityWindowMock|g
+s|\<UnityScreen\>|UnityScreenMock|g
+s|\<InputArea\>|InputAreaMock|g
+s|\<Nux/Nux\.h\>|NuxMock.h|g
diff --git a/tests/test-gestures/test_gesture_broker.cpp b/tests/test-gestures/test_gesture_broker.cpp
new file mode 100644
index 000000000..b7f30ec04
--- /dev/null
+++ b/tests/test-gestures/test_gesture_broker.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <compiz_mock/core/core.h>
+#include "UnityGestureBroker.h"
+#include "FakeGestureEvent.h"
+#include "unityshell_mock.h"
+#include "WindowGestureTargetMock.h"
+
+class GestureBrokerTest : public ::testing::Test
+{
+ protected:
+ virtual void SetUp()
+ {
+ screen_mock->width_ = 1280;
+ screen_mock->height_ = 1024;
+
+ GenerateWindows();
+ }
+
+ private:
+ void GenerateWindows()
+ {
+ /* remove windows from previous test */
+ for (auto window : screen_mock->client_list_stacking_) {
+ delete window;
+ }
+ screen_mock->client_list_stacking_.clear();
+
+ /* and generate new ones */
+ CompWindowMock *window;
+
+ /* the root window */
+ window = new unity::UnityWindowMock;
+ window->id_ = 0;
+ /* x, y, width, height, border */
+ window->geometry_.set(0, 0, screen_mock->width(), screen_mock->height(), 0);
+ window->server_geometry_ = window->geometry_;
+ window->actions_ = 0;
+ window->state_ = 0;
+ screen_mock->client_list_stacking_.push_back(window);
+
+ /* middle window */
+ window = new unity::UnityWindowMock;
+ window->id_ = 1;
+ window->geometry_.set(10, 10, 400, 400, 0);
+ window->server_geometry_ = window->geometry_;
+ window->actions_ = CompWindowActionMoveMask;
+ window->state_ = 0;
+ screen_mock->client_list_stacking_.push_back(window);
+
+ /* top-level window */
+ window = new unity::UnityWindowMock;
+ window->id_ = 2;
+ window->geometry_.set(500, 500, 410, 410, 0);
+ window->server_geometry_ = window->geometry_;
+ window->actions_ = CompWindowActionMoveMask;
+ window->state_ = 0;
+ screen_mock->client_list_stacking_.push_back(window);
+
+ screen_mock->client_list_ = screen_mock->client_list_stacking_;
+ std::reverse(screen_mock->client_list_.begin(),
+ screen_mock->client_list_.end());
+ }
+};
+
+/*
+ Tests that events from a three-fingers' Touch gesture goes to the
+ correct window. I.e., to the window that lies where the gesture starts.
+ */
+TEST_F(GestureBrokerTest, ThreeFingersTouchHitsCorrectWindow)
+{
+ UnityGestureBroker gesture_broker;
+ CompWindowMock *middle_window = screen_mock->client_list_stacking_[1];
+ nux::FakeGestureEvent fake_event;
+
+ // init counters
+ g_gesture_event_accept_count[0] = 0;
+ g_gesture_event_reject_count[0] = 0;
+
+ /* prepare and send the fake event */
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 0;
+ fake_event.is_direct_touch = false;
+ fake_event.focus.x = 100.0f; // hits the middle window
+ fake_event.focus.y = 100.0f;
+ // in touch device's coordinate system (because it's not a direct device).
+ // Thus not used by WindowCompositor
+ fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f));
+ fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f));
+ fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f));
+ fake_event.is_construction_finished = false;
+ gesture_broker.ProcessGestureBegin(fake_event.ToGestureEvent());
+
+ // Gesture shouldn't be accepted as constructions hasn't finished
+ ASSERT_EQ(0, g_gesture_event_accept_count[0]);
+ ASSERT_EQ(0, g_gesture_event_reject_count[0]);
+ ASSERT_EQ(1, g_window_target_mocks.size());
+ WindowGestureTargetMock *target_mock = *g_window_target_mocks.begin();
+ ASSERT_TRUE(target_mock->window == middle_window);
+ // No events yet as the broker didn't accept the gesture yet
+ ASSERT_EQ(0, target_mock->events_received.size());
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.delta.x += 10.0f;
+ fake_event.delta.y += 20.0f;
+ fake_event.focus.x += fake_event.delta.x;
+ fake_event.focus.y += fake_event.delta.y;
+ fake_event.is_construction_finished = true;
+ gesture_broker.ProcessGestureUpdate(fake_event.ToGestureEvent());
+
+ // Gesture should have been accepted now since the construction has finished.
+ ASSERT_EQ(1, g_gesture_event_accept_count[0]);
+ ASSERT_EQ(0, g_gesture_event_reject_count[0]);
+ // Check that this gesture target is still valid
+ ASSERT_EQ(1, g_window_target_mocks.count(target_mock));
+ // Gesture events should have been sent to the target by now
+ ASSERT_EQ(2, target_mock->events_received.size());
+}
diff --git a/tests/test-gestures/test_gestures_main.cpp b/tests/test-gestures/test_gestures_main.cpp
new file mode 100644
index 000000000..d362b5746
--- /dev/null
+++ b/tests/test-gestures/test_gestures_main.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <compiz_mock/core/core.h>
+#include <NuxGraphics/GestureEvent.h>
+#include "WindowGestureTargetMock.h"
+#include "unityshell_mock.h"
+
+unity::UnityScreenMock concrete_screen_mock;
+CompScreenMock *screen_mock = &concrete_screen_mock;
+int pointerX_mock = 0;
+int pointerY_mock = 0;
+
+std::map<int, int> g_gesture_event_accept_count;
+void nux::GestureEvent::Accept()
+{
+ g_gesture_event_accept_count[gesture_id_] =
+ g_gesture_event_accept_count[gesture_id_] + 1;
+}
+
+std::map<int, int> g_gesture_event_reject_count;
+void nux::GestureEvent::Reject()
+{
+ g_gesture_event_reject_count[gesture_id_] =
+ g_gesture_event_reject_count[gesture_id_] + 1;
+}
+
+Cursor WindowGestureTargetMock::fleur_cursor = 0;
+std::set<WindowGestureTargetMock*> g_window_target_mocks;
+
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+
+ int ret = RUN_ALL_TESTS();
+
+ return ret;
+}
diff --git a/tests/test-gestures/test_window_gesture_target.cpp b/tests/test-gestures/test_window_gesture_target.cpp
new file mode 100644
index 000000000..4491a9ca3
--- /dev/null
+++ b/tests/test-gestures/test_window_gesture_target.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2012 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com>
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <compiz_mock/core/core.h>
+#include "FakeGestureEvent.h"
+#include "unityshell_mock.h"
+#include <WindowGestureTarget.h>
+
+class WindowGestureTargetTest : public ::testing::Test
+{
+ protected:
+ virtual void SetUp()
+ {
+ screen_mock->width_ = 1280;
+ screen_mock->height_ = 1024;
+ }
+
+ void PerformPinch(WindowGestureTarget &gesture_target, float peak_radius)
+ {
+ nux::FakeGestureEvent fake_event;
+
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 0;
+ fake_event.gesture_classes = nux::PINCH_GESTURE;
+ fake_event.is_direct_touch = false;
+ // in touch device's coordinate system (because it's not a direct device).
+ // Thus not used by WindowCompositor
+ fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f));
+ fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f));
+ fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f));
+ fake_event.focus.x = gesture_target.window()->geometry_.centerX();
+ fake_event.focus.y = gesture_target.window()->geometry_.centerY();;
+ fake_event.radius = 1.0;
+ fake_event.is_construction_finished = false;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.radius = peak_radius;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+ }
+};
+
+TEST_F(WindowGestureTargetTest, ThreeFingersDragMovesWindow)
+{
+ unity::UnityWindowMock window;
+ window.geometry_.set(10, 10, 400, 400, 0);
+ window.server_geometry_ = window.geometry_;
+ window.actions_ = CompWindowActionMoveMask;
+ window.state_ = 0;
+ window.id_ = 1;
+
+ WindowGestureTarget gesture_target(&window);
+
+ nux::FakeGestureEvent fake_event;
+
+ /* prepare and send the fake event */
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 0;
+ fake_event.gesture_classes = nux::TOUCH_GESTURE;
+ fake_event.is_direct_touch = false;
+ fake_event.focus.x = 100.0f; // hits the middle window
+ fake_event.focus.y = 100.0f;
+ // in touch device's coordinate system (because it's not a direct device).
+ // Thus not used by WindowCompositor
+ fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f));
+ fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f));
+ fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f));
+ fake_event.is_construction_finished = false;
+ fake_event.radius = 1.0f;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ ASSERT_FALSE(window.moved_);
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.gesture_classes = nux::TOUCH_GESTURE | nux::DRAG_GESTURE;
+ fake_event.delta.x = 10.0f;
+ fake_event.delta.y = 20.0f;
+ fake_event.focus.x += fake_event.delta.x;
+ fake_event.focus.y += fake_event.delta.y;
+ fake_event.is_construction_finished = true;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ ASSERT_TRUE(window.moved_);
+ ASSERT_EQ(fake_event.delta.x, window.movement_x_);
+ ASSERT_EQ(fake_event.delta.y, window.movement_y_);
+}
+
+TEST_F(WindowGestureTargetTest, ThreeFingersDragDoesntMoveStaticWindow)
+{
+
+ unity::UnityWindowMock window;
+ window.geometry_.set(10, 10, 400, 400, 0);
+ window.server_geometry_ = window.geometry_;
+ window.actions_ = 0; /* can't be moved */
+ window.state_ = 0;
+ window.id_ = 1;
+
+ WindowGestureTarget gesture_target(&window);
+
+ nux::FakeGestureEvent fake_event;
+
+ /* prepare and send the fake event */
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 0;
+ fake_event.is_direct_touch = false;
+ fake_event.focus.x = 100.0f; // hits the middle window
+ fake_event.focus.y = 100.0f;
+ // in touch device's coordinate system (because it's not a direct device).
+ // Thus not used by WindowCompositor
+ fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f));
+ fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f));
+ fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f));
+ fake_event.is_construction_finished = false;
+ fake_event.radius = 1.0f;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ ASSERT_FALSE(window.moved_);
+
+ fake_event.type = nux::EVENT_GESTURE_UPDATE;
+ fake_event.delta.x += 10.0f;
+ fake_event.delta.y += 20.0f;
+ fake_event.focus.x += fake_event.delta.x;
+ fake_event.focus.y += fake_event.delta.y;
+ fake_event.is_construction_finished = true;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ ASSERT_FALSE(window.moved_);
+}
+
+TEST_F(WindowGestureTargetTest, ThreeFingersPinchMaximizesWindow)
+{
+ unity::UnityWindowMock window;
+ window.geometry_.set(10, 10, 400, 400, 0);
+ window.server_geometry_ = window.geometry_;
+ window.actions_ = CompWindowActionMoveMask;
+ window.state_ = 0;
+ window.id_ = 1;
+
+ WindowGestureTarget gesture_target(&window);
+
+ PerformPinch(gesture_target, 2.0);
+
+ ASSERT_EQ(1, window.maximize_count_);
+ ASSERT_EQ(MAXIMIZE_STATE, window.maximize_state_);
+}
+
+TEST_F(WindowGestureTargetTest, ThreeFingersPinchRestoresWindow)
+{
+ unity::UnityWindowMock window;
+ window.geometry_.set(10, 10, 400, 400, 0);
+ window.server_geometry_ = window.geometry_;
+ window.actions_ = CompWindowActionMoveMask;
+ window.state_ = MAXIMIZE_STATE;
+ window.id_ = 1;
+
+ WindowGestureTarget gesture_target(&window);
+
+ PerformPinch(gesture_target, 0.3);
+
+ ASSERT_EQ(1, window.maximize_count_);
+ ASSERT_EQ(0, window.maximize_state_);
+}
+
+TEST_F(WindowGestureTargetTest, MinimalThreeFingersPinchDoesNothing)
+{
+ unity::UnityWindowMock window;
+ window.geometry_.set(10, 10, 400, 400, 0);
+ window.server_geometry_ = window.geometry_;
+ window.actions_ = CompWindowActionMoveMask;
+ window.state_ = 0;
+ window.id_ = 1;
+
+ WindowGestureTarget gesture_target(&window);
+
+ PerformPinch(gesture_target, 1.1);
+
+ ASSERT_EQ(0, window.maximize_count_);
+}
+
+/* Regression test for lp:979418, where the grab is not removed if the gesture
+ * id is 0. */
+TEST_F(WindowGestureTargetTest, DragGrabCheck)
+{
+ screen_mock->grab_count_ = 0;
+
+ unity::UnityWindowMock window;
+ window.geometry_.set(10, 10, 400, 400, 0);
+ window.server_geometry_ = window.geometry_;
+ window.actions_ = CompWindowActionMoveMask;
+ window.state_ = 0;
+ window.id_ = 1;
+
+ WindowGestureTarget gesture_target(&window);
+
+ /* prepare and send the fake event */
+ nux::FakeGestureEvent fake_event;
+ fake_event.type = nux::EVENT_GESTURE_BEGIN;
+ fake_event.gesture_id = 0;
+ fake_event.is_direct_touch = false;
+ fake_event.focus.x = 100.0f; // hits the middle window
+ fake_event.focus.y = 100.0f;
+ // in touch device's coordinate system (because it's not a direct device).
+ // Thus not used by WindowCompositor
+ fake_event.touches.push_back(nux::TouchPoint(0, 10.0f, 10.0f));
+ fake_event.touches.push_back(nux::TouchPoint(1, 20.0f, 20.0f));
+ fake_event.touches.push_back(nux::TouchPoint(2, 22.0f, 22.0f));
+ fake_event.is_construction_finished = false;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ fake_event.type = nux::EVENT_GESTURE_END;
+ gesture_target.GestureEvent(fake_event.ToGestureEvent());
+
+ ASSERT_EQ(0, screen_mock->grab_count_);
+}
diff --git a/tests/test-gesture-engine/ubus-server-mock.cpp b/tests/test-gestures/ubus-server-mock.cpp
index 8305aedff..8305aedff 100644
--- a/tests/test-gesture-engine/ubus-server-mock.cpp
+++ b/tests/test-gestures/ubus-server-mock.cpp
diff --git a/tests/test-gesture-engine/ubus-server-mock.h b/tests/test-gestures/ubus-server-mock.h
index 21a642253..21a642253 100644
--- a/tests/test-gesture-engine/ubus-server-mock.h
+++ b/tests/test-gestures/ubus-server-mock.h
diff --git a/tests/test-gestures/unityshell_mock.h b/tests/test-gestures/unityshell_mock.h
new file mode 100644
index 000000000..dd054abf4
--- /dev/null
+++ b/tests/test-gestures/unityshell_mock.h
@@ -0,0 +1,52 @@
+#ifndef UNITYSHELL_MOCK_H
+#define UNITYSHELL_MOCK_H
+
+#include <compiz_mock/core/core.h>
+#include <sigc++/sigc++.h>
+#include <NuxMock.h>
+
+namespace unity
+{
+
+class UnityWindowMock : public CompWindowMock
+{
+ public:
+ static UnityWindowMock *get(CompWindowMock *window)
+ {
+ return static_cast<UnityWindowMock*>(window);
+
+ }
+
+ sigc::signal<void> being_destroyed;
+};
+
+class UnityScreenMock : public CompScreenMock
+{
+ public:
+ UnityScreenMock()
+ : launcher_(new nux::InputAreaMock)
+ {
+ }
+
+ virtual ~UnityScreenMock()
+ {
+ launcher_->Dispose();
+ }
+
+ static UnityScreenMock *get(CompScreenMock *screen)
+ {
+ return static_cast<UnityScreenMock*>(screen);
+
+ }
+
+ nux::InputAreaMock *LauncherView()
+ {
+ return launcher_;
+ }
+
+ nux::InputAreaMock *launcher_;
+};
+
+} // namespace unity
+
+#endif // UNITYSHELL_MOCK_H
diff --git a/tests/test_launcher_controller.cpp b/tests/test_launcher_controller.cpp
index bbc461de2..d3908b789 100644
--- a/tests/test_launcher_controller.cpp
+++ b/tests/test_launcher_controller.cpp
@@ -74,7 +74,6 @@ protected:
Settings settings;
panel::Style panel_style;
MockFavoriteStore favorite_store;
- GeisAdapter geis_adapter;
Controller lc;
};
}
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index e2c6a9116..a92978dab 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -4,7 +4,6 @@
#include <NuxCore/Logger.h>
#include <Nux/Nux.h>
-#include "GestureEngine.h"
#include "unity-shared/PluginAdapter.h"
#include "unity-shared/WindowManager.h"
@@ -27,7 +26,6 @@ int main(int argc, char** argv)
// Setting the PluginAdapter to null, using the Standalone version at link time.
PluginAdapter::Initialize(NULL);
WindowManager::SetDefault(PluginAdapter::Default());
- GeisAdapter geis_adapter;
int ret = RUN_ALL_TESTS();
diff --git a/unity-standalone/StandaloneUnity.cpp b/unity-standalone/StandaloneUnity.cpp
index 80638c7a7..fa0662bed 100644
--- a/unity-standalone/StandaloneUnity.cpp
+++ b/unity-standalone/StandaloneUnity.cpp
@@ -164,7 +164,6 @@ int main(int argc, char **argv)
dash::Style dash_style;
panel::Style panel_style;
- GeisAdapter geis_adapter;
internal::FavoriteStoreGSettings favorite_store;
BackgroundEffectHelper::blur_type = BLUR_NONE;