From fe9faa8f6f28a95257c64c7ddea5a2861ad41e45 Mon Sep 17 00:00:00 2001
From: Eike Ziller <eike.ziller@nokia.com>
Date: Thu, 15 Mar 2012 19:41:18 +0100
Subject: [PATCH] added MacFullScreen class to enable Mac OS X Lion full-screen
 feature

Done with Max Desyatov<max.desyatov@gmail.com>

Change-Id: I2c3ff188b5f05dc3b8ec106fec0db3766b43a205
Reviewed-by: Erik Verbruggen <erik.verbruggen@nokia.com>
---
 src/plugins/coreplugin/coreplugin.pro   |   6 +-
 src/plugins/coreplugin/macfullscreen.h  |  51 ++++++++++
 src/plugins/coreplugin/macfullscreen.mm | 122 ++++++++++++++++++++++++
 src/plugins/coreplugin/mainwindow.cpp   |  44 ++++++++-
 src/plugins/coreplugin/mainwindow.h     |   3 +
 5 files changed, 219 insertions(+), 7 deletions(-)
 create mode 100644 src/plugins/coreplugin/macfullscreen.h
 create mode 100644 src/plugins/coreplugin/macfullscreen.mm

diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro
index 886e54f7c8a..c32ec82c721 100644
--- a/src/plugins/coreplugin/coreplugin.pro
+++ b/src/plugins/coreplugin/coreplugin.pro
@@ -211,7 +211,10 @@ win32 {
     LIBS += -lole32
 }
 else:macx {
-    OBJECTIVE_SOURCES += progressmanager/progressmanager_mac.mm
+    HEADERS += macfullscreen.h
+    OBJECTIVE_SOURCES += \
+        progressmanager/progressmanager_mac.mm \
+        macfullscreen.mm
     LIBS += -framework AppKit
 }
 else:unix {
@@ -226,4 +229,3 @@ else:unix {
     }
 }
 OTHER_FILES += editormanager/BinFiles.mimetypes.xml
-
diff --git a/src/plugins/coreplugin/macfullscreen.h b/src/plugins/coreplugin/macfullscreen.h
new file mode 100644
index 00000000000..3a8a99aeff9
--- /dev/null
+++ b/src/plugins/coreplugin/macfullscreen.h
@@ -0,0 +1,51 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#ifndef MACFULLSCREEN_H
+#define MACFULLSCREEN_H
+
+#include "mainwindow.h"
+
+namespace Core {
+namespace Internal {
+namespace MacFullScreen {
+
+bool supportsFullScreen();
+// adds fullscreen button to window for lion
+void addFullScreen(Core::Internal::MainWindow *window);
+void toggleFullScreen(Core::Internal::MainWindow *window);
+
+} // MacFullScreen
+} // Internal
+} // Core
+
+#endif // MACFULLSCREEN_H
diff --git a/src/plugins/coreplugin/macfullscreen.mm b/src/plugins/coreplugin/macfullscreen.mm
new file mode 100644
index 00000000000..f9652ae0707
--- /dev/null
+++ b/src/plugins/coreplugin/macfullscreen.mm
@@ -0,0 +1,122 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**************************************************************************/
+
+#include "macfullscreen.h"
+
+#include <AppKit/NSView.h>
+#include <AppKit/NSWindow.h>
+#include <Foundation/NSNotification.h>
+
+#include <QSysInfo>
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+enum {
+    NSWindowCollectionBehaviorFullScreenPrimary = (1 << 7)
+};
+
+static const NSString *NSWindowDidEnterFullScreenNotification = @"NSWindowDidEnterFullScreenNotification";
+static const NSString *NSWindowDidExitFullScreenNotification = @"NSWindowDidExitFullScreenNotification";
+#endif
+
+@interface WindowObserver : NSObject {
+    Core::Internal::MainWindow *window;
+}
+
+- (id)initWithMainWindow:(Core::Internal::MainWindow *)w;
+
+- (void)notifyDidEnterFullScreen:(NSNotification *)notification;
+- (void)notifyDidExitFullScreen:(NSNotification *)notification;
+
+@end
+
+@implementation WindowObserver
+
+- (id)initWithMainWindow:(Core::Internal::MainWindow *)w;
+{
+    if ((self = [self init])) {
+        window = w;
+    }
+    return self;
+}
+
+- (void)notifyDidEnterFullScreen:(NSNotification *)notification
+{
+    Q_UNUSED(notification)
+    window->setIsFullScreen(true);
+}
+
+- (void)notifyDidExitFullScreen:(NSNotification* )notification
+{
+    Q_UNUSED(notification)
+    window->setIsFullScreen(false);
+}
+
+@end
+
+static WindowObserver *observer = nil;
+
+using namespace Core::Internal;
+
+bool MacFullScreen::supportsFullScreen()
+{
+#if QT_VERSION >= 0x040800
+    return QSysInfo::MacintoshVersion >= QSysInfo::MV_LION;
+#else
+    return QSysInfo::MacintoshVersion >= 0x0009; /* MV_LION not defined */
+#endif
+}
+
+void MacFullScreen::addFullScreen(MainWindow *window)
+{
+    if (supportsFullScreen()) {
+        NSView *nsview = (NSView *) window->winId();
+        NSWindow *nswindow = [nsview window];
+        [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
+
+        if (observer == nil)
+            observer = [[WindowObserver alloc] initWithMainWindow:window];
+        NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+        [nc addObserver:observer selector:@selector(notifyDidEnterFullScreen:)
+            name:NSWindowDidEnterFullScreenNotification object:nswindow];
+        [nc addObserver:observer selector:@selector(notifyDidExitFullScreen:)
+            name:NSWindowDidExitFullScreenNotification object:nswindow];
+    }
+}
+
+void MacFullScreen::toggleFullScreen(MainWindow *window)
+{
+    if (supportsFullScreen()) {
+        NSView *nsview = (NSView *) window->winId();
+        NSWindow *nswindow = [nsview window];
+        [nswindow performSelector:@selector(toggleFullScreen:) withObject: nil];
+    }
+}
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index 90ba6e962ac..a1dac7a7ef9 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -58,7 +58,6 @@
 #include "shortcutsettings.h"
 #include "vcsmanager.h"
 #include "variablechooser.h"
-
 #include "scriptmanager_p.h"
 #include "settingsdialog.h"
 #include "variablemanager.h"
@@ -75,6 +74,10 @@
 #include "externaltoolmanager.h"
 #include "editormanager/systemeditor.h"
 
+#if defined(Q_OS_MAC)
+#include "macfullscreen.h"
+#endif
+
 #include <app/app_version.h>
 #include <coreplugin/findplaceholder.h>
 #include <coreplugin/icorelistener.h>
@@ -227,6 +230,10 @@ MainWindow::MainWindow() :
 
     statusBar()->setProperty("p_styled", true);
     setAcceptDrops(true);
+
+#if defined(Q_OS_MAC)
+    MacFullScreen::addFullScreen(this);
+#endif
 }
 
 void MainWindow::setSidebarVisible(bool visible)
@@ -262,6 +269,16 @@ void MainWindow::setPresentationModeEnabled(bool enabled)
     m_actionManager->setPresentationModeEnabled(enabled);
 }
 
+#ifdef Q_OS_MAC
+void MainWindow::setIsFullScreen(bool fullScreen)
+{
+    if (fullScreen)
+        m_toggleFullScreenAction->setText(tr("Exit Full Screen"));
+    else
+        m_toggleFullScreenAction->setText(tr("Enter Full Screen"));
+}
+#endif
+
 MainWindow::~MainWindow()
 {
     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
@@ -772,14 +789,26 @@ void MainWindow::registerDefaultActions()
     mwindow->addAction(cmd, Constants::G_WINDOW_VIEWS);
     m_toggleSideBarAction->setEnabled(false);
 
-#ifndef Q_OS_MAC
+#if defined(Q_OS_MAC)
+    bool fullScreenCheckable = false;
+    QKeySequence fullScreenKeySequence(tr("Ctrl+Meta+F"));
+    const QString fullScreenActionText(tr("Enter Full Screen"));
+    if (MacFullScreen::supportsFullScreen()) {
+#else
+    bool fullScreenCheckable = true;
+    QKeySequence fullScreenKeySequence(tr("Ctrl+Shift+F11"));
+    const QString fullScreenActionText(tr("Full Screen"));
+#endif
     // Full Screen Action
-    m_toggleFullScreenAction = new QAction(tr("Full Screen"), this);
-    m_toggleFullScreenAction->setCheckable(true);
+    m_toggleFullScreenAction = new QAction(fullScreenActionText, this);
+    m_toggleFullScreenAction->setCheckable(fullScreenCheckable);
     cmd = am->registerAction(m_toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext);
-    cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F11")));
+    cmd->setDefaultKeySequence(fullScreenKeySequence);
+    cmd->setAttribute(Command::CA_UpdateText); /* for Mac */
     mwindow->addAction(cmd, Constants::G_WINDOW_SIZE);
     connect(m_toggleFullScreenAction, SIGNAL(triggered(bool)), this, SLOT(setFullScreen(bool)));
+#ifdef Q_OS_MAC
+    }
 #endif
 
     // Window->Views
@@ -1351,6 +1380,10 @@ QPrinter *MainWindow::printer() const
 
 void MainWindow::setFullScreen(bool on)
 {
+#if defined(Q_OS_MAC)
+    Q_UNUSED(on)
+    MacFullScreen::toggleFullScreen(this);
+#else
     if (bool(windowState() & Qt::WindowFullScreen) == on)
         return;
 
@@ -1363,6 +1396,7 @@ void MainWindow::setFullScreen(bool on)
         //menuBar()->show();
         //statusBar()->show();
     }
+#endif
 }
 
 // Display a warning with an additional button to open
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index f510a9c50ad..48d33bc90a4 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -127,6 +127,9 @@ public:
     bool isPresentationModeEnabled();
     void setPresentationModeEnabled(bool);
 
+#ifdef Q_OS_MAC
+    void setIsFullScreen(bool fullScreen);
+#endif
 signals:
     void windowActivated();
 
-- 
GitLab