VirtualBox

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

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

FE/Qt: 6660: Advanced extra-data management framework: Integrate GUI_ShowMiniToolBar, GUI_MiniToolBarAutoHide, GUI_MiniToolBarAlignment.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.1 KB
Line 
1/* $Id: UIMachineWindowFullscreen.cpp 51654 2014-06-18 18:14:46Z 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 "UIExtraDataManager.h"
28#include "UISession.h"
29#include "UIActionPoolRuntime.h"
30#include "UIMachineLogicFullscreen.h"
31#include "UIMachineWindowFullscreen.h"
32#include "UIMachineView.h"
33#include "UIMachineDefs.h"
34#include "UIMiniToolBar.h"
35#ifdef Q_WS_MAC
36# include "VBoxUtils-darwin.h"
37# include "UICocoaApplication.h"
38#endif /* Q_WS_MAC */
39
40/* COM includes: */
41#include "CSnapshot.h"
42
43UIMachineWindowFullscreen::UIMachineWindowFullscreen(UIMachineLogic *pMachineLogic, ulong uScreenId)
44 : UIMachineWindow(pMachineLogic, uScreenId)
45 , m_pMainMenu(0)
46 , m_pMiniToolBar(0)
47#ifdef Q_WS_MAC
48 , m_fIsInFullscreenTransition(false)
49#endif /* Q_WS_MAC */
50{
51}
52
53#ifdef Q_WS_MAC
54void UIMachineWindowFullscreen::handleNativeNotification(const QString &strNativeNotificationName)
55{
56 /* Make sure this method is only used for ML and next: */
57 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
58
59 /* Log all arrived notifications: */
60 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: Notification '%s' received.\n",
61 strNativeNotificationName.toAscii().constData()));
62
63 /* Handle 'NSWindowWillEnterFullScreenNotification' notification: */
64 if (strNativeNotificationName == "NSWindowWillEnterFullScreenNotification")
65 {
66 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
67 "Native fullscreen mode about to enter, notifying listener...\n"));
68 emit sigNotifyAboutNativeFullscreenWillEnter();
69 }
70 /* Handle 'NSWindowDidEnterFullScreenNotification' notification: */
71 else if (strNativeNotificationName == "NSWindowDidEnterFullScreenNotification")
72 {
73 /* Mark window transition complete: */
74 m_fIsInFullscreenTransition = false;
75 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
76 "Native fullscreen mode entered, notifying listener...\n"));
77 emit sigNotifyAboutNativeFullscreenDidEnter();
78 }
79 /* Handle 'NSWindowWillExitFullScreenNotification' notification: */
80 else if (strNativeNotificationName == "NSWindowWillExitFullScreenNotification")
81 {
82 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
83 "Native fullscreen mode about to exit, notifying listener...\n"));
84 emit sigNotifyAboutNativeFullscreenWillExit();
85 }
86 /* Handle 'NSWindowDidExitFullScreenNotification' notification: */
87 else if (strNativeNotificationName == "NSWindowDidExitFullScreenNotification")
88 {
89 /* Mark window transition complete: */
90 m_fIsInFullscreenTransition = false;
91 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
92 "Native fullscreen mode exited, notifying listener...\n"));
93 emit sigNotifyAboutNativeFullscreenDidExit();
94 }
95 /* Handle 'NSWindowDidFailToEnterFullScreenNotification' notification: */
96 else if (strNativeNotificationName == "NSWindowDidFailToEnterFullScreenNotification")
97 {
98 /* Mark window transition complete: */
99 m_fIsInFullscreenTransition = false;
100 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
101 "Native fullscreen mode fail to enter, notifying listener...\n"));
102 emit sigNotifyAboutNativeFullscreenFailToEnter();
103 }
104}
105#endif /* Q_WS_MAC */
106
107void UIMachineWindowFullscreen::sltMachineStateChanged()
108{
109 /* Call to base-class: */
110 UIMachineWindow::sltMachineStateChanged();
111
112 /* Update mini-toolbar: */
113 updateAppearanceOf(UIVisualElement_MiniToolBar);
114}
115
116void UIMachineWindowFullscreen::sltPopupMainMenu()
117{
118 /* Popup main-menu if present: */
119 if (m_pMainMenu && !m_pMainMenu->isEmpty())
120 {
121 m_pMainMenu->popup(geometry().center());
122 QTimer::singleShot(0, m_pMainMenu, SLOT(sltHighlightFirstAction()));
123 }
124}
125
126#ifdef Q_WS_MAC
127void UIMachineWindowFullscreen::sltEnterNativeFullscreen(UIMachineWindow *pMachineWindow)
128{
129 /* Make sure this slot is called only under ML and next: */
130 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
131
132 /* Make sure it is NULL or 'this' window passed: */
133 if (pMachineWindow && pMachineWindow != this)
134 return;
135
136 /* Make sure this window should be shown at all: */
137 if (!uisession()->isScreenVisible(m_uScreenId))
138 return;
139
140 /* Make sure this window has fullscreen logic: */
141 UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
142 if (!pFullscreenLogic)
143 return;
144
145 /* Make sure this window mapped to some host-screen: */
146 if (!pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
147 return;
148
149 /* Mark window 'transitioned to fullscreen': */
150 m_fIsInFullscreenTransition = true;
151
152 /* Enter native fullscreen mode if necessary: */
153 if ( (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
154 && !darwinIsInFullscreenMode(this))
155 darwinToggleFullscreenMode(this);
156}
157
158void UIMachineWindowFullscreen::sltExitNativeFullscreen(UIMachineWindow *pMachineWindow)
159{
160 /* Make sure this slot is called only under ML and next: */
161 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
162
163 /* Make sure it is NULL or 'this' window passed: */
164 if (pMachineWindow && pMachineWindow != this)
165 return;
166
167 /* Mark window 'transitioned from fullscreen': */
168 m_fIsInFullscreenTransition = true;
169
170 /* Exit native fullscreen mode if necessary: */
171 if ( (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
172 && darwinIsInFullscreenMode(this))
173 darwinToggleFullscreenMode(this);
174}
175#endif /* Q_WS_MAC */
176
177void UIMachineWindowFullscreen::sltRevokeFocus()
178{
179 /* Revoke stolen focus: */
180 m_pMachineView->setFocus();
181}
182
183void UIMachineWindowFullscreen::prepareMenu()
184{
185 /* Call to base-class: */
186 UIMachineWindow::prepareMenu();
187
188 /* Prepare menu: */
189 RuntimeMenuType restrictedMenus = gEDataManager->restrictedRuntimeMenuTypes(vboxGlobal().managedVMUuid());
190 RuntimeMenuType allowedMenus = static_cast<RuntimeMenuType>(RuntimeMenuType_All ^ restrictedMenus);
191 m_pMainMenu = uisession()->newMenu(allowedMenus);
192}
193
194void UIMachineWindowFullscreen::prepareVisualState()
195{
196 /* Call to base-class: */
197 UIMachineWindow::prepareVisualState();
198
199 /* The background has to go black: */
200 QPalette palette(centralWidget()->palette());
201 palette.setColor(centralWidget()->backgroundRole(), Qt::black);
202 centralWidget()->setPalette(palette);
203 centralWidget()->setAutoFillBackground(true);
204 setAutoFillBackground(true);
205
206 /* Prepare mini-toolbar: */
207 prepareMiniToolbar();
208
209#ifdef Q_WS_MAC
210 /* Native fullscreen stuff on ML and next: */
211 if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
212 {
213 /* Enable fullscreen support for every screen which requires it: */
214 if (darwinScreensHaveSeparateSpaces() || m_uScreenId == 0)
215 darwinEnableFullscreenSupport(this);
216 /* Enable transience support for other screens: */
217 else
218 darwinEnableTransienceSupport(this);
219 /* Register to native fullscreen notifications: */
220 UICocoaApplication::instance()->registerToNativeNotification("NSWindowWillEnterFullScreenNotification", this,
221 UIMachineWindow::handleNativeNotification);
222 UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidEnterFullScreenNotification", this,
223 UIMachineWindow::handleNativeNotification);
224 UICocoaApplication::instance()->registerToNativeNotification("NSWindowWillExitFullScreenNotification", this,
225 UIMachineWindow::handleNativeNotification);
226 UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidExitFullScreenNotification", this,
227 UIMachineWindow::handleNativeNotification);
228 UICocoaApplication::instance()->registerToNativeNotification("NSWindowDidFailToEnterFullScreenNotification", this,
229 UIMachineWindow::handleNativeNotification);
230 }
231#endif /* Q_WS_MAC */
232}
233
234void UIMachineWindowFullscreen::prepareMiniToolbar()
235{
236 /* Make sure mini-toolbar is not restricted: */
237 if (!gEDataManager->showMiniToolbar(vboxGlobal().managedVMUuid()))
238 return;
239
240 /* Create mini-toolbar: */
241 m_pMiniToolBar = new UIRuntimeMiniToolBar(this,
242 IntegrationMode_Embedded,
243 gEDataManager->miniToolbarAlignment(vboxGlobal().managedVMUuid()),
244 gEDataManager->autoHideMiniToolbar(vboxGlobal().managedVMUuid()));
245 QList<QMenu*> menus;
246 RuntimeMenuType restrictedMenus = gEDataManager->restrictedRuntimeMenuTypes(vboxGlobal().managedVMUuid());
247 RuntimeMenuType allowedMenus = static_cast<RuntimeMenuType>(RuntimeMenuType_All ^ restrictedMenus);
248 QList<QAction*> actions = uisession()->newMenu(allowedMenus)->actions();
249 for (int i=0; i < actions.size(); ++i)
250 menus << actions.at(i)->menu();
251 m_pMiniToolBar->addMenus(menus);
252#ifndef RT_OS_DARWIN
253 connect(m_pMiniToolBar, SIGNAL(sigMinimizeAction()), this, SLOT(showMinimized()));
254#endif /* !RT_OS_DARWIN */
255 connect(m_pMiniToolBar, SIGNAL(sigExitAction()),
256 gActionPool->action(UIActionIndexRuntime_Toggle_Fullscreen), SLOT(trigger()));
257 connect(m_pMiniToolBar, SIGNAL(sigCloseAction()),
258 gActionPool->action(UIActionIndexRuntime_Simple_Close), SLOT(trigger()));
259 connect(m_pMiniToolBar, SIGNAL(sigNotifyAboutFocusStolen()), this, SLOT(sltRevokeFocus()));
260}
261
262void UIMachineWindowFullscreen::cleanupMiniToolbar()
263{
264 /* Make sure mini-toolbar was created: */
265 if (!m_pMiniToolBar)
266 return;
267
268 /* Save mini-toolbar settings: */
269 gEDataManager->setAutoHideMiniToolbar(m_pMiniToolBar->autoHide(), vboxGlobal().managedVMUuid());
270 /* Delete mini-toolbar: */
271 delete m_pMiniToolBar;
272 m_pMiniToolBar = 0;
273}
274
275void UIMachineWindowFullscreen::cleanupVisualState()
276{
277#ifdef Q_WS_MAC
278 /* Native fullscreen stuff on ML and next: */
279 if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
280 {
281 /* Unregister from native fullscreen notifications: */
282 UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowWillEnterFullScreenNotification", this);
283 UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidEnterFullScreenNotification", this);
284 UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowWillExitFullScreenNotification", this);
285 UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidExitFullScreenNotification", this);
286 UICocoaApplication::instance()->unregisterFromNativeNotification("NSWindowDidFailToEnterFullScreenNotification", this);
287 }
288#endif /* Q_WS_MAC */
289
290 /* Cleanup mini-toolbar: */
291 cleanupMiniToolbar();
292
293 /* Call to base-class: */
294 UIMachineWindow::cleanupVisualState();
295}
296
297void UIMachineWindowFullscreen::cleanupMenu()
298{
299 /* Cleanup menu: */
300 delete m_pMainMenu;
301 m_pMainMenu = 0;
302
303 /* Call to base-class: */
304 UIMachineWindow::cleanupMenu();
305}
306
307void UIMachineWindowFullscreen::placeOnScreen()
308{
309 /* Get corresponding screen: */
310 int iScreen = qobject_cast<UIMachineLogicFullscreen*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId);
311 /* Calculate working area: */
312 QRect workingArea = QApplication::desktop()->screenGeometry(iScreen);
313 /* Move to the appropriate position: */
314 move(workingArea.topLeft());
315#ifdef Q_WS_MAC
316 /* Resize to the appropriate size on Lion and previous: */
317 if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
318 resize(workingArea.size());
319 /* Resize to the appropriate size on ML and next
320 * only if that screen has no own user-space: */
321 else if (!darwinScreensHaveSeparateSpaces() && m_uScreenId != 0)
322 resize(workingArea.size());
323#else /* !Q_WS_MAC */
324 /* Resize to the appropriate size: */
325 resize(workingArea.size());
326#endif /* !Q_WS_MAC */
327 /* Adjust guest screen size if necessary: */
328 machineView()->maybeAdjustGuestScreenSize();
329 /* Move mini-toolbar into appropriate place: */
330 if (m_pMiniToolBar)
331 m_pMiniToolBar->adjustGeometry();
332}
333
334void UIMachineWindowFullscreen::showInNecessaryMode()
335{
336 /* Make sure this window should be shown at all: */
337 if (!uisession()->isScreenVisible(m_uScreenId))
338 return hide();
339
340 /* Make sure this window has fullscreen logic: */
341 UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
342 if (!pFullscreenLogic)
343 return hide();
344
345 /* Make sure this window mapped to some host-screen: */
346 if (!pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
347 return hide();
348
349 /* Make sure this window is not minimized: */
350 if (isMinimized())
351 return;
352
353 /* Make sure this window is maximized and placed on valid screen: */
354 placeOnScreen();
355
356#ifdef Q_WS_MAC
357 /* ML and next using native stuff, so we can call for simple show(): */
358 if (vboxGlobal().osRelease() > MacOSXRelease_Lion) show();
359 /* Lion and previous using Qt stuff, so we should call for showFullScreen(): */
360 else showFullScreen();
361#else /* !Q_WS_MAC */
362 /* Show in fullscreen mode: */
363 showFullScreen();
364#endif /* !Q_WS_MAC */
365
366#ifdef Q_WS_X11
367 /* Make sure the window is placed on valid screen again
368 * after window is shown & window's decorations applied.
369 * That is required (still?) due to X11 Window Geometry Rules. */
370 placeOnScreen();
371#endif /* Q_WS_X11 */
372}
373
374void UIMachineWindowFullscreen::updateAppearanceOf(int iElement)
375{
376 /* Call to base-class: */
377 UIMachineWindow::updateAppearanceOf(iElement);
378
379 /* Update mini-toolbar: */
380 if (iElement & UIVisualElement_MiniToolBar)
381 {
382 if (m_pMiniToolBar)
383 {
384 /* Get machine: */
385 const CMachine &m = machine();
386 /* Get snapshot(s): */
387 QString strSnapshotName;
388 if (m.GetSnapshotCount() > 0)
389 {
390 CSnapshot snapshot = m.GetCurrentSnapshot();
391 strSnapshotName = " (" + snapshot.GetName() + ")";
392 }
393 /* Update mini-toolbar text: */
394 m_pMiniToolBar->setText(m.GetName() + strSnapshotName);
395 }
396 }
397}
398
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