VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/fullscreen/UIMachineWindowFullscreen.cpp@ 50505

Last change on this file since 50505 was 50505, checked in by vboxsync, 11 years ago

FE/Qt: Mac OS X: 7016: Check if *screens have separate spaces* feature is supported/enabled, use *transience* for non-primary screens otherwise.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.4 KB
Line 
1/* $Id: UIMachineWindowFullscreen.cpp 50505 2014-02-19 15:03:24Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UIMachineWindowFullscreen class implementation
6 */
7
8/*
9 * Copyright (C) 2010-2013 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Qt includes: */
21#include <QDesktopWidget>
22#include <QMenu>
23#include <QTimer>
24
25/* GUI includes: */
26#include "VBoxGlobal.h"
27#include "UISession.h"
28#include "UIActionPoolRuntime.h"
29#include "UIMachineLogicFullscreen.h"
30#include "UIMachineWindowFullscreen.h"
31#include "UIMachineView.h"
32#include "UIMachineDefs.h"
33#include "UIMiniToolBar.h"
34#ifdef Q_WS_MAC
35# include "VBoxUtils-darwin.h"
36# include "UICocoaApplication.h"
37#endif /* Q_WS_MAC */
38
39/* COM includes: */
40#include "CSnapshot.h"
41
42UIMachineWindowFullscreen::UIMachineWindowFullscreen(UIMachineLogic *pMachineLogic, ulong uScreenId)
43 : UIMachineWindow(pMachineLogic, uScreenId)
44 , m_pMainMenu(0)
45 , m_pMiniToolBar(0)
46{
47}
48
49#ifdef Q_WS_MAC
50void UIMachineWindowFullscreen::handleNativeNotification(const QString &strNativeNotificationName)
51{
52 /* Make sure this method is only used for ML and next: */
53 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
54
55 /* Handle arrived notification: */
56 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: Notification '%s' received.\n",
57 strNativeNotificationName.toAscii().constData()));
58 /* Handle 'NSWindowDidEnterFullScreenNotification' notification: */
59 if (strNativeNotificationName == "NSWindowDidEnterFullScreenNotification")
60 {
61 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
62 "Native fullscreen mode entered, notifying listener...\n"));
63 emit sigNotifyAboutNativeFullscreenDidEnter();
64 }
65 /* Handle 'NSWindowDidExitFullScreenNotification' notification: */
66 else if (strNativeNotificationName == "NSWindowDidExitFullScreenNotification")
67 {
68 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
69 "Native fullscreen mode exited, notifying listener...\n"));
70 emit sigNotifyAboutNativeFullscreenDidExit();
71 }
72}
73#endif /* Q_WS_MAC */
74
75#ifdef RT_OS_DARWIN
76void UIMachineWindowFullscreen::sltToggleNativeFullscreenMode()
77{
78 /* Make sure this method is only used for ML and next: */
79 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
80
81 /* Toggle native fullscreen mode: */
82 darwinToggleFullscreenMode(this);
83}
84#endif /* RT_OS_DARWIN */
85
86void UIMachineWindowFullscreen::sltMachineStateChanged()
87{
88 /* Call to base-class: */
89 UIMachineWindow::sltMachineStateChanged();
90
91 /* Update mini-toolbar: */
92 updateAppearanceOf(UIVisualElement_MiniToolBar);
93}
94
95void UIMachineWindowFullscreen::sltPopupMainMenu()
96{
97 /* Popup main-menu if present: */
98 if (m_pMainMenu && !m_pMainMenu->isEmpty())
99 {
100 m_pMainMenu->popup(geometry().center());
101 QTimer::singleShot(0, m_pMainMenu, SLOT(sltHighlightFirstAction()));
102 }
103}
104
105void UIMachineWindowFullscreen::prepareMenu()
106{
107 /* Call to base-class: */
108 UIMachineWindow::prepareMenu();
109
110 /* Prepare menu: */
111 CMachine machine = session().GetMachine();
112 RuntimeMenuType restrictedMenus = VBoxGlobal::restrictedRuntimeMenuTypes(machine);
113 RuntimeMenuType allowedMenus = static_cast<RuntimeMenuType>(RuntimeMenuType_All ^ restrictedMenus);
114 m_pMainMenu = uisession()->newMenu(allowedMenus);
115}
116
117void UIMachineWindowFullscreen::prepareVisualState()
118{
119 /* Call to base-class: */
120 UIMachineWindow::prepareVisualState();
121
122 /* The background has to go black: */
123 QPalette palette(centralWidget()->palette());
124 palette.setColor(centralWidget()->backgroundRole(), Qt::black);
125 centralWidget()->setPalette(palette);
126 centralWidget()->setAutoFillBackground(true);
127 setAutoFillBackground(true);
128
129 /* Prepare mini-toolbar: */
130 prepareMiniToolbar();
131
132#ifdef Q_WS_MAC
133 /* Native fullscreen stuff on ML and next: */
134 if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
135 {
136 /* Enable fullscreen support for every screen which requires it: */
137 if (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
138 darwinEnableFullscreenSupport(this);
139 /* Enable transience support for other screens: */
140 else
141 darwinEnableTransienceSupport(this);
142 /* Register to native fullscreen notifications: */
143 UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidEnterFullScreenNotification", this,
144 UIMachineWindow::handleNativeNotification);
145 UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidExitFullScreenNotification", this,
146 UIMachineWindow::handleNativeNotification);
147 /* Asynchronously toggle fullscreen mode for every screen which requires it: */
148 if (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
149 QTimer::singleShot(0, this, SLOT(sltToggleNativeFullscreenMode()));
150 }
151#endif /* Q_WS_MAC */
152}
153
154void UIMachineWindowFullscreen::prepareMiniToolbar()
155{
156 /* Get machine: */
157 CMachine m = machine();
158
159 /* Make sure mini-toolbar is necessary: */
160 bool fIsActive = m.GetExtraData(GUI_ShowMiniToolBar) != "no";
161 if (!fIsActive)
162 return;
163
164 /* Get the mini-toolbar alignment: */
165 bool fIsAtTop = m.GetExtraData(GUI_MiniToolBarAlignment) == "top";
166 /* Get the mini-toolbar auto-hide feature availability: */
167 bool fIsAutoHide = m.GetExtraData(GUI_MiniToolBarAutoHide) != "off";
168 /* Create mini-toolbar: */
169 m_pMiniToolBar = new UIRuntimeMiniToolBar(this,
170 fIsAtTop ? Qt::AlignTop : Qt::AlignBottom,
171 IntegrationMode_Embedded,
172 fIsAutoHide);
173 QList<QMenu*> menus;
174 RuntimeMenuType restrictedMenus = VBoxGlobal::restrictedRuntimeMenuTypes(m);
175 RuntimeMenuType allowedMenus = static_cast<RuntimeMenuType>(RuntimeMenuType_All ^ restrictedMenus);
176 QList<QAction*> actions = uisession()->newMenu(allowedMenus)->actions();
177 for (int i=0; i < actions.size(); ++i)
178 menus << actions.at(i)->menu();
179 m_pMiniToolBar->addMenus(menus);
180#ifndef RT_OS_DARWIN
181 connect(m_pMiniToolBar, SIGNAL(sigMinimizeAction()), this, SLOT(showMinimized()));
182#endif /* !RT_OS_DARWIN */
183 connect(m_pMiniToolBar, SIGNAL(sigExitAction()),
184 gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SLOT(trigger()));
185 connect(m_pMiniToolBar, SIGNAL(sigCloseAction()),
186 gActionPool->action(UIActionIndexRuntime_Simple_Close), SLOT(trigger()));
187}
188
189void UIMachineWindowFullscreen::cleanupMiniToolbar()
190{
191 /* Make sure mini-toolbar was created: */
192 if (!m_pMiniToolBar)
193 return;
194
195 /* Save mini-toolbar settings: */
196 machine().SetExtraData(GUI_MiniToolBarAutoHide, m_pMiniToolBar->autoHide() ? QString() : "off");
197 /* Delete mini-toolbar: */
198 delete m_pMiniToolBar;
199 m_pMiniToolBar = 0;
200}
201
202void UIMachineWindowFullscreen::cleanupVisualState()
203{
204#ifdef Q_WS_MAC
205 /* Native fullscreen stuff on ML and next: */
206 if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
207 {
208 /* Unregister from native fullscreen notifications: */
209 UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidEnterFullScreenNotification", this);
210 UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidExitFullScreenNotification", this);
211 }
212#endif /* Q_WS_MAC */
213
214 /* Cleanup mini-toolbar: */
215 cleanupMiniToolbar();
216
217 /* Call to base-class: */
218 UIMachineWindow::cleanupVisualState();
219}
220
221void UIMachineWindowFullscreen::cleanupMenu()
222{
223 /* Cleanup menu: */
224 delete m_pMainMenu;
225 m_pMainMenu = 0;
226
227 /* Call to base-class: */
228 UIMachineWindow::cleanupMenu();
229}
230
231void UIMachineWindowFullscreen::placeOnScreen()
232{
233 /* Get corresponding screen: */
234 int iScreen = qobject_cast<UIMachineLogicFullscreen*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId);
235 /* Calculate working area: */
236 QRect workingArea = QApplication::desktop()->screenGeometry(iScreen);
237 /* Move to the appropriate position: */
238 move(workingArea.topLeft());
239 /* Resize to the appropriate size: */
240 resize(workingArea.size());
241 /* Adjust guest screen size if necessary: */
242 machineView()->maybeAdjustGuestScreenSize();
243 /* Move mini-toolbar into appropriate place: */
244 if (m_pMiniToolBar)
245 m_pMiniToolBar->adjustGeometry();
246 /* Process pending move & resize events: */
247 qApp->processEvents();
248}
249
250void UIMachineWindowFullscreen::showInNecessaryMode()
251{
252 /* Should we show window?: */
253 if (uisession()->isScreenVisible(m_uScreenId))
254 {
255 /* Do we have the seamless logic? */
256 if (UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic()))
257 {
258 /* Is this guest screen has own host screen? */
259 if (pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
260 {
261 /* Make sure the window is maximized and placed on valid screen: */
262 placeOnScreen();
263
264#ifdef Q_WS_WIN
265 /* On Windows we should activate main window first,
266 * because entering fullscreen there doesn't means window will be auto-activated,
267 * so no window-activation event will be received
268 * and no keyboard-hook created otherwise... */
269 if (m_uScreenId == 0)
270 setWindowState(windowState() | Qt::WindowActive);
271#endif /* Q_WS_WIN */
272
273#ifdef Q_WS_MAC
274 /* ML and next using native stuff, so we can call for simple show(): */
275 if (vboxGlobal().osRelease() > MacOSXRelease_Lion) show();
276 /* Lion and previous still using Qt one, call for showFullScreen(): */
277 else showFullScreen();
278#else /* !Q_WS_MAC */
279 /* Show in fullscreen mode: */
280 showFullScreen();
281#endif /* !Q_WS_MAC */
282
283 /* Make sure the window is placed on valid screen again
284 * after window is shown & window's decorations applied.
285 * That is required (still?) due to X11 Window Geometry Rules. */
286 placeOnScreen();
287
288 /* Return early: */
289 return;
290 }
291 }
292 }
293 /* Hide in other cases: */
294 hide();
295}
296
297void UIMachineWindowFullscreen::updateAppearanceOf(int iElement)
298{
299 /* Call to base-class: */
300 UIMachineWindow::updateAppearanceOf(iElement);
301
302 /* Update mini-toolbar: */
303 if (iElement & UIVisualElement_MiniToolBar)
304 {
305 if (m_pMiniToolBar)
306 {
307 /* Get machine: */
308 const CMachine &m = machine();
309 /* Get snapshot(s): */
310 QString strSnapshotName;
311 if (m.GetSnapshotCount() > 0)
312 {
313 CSnapshot snapshot = m.GetCurrentSnapshot();
314 strSnapshotName = " (" + snapshot.GetName() + ")";
315 }
316 /* Update mini-toolbar text: */
317 m_pMiniToolBar->setText(m.GetName() + strSnapshotName);
318 }
319 }
320}
321
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette