VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp@ 104158

Last change on this file since 104158 was 103538, checked in by vboxsync, 9 months ago

FE/Qt: Moving out logging stuff from UIDefs.h to separate UILoggingDefs.h; This breaks dependency of UIDefs/UICommon headers from VBox/log.h

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.5 KB
Line 
1/* $Id: UIMachineWindow.cpp 103538 2024-02-22 17:06:26Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMachineWindow 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 <QCloseEvent>
30#include <QGridLayout>
31#include <QProcess>
32#include <QStyle>
33#include <QTimer>
34
35/* GUI includes: */
36#include "UIActionPoolRuntime.h"
37#include "UICommon.h"
38#include "UIConverter.h"
39#include "UIModalWindowManager.h"
40#include "UIExtraDataManager.h"
41#include "UILoggingDefs.h"
42#include "UIMachine.h"
43#include "UIMessageCenter.h"
44#include "UIMachineLogic.h"
45#include "UIMachineWindow.h"
46#include "UIMachineWindowNormal.h"
47#include "UIMachineWindowFullscreen.h"
48#include "UIMachineWindowSeamless.h"
49#include "UIMachineWindowScale.h"
50#include "UIMachineView.h"
51#include "UIKeyboardHandler.h"
52#include "UIMouseHandler.h"
53#include "UIVMCloseDialog.h"
54
55/* COM includes: */
56#include "CGraphicsAdapter.h"
57#include "CSnapshot.h"
58
59/* Other VBox includes: */
60#include <VBox/version.h>
61#ifdef VBOX_BLEEDING_EDGE
62# include <iprt/buildconfig.h>
63#endif /* VBOX_BLEEDING_EDGE */
64
65
66/* static */
67UIMachineWindow* UIMachineWindow::create(UIMachineLogic *pMachineLogic, ulong uScreenId)
68{
69 /* Create machine-window: */
70 UIMachineWindow *pMachineWindow = 0;
71 switch (pMachineLogic->visualStateType())
72 {
73 case UIVisualStateType_Normal:
74 pMachineWindow = new UIMachineWindowNormal(pMachineLogic, uScreenId);
75 break;
76 case UIVisualStateType_Fullscreen:
77 pMachineWindow = new UIMachineWindowFullscreen(pMachineLogic, uScreenId);
78 break;
79 case UIVisualStateType_Seamless:
80 pMachineWindow = new UIMachineWindowSeamless(pMachineLogic, uScreenId);
81 break;
82 case UIVisualStateType_Scale:
83 pMachineWindow = new UIMachineWindowScale(pMachineLogic, uScreenId);
84 break;
85 default:
86 AssertMsgFailed(("Incorrect visual state!"));
87 break;
88 }
89 /* Prepare machine-window: */
90 pMachineWindow->prepare();
91 /* Return machine-window: */
92 return pMachineWindow;
93}
94
95/* static */
96void UIMachineWindow::destroy(UIMachineWindow *pWhichWindow)
97{
98 /* Cleanup machine-window: */
99 pWhichWindow->cleanup();
100 /* Delete machine-window: */
101 delete pWhichWindow;
102}
103
104void UIMachineWindow::prepare()
105{
106 /* Prepare dialog itself: */
107 prepareSelf();
108
109 /* Prepare session-connections: */
110 prepareSessionConnections();
111
112 /* Prepare main-layout: */
113 prepareMainLayout();
114
115 /* Prepare menu: */
116 prepareMenu();
117
118 /* Prepare status-bar: */
119 prepareStatusBar();
120
121 /* Prepare visual-state: */
122 prepareVisualState();
123
124 /* Prepare machine-view: */
125 prepareMachineView();
126
127 /* Prepare notification-center: */
128 prepareNotificationCenter();
129
130 /* Prepare handlers: */
131 prepareHandlers();
132
133 /* Load settings: */
134 loadSettings();
135
136 /* Retranslate window: */
137 retranslateUi();
138
139 /* Show (must be done before updating the appearance): */
140 showInNecessaryMode();
141
142 /* Update all the elements: */
143 updateAppearanceOf(UIVisualElement_AllStuff);
144
145#ifdef VBOX_WS_NIX
146 /* Prepare default class/name values: */
147 const QString strWindowClass = QString("VirtualBox Machine");
148 QString strWindowName = strWindowClass;
149 /* Check if we want Window Manager to distinguish Virtual Machine windows: */
150 if (gEDataManager->distinguishMachineWindowGroups(uiCommon().managedVMUuid()))
151 strWindowName = QString("VirtualBox Machine UUID: %1").arg(uiCommon().managedVMUuid().toString());
152 /* Assign WM_CLASS property: */
153 NativeWindowSubsystem::setWMClass(uiCommon().X11ServerAvailable(), this, strWindowName, strWindowClass);
154 /* Tell the WM we are well behaved wrt Xwayland keyboard-grabs: */
155 NativeWindowSubsystem::setXwaylandMayGrabKeyboardFlag(uiCommon().X11ServerAvailable(), this);
156#endif
157}
158
159void UIMachineWindow::cleanup()
160{
161 /* Save window settings: */
162 saveSettings();
163
164 /* Cleanup handlers: */
165 cleanupHandlers();
166
167 /* Cleanup visual-state: */
168 cleanupVisualState();
169
170 /* Cleanup notification-center: */
171 cleanupNotificationCenter();
172
173 /* Cleanup machine-view: */
174 cleanupMachineView();
175
176 /* Cleanup status-bar: */
177 cleanupStatusBar();
178
179 /* Cleanup menu: */
180 cleanupMenu();
181
182 /* Cleanup main layout: */
183 cleanupMainLayout();
184
185 /* Cleanup session connections: */
186 cleanupSessionConnections();
187}
188
189void UIMachineWindow::sltMachineStateChanged()
190{
191 /* Update window-title: */
192 updateAppearanceOf(UIVisualElement_WindowTitle);
193}
194
195UIMachineWindow::UIMachineWindow(UIMachineLogic *pMachineLogic, ulong uScreenId)
196 : QIWithRetranslateUI2<QMainWindow>(0, pMachineLogic->windowFlags(uScreenId))
197 , m_pMachineLogic(pMachineLogic)
198 , m_pMachineView(0)
199 , m_uScreenId(uScreenId)
200 , m_pMainLayout(0)
201 , m_pTopSpacer(0)
202 , m_pBottomSpacer(0)
203 , m_pLeftSpacer(0)
204 , m_pRightSpacer(0)
205{
206}
207
208UIMachine *UIMachineWindow::uimachine() const
209{
210 return machineLogic()->uimachine();
211}
212
213UIActionPool *UIMachineWindow::actionPool() const
214{
215 return machineLogic()->actionPool();
216}
217
218QString UIMachineWindow::machineName() const
219{
220 return uimachine()->machineName();
221}
222
223bool UIMachineWindow::shouldResizeToGuestDisplay() const
224{
225 return actionPool()
226 && actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize)
227 && actionPool()->action(UIActionIndexRT_M_View_T_GuestAutoresize)->isChecked();
228}
229
230void UIMachineWindow::adjustMachineViewSize()
231{
232 /* We need to adjust guest-screen size if necessary: */
233 machineView()->adjustGuestScreenSize();
234}
235
236void UIMachineWindow::sendMachineViewSizeHint()
237{
238 /* Send machine-view size-hint to the guest: */
239 machineView()->resendSizeHint();
240}
241
242#ifdef VBOX_WITH_MASKED_SEAMLESS
243void UIMachineWindow::setMask(const QRegion &region)
244{
245 /* Call to base-class: */
246 QMainWindow::setMask(region);
247}
248#endif /* VBOX_WITH_MASKED_SEAMLESS */
249
250void UIMachineWindow::updateAppearanceOf(int iElement)
251{
252 /* Update window title: */
253 if (iElement & UIVisualElement_WindowTitle)
254 {
255 /* Make sure machine state is one of valid: */
256 const KMachineState enmState = uimachine()->machineState();
257 if (enmState == KMachineState_Null)
258 {
259 /* Assign default window title: */
260 setWindowTitle(defaultWindowTitle());
261 }
262 else
263 {
264 /* Prepare full name: */
265 QString strMachineName = machineName();
266
267 /* Append snapshot name: */
268 ulong uSnapshotCount = 0;
269 uimachine()->acquireSnapshotCount(uSnapshotCount);
270 if (uSnapshotCount > 0)
271 {
272 QString strCurrentSnapshotName;
273 uimachine()->acquireCurrentSnapshotName(strCurrentSnapshotName);
274 strMachineName += " (" + strCurrentSnapshotName + ")";
275 }
276
277 /* Append state name: */
278 strMachineName += " [" + gpConverter->toString(enmState) + "]";
279
280#ifndef VBOX_WS_MAC
281 /* Append user product name (besides macOS): */
282 const QString strUserProductName = uimachine()->machineWindowNamePostfix();
283 strMachineName += " - " + (strUserProductName.isEmpty() ? defaultWindowTitle() : strUserProductName);
284#endif /* !VBOX_WS_MAC */
285
286 /* Append screen number only if there are more than one present: */
287 ulong cMonitorCount = 0;
288 uimachine()->acquireMonitorCount(cMonitorCount);
289 if (cMonitorCount > 1)
290 strMachineName += QString(" : %1").arg(m_uScreenId + 1);
291
292 /* Assign title finally: */
293 setWindowTitle(strMachineName);
294 }
295 }
296}
297
298void UIMachineWindow::retranslateUi()
299{
300 /* Compose window-title prefix: */
301 m_strWindowTitlePrefix = VBOX_PRODUCT;
302#ifdef VBOX_BLEEDING_EDGE
303 m_strWindowTitlePrefix += UIMachineWindow::tr(" EXPERIMENTAL build %1r%2 - %3")
304 .arg(RTBldCfgVersion())
305 .arg(RTBldCfgRevisionStr())
306 .arg(VBOX_BLEEDING_EDGE);
307#endif /* VBOX_BLEEDING_EDGE */
308 /* Update appearance of the window-title: */
309 updateAppearanceOf(UIVisualElement_WindowTitle);
310}
311
312bool UIMachineWindow::event(QEvent *pEvent)
313{
314 /* Call to base-class: */
315 const bool fResult = QIWithRetranslateUI2<QMainWindow>::event(pEvent);
316
317 /* Handle particular events: */
318 switch (pEvent->type())
319 {
320 case QEvent::WindowActivate:
321 {
322 /* Initiate registration in the modal window manager: */
323 windowManager().setMainWindowShown(this);
324 break;
325 }
326 default:
327 break;
328 }
329
330 /* Return result: */
331 return fResult;
332}
333
334void UIMachineWindow::showEvent(QShowEvent *pEvent)
335{
336 /* Call to base-class: */
337 QMainWindow::showEvent(pEvent);
338
339 /* Initiate registration in the modal window manager: */
340 windowManager().setMainWindowShown(this);
341
342 /* Update appearance for indicator-pool: */
343 updateAppearanceOf(UIVisualElement_IndicatorPool);
344}
345
346void UIMachineWindow::hideEvent(QHideEvent *pEvent)
347{
348 /* Update registration in the modal window manager: */
349 if (windowManager().mainWindowShown() == this)
350 {
351 if (machineLogic()->activeMachineWindow())
352 windowManager().setMainWindowShown(machineLogic()->activeMachineWindow());
353 else
354 windowManager().setMainWindowShown(machineLogic()->mainMachineWindow());
355 }
356
357 /* Call to base-class: */
358 QMainWindow::hideEvent(pEvent);
359}
360
361void UIMachineWindow::closeEvent(QCloseEvent *pCloseEvent)
362{
363 /* Always ignore close-event first: */
364 pCloseEvent->ignore();
365 /* But accept close-event if app quit was requested: */
366 if (uimachine()->isQuitRequested())
367 {
368 pCloseEvent->accept();
369 return;
370 }
371
372 /* In certain cases we need to just request app quit: */
373 if ( !uimachine()->isSessionValid()
374 || uimachine()->isTurnedOff())
375 {
376 uimachine()->closeRuntimeUI();
377 return;
378 }
379
380 /* Make sure machine is in one of the allowed states: */
381 if (!uimachine()->isRunning() && !uimachine()->isPaused() && !uimachine()->isStuck())
382 return;
383
384 /* If there is a close hook script defined: */
385 const QString strScript = gEDataManager->machineCloseHookScript(uiCommon().managedVMUuid());
386 if (!strScript.isEmpty())
387 {
388 /* Execute asynchronously and leave: */
389 QProcess::startDetached(strScript, QStringList() << uiCommon().managedVMUuid().toString());
390 return;
391 }
392
393 /* Choose the close action: */
394 MachineCloseAction closeAction = MachineCloseAction_Invalid;
395
396 /* If default close-action defined and not restricted: */
397 MachineCloseAction defaultCloseAction = uimachine()->defaultCloseAction();
398 MachineCloseAction restrictedCloseActions = uimachine()->restrictedCloseActions();
399 if ((defaultCloseAction != MachineCloseAction_Invalid) &&
400 !(restrictedCloseActions & defaultCloseAction))
401 {
402 switch (defaultCloseAction)
403 {
404 /* If VM is stuck, and the default close-action is 'detach', 'save-state' or 'shutdown',
405 * we should ask the user about what to do: */
406 case MachineCloseAction_Detach:
407 case MachineCloseAction_SaveState:
408 case MachineCloseAction_Shutdown:
409 closeAction = uimachine()->isStuck() ? MachineCloseAction_Invalid : defaultCloseAction;
410 break;
411 /* Otherwise we just use what we have: */
412 default:
413 closeAction = defaultCloseAction;
414 break;
415 }
416 }
417
418 /* If the close-action still undefined: */
419 if (closeAction == MachineCloseAction_Invalid)
420 {
421 /* Prepare close-dialog: */
422 QWidget *pParentDlg = windowManager().realParentWindow(this);
423 bool fInACPIMode = false;
424 uimachine()->acquireWhetherGuestEnteredACPIMode(fInACPIMode);
425 QPointer<UIVMCloseDialog> pCloseDlg = new UIVMCloseDialog(pParentDlg, uimachine(),
426 fInACPIMode,
427 restrictedCloseActions);
428 /* Configure close-dialog: */
429 if (uimachine()->machineWindowIcon())
430 pCloseDlg->setIcon(*uimachine()->machineWindowIcon());
431
432 /* Make sure close-dialog is valid: */
433 if (pCloseDlg->isValid())
434 {
435 /* We are going to show close-dialog: */
436 bool fShowCloseDialog = true;
437 /* Check if VM is paused or stuck: */
438 const bool fWasPaused = uimachine()->isPaused();
439 const bool fIsStuck = uimachine()->isStuck();
440 /* If VM is NOT paused and NOT stuck: */
441 if (!fWasPaused && !fIsStuck)
442 {
443 /* We should pause it first: */
444 const bool fIsPaused = uimachine()->pause();
445 /* If we were unable to pause VM: */
446 if (!fIsPaused)
447 {
448 /* If that is NOT the separate VM process UI: */
449 if (!uiCommon().isSeparateProcess())
450 {
451 /* We are not going to show close-dialog: */
452 fShowCloseDialog = false;
453 }
454 /* If that is the separate VM process UI: */
455 else
456 {
457 // WORKAROUND:
458 // We are going to show close-dialog only
459 // if headless frontend stopped/killed already:
460 KMachineState enmActualState = KMachineState_Null;
461 uimachine()->acquireLiveMachineState(enmActualState);
462 fShowCloseDialog = enmActualState == KMachineState_Null;
463 }
464 }
465 }
466 /* If we are going to show close-dialog: */
467 if (fShowCloseDialog)
468 {
469 /* Show close-dialog to let the user make the choice: */
470 windowManager().registerNewParent(pCloseDlg, pParentDlg);
471 closeAction = static_cast<MachineCloseAction>(pCloseDlg->exec());
472
473 /* Make sure the dialog still valid: */
474 if (!pCloseDlg)
475 return;
476
477 /* If VM was not paused before but paused now,
478 * we should resume it if user canceled dialog or chosen shutdown: */
479 if (!fWasPaused && uimachine()->isPaused() &&
480 (closeAction == MachineCloseAction_Invalid ||
481 closeAction == MachineCloseAction_Detach ||
482 closeAction == MachineCloseAction_Shutdown))
483 {
484 /* If we unable to resume VM, cancel closing: */
485 if (!uimachine()->unpause())
486 closeAction = MachineCloseAction_Invalid;
487 }
488 }
489 }
490 else
491 {
492 /* Else user misconfigured .vbox file, we will reject closing UI: */
493 closeAction = MachineCloseAction_Invalid;
494 }
495
496 /* Cleanup close-dialog: */
497 delete pCloseDlg;
498 }
499
500 /* Depending on chosen result: */
501 switch (closeAction)
502 {
503 case MachineCloseAction_Detach:
504 {
505 /* Detach GUI: */
506 LogRel(("GUI: Request for close-action to detach GUI.\n"));
507 uimachine()->detachUi();
508 break;
509 }
510 case MachineCloseAction_SaveState:
511 {
512 /* Save VM state: */
513 LogRel(("GUI: Request for close-action to save VM state.\n"));
514 uimachine()->saveState();
515 break;
516 }
517 case MachineCloseAction_Shutdown:
518 {
519 /* Shutdown VM: */
520 LogRel(("GUI: Request for close-action to shutdown VM.\n"));
521 uimachine()->shutdown();
522 break;
523 }
524 case MachineCloseAction_PowerOff:
525 case MachineCloseAction_PowerOff_RestoringSnapshot:
526 {
527 /* Power VM off: */
528 LogRel(("GUI: Request for close-action to power VM off.\n"));
529 ulong uSnapshotCount = 0;
530 uimachine()->acquireSnapshotCount(uSnapshotCount);
531 const bool fDiscardStateOnPowerOff = gEDataManager->discardStateOnPowerOff(uiCommon().managedVMUuid())
532 || closeAction == MachineCloseAction_PowerOff_RestoringSnapshot;
533 uimachine()->powerOff(uSnapshotCount > 0 && fDiscardStateOnPowerOff);
534 break;
535 }
536 default:
537 break;
538 }
539}
540
541void UIMachineWindow::prepareSelf()
542{
543#ifndef VBOX_WS_MAC
544 /* Set machine-window icon if any: */
545 // On macOS window icon is referenced in info.plist.
546 if (uimachine()->machineWindowIcon())
547 setWindowIcon(*uimachine()->machineWindowIcon());
548#endif /* !VBOX_WS_MAC */
549}
550
551void UIMachineWindow::prepareSessionConnections()
552{
553 /* We should watch for console events: */
554 connect(uimachine(), &UIMachine::sigMachineStateChange, this, &UIMachineWindow::sltMachineStateChanged);
555}
556
557void UIMachineWindow::prepareMainLayout()
558{
559 /* Create central-widget: */
560 setCentralWidget(new QWidget);
561
562 /* Create main-layout: */
563 m_pMainLayout = new QGridLayout(centralWidget());
564 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
565 m_pMainLayout->setSpacing(0);
566
567 /* Create shifting-spacers: */
568 m_pTopSpacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
569 m_pBottomSpacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
570 m_pLeftSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
571 m_pRightSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed);
572
573 /* Add shifting-spacers into main-layout: */
574 m_pMainLayout->addItem(m_pTopSpacer, 0, 1);
575 m_pMainLayout->addItem(m_pBottomSpacer, 2, 1);
576 m_pMainLayout->addItem(m_pLeftSpacer, 1, 0);
577 m_pMainLayout->addItem(m_pRightSpacer, 1, 2);
578}
579
580void UIMachineWindow::prepareMachineView()
581{
582 /* Get visual-state type: */
583 UIVisualStateType visualStateType = machineLogic()->visualStateType();
584
585 /* Create machine-view: */
586 m_pMachineView = UIMachineView::create(this, m_uScreenId, visualStateType);
587
588 /* Add machine-view into main-layout: */
589 m_pMainLayout->addWidget(m_pMachineView, 1, 1, viewAlignment(visualStateType));
590
591 /* Install focus-proxy: */
592 setFocusProxy(m_pMachineView);
593}
594
595void UIMachineWindow::prepareNotificationCenter()
596{
597 // for now it will be added from within particular visual mode windows ..
598}
599
600void UIMachineWindow::prepareHandlers()
601{
602 /* Register keyboard-handler: */
603 machineLogic()->keyboardHandler()->prepareListener(m_uScreenId, this);
604
605 /* Register mouse-handler: */
606 machineLogic()->mouseHandler()->prepareListener(m_uScreenId, this);
607}
608
609void UIMachineWindow::cleanupHandlers()
610{
611 /* Unregister mouse-handler: */
612 machineLogic()->mouseHandler()->cleanupListener(m_uScreenId);
613
614 /* Unregister keyboard-handler: */
615 machineLogic()->keyboardHandler()->cleanupListener(m_uScreenId);
616}
617
618void UIMachineWindow::cleanupNotificationCenter()
619{
620 // for now it will be removed from within particular visual mode windows ..
621}
622
623void UIMachineWindow::cleanupMachineView()
624{
625 /* Destroy machine-view: */
626 UIMachineView::destroy(m_pMachineView);
627 m_pMachineView = 0;
628}
629
630void UIMachineWindow::cleanupSessionConnections()
631{
632 /* We should stop watching for console events: */
633 disconnect(uimachine(), &UIMachine::sigMachineStateChange, this, &UIMachineWindow::sltMachineStateChanged);
634}
635
636#ifdef VBOX_WITH_DEBUGGER_GUI
637void UIMachineWindow::updateDbgWindows()
638{
639 /* The debugger windows are bind to the main VM window. */
640 if (m_uScreenId == 0)
641 uimachine()->dbgAdjustRelativePos();
642}
643#endif /* VBOX_WITH_DEBUGGER_GUI */
644
645/* static */
646Qt::Alignment UIMachineWindow::viewAlignment(UIVisualStateType visualStateType)
647{
648 switch (visualStateType)
649 {
650 case UIVisualStateType_Normal: return Qt::Alignment();
651 case UIVisualStateType_Fullscreen: return Qt::AlignVCenter | Qt::AlignHCenter;
652 case UIVisualStateType_Seamless: return Qt::Alignment();
653 case UIVisualStateType_Scale: return Qt::Alignment();
654 case UIVisualStateType_Invalid: case UIVisualStateType_All: break; /* Shut up, MSC! */
655 }
656 AssertMsgFailed(("Incorrect visual state!"));
657 return Qt::Alignment();
658}
659
660#ifdef VBOX_WS_MAC
661void UIMachineWindow::handleStandardWindowButtonCallback(StandardWindowButtonType enmButtonType, bool fWithOptionKey)
662{
663 switch (enmButtonType)
664 {
665 case StandardWindowButtonType_Zoom:
666 {
667 /* Handle 'Zoom' button for 'Normal' and 'Scaled' modes: */
668 if ( machineLogic()->visualStateType() == UIVisualStateType_Normal
669 || machineLogic()->visualStateType() == UIVisualStateType_Scale)
670 {
671 if (fWithOptionKey)
672 {
673 /* Toggle window zoom: */
674 darwinToggleWindowZoom(this);
675 }
676 else
677 {
678 /* Enter 'full-screen' mode: */
679 uimachine()->setRequestedVisualState(UIVisualStateType_Invalid);
680 uimachine()->asyncChangeVisualState(UIVisualStateType_Fullscreen);
681 }
682 }
683 break;
684 }
685 default:
686 break;
687 }
688}
689
690/* static */
691void UIMachineWindow::handleNativeNotification(const QString &strNativeNotificationName, QWidget *pWidget)
692{
693 /* Handle arrived notification: */
694 LogRel(("GUI: UIMachineWindow::handleNativeNotification: Notification '%s' received\n",
695 strNativeNotificationName.toLatin1().constData()));
696 AssertPtrReturnVoid(pWidget);
697 if (UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(pWidget))
698 {
699 /* Redirect arrived notification: */
700 LogRel2(("UIMachineWindow::handleNativeNotification: Redirecting '%s' notification to corresponding machine-window...\n",
701 strNativeNotificationName.toLatin1().constData()));
702 pMachineWindow->handleNativeNotification(strNativeNotificationName);
703 }
704}
705
706/* static */
707void UIMachineWindow::handleStandardWindowButtonCallback(StandardWindowButtonType enmButtonType, bool fWithOptionKey, QWidget *pWidget)
708{
709 /* Handle arrived callback: */
710 LogRel(("GUI: UIMachineWindow::handleStandardWindowButtonCallback: Callback for standard window button '%d' with option key '%d' received\n",
711 (int)enmButtonType, (int)fWithOptionKey));
712 AssertPtrReturnVoid(pWidget);
713 if (UIMachineWindow *pMachineWindow = qobject_cast<UIMachineWindow*>(pWidget))
714 {
715 /* Redirect arrived callback: */
716 LogRel2(("UIMachineWindow::handleStandardWindowButtonCallback: Redirecting callback for standard window button '%d' with option key '%d' to corresponding machine-window...\n",
717 (int)enmButtonType, (int)fWithOptionKey));
718 pMachineWindow->handleStandardWindowButtonCallback(enmButtonType, fWithOptionKey);
719 }
720}
721#endif /* VBOX_WS_MAC */
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