diff options
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) @@ -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(¤t, &_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; |
