VirtualBox

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

Last change on this file since 52133 was 52133, checked in by vboxsync, 10 years ago

FE/Qt: 7462: Runtime UI: Menu-bar, menu cleanup/rework (part 05).

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