VirtualBox

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

Last change on this file since 57100 was 57100, checked in by vboxsync, 9 years ago

FE/Qt: 5978: X11: Unity workaround to have mini-toolbar in full-screen in 95% of cases instead of 60%.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.6 KB
Line 
1/* $Id: UIMachineWindowFullscreen.cpp 57100 2015-07-27 15:06:45Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineWindowFullscreen class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifdef VBOX_WITH_PRECOMPILED_HEADERS
19# include <precomp.h>
20#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
21
22/* Qt includes: */
23# include <QDesktopWidget>
24# include <QMenu>
25# include <QTimer>
26
27/* GUI includes: */
28# include "VBoxGlobal.h"
29# include "UIExtraDataManager.h"
30# include "UISession.h"
31# include "UIActionPoolRuntime.h"
32# include "UIMachineLogicFullscreen.h"
33# include "UIMachineWindowFullscreen.h"
34# include "UIMachineView.h"
35# if defined(Q_WS_WIN) || defined(Q_WS_X11)
36# include "UIMachineDefs.h"
37# include "UIMiniToolBar.h"
38# elif defined(Q_WS_MAC)
39# include "UIFrameBuffer.h"
40# include "VBoxUtils-darwin.h"
41# include "UICocoaApplication.h"
42# endif /* Q_WS_MAC */
43
44/* COM includes: */
45# include "CSnapshot.h"
46
47#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
48
49
50UIMachineWindowFullscreen::UIMachineWindowFullscreen(UIMachineLogic *pMachineLogic, ulong uScreenId)
51 : UIMachineWindow(pMachineLogic, uScreenId)
52#if defined(Q_WS_WIN) || defined(Q_WS_X11)
53 , m_pMiniToolBar(0)
54#endif /* Q_WS_WIN || Q_WS_X11 */
55#ifdef Q_WS_MAC
56 , m_fIsInFullscreenTransition(false)
57#endif /* Q_WS_MAC */
58{
59}
60
61#ifdef Q_WS_MAC
62void UIMachineWindowFullscreen::handleNativeNotification(const QString &strNativeNotificationName)
63{
64 /* Make sure this method is only used for ML and next: */
65 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
66
67 /* Log all arrived notifications: */
68 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: Notification '%s' received.\n",
69 strNativeNotificationName.toAscii().constData()));
70
71 /* Handle 'NSWindowWillEnterFullScreenNotification' notification: */
72 if (strNativeNotificationName == "NSWindowWillEnterFullScreenNotification")
73 {
74 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
75 "Native fullscreen mode about to enter, notifying listener...\n"));
76 emit sigNotifyAboutNativeFullscreenWillEnter();
77 }
78 /* Handle 'NSWindowDidEnterFullScreenNotification' notification: */
79 else if (strNativeNotificationName == "NSWindowDidEnterFullScreenNotification")
80 {
81 /* Mark window transition complete: */
82 m_fIsInFullscreenTransition = false;
83 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
84 "Native fullscreen mode entered, notifying listener...\n"));
85 emit sigNotifyAboutNativeFullscreenDidEnter();
86 }
87 /* Handle 'NSWindowWillExitFullScreenNotification' notification: */
88 else if (strNativeNotificationName == "NSWindowWillExitFullScreenNotification")
89 {
90 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
91 "Native fullscreen mode about to exit, notifying listener...\n"));
92 emit sigNotifyAboutNativeFullscreenWillExit();
93 }
94 /* Handle 'NSWindowDidExitFullScreenNotification' notification: */
95 else if (strNativeNotificationName == "NSWindowDidExitFullScreenNotification")
96 {
97 /* Mark window transition complete: */
98 m_fIsInFullscreenTransition = false;
99 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
100 "Native fullscreen mode exited, notifying listener...\n"));
101 emit sigNotifyAboutNativeFullscreenDidExit();
102 }
103 /* Handle 'NSWindowDidFailToEnterFullScreenNotification' notification: */
104 else if (strNativeNotificationName == "NSWindowDidFailToEnterFullScreenNotification")
105 {
106 /* Mark window transition complete: */
107 m_fIsInFullscreenTransition = false;
108 LogRel(("UIMachineWindowFullscreen::handleNativeNotification: "
109 "Native fullscreen mode fail to enter, notifying listener...\n"));
110 emit sigNotifyAboutNativeFullscreenFailToEnter();
111 }
112}
113#endif /* Q_WS_MAC */
114
115#if defined(Q_WS_WIN) || defined(Q_WS_X11)
116void UIMachineWindowFullscreen::sltMachineStateChanged()
117{
118 /* Call to base-class: */
119 UIMachineWindow::sltMachineStateChanged();
120
121 /* Update mini-toolbar: */
122 updateAppearanceOf(UIVisualElement_MiniToolBar);
123}
124
125void UIMachineWindowFullscreen::sltRevokeWindowActivation()
126{
127 /* Make sure window is visible: */
128 if (!isVisible() || isMinimized())
129 return;
130
131 /* Revoke stolen activation: */
132 activateWindow();
133}
134#endif /* Q_WS_WIN || Q_WS_X11 */
135
136#ifdef Q_WS_MAC
137void UIMachineWindowFullscreen::sltEnterNativeFullscreen(UIMachineWindow *pMachineWindow)
138{
139 /* Make sure this slot is called only under ML and next: */
140 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
141
142 /* Make sure it is NULL or 'this' window passed: */
143 if (pMachineWindow && pMachineWindow != this)
144 return;
145
146 /* Make sure this window has fullscreen logic: */
147 UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
148 AssertPtrReturnVoid(pFullscreenLogic);
149
150 /* Make sure this window should be shown and mapped to host-screen: */
151 if (!uisession()->isScreenVisible(m_uScreenId) ||
152 !pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
153 return;
154
155 /* Mark window 'transitioned to fullscreen': */
156 m_fIsInFullscreenTransition = true;
157
158 /* Enter native fullscreen mode if necessary: */
159 if ( (pFullscreenLogic->screensHaveSeparateSpaces() || m_uScreenId == 0)
160 && !darwinIsInFullscreenMode(this))
161 darwinToggleFullscreenMode(this);
162}
163
164void UIMachineWindowFullscreen::sltExitNativeFullscreen(UIMachineWindow *pMachineWindow)
165{
166 /* Make sure this slot is called only under ML and next: */
167 AssertReturnVoid(vboxGlobal().osRelease() > MacOSXRelease_Lion);
168
169 /* Make sure it is NULL or 'this' window passed: */
170 if (pMachineWindow && pMachineWindow != this)
171 return;
172
173 /* Make sure this window has fullscreen logic: */
174 UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
175 AssertPtrReturnVoid(pFullscreenLogic);
176
177 /* Mark window 'transitioned from fullscreen': */
178 m_fIsInFullscreenTransition = true;
179
180 /* Exit native fullscreen mode if necessary: */
181 if ( (pFullscreenLogic->screensHaveSeparateSpaces() || m_uScreenId == 0)
182 && darwinIsInFullscreenMode(this))
183 darwinToggleFullscreenMode(this);
184}
185#endif /* Q_WS_MAC */
186
187void UIMachineWindowFullscreen::prepareVisualState()
188{
189 /* Call to base-class: */
190 UIMachineWindow::prepareVisualState();
191
192 /* The background has to go black: */
193 QPalette palette(centralWidget()->palette());
194 palette.setColor(centralWidget()->backgroundRole(), Qt::black);
195 centralWidget()->setPalette(palette);
196 centralWidget()->setAutoFillBackground(true);
197 setAutoFillBackground(true);
198
199#if defined(Q_WS_WIN) || defined(Q_WS_X11)
200 /* Prepare mini-toolbar: */
201 prepareMiniToolbar();
202#endif /* Q_WS_WIN || Q_WS_X11 */
203
204#ifdef Q_WS_MAC
205 /* Native fullscreen stuff on ML and next: */
206 if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
207 {
208 /* Make sure this window has fullscreen logic: */
209 UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
210 AssertPtrReturnVoid(pFullscreenLogic);
211 /* Enable fullscreen support for every screen which requires it: */
212 if (pFullscreenLogic->screensHaveSeparateSpaces() || m_uScreenId == 0)
213 darwinEnableFullscreenSupport(this);
214 /* Enable transience support for other screens: */
215 else
216 darwinEnableTransienceSupport(this);
217 /* Register to native fullscreen notifications: */
218 UICocoaApplication::instance()->registerToNotificationOfWindow("NSWindowWillEnterFullScreenNotification", this,
219 UIMachineWindow::handleNativeNotification);
220 UICocoaApplication::instance()->registerToNotificationOfWindow("NSWindowDidEnterFullScreenNotification", this,
221 UIMachineWindow::handleNativeNotification);
222 UICocoaApplication::instance()->registerToNotificationOfWindow("NSWindowWillExitFullScreenNotification", this,
223 UIMachineWindow::handleNativeNotification);
224 UICocoaApplication::instance()->registerToNotificationOfWindow("NSWindowDidExitFullScreenNotification", this,
225 UIMachineWindow::handleNativeNotification);
226 UICocoaApplication::instance()->registerToNotificationOfWindow("NSWindowDidFailToEnterFullScreenNotification", this,
227 UIMachineWindow::handleNativeNotification);
228 }
229#endif /* Q_WS_MAC */
230}
231
232#if defined(Q_WS_WIN) || defined(Q_WS_X11)
233void UIMachineWindowFullscreen::prepareMiniToolbar()
234{
235 /* Make sure mini-toolbar is not restricted: */
236 if (!gEDataManager->miniToolbarEnabled(vboxGlobal().managedVMUuid()))
237 return;
238
239 /* Create mini-toolbar: */
240 m_pMiniToolBar = new UIMiniToolBar(this,
241 GeometryType_Full,
242 gEDataManager->miniToolbarAlignment(vboxGlobal().managedVMUuid()),
243 gEDataManager->autoHideMiniToolbar(vboxGlobal().managedVMUuid()));
244 AssertPtrReturnVoid(m_pMiniToolBar);
245 {
246 /* Configure mini-toolbar: */
247 m_pMiniToolBar->addMenus(actionPool()->menus());
248 connect(m_pMiniToolBar, SIGNAL(sigMinimizeAction()),
249 this, SLOT(showMinimized()), Qt::QueuedConnection);
250 connect(m_pMiniToolBar, SIGNAL(sigExitAction()),
251 actionPool()->action(UIActionIndexRT_M_View_T_Fullscreen), SLOT(trigger()));
252 connect(m_pMiniToolBar, SIGNAL(sigCloseAction()),
253 actionPool()->action(UIActionIndex_M_Application_S_Close), SLOT(trigger()));
254 connect(m_pMiniToolBar, SIGNAL(sigNotifyAboutWindowActivationStolen()),
255 this, SLOT(sltRevokeWindowActivation()), Qt::QueuedConnection);
256# ifdef Q_WS_X11
257 // WORKAROUND:
258 // Due to Unity bug we want native full-screen flag to be set
259 // for mini-toolbar _before_ trying to show it in full-screen mode.
260 // That significantly improves of chances to have required geometry.
261 if (vboxGlobal().typeOfWindowManager() == X11WMType_Compiz)
262 vboxGlobal().setFullScreenFlag(m_pMiniToolBar);
263# endif /* Q_WS_X11 */
264 }
265}
266#endif /* Q_WS_WIN || Q_WS_X11 */
267
268#if defined(Q_WS_WIN) || defined(Q_WS_X11)
269void UIMachineWindowFullscreen::cleanupMiniToolbar()
270{
271 /* Make sure mini-toolbar was created: */
272 if (!m_pMiniToolBar)
273 return;
274
275 /* Save mini-toolbar settings: */
276 gEDataManager->setAutoHideMiniToolbar(m_pMiniToolBar->autoHide(), vboxGlobal().managedVMUuid());
277 /* Delete mini-toolbar: */
278 delete m_pMiniToolBar;
279 m_pMiniToolBar = 0;
280}
281#endif /* Q_WS_WIN || Q_WS_X11 */
282
283void UIMachineWindowFullscreen::cleanupVisualState()
284{
285#ifdef Q_WS_MAC
286 /* Native fullscreen stuff on ML and next: */
287 if (vboxGlobal().osRelease() > MacOSXRelease_Lion)
288 {
289 /* Unregister from native fullscreen notifications: */
290 UICocoaApplication::instance()->unregisterFromNotificationOfWindow("NSWindowWillEnterFullScreenNotification", this);
291 UICocoaApplication::instance()->unregisterFromNotificationOfWindow("NSWindowDidEnterFullScreenNotification", this);
292 UICocoaApplication::instance()->unregisterFromNotificationOfWindow("NSWindowWillExitFullScreenNotification", this);
293 UICocoaApplication::instance()->unregisterFromNotificationOfWindow("NSWindowDidExitFullScreenNotification", this);
294 UICocoaApplication::instance()->unregisterFromNotificationOfWindow("NSWindowDidFailToEnterFullScreenNotification", this);
295 }
296#endif /* Q_WS_MAC */
297
298#if defined(Q_WS_WIN) || defined(Q_WS_X11)
299 /* Cleanup mini-toolbar: */
300 cleanupMiniToolbar();
301#endif /* Q_WS_WIN || Q_WS_X11 */
302
303 /* Call to base-class: */
304 UIMachineWindow::cleanupVisualState();
305}
306
307void UIMachineWindowFullscreen::placeOnScreen()
308{
309 /* Get corresponding host-screen: */
310 const int iHostScreen = qobject_cast<UIMachineLogicFullscreen*>(machineLogic())->hostScreenForGuestScreen(m_uScreenId);
311 /* And corresponding working area: */
312 const QRect workingArea = QApplication::desktop()->screenGeometry(iHostScreen);
313
314#if defined(Q_WS_WIN) || defined(Q_WS_X11)
315 /* Set appropriate geometry for window: */
316 move(workingArea.topLeft());
317 resize(workingArea.size());
318
319 /* If there is a mini-toolbar: */
320 if (m_pMiniToolBar)
321 {
322 /* Set appropriate geometry for mini-toolbar: */
323 m_pMiniToolBar->move(workingArea.topLeft());
324 m_pMiniToolBar->resize(workingArea.size());
325 }
326#elif defined(Q_WS_MAC)
327 /* Make sure this window has fullscreen logic: */
328 UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
329 AssertPtrReturnVoid(pFullscreenLogic);
330
331 /* Move window to the appropriate position: */
332 move(workingArea.topLeft());
333
334 /* Resize window to the appropriate size on Lion and previous: */
335 if (vboxGlobal().osRelease() <= MacOSXRelease_Lion)
336 resize(workingArea.size());
337 /* Resize window to the appropriate size on ML and next
338 * only if that screen has no own user-space: */
339 else if (!pFullscreenLogic->screensHaveSeparateSpaces() && m_uScreenId != 0)
340 resize(workingArea.size());
341 else
342 {
343 /* Load normal geometry first of all: */
344 QRect geo = gEDataManager->machineWindowGeometry(UIVisualStateType_Normal, m_uScreenId, vboxGlobal().managedVMUuid());
345 /* If normal geometry is null => use frame-buffer size: */
346 if (geo.isNull())
347 {
348 const UIFrameBuffer *pFrameBuffer = uisession()->frameBuffer(m_uScreenId);
349 geo = QRect(QPoint(0, 0), QSize(pFrameBuffer->width(), pFrameBuffer->height()).boundedTo(workingArea.size()));
350 }
351 /* If frame-buffer size is null => use default size: */
352 if (geo.isNull())
353 geo = QRect(QPoint(0, 0), QSize(800, 600).boundedTo(workingArea.size()));
354 /* Move window to the center of working-area: */
355 geo.moveCenter(workingArea.center());
356 setGeometry(geo);
357 }
358#endif /* Q_WS_MAC */
359}
360
361void UIMachineWindowFullscreen::showInNecessaryMode()
362{
363 /* Make sure window has fullscreen logic: */
364 UIMachineLogicFullscreen *pFullscreenLogic = qobject_cast<UIMachineLogicFullscreen*>(machineLogic());
365 AssertPtrReturnVoid(pFullscreenLogic);
366
367 /* Make sure window should be shown and mapped to some host-screen: */
368 if (!uisession()->isScreenVisible(m_uScreenId) ||
369 !pFullscreenLogic->hasHostScreenForGuestScreen(m_uScreenId))
370 {
371#if defined(Q_WS_WIN) || defined(Q_WS_X11)
372 /* If there is a mini-toolbar: */
373 if (m_pMiniToolBar)
374 {
375 /* Hide mini-toolbar: */
376 m_pMiniToolBar->hide();
377 }
378#endif /* Q_WS_WIN || Q_WS_X11 */
379
380 /* Hide window: */
381 hide();
382 }
383 else
384 {
385 /* Ignore if window minimized: */
386 if (isMinimized())
387 return;
388
389#ifdef Q_WS_X11
390 /* If WM doesn't support native stuff, we need to call for placeOnScreen(): */
391 const bool fSupportsNativeFullScreen = VBoxGlobal::supportsFullScreenMonitorsProtocolX11() &&
392 !gEDataManager->legacyFullscreenModeRequested();
393 if (!fSupportsNativeFullScreen)
394 {
395 /* Make sure window have appropriate geometry: */
396 placeOnScreen();
397 }
398#else /* !Q_WS_X11 */
399 /* Make sure window have appropriate geometry: */
400 placeOnScreen();
401#endif /* !Q_WS_X11 */
402
403#if defined(Q_WS_MAC)
404 /* ML and next using native stuff, so we can call for simple show(),
405 * Lion and previous using Qt stuff, so we should call for showFullScreen(): */
406 const bool fSupportsNativeFullScreen = vboxGlobal().osRelease() > MacOSXRelease_Lion;
407 if (fSupportsNativeFullScreen)
408 {
409 /* Show window in normal mode: */
410 show();
411 }
412 else
413 {
414 /* Show window in fullscreen mode: */
415 showFullScreen();
416 }
417#elif defined(Q_WS_WIN) || defined(Q_WS_X11)
418 /* Show window in fullscreen mode: */
419 showFullScreen();
420
421 /* If there is a mini-toolbar: */
422 if (m_pMiniToolBar)
423 {
424 /* Show mini-toolbar in full-screen mode: */
425 m_pMiniToolBar->showFullScreen();
426 }
427#endif /* Q_WS_WIN || Q_WS_X11 */
428
429#ifdef Q_WS_X11
430 /* If WM supports native stuff, we need to map window to corresponding host-screen. */
431 if (fSupportsNativeFullScreen)
432 {
433 /* Tell recent window managers which host-screen this window should be mapped to: */
434 VBoxGlobal::setFullScreenMonitorX11(this, pFullscreenLogic->hostScreenForGuestScreen(m_uScreenId));
435
436 /* If there is a mini-toolbar: */
437 if (m_pMiniToolBar)
438 {
439 /* Tell recent window managers which host-screen this mini-toolbar should be mapped to: */
440 VBoxGlobal::setFullScreenMonitorX11(m_pMiniToolBar, pFullscreenLogic->hostScreenForGuestScreen(m_uScreenId));
441 }
442 }
443#endif /* Q_WS_X11 */
444
445 /* Adjust machine-view size if necessary: */
446 adjustMachineViewSize();
447
448 /* Make sure machine-view have focus: */
449 m_pMachineView->setFocus();
450 }
451}
452
453#if defined(Q_WS_WIN) || defined(Q_WS_X11)
454void UIMachineWindowFullscreen::updateAppearanceOf(int iElement)
455{
456 /* Call to base-class: */
457 UIMachineWindow::updateAppearanceOf(iElement);
458
459 /* Update mini-toolbar: */
460 if (iElement & UIVisualElement_MiniToolBar)
461 {
462 /* If there is a mini-toolbar: */
463 if (m_pMiniToolBar)
464 {
465 /* Get snapshot(s): */
466 QString strSnapshotName;
467 if (machine().GetSnapshotCount() > 0)
468 {
469 CSnapshot snapshot = machine().GetCurrentSnapshot();
470 strSnapshotName = " (" + snapshot.GetName() + ")";
471 }
472 /* Update mini-toolbar text: */
473 m_pMiniToolBar->setText(machineName() + strSnapshotName);
474 }
475 }
476}
477#endif /* Q_WS_WIN || Q_WS_X11 */
478
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