From d0966f59c32eb613c214af936f70866254e23d9b Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Thu, 24 Oct 2013 14:56:39 +0200
Subject: Fix shortcut handling in QtTabbable.

Tested under Gnome 2.32, OS X 10.8 and Win 8.1.

Change-Id: If7d41c2254e53ad0d9b745e27dc1db77d64cec50
License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.

diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 224f343..49f57c9 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -226,7 +226,6 @@ void QtChatWindow::setTabComplete(TabComplete* completer) {
 
 void QtChatWindow::handleKeyPressEvent(QKeyEvent* event) {
 	event->ignore();
-	QtTabbable::handleKeyPressEvent(event);
 	if (event->isAccepted()) {
 		return;
 	}
diff --git a/Swift/QtUI/QtTabbable.cpp b/Swift/QtUI/QtTabbable.cpp
index 84a5100..5659157 100644
--- a/Swift/QtUI/QtTabbable.cpp
+++ b/Swift/QtUI/QtTabbable.cpp
@@ -4,15 +4,37 @@
  * See Documentation/Licenses/GPLv3.txt for more information.
  */
 
-#include "QtTabbable.h"
+#include <Swift/QtUI/QtTabbable.h>
 
 #include <QApplication>
+#include <QKeyEvent>
 
-#include "QtChatTabs.h"
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/Platform.h>
+
+#include <Swift/QtUI/QtChatTabs.h>
 
 namespace Swift {
 
+namespace {
+#ifdef SWIFTEN_PLATFORM_MACOSX
+const Qt::KeyboardModifier ctrlHardwareKeyModifier = Qt::MetaModifier;
+#else
+const Qt::KeyboardModifier ctrlHardwareKeyModifier = Qt::ControlModifier;
+#endif
+}
+
+QtTabbable::QtTabbable() : QWidget() {
+	shortcuts << new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), window(), SLOT(close()));
+	shortcuts << new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageUp), window(), SIGNAL(requestPreviousTab()));
+	shortcuts << new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageDown), window(), SIGNAL(requestNextTab()));
+	shortcuts << new QShortcut(QKeySequence(Qt::ALT + Qt::Key_A), window(), SIGNAL(requestActiveTab()));
+}
+
 QtTabbable::~QtTabbable() {
+	foreach (QShortcut* shortcut, shortcuts) {
+		delete shortcut;
+	}
 	emit windowClosing();
 }
 
@@ -25,36 +47,20 @@ bool QtTabbable::isWidgetSelected() {
 	return parent ? parent->getCurrentTab() == this : isAncestorOf(QApplication::focusWidget());
 }
 
-void QtTabbable::keyPressEvent(QKeyEvent *event) {
-	handleKeyPressEvent(event);
-}
-
-void QtTabbable::handleKeyPressEvent(QKeyEvent *event) {
-	event->ignore();
-	int key = event->key();
-	Qt::KeyboardModifiers modifiers = event->modifiers();
-	if (key == Qt::Key_W && modifiers == Qt::ControlModifier) {
-		close();
-		event->accept();
-	} else if (
-		(key == Qt::Key_PageUp && modifiers == Qt::ControlModifier)
-//		|| (key == Qt::Key_Left && modifiers == (Qt::ControlModifier & Qt::ShiftModifier))
-	) {
-		emit requestPreviousTab();
-		event->accept();
-	} else if (
-		(key == Qt::Key_PageDown && modifiers == Qt::ControlModifier)
-//		|| (key == Qt::Key_Right && modifiers == (Qt::ControlModifier & Qt::ShiftModifier)
-		|| (key == Qt::Key_Tab && modifiers == Qt::ControlModifier)
-	) {
-		emit requestNextTab();
-		event->accept();
-	} else if (
-		(key == Qt::Key_A && modifiers == Qt::AltModifier)
-	)  {
-		emit requestActiveTab();
-		event->accept();
+bool QtTabbable::event(QEvent* event) {
+	QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
+	if (keyEvent) {
+		// According to Qt's focus documentation, one can only override CTRL+TAB via reimplementing QWidget::event().
+#ifdef SWIFTEN_PLATFORM_LINUX
+		if (keyEvent->modifiers() == ctrlHardwareKeyModifier && keyEvent->key() == Qt::Key_Tab && event->type() != QEvent::KeyRelease) {
+#else
+		if (keyEvent->modifiers() == ctrlHardwareKeyModifier && keyEvent->key() == Qt::Key_Tab) {
+#endif
+			emit requestNextTab();
+			return true;
+		}
 	}
+	return QWidget::event(event);
 }
 
 }
diff --git a/Swift/QtUI/QtTabbable.h b/Swift/QtUI/QtTabbable.h
index 0b67b19..fc131ca 100644
--- a/Swift/QtUI/QtTabbable.h
+++ b/Swift/QtUI/QtTabbable.h
@@ -6,8 +6,9 @@
 
 #pragma once
 
-#include <QKeyEvent>
 #include <QWidget>
+#include <QShortcut>
+#include <QList>
 
 
 namespace Swift {
@@ -15,16 +16,13 @@ namespace Swift {
 		Q_OBJECT
 		public:
 			enum AlertType {NoActivity, WaitingActivity, ImpendingActivity};
-			~QtTabbable();
+			virtual ~QtTabbable();
 			bool isWidgetSelected();
 			virtual AlertType getWidgetAlertState() {return NoActivity;}
 			virtual int getCount() {return 0;}
 		protected:
-			QtTabbable() : QWidget() {}
-			void keyPressEvent(QKeyEvent* event);
-
-		protected slots:
-			void handleKeyPressEvent(QKeyEvent* event);
+			QtTabbable();
+			bool event(QEvent* event);
 
 		signals:
 			void titleUpdated();
@@ -36,5 +34,8 @@ namespace Swift {
 			void requestNextTab();
 			void requestActiveTab();
 			void requestFlash();
+
+		private:
+			QList<QShortcut*> shortcuts;
 	};
 }
-- 
cgit v0.10.2-6-g49f6