bool DashboardWindowContainer::sceneEvent(QEvent* event)
{
	if (event->type() == QEvent::GestureOverride) {
		QGestureEvent* ge = static_cast<QGestureEvent*>(event);
		ge->accept();
		return true;
	}
	else if (event->type() == QEvent::Gesture) {
		QGesture* g = static_cast<QGestureEvent*>(event)->gesture(Qt::TapGesture);
		if (g) {
			QTapGesture* tap = static_cast<QTapGesture*>(g);
			if (tap->state() == Qt::GestureFinished) {
				handleTap(mapFromScene(tap->position()));
			}
			
			return true;
		}

		if(!m_isMenu) {
#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
			g = static_cast<QGestureEvent*>(event)->gesture((Qt::GestureType) SysMgrGestureFlick);
#else
            g = static_cast<QGestureEvent*>(event)->gesture(FlickGesture::gestureType());
#endif
			if (g) {
				FlickGesture* flick = static_cast<FlickGesture*>(g);
				if (flick->state() == Qt::GestureFinished) {
					bool flick_delete = abs(flick->velocity().x()) > abs(flick->velocity().y());

					if (flick_delete) {
						if (DashboardWindow* w = m_draggedWindow.data()) {
							m_draggedWindow.clear();
							if (!w->persistent()) {
								m_seenFlick = true;
								triggerItemDelete(w);
							}
						}
					}
				}
				return true;
			}
		}
	} else if (event->type() == QEvent::TouchBegin) {
		return true;
	} else if (event->type() == QEvent::TouchUpdate) {
		return true;
	} else if (event->type() == QEvent::TouchEnd){
		return true;
	}

	return QGraphicsObject::sceneEvent(event);        
}
void DashboardWindowContainer::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
	event->accept();

	Q_EMIT signalItemDragState(false);

	if (m_seenFlick) {
		m_seenFlick = false;
		m_dashboardManualDrag = false;
		return;
	}

	if (DashboardWindow* w = m_draggedWindow.data()) {

		if(!m_dashboardManualDrag) {
			if (event->canceled() || w->persistent())
				goto Done;

			// A window was being dragged around. Did it move too far?
			int width = w->boundingRect().width();
			if(!m_isMenu) {
				if (abs(w->pos().x()) > width/4) {
					triggerItemDelete(w);
					// Restoring of other items will occur when the delete animation finished
					return;
				}
			} else {
				if (abs(w->pos().x() - width/2) > width/4) {
					triggerItemDelete(w);
					// Restoring of other items will occur when the delete animation finished
					return;
				}
			}
		} else {
			// send the mouse event to the window
			int winX = event->pos().x() + (m_isMenu ? 0 : w->boundingRect().width()/2);
			int winY = event->pos().y() - w->pos().y() + w->boundingRect().height()/2;

			Event ev;
			if (event->canceled())
				ev.type = Event::PenCancel;
			else
				ev.type = Event::PenUp;
			ev.setMainFinger(true);
			ev.x = winX;
			ev.y = winY;
			ev.clickCount = 1;
			ev.modifiers = Event::modifiersFromQt(event->modifiers());
			ev.time = Time::curSysTimeMs();

			w->inputEvent(&ev);
		}

		m_draggedWindow.clear();
	}

Done:
	if(!m_isMenu)
		restoreNonDeletedItems();
	else {
		// If we are flicking down, then we always need to snap back up to the first window, so there is no need to recalculate the new scroll bottom. Same is the case if we have 5 windows
		restoreNonDeletedItems(false);
	}
}