VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

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