VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp@ 98859

Last change on this file since 98859 was 98859, checked in by vboxsync, 15 months ago

FE/Qt: bugref:10322: Runtime UI: A bit of includes cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
Line 
1/* $Id: UIMachineViewNormal.cpp 98859 2023-03-07 13:31:06Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineViewNormal class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QApplication>
30#include <QMainWindow>
31#include <QMenuBar>
32#include <QScrollBar>
33#include <QTimer>
34
35/* GUI includes: */
36#include "UIActionPoolRuntime.h"
37#include "UIDesktopWidgetWatchdog.h"
38#include "UIExtraDataManager.h"
39#include "UIFrameBuffer.h"
40#include "UIMachine.h"
41#include "UIMachineLogic.h"
42#include "UIMachineViewNormal.h"
43#include "UIMachineWindow.h"
44
45/* Other VBox includes: */
46#include "VBox/log.h"
47
48
49UIMachineViewNormal::UIMachineViewNormal(UIMachineWindow *pMachineWindow, ulong uScreenId)
50 : UIMachineView(pMachineWindow, uScreenId)
51 , m_fGuestAutoresizeEnabled(actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize)->isChecked())
52{
53}
54
55void UIMachineViewNormal::sltAdditionsStateChanged()
56{
57 adjustGuestScreenSize();
58}
59
60bool UIMachineViewNormal::eventFilter(QObject *pWatched, QEvent *pEvent)
61{
62 if (pWatched != 0 && pWatched == machineWindow())
63 {
64 switch (pEvent->type())
65 {
66 case QEvent::Resize:
67 {
68 /* Recalculate maximum guest size: */
69 setMaximumGuestSize();
70 /* And resize guest to current window size: */
71 if (m_fGuestAutoresizeEnabled && uimachine()->isGuestSupportsGraphics())
72 QTimer::singleShot(300, this, SLOT(sltPerformGuestResize()));
73 break;
74 }
75 default:
76 break;
77 }
78 }
79
80 /* For scroll-bars of the machine-view: */
81 if ( pWatched == verticalScrollBar()
82 || pWatched == horizontalScrollBar())
83 {
84 switch (pEvent->type())
85 {
86 /* On show/hide event: */
87 case QEvent::Show:
88 case QEvent::Hide:
89 {
90 /* Set maximum-size to size-hint: */
91 setMaximumSize(sizeHint());
92 break;
93 }
94 default:
95 break;
96 }
97 }
98
99 return UIMachineView::eventFilter(pWatched, pEvent);
100}
101
102void UIMachineViewNormal::prepareCommon()
103{
104 /* Base class common settings: */
105 UIMachineView::prepareCommon();
106
107 /* Setup size-policy: */
108 setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum));
109 /* Set maximum-size to size-hint: */
110 setMaximumSize(sizeHint());
111}
112
113void UIMachineViewNormal::prepareFilters()
114{
115 /* Base class filters: */
116 UIMachineView::prepareFilters();
117
118 /* Install scroll-bars event-filters: */
119 verticalScrollBar()->installEventFilter(this);
120 horizontalScrollBar()->installEventFilter(this);
121
122#ifdef VBOX_WS_WIN
123 /* Install menu-bar event-filter: */
124 machineWindow()->menuBar()->installEventFilter(this);
125#endif /* VBOX_WS_WIN */
126}
127
128void UIMachineViewNormal::prepareConsoleConnections()
129{
130 /* Base class connections: */
131 UIMachineView::prepareConsoleConnections();
132
133 /* Guest additions state-change updater: */
134 connect(uimachine(), &UIMachine::sigAdditionsStateActualChange, this, &UIMachineViewNormal::sltAdditionsStateChanged);
135}
136
137void UIMachineViewNormal::setGuestAutoresizeEnabled(bool fEnabled)
138{
139 if (m_fGuestAutoresizeEnabled != fEnabled)
140 {
141 m_fGuestAutoresizeEnabled = fEnabled;
142
143 if (m_fGuestAutoresizeEnabled && uimachine()->isGuestSupportsGraphics())
144 sltPerformGuestResize();
145 }
146}
147
148void UIMachineViewNormal::resendSizeHint()
149{
150 /* Skip if VM isn't running/paused yet: */
151 if ( !uimachine()->isRunning()
152 && !uimachine()->isPaused())
153 return;
154
155 /* Skip if another visual representation mode requested: */
156 if (uimachine()->requestedVisualState() == UIVisualStateType_Seamless) // Seamless only for now.
157 return;
158
159 /* Get the last guest-screen size-hint, taking the scale factor into account. */
160 const QSize storedSizeHint = storedGuestScreenSizeHint();
161 const QSize effectiveSizeHint = scaledBackward(storedSizeHint);
162 LogRel(("GUI: UIMachineViewNormal::resendSizeHint: Restoring guest size-hint for screen %d to %dx%d\n",
163 (int)screenId(), effectiveSizeHint.width(), effectiveSizeHint.height()));
164
165 /* Expand current limitations: */
166 setMaximumGuestSize(effectiveSizeHint);
167
168 /* Temporarily restrict the size to prevent a brief resize to the
169 * frame-buffer dimensions when we exit full-screen. This is only
170 * applied if the frame-buffer is at full-screen dimensions and
171 * until the first machine view resize. */
172 m_sizeHintOverride = scaledForward(QSize(640, 480)).expandedTo(storedSizeHint);
173
174 /* Restore saved monitor information to the guest. The guest may not respond
175 * until a suitable driver or helper is enabled (or at all). We do not notify
176 * the guest (aNotify == false), because there is technically no change (same
177 * hardware as before shutdown), and notifying would interfere with the Windows
178 * guest driver which saves the video mode to the registry on shutdown. */
179 uimachine()->setScreenVisibleHostDesires(screenId(), guestScreenVisibilityStatus());
180 uimachine()->setVideoModeHint(screenId(),
181 guestScreenVisibilityStatus(),
182 false /* change origin? */,
183 0 /* origin x */, 0 /* origin y */,
184 effectiveSizeHint.width(), effectiveSizeHint.height(),
185 0 /* bits per pixel */,
186 false /* notify? */);
187}
188
189void UIMachineViewNormal::adjustGuestScreenSize()
190{
191 LogRel(("GUI: UIMachineViewNormal::adjustGuestScreenSize: Adjust guest-screen size if necessary\n"));
192
193 /* Acquire requested guest-screen size-hint or at least actual frame-buffer size: */
194 QSize guestScreenSizeHint = requestedGuestScreenSizeHint();
195 /* Take the scale-factor(s) into account: */
196 guestScreenSizeHint = scaledForward(guestScreenSizeHint);
197
198 /* Calculate maximum possible guest screen size: */
199 const QSize maximumGuestScreenSize = calculateMaxGuestSize();
200
201 /* Adjust guest-screen size if the requested one is too big for the screen: */
202 if ( guestScreenSizeHint.width() > maximumGuestScreenSize.width()
203 || guestScreenSizeHint.height() > maximumGuestScreenSize.height())
204 sltPerformGuestResize(machineWindow()->centralWidget()->size());
205}
206
207QSize UIMachineViewNormal::sizeHint() const
208{
209 /* Call to base-class: */
210 QSize size = UIMachineView::sizeHint();
211
212 /* If guest-screen auto-resize is not enabled
213 * or the guest-additions doesn't support graphics
214 * we should take scroll-bars size-hints into account: */
215 if (!m_fGuestAutoresizeEnabled || !uimachine()->isGuestSupportsGraphics())
216 {
217 if (verticalScrollBar()->isVisible())
218 size += QSize(verticalScrollBar()->sizeHint().width(), 0);
219 if (horizontalScrollBar()->isVisible())
220 size += QSize(0, horizontalScrollBar()->sizeHint().height());
221 }
222
223 /* Return resulting size-hint finally: */
224 return size;
225}
226
227QRect UIMachineViewNormal::workingArea() const
228{
229 return gpDesktop->availableGeometry(this);
230}
231
232QSize UIMachineViewNormal::calculateMaxGuestSize() const
233{
234 /* 1) The calculation below is not reliable on some (X11) platforms until we
235 * have been visible for a fraction of a second, so do the best we can
236 * otherwise.
237 * 2) We also get called early before "machineWindow" has been fully
238 * initialised, at which time we can't perform the calculation. */
239 if (!isVisible())
240 return workingArea().size() * 0.95;
241 /* The area taken up by the machine window on the desktop, including window
242 * frame, title, menu bar and status bar. */
243 QSize windowSize = machineWindow()->frameGeometry().size();
244 /* The window shouldn't be allowed to expand beyond the working area
245 * unless it already does. In that case the guest shouldn't expand it
246 * any further though. */
247 QSize maximumSize = workingArea().size().expandedTo(windowSize);
248 /* The current size of the machine display. */
249 QSize centralWidgetSize = machineWindow()->centralWidget()->size();
250 /* To work out how big the guest display can get without the window going
251 * over the maximum size we calculated above, we work out how much space
252 * the other parts of the window (frame, menu bar, status bar and so on)
253 * take up and subtract that space from the maximum window size. The
254 * central widget shouldn't be bigger than the window, but we bound it for
255 * sanity (or insanity) reasons. */
256 return maximumSize - (windowSize - centralWidgetSize.boundedTo(windowSize));
257}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use