- Timestamp:
- Feb 26, 2010 11:56:51 PM (15 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/runtime
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp
r26823 r26878 184 184 return E_POINTER; 185 185 *pbSupported = TRUE; 186 Q Rectscreen = m_pMachineView->desktopGeometry();186 QSize screen = m_pMachineView->desktopGeometry(); 187 187 if ((screen.width() != 0) && (uWidth > (ULONG)screen.width())) 188 188 *pbSupported = FALSE; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.cpp
r26862 r26878 148 148 } 149 149 150 void UIMachineView::destroy(UIMachineView *pWhichView) 151 { 152 delete pWhichView; 153 } 154 150 155 int UIMachineView::keyboardState() const 151 156 { … … 197 202 , m_bIsHostkeyAlone (false) 198 203 , m_bIsHostkeyInCapture(false) 199 , m_bIsMachineWindowResizeIgnored( true)204 , m_bIsMachineWindowResizeIgnored(false) 200 205 , m_bIsFrameBufferResizeIgnored(false) 201 206 , m_fPassCAD(false) 202 207 #ifdef VBOX_WITH_VIDEOHWACCEL 203 208 , m_fAccelerate2DVideo(bAccelerate2DVideo) 204 #endif205 #if 0 // TODO: Do we need this?206 , mDoResize(false)207 209 #endif 208 210 #if defined(Q_WS_MAC) … … 214 216 , mDockIconEnabled(true) 215 217 #endif 216 , m_desktopGeometryType(DesktopGeo_Invalid)217 /* Don't show a hardware pointer until we have one to show */218 218 { 219 219 } … … 277 277 } 278 278 279 QRect UIMachineView::desktopGeometry() const 280 { 281 QRect geometry; 282 switch (m_desktopGeometryType) 283 { 284 case DesktopGeo_Fixed: 285 case DesktopGeo_Automatic: 286 geometry = QRect(0, 0, 287 qMax(m_desktopGeometry.width(), m_storedConsoleSize.width()), 288 qMax(m_desktopGeometry.height(), m_storedConsoleSize.height())); 289 break; 290 case DesktopGeo_Any: 291 geometry = QRect(0, 0, 0, 0); 292 break; 293 default: 294 AssertMsgFailed(("Bad geometry type %d!\n", m_desktopGeometryType)); 295 } 296 return geometry; 297 } 298 299 void UIMachineView::calculateDesktopGeometry() 300 { 301 /* This method should not get called until we have initially set up the m_desktopGeometryType: */ 302 Assert((m_desktopGeometryType != DesktopGeo_Invalid)); 303 /* If we are not doing automatic geometry calculation then there is nothing to do: */ 304 if (DesktopGeo_Automatic == m_desktopGeometryType) 305 { 306 /* Available geometry of the desktop. If the desktop is a single 307 * screen, this will exclude space taken up by desktop taskbars 308 * and things, but this is unfortunately not true for the more 309 * complex case of a desktop spanning multiple screens: */ 310 QRect desktop = availableGeometry(); 311 /* The area taken up by the machine window on the desktop, 312 * including window frame, title and menu bar and whatnot: */ 313 QRect frame = machineWindowWrapper()->machineWindow()->frameGeometry(); 314 /* The area taken up by the machine view, so excluding all decorations: */ 315 QRect window = geometry(); 316 /* To work out how big we can make the console window while still 317 * fitting on the desktop, we calculate desktop - frame + window. 318 * This works because the difference between frame and window 319 * (or at least its width and height) is a constant. */ 320 m_desktopGeometry = QRect(0, 0, desktop.width() - frame.width() + window.width(), 321 desktop.height() - frame.height() + window.height()); 322 } 323 } 324 325 void UIMachineView::setDesktopGeometry(DesktopGeo geometry, int aWidth, int aHeight) 326 { 327 switch (geometry) 328 { 329 case DesktopGeo_Fixed: 330 m_desktopGeometryType = DesktopGeo_Fixed; 331 if (aWidth != 0 && aHeight != 0) 332 m_desktopGeometry = QRect(0, 0, aWidth, aHeight); 333 else 334 m_desktopGeometry = QRect(0, 0, 0, 0); 335 storeConsoleSize(0, 0); 336 break; 337 case DesktopGeo_Automatic: 338 m_desktopGeometryType = DesktopGeo_Automatic; 339 m_desktopGeometry = QRect(0, 0, 0, 0); 340 storeConsoleSize(0, 0); 341 break; 342 case DesktopGeo_Any: 343 m_desktopGeometryType = DesktopGeo_Any; 344 m_desktopGeometry = QRect(0, 0, 0, 0); 345 break; 346 default: 347 AssertMsgFailed(("Invalid desktop geometry type %d\n", geometry)); 348 m_desktopGeometryType = DesktopGeo_Invalid; 349 } 350 } 351 352 void UIMachineView::storeConsoleSize(int aWidth, int aHeight) 353 { 354 LogFlowThisFunc(("aWidth=%d, aHeight=%d\n", aWidth, aHeight)); 355 m_storedConsoleSize = QRect(0, 0, aWidth, aHeight); 356 } 357 358 QRect UIMachineView::availableGeometry() 359 { 360 return machineWindowWrapper()->machineWindow()->isFullScreen() ? 361 QApplication::desktop()->screenGeometry(this) : 362 QApplication::desktop()->availableGeometry(this); 279 void UIMachineView::updateMouseClipping() 280 { 281 if (uisession()->isMouseCaptured()) 282 { 283 viewport()->setCursor(QCursor(Qt::BlankCursor)); 284 #ifdef Q_WS_WIN32 285 QRect r = viewport()->rect(); 286 r.moveTopLeft(viewport()->mapToGlobal(QPoint (0, 0))); 287 RECT rect = { r.left(), r.top(), r.right() + 1, r.bottom() + 1 }; 288 ::ClipCursor(&rect); 289 #endif 290 } 291 else 292 { 293 #ifdef Q_WS_WIN32 294 ::ClipCursor(NULL); 295 #endif 296 /* return the cursor to where it was when we captured it and show it */ 297 QCursor::setPos(m_capturedMousePos); 298 viewport()->unsetCursor(); 299 } 300 } 301 302 void UIMachineView::updateSliders() 303 { 304 QSize p = viewport()->size(); 305 QSize m = maximumViewportSize(); 306 307 QSize v = QSize(m_pFrameBuffer->width(), m_pFrameBuffer->height()); 308 /* no scroll bars needed */ 309 if (m.expandedTo(v) == m) 310 p = m; 311 312 horizontalScrollBar()->setRange(0, v.width() - p.width()); 313 verticalScrollBar()->setRange(0, v.height() - p.height()); 314 horizontalScrollBar()->setPageStep(p.width()); 315 verticalScrollBar()->setPageStep(p.height()); 363 316 } 364 317 … … 543 496 void UIMachineView::prepareConsoleConnections() 544 497 { 545 /* UISession notifier: */546 UISession *sender = machineWindowWrapper()->machineLogic()->uisession();547 548 498 /* Machine state-change updater: */ 549 connect(sender, SIGNAL(sigMachineStateChange()), this, SLOT(sltMachineStateChanged())); 550 551 /* Guest additions state-change updater: */ 552 connect(sender, SIGNAL(sigAdditionsStateChange()), this, SLOT(sltAdditionsStateChanged())); 499 connect(uisession(), SIGNAL(sigMachineStateChange()), this, SLOT(sltMachineStateChanged())); 553 500 554 501 /* Mouse pointer shape state-change updater: */ 555 connect( sender, SIGNAL(sigMousePointerShapeChange()), this, SLOT(sltMousePointerShapeChanged()));502 connect(uisession(), SIGNAL(sigMousePointerShapeChange()), this, SLOT(sltMousePointerShapeChanged())); 556 503 557 504 /* Mouse capability state-change updater: */ 558 connect( sender, SIGNAL(sigMouseCapabilityChange()), this, SLOT(sltMouseCapabilityChanged()));505 connect(uisession(), SIGNAL(sigMouseCapabilityChange()), this, SLOT(sltMouseCapabilityChanged())); 559 506 } 560 507 … … 563 510 /* Global settings: */ 564 511 { 565 /* Remember the desktop geometry and register for geometry566 * change events for telling the guest about video modes we like: */567 QString desktopGeometry = vboxGlobal().settings().publicProperty("GUI/MaxGuestResolution");568 if ((desktopGeometry == QString::null) || (desktopGeometry == "auto"))569 setDesktopGeometry(DesktopGeo_Automatic, 0, 0);570 else if (desktopGeometry == "any")571 setDesktopGeometry(DesktopGeo_Any, 0, 0);572 else573 {574 int width = desktopGeometry.section(',', 0, 0).toInt();575 int height = desktopGeometry.section(',', 1, 1).toInt();576 setDesktopGeometry(DesktopGeo_Fixed, width, height);577 }578 connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(sltDesktopResized()));579 580 512 #ifdef Q_WS_X11 581 513 /* Initialize the X keyboard subsystem: */ … … 644 576 } 645 577 646 void UIMachineView::sltMachineStateChanged()647 {648 /* Get machine state: */649 KMachineState state = uisession()->machineState();650 switch (state)651 {652 case KMachineState_Paused:653 case KMachineState_TeleportingPausedVM:654 {655 if (mode() != VBoxDefs::TimerMode && m_pFrameBuffer &&656 (state != KMachineState_TeleportingPausedVM || m_previousState != KMachineState_Teleporting))657 {658 /* Take a screen snapshot. Note that TakeScreenShot() always needs a 32bpp image: */659 QImage shot = QImage(m_pFrameBuffer->width(), m_pFrameBuffer->height(), QImage::Format_RGB32);660 CDisplay dsp = session().GetConsole().GetDisplay();661 dsp.TakeScreenShot(shot.bits(), shot.width(), shot.height());662 /* TakeScreenShot() may fail if, e.g. the Paused notification was delivered663 * after the machine execution was resumed. It's not fatal: */664 if (dsp.isOk())665 {666 dimImage(shot);667 m_pauseShot = QPixmap::fromImage(shot);668 /* Fully repaint to pick up m_pauseShot: */669 repaint();670 }671 }672 }673 case KMachineState_Stuck:674 {675 /* Reuse the focus event handler to uncapture everything: */676 if (hasFocus())677 focusEvent(false /* aHasFocus*/, false /* aReleaseHostKey */);678 break;679 }680 case KMachineState_Running:681 {682 if (m_previousState == KMachineState_Paused || m_previousState == KMachineState_TeleportingPausedVM)683 {684 if (mode() != VBoxDefs::TimerMode && m_pFrameBuffer)685 {686 /* Reset the pixmap to free memory: */687 m_pauseShot = QPixmap();688 /* Ask for full guest display update (it will also update689 * the viewport through IFramebuffer::NotifyUpdate): */690 CDisplay dsp = session().GetConsole().GetDisplay();691 dsp.InvalidateAndUpdate();692 }693 }694 /* Reuse the focus event handler to capture input: */695 if (hasFocus())696 focusEvent(true /* aHasFocus */);697 break;698 }699 default:700 break;701 }702 703 #ifdef Q_WS_MAC704 /* Update Dock Overlay: */705 updateDockOverlay();706 #endif /* Q_WS_MAC */707 708 m_previousState = state;709 }710 711 void UIMachineView::sltAdditionsStateChanged()712 {713 /* Check if we should restrict minimum size: */714 maybeRestrictMinimumSize();715 716 #if 0 // TODO: Do we need this?717 if (!mDoResize && !isGuestSupportsGraphics() && fIsGuestSupportsGraphics &&718 (machineWindowWrapper()->isTrueSeamless() || machineWindowWrapper()->isTrueFullscreen()))719 mDoResize = true;720 /* This will only be acted upon if mDoResize is true: */721 sltPerformGuestResize();722 #endif723 }724 725 void UIMachineView::sltMousePointerShapeChanged()726 {727 if (uisession()->isMouseSupportsAbsolute())728 {729 /* Should we hide/show pointer? */730 if (uisession()->isHidingHostPointer())731 viewport()->setCursor(Qt::BlankCursor);732 else733 viewport()->setCursor(uisession()->cursor());734 }735 }736 737 void UIMachineView::sltMouseCapabilityChanged()738 {739 /* Correct the mouse capture state and reset the cursor to the default shape if necessary: */740 if (uisession()->isMouseSupportsAbsolute())741 {742 CMouse mouse = session().GetConsole().GetMouse();743 mouse.PutMouseEventAbsolute(-1, -1, 0, 0, 0);744 captureMouse(false, false);745 }746 else747 viewport()->unsetCursor();748 749 /* Notify user about mouse integration state: */750 vboxProblem().remindAboutMouseIntegration(uisession()->isMouseSupportsAbsolute());751 752 /* Notify all listeners: */753 emitMouseStateChanged();754 }755 756 /* If the desktop geometry is set automatically, this will update it: */757 void UIMachineView::sltDesktopResized()758 {759 calculateDesktopGeometry();760 }761 762 #ifdef Q_WS_MAC763 void UIMachineView::sltChangeDockIconUpdate(const VBoxChangeDockIconUpdateEvent &event)764 {765 setDockIconEnabled(event.mChanged);766 updateDockOverlay();767 }768 769 # ifdef QT_MAC_USE_COCOA770 void UIMachineView::sltChangePresentationMode(const VBoxChangePresentationModeEvent &event)771 {772 // TODO_NEW_CORE773 // this is full screen related774 #if 0775 if (mIsFullscreen)776 {777 /* First check if we are on the primary screen, only than the presentation mode have to be changed. */778 QDesktopWidget* pDesktop = QApplication::desktop();779 if (pDesktop->screenNumber(this) == pDesktop->primaryScreen())780 {781 QString testStr = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_PresentationModeEnabled).toLower();782 /* Default to false if it is an empty value */783 if (testStr.isEmpty() || testStr == "false")784 SetSystemUIMode(kUIModeAllHidden, 0);785 else786 SetSystemUIMode(kUIModeAllSuppressed, 0);787 }788 }789 else790 SetSystemUIMode(kUIModeNormal, 0);791 #endif792 }793 # endif /* QT_MAC_USE_COCOA */794 #endif795 796 578 bool UIMachineView::event(QEvent *pEvent) 797 579 { … … 818 600 } 819 601 820 case VBoxDefs::ResizeEventType:821 {822 /* Some situations require initial VGA Resize Request823 * to be ignored at all, leaving previous framebuffer,824 * machine view and machine window sizes preserved: */825 if (uisession()->isGuestResizeIgnored())826 return true;827 828 bool oldIgnoreMainwndResize = m_bIsMachineWindowResizeIgnored;829 m_bIsMachineWindowResizeIgnored = true;830 831 UIResizeEvent *pResizeEvent = static_cast<UIResizeEvent*>(pEvent);832 833 /* Store the new size to prevent unwanted resize hints being sent back. */834 storeConsoleSize(pResizeEvent->width(), pResizeEvent->height());835 836 /* Unfortunately restoreOverrideCursor() is broken in Qt 4.4.0 if WA_PaintOnScreen widgets are present.837 * This is the case on linux with SDL. As workaround we save/restore the arrow cursor manually.838 * See http://trolltech.com/developer/task-tracker/index_html?id=206165&method=entry for details.839 * Moreover the current cursor, which could be set by the guest, should be restored after resize: */840 QCursor cursor;841 if (uisession()->isHidingHostPointer())842 cursor = QCursor(Qt::BlankCursor);843 else844 cursor = viewport()->cursor();845 m_pFrameBuffer->resizeEvent(pResizeEvent);846 viewport()->setCursor(cursor);847 848 #ifdef Q_WS_MAC849 // TODO_NEW_CORE850 // mDockIconPreview->setOriginalSize(pResizeEvent->width(), pResizeEvent->height());851 #endif /* Q_WS_MAC */852 853 /* This event appears in case of guest video was changed for somehow even without video resolution change.854 * In this last case the host VM window will not be resized according this event and the host mouse cursor855 * which was unset to default here will not be hidden in capture state. So it is necessary to perform856 * updateMouseClipping() for the guest resize event if the mouse cursor was captured: */857 if (uisession()->isMouseCaptured())858 updateMouseClipping();859 860 /* Apply maximum size restriction: */861 setMaximumSize(sizeHint());862 863 /* May be we have to restrict minimum size? */864 maybeRestrictMinimumSize();865 866 /* Resize the guest canvas: */867 if (!m_bIsFrameBufferResizeIgnored)868 resize(pResizeEvent->width(), pResizeEvent->height());869 updateSliders();870 871 /* Let our toplevel widget calculate its sizeHint properly. */872 #ifdef Q_WS_X11873 /* We use processEvents rather than sendPostedEvents & set the time out value to max cause on X11 otherwise874 * the layout isn't calculated correctly. Dosn't find the bug in Qt, but this could be triggered through875 * the async nature of the X11 window event system. */876 QCoreApplication::processEvents(QEventLoop::AllEvents, INT_MAX);877 #else /* Q_WS_X11 */878 QCoreApplication::sendPostedEvents(0, QEvent::LayoutRequest);879 #endif /* Q_WS_X11 */880 881 if (!m_bIsFrameBufferResizeIgnored)882 normalizeGeometry(true /* adjustPosition */);883 884 /* Report to the VM thread that we finished resizing */885 session().GetConsole().GetDisplay().ResizeCompleted(0);886 887 m_bIsMachineWindowResizeIgnored = oldIgnoreMainwndResize;888 889 /* Make sure that all posted signals are processed: */890 qApp->processEvents();891 892 /* Emit a signal about guest was resized: */893 emit resizeHintDone();894 895 /* We also recalculate the desktop geometry if this is determined896 * automatically. In fact, we only need this on the first resize,897 * but it is done every time to keep the code simpler. */898 calculateDesktopGeometry();899 900 /* Enable frame-buffer resize watching: */901 if (m_bIsFrameBufferResizeIgnored)902 m_bIsFrameBufferResizeIgnored = false;903 904 return true;905 }906 907 /* See VBox[QImage|SDL]FrameBuffer::NotifyUpdate(): */908 602 case VBoxDefs::RepaintEventType: 909 603 { … … 1021 715 if (m_bIsHostkeyPressed && pEvent->type() == QEvent::KeyPress) 1022 716 { 717 /* Passing F1-F12 keys to the guest: */ 1023 718 if (pKeyEvent->key() >= Qt::Key_F1 && pKeyEvent->key() <= Qt::Key_F12) 1024 719 { … … 1048 743 if (pKeyEvent->key() == Qt::Key_Home) 1049 744 { 1050 #if 0 // TODO: Divide tha code to specific parts and move it there:745 #if 0 // TODO: Divide tha code to specific parts of fullscreen & seamless and move it there: 1051 746 /* Activate the main menu */ 1052 747 if (machineWindowWrapper()->isTrueSeamless() || machineWindowWrapper()->isTrueFullscreen()) 1053 748 machineWindowWrapper()->popupMainMenu (uisession()->isMouseCaptured()); 1054 else1055 {1056 /* In Qt4 it is not enough to just set the focus to menu-bar.1057 * So to get the menu-bar we have to send Qt::Key_Alt press/release events directly: */1058 QKeyEvent e1(QEvent::KeyPress, Qt::Key_Alt, Qt::NoModifier);1059 QKeyEvent e2(QEvent::KeyRelease, Qt::Key_Alt, Qt::NoModifier);1060 QApplication::sendEvent(machineWindowWrapper()->menuBar(), &e1);1061 QApplication::sendEvent(machineWindowWrapper()->menuBar(), &e2);1062 }1063 749 #endif 1064 750 } … … 1190 876 switch (pEvent->type()) 1191 877 { 1192 #if 0 // TODO Move to normal specific event handler:1193 case QEvent::Resize:1194 {1195 /* Set the "guest needs to resize" hint. This hint is acted upon when (and only when)1196 * the autoresize property is "true": */1197 mDoResize = isGuestSupportsGraphics() || machineWindowWrapper()->isTrueFullscreen();1198 if (!m_bIsMachineWindowResizeIgnored && isGuestSupportsGraphics() && m_bIsGuestAutoresizeEnabled)1199 QTimer::singleShot(300, this, SLOT(sltPerformGuestResize()));1200 break;1201 }1202 #endif1203 878 case QEvent::WindowStateChange: 1204 879 { 1205 /* During minimizing and state restoring machineWindowWrapper() gets the focus1206 * which belongs to console view window, so returning it properly. */880 /* During minimizing and state restoring machineWindowWrapper() gets 881 * the focus which belongs to console view window, so returning it properly. */ 1207 882 QWindowStateChangeEvent *pWindowEvent = static_cast<QWindowStateChangeEvent*>(pEvent); 1208 883 if (pWindowEvent->oldState() & Qt::WindowMinimized) … … 1218 893 } 1219 894 #if defined (Q_WS_WIN32) 1220 #if defined (VBOX_GUI_USE_DDRAW)1221 case QEvent::Move:1222 {1223 /* Notification from our parent that it has moved. We need this in order1224 * to possibly adjust the direct screen blitting: */1225 if (m_pFrameBuffer)1226 m_pFrameBuffer->moveEvent(static_cast<QMoveEvent*>(pEvent));1227 break;1228 }1229 #endif1230 895 /* Install/uninstall low-level kbd hook on every activation/deactivation to: 1231 896 * a) avoid excess hook calls when we're not active and … … 1260 925 } 1261 926 } 1262 #if 0 // TODO Move to normal specific event handler:1263 else if (pWatched == machineWindowWrapper()->menuBar())1264 {1265 /* Sometimes when we press ESC in the menu it brings the focus away (Qt bug?)1266 * causing no widget to have a focus, or holds the focus itself, instead of1267 * returning the focus to the console window. Here we fix this: */1268 switch (pEvent->type())1269 {1270 case QEvent::FocusOut:1271 {1272 if (qApp->focusWidget() == 0)1273 setFocus();1274 break;1275 }1276 case QEvent::KeyPress:1277 {1278 QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(pEvent);1279 if (pKeyEvent->key() == Qt::Key_Escape && (pKeyEvent->modifiers() == Qt::NoModifier))1280 if (machineWindowWrapper()->menuBar()->hasFocus())1281 setFocus();1282 break;1283 }1284 default:1285 break;1286 }1287 }1288 #endif1289 927 1290 928 return QAbstractScrollArea::eventFilter (pWatched, pEvent); 1291 929 } 930 931 void UIMachineView::sltMachineStateChanged() 932 { 933 /* Get machine state: */ 934 KMachineState state = uisession()->machineState(); 935 switch (state) 936 { 937 case KMachineState_Paused: 938 case KMachineState_TeleportingPausedVM: 939 { 940 if (mode() != VBoxDefs::TimerMode && m_pFrameBuffer && 941 (state != KMachineState_TeleportingPausedVM || m_previousState != KMachineState_Teleporting)) 942 { 943 /* Take a screen snapshot. Note that TakeScreenShot() always needs a 32bpp image: */ 944 QImage shot = QImage(m_pFrameBuffer->width(), m_pFrameBuffer->height(), QImage::Format_RGB32); 945 CDisplay dsp = session().GetConsole().GetDisplay(); 946 dsp.TakeScreenShot(shot.bits(), shot.width(), shot.height()); 947 /* TakeScreenShot() may fail if, e.g. the Paused notification was delivered 948 * after the machine execution was resumed. It's not fatal: */ 949 if (dsp.isOk()) 950 { 951 dimImage(shot); 952 m_pauseShot = QPixmap::fromImage(shot); 953 /* Fully repaint to pick up m_pauseShot: */ 954 repaint(); 955 } 956 } 957 } 958 case KMachineState_Stuck: 959 { 960 /* Reuse the focus event handler to uncapture everything: */ 961 if (hasFocus()) 962 focusEvent(false /* aHasFocus*/, false /* aReleaseHostKey */); 963 break; 964 } 965 case KMachineState_Running: 966 { 967 if (m_previousState == KMachineState_Paused || m_previousState == KMachineState_TeleportingPausedVM) 968 { 969 if (mode() != VBoxDefs::TimerMode && m_pFrameBuffer) 970 { 971 /* Reset the pixmap to free memory: */ 972 m_pauseShot = QPixmap(); 973 /* Ask for full guest display update (it will also update 974 * the viewport through IFramebuffer::NotifyUpdate): */ 975 CDisplay dsp = session().GetConsole().GetDisplay(); 976 dsp.InvalidateAndUpdate(); 977 } 978 } 979 /* Reuse the focus event handler to capture input: */ 980 if (hasFocus()) 981 focusEvent(true /* aHasFocus */); 982 break; 983 } 984 default: 985 break; 986 } 987 988 #ifdef Q_WS_MAC 989 /* Update Dock Overlay: */ 990 updateDockOverlay(); 991 #endif /* Q_WS_MAC */ 992 993 m_previousState = state; 994 } 995 996 void UIMachineView::sltMousePointerShapeChanged() 997 { 998 if (uisession()->isMouseSupportsAbsolute()) 999 { 1000 /* Should we hide/show pointer? */ 1001 if (uisession()->isHidingHostPointer()) 1002 viewport()->setCursor(Qt::BlankCursor); 1003 else 1004 viewport()->setCursor(uisession()->cursor()); 1005 } 1006 } 1007 1008 void UIMachineView::sltMouseCapabilityChanged() 1009 { 1010 /* Correct the mouse capture state and reset the cursor to the default shape if necessary: */ 1011 if (uisession()->isMouseSupportsAbsolute()) 1012 { 1013 CMouse mouse = session().GetConsole().GetMouse(); 1014 mouse.PutMouseEventAbsolute(-1, -1, 0, 0, 0); 1015 captureMouse(false, false); 1016 } 1017 else 1018 viewport()->unsetCursor(); 1019 1020 /* Notify user about mouse integration state: */ 1021 vboxProblem().remindAboutMouseIntegration(uisession()->isMouseSupportsAbsolute()); 1022 1023 /* Notify all listeners: */ 1024 emitMouseStateChanged(); 1025 } 1026 1027 #ifdef Q_WS_MAC 1028 void UIMachineView::sltChangeDockIconUpdate(const VBoxChangeDockIconUpdateEvent &event) 1029 { 1030 setDockIconEnabled(event.mChanged); 1031 updateDockOverlay(); 1032 } 1033 1034 # ifdef QT_MAC_USE_COCOA 1035 void UIMachineView::sltChangePresentationMode(const VBoxChangePresentationModeEvent &event) 1036 { 1037 // TODO_NEW_CORE 1038 // this is full screen related 1039 #if 0 1040 if (mIsFullscreen) 1041 { 1042 /* First check if we are on the primary screen, only than the presentation mode have to be changed. */ 1043 QDesktopWidget* pDesktop = QApplication::desktop(); 1044 if (pDesktop->screenNumber(this) == pDesktop->primaryScreen()) 1045 { 1046 QString testStr = vboxGlobal().virtualBox().GetExtraData(VBoxDefs::GUI_PresentationModeEnabled).toLower(); 1047 /* Default to false if it is an empty value */ 1048 if (testStr.isEmpty() || testStr == "false") 1049 SetSystemUIMode(kUIModeAllHidden, 0); 1050 else 1051 SetSystemUIMode(kUIModeAllSuppressed, 0); 1052 } 1053 } 1054 else 1055 SetSystemUIMode(kUIModeNormal, 0); 1056 #endif 1057 } 1058 # endif /* QT_MAC_USE_COCOA */ 1059 #endif 1292 1060 1293 1061 void UIMachineView::focusEvent(bool fHasFocus, bool fReleaseHostKey /* = true */) … … 1599 1367 1600 1368 bool UIMachineView::mouseEvent(int aType, const QPoint &aPos, const QPoint &aGlobalPos, 1601 Qt::MouseButtons aButtons, Qt::KeyboardModifiers aModifiers,1369 Qt::MouseButtons aButtons, Qt::KeyboardModifiers /* aModifiers */, 1602 1370 int aWheelDelta, Qt::Orientation aWheelDir) 1603 1371 { 1604 #if 01605 LogRel3(("%s: type=%03d x=%03d y=%03d btns=%08X wdelta=%03d wdir=%s\n",1606 __PRETTY_FUNCTION__ , aType, aPos.x(), aPos.y(),1607 (aButtons & Qt::LeftButton ? 1 : 0)1608 | (aButtons & Qt::RightButton ? 2 : 0)1609 | (aButtons & Qt::MidButton ? 4 : 0)1610 | (aButtons & Qt::XButton1 ? 8 : 0)1611 | (aButtons & Qt::XButton2 ? 16 : 0),1612 aWheelDelta,1613 aWheelDir == Qt::Horizontal ? "Horizontal"1614 : aWheelDir == Qt::Vertical ? "Vertical" : "Unknown"));1615 Q_UNUSED (aModifiers);1616 #else1617 Q_UNUSED (aModifiers);1618 #endif1619 1620 1372 int state = 0; 1621 1373 if (aButtons & Qt::LeftButton) … … 1631 1383 1632 1384 #ifdef Q_WS_MAC 1633 /* Simulate the right click on 1634 * Host+Left Mouse */ 1385 /* Simulate the right click on Host+Left Mouse: */ 1635 1386 if (m_bIsHostkeyPressed && 1636 1387 m_bIsHostkeyAlone && … … 1655 1406 #ifdef Q_WS_WIN32 1656 1407 /* send pending WM_PAINT events */ 1657 ::UpdateWindow 1408 ::UpdateWindow(viewport()->winId()); 1658 1409 #endif 1659 1410 … … 2519 2270 } 2520 2271 2521 void UIMachineView::updateSliders()2522 {2523 QSize p = viewport()->size();2524 QSize m = maximumViewportSize();2525 2526 QSize v = QSize(m_pFrameBuffer->width(), m_pFrameBuffer->height());2527 /* no scroll bars needed */2528 if (m.expandedTo(v) == m)2529 p = m;2530 2531 horizontalScrollBar()->setRange(0, v.width() - p.width());2532 verticalScrollBar()->setRange(0, v.height() - p.height());2533 horizontalScrollBar()->setPageStep(p.width());2534 verticalScrollBar()->setPageStep(p.height());2535 }2536 2537 2272 void UIMachineView::scrollBy(int dx, int dy) 2538 2273 { … … 2577 2312 #elif defined(Q_WS_X11) 2578 2313 if (fCapture) 2579 2314 XGrabKey(QX11Info::display(), AnyKey, AnyModifier, window()->winId(), False, GrabModeAsync, GrabModeAsync); 2580 2315 else 2581 2316 XUngrabKey(QX11Info::display(), AnyKey, AnyModifier, window()->winId()); 2582 2317 #elif defined(Q_WS_MAC) 2583 2318 if (fCapture) … … 2636 2371 /* Release mouse buttons: */ 2637 2372 CMouse mouse = session().GetConsole().GetMouse(); 2638 mouse.PutMouseEvent 2373 mouse.PutMouseEvent(0, 0, 0, 0 /* Horizontal wheel */, 0); 2639 2374 } 2640 2375 … … 2724 2459 keyboard.PutScancodes(codes); 2725 2460 } 2726 }2727 }2728 2729 void UIMachineView::updateMouseClipping()2730 {2731 if (uisession()->isMouseCaptured())2732 {2733 viewport()->setCursor(QCursor(Qt::BlankCursor));2734 #ifdef Q_WS_WIN322735 QRect r = viewport()->rect();2736 r.moveTopLeft(viewport()->mapToGlobal(QPoint (0, 0)));2737 RECT rect = { r.left(), r.top(), r.right() + 1, r.bottom() + 1 };2738 ::ClipCursor(&rect);2739 #endif2740 }2741 else2742 {2743 #ifdef Q_WS_WIN322744 ::ClipCursor(NULL);2745 #endif2746 /* return the cursor to where it was when we captured it and show it */2747 QCursor::setPos(m_capturedMousePos);2748 viewport()->unsetCursor();2749 2461 } 2750 2462 } -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineView.h
r26816 r26878 59 59 #endif 60 60 , UIVisualStateType visualStateType); 61 static void destroy(UIMachineView *pWhichView); 61 62 62 63 /* Public getters: */ … … 67 68 virtual void setGuestAutoresizeEnabled(bool bEnabled) = 0; 68 69 virtual void setMouseIntegrationEnabled(bool bEnabled); 69 //void setMachineViewFinalized(bool fTrue = true) { m_bIsMachineWindowResizeIgnored = !fTrue; }70 70 71 71 /* Public members: */ … … 85 85 void mouseStateChanged(int iState); 86 86 87 /* Utility signals: */88 void resizeHintDone();89 90 87 protected: 91 88 … … 99 96 virtual ~UIMachineView(); 100 97 101 /* Desktop geometry types: */102 enum DesktopGeo { DesktopGeo_Invalid = 0, DesktopGeo_Fixed, DesktopGeo_Automatic, DesktopGeo_Any };103 104 98 /* Protected getters: */ 105 99 UISession* uisession() const; 106 100 CSession& session(); 107 UIMachineWindow* machineWindowWrapper() const { return m_pMachineWindow; }108 VBoxDefs::RenderMode mode() const { return m_mode; }109 101 QSize sizeHint() const; 110 102 int contentsX() const; … … 114 106 int visibleWidth() const; 115 107 int visibleHeight() const; 116 QRect desktopGeometry() const; 108 VBoxDefs::RenderMode mode() const { return m_mode; } 109 UIFrameBuffer* frameBuffer() const { return m_pFrameBuffer; } 110 UIMachineWindow* machineWindowWrapper() const { return m_pMachineWindow; } 111 bool isHostKeyPressed() const { return m_bIsHostkeyPressed; } 112 bool isMachineWindowResizeIgnored() const { return m_bIsMachineWindowResizeIgnored; } 113 bool isFrameBufferResizeIgnored() const { return m_bIsFrameBufferResizeIgnored; } 117 114 const QPixmap& pauseShot() const { return m_pauseShot; } 118 119 /* Protected members: */ 120 void calculateDesktopGeometry(); 121 void setDesktopGeometry(DesktopGeo geometry, int iWidth, int iHeight); 122 void storeConsoleSize(int iWidth, int iHeight); 123 QRect availableGeometry(); 124 virtual void maybeRestrictMinimumSize() = 0; 115 virtual QSize desktopGeometry() const = 0; 116 117 /* Protected setters: */ 118 void setMachineWindowResizeIgnored(bool fIgnore = true) { m_bIsMachineWindowResizeIgnored = fIgnore; } 119 void setFrameBufferResizeIgnored(bool fIgnore = true) { m_bIsFrameBufferResizeIgnored = fIgnore; } 120 121 /* Protected helpers: */ 122 void updateMouseClipping(); 123 void updateSliders(); 125 124 126 125 /* Prepare routines: */ … … 138 137 virtual void cleanupFrameBuffer(); 139 138 139 /* Cross-platforms event processors: */ 140 bool event(QEvent *pEvent); 141 bool eventFilter(QObject *pWatched, QEvent *pEvent); 142 140 143 protected slots: 141 144 142 145 /* Console callback handlers: */ 143 146 virtual void sltMachineStateChanged(); 144 virtual void sltAdditionsStateChanged();145 147 virtual void sltMousePointerShapeChanged(); 146 148 virtual void sltMouseCapabilityChanged(); 147 149 148 /* Initiate resize request to guest: */149 virtual void sltPerformGuestResize(const QSize &aSize = QSize()) = 0;150 151 150 private slots: 152 153 /* Watch dog for desktop resizes: */154 void sltDesktopResized();155 151 156 152 #ifdef Q_WS_MAC … … 166 162 167 163 /* Cross-platforms event processors: */ 168 bool event(QEvent *pEvent);169 bool eventFilter(QObject *pWatched, QEvent *pEvent);170 164 void focusEvent(bool aHasFocus, bool aReleaseHostKey = true); 171 165 bool keyEvent(int aKey, uint8_t aScan, int aFlags, wchar_t *aUniKey = NULL); … … 199 193 void fixModifierState(int *piCodes, uint *puCount); 200 194 QPoint viewportToContents(const QPoint &vp) const; 201 void updateSliders();202 195 void scrollBy(int dx, int dy); 203 196 #ifdef VBOX_WITH_VIDEOHWACCEL … … 211 204 void releaseAllPressedKeys(bool aReleaseHostKey = true); 212 205 void sendChangedKeyStates(); 213 void updateMouseClipping();214 206 215 207 static void dimImage(QImage &img); … … 239 231 #ifdef VBOX_WITH_VIDEOHWACCEL 240 232 bool m_fAccelerate2DVideo; 241 #endif242 #if 0 // TODO: Do we need this flag?243 bool mDoResize : 1;244 233 #endif 245 234 … … 263 252 bool mDockIconEnabled; 264 253 #endif 265 DesktopGeo m_desktopGeometryType;266 QRect m_desktopGeometry;267 QRect m_storedConsoleSize;268 254 269 255 /* Friend classes: */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.cpp
r26868 r26878 91 91 : m_pMachineLogic(pMachineLogic) 92 92 , m_pMachineWindow(0) 93 , m_pMachineViewContainer(0) 94 , m_pTopSpacer(0) 95 , m_pBottomSpacer(0) 96 , m_pLeftSpacer(0) 97 , m_pRightSpacer(0) 93 98 , m_pMachineView(0) 94 99 { … … 490 495 } 491 496 497 void UIMachineWindow::prepareMachineViewContainer() 498 { 499 /* Create view container. 500 * After it will be passed to parent widget of some mode, 501 * there will be no need to delete it, so no need to cleanup: */ 502 m_pMachineViewContainer = new QGridLayout(); 503 m_pMachineViewContainer->setMargin(0); 504 m_pMachineViewContainer->setSpacing(0); 505 506 /* Create and add shifting spacers. 507 * After they will be inserted into layout, it will get the parentness 508 * of those spacers, so there will be no need to cleanup them. */ 509 m_pTopSpacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding); 510 m_pBottomSpacer = new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding); 511 m_pLeftSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed); 512 m_pRightSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed); 513 m_pMachineViewContainer->addItem(m_pTopSpacer, 0, 1); 514 m_pMachineViewContainer->addItem(m_pBottomSpacer, 2, 1); 515 m_pMachineViewContainer->addItem(m_pLeftSpacer, 1, 0); 516 m_pMachineViewContainer->addItem(m_pRightSpacer, 1, 2); 517 } 518 492 519 void UIMachineWindow::updateAppearanceOf(int iElement) 493 520 { -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIMachineWindow.h
r26820 r26878 29 29 /* Global forwards */ 30 30 class QWidget; 31 class QGridLayout; 32 class QSpacerItem; 31 33 class QCloseEvent; 32 34 … … 81 83 #endif 82 84 virtual void prepareMenuHelp(); 85 virtual void prepareMachineViewContainer(); 83 86 //virtual void loadWindowSettings() {} 84 87 85 88 /* Cleanup helpers: */ 86 89 //virtual void saveWindowSettings() {} 90 //virtual void cleanupMachineViewContainer() {} 91 //virtual void cleanupMenuHelp() {} 87 92 #ifdef VBOX_WITH_DEBUGGER_GUI 88 93 //virtual void prepareMenuDebug() {} … … 102 107 UIMachineLogic *m_pMachineLogic; 103 108 QWidget *m_pMachineWindow; 109 110 QGridLayout *m_pMachineViewContainer; 111 QSpacerItem *m_pTopSpacer; 112 QSpacerItem *m_pBottomSpacer; 113 QSpacerItem *m_pLeftSpacer; 114 QSpacerItem *m_pRightSpacer; 115 104 116 UIMachineView *m_pMachineView; 105 117 QString m_strWindowTitlePrefix; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.cpp
r26815 r26878 25 25 #include <QApplication> 26 26 #include <QDesktopWidget> 27 #include <QMainWindow>28 27 #include <QMenuBar> 28 #include <QTimer> 29 29 30 30 /* Local includes */ … … 34 34 #include "UIMachineLogic.h" 35 35 #include "UIMachineWindow.h" 36 #include "UIFrameBuffer.h" 36 37 #include "UIMachineViewNormal.h" 38 #include "QIMainDialog.h" 37 39 38 40 UIMachineViewNormal::UIMachineViewNormal( UIMachineWindow *pMachineWindow … … 48 50 #endif 49 51 ) 52 , m_desktopGeometryType(DesktopGeo_Invalid) 53 , m_bIsGuestAutoresizeEnabled(pMachineWindow->machineLogic()->actionsPool()->action(UIActionIndex_Toggle_GuestAutoresize)->isChecked()) 54 , m_fShouldWeDoResize(false) 50 55 { 51 56 /* Prepare frame buffer: */ … … 80 85 } 81 86 82 void UIMachineViewNormal::sltPerformGuestResize(const QSize & /* toSize */) 83 { 84 #if 0 // TODO: fix that logic! 85 if (isGuestSupportsGraphics() && m_bIsGuestAutoresizeEnabled) 86 { 87 void UIMachineViewNormal::sltAdditionsStateChanged() 88 { 89 /* Check if we should restrict minimum size: */ 90 maybeRestrictMinimumSize(); 91 } 92 93 void UIMachineViewNormal::sltPerformGuestResize(const QSize &toSize) 94 { 95 if (m_bIsGuestAutoresizeEnabled && uisession()->isGuestSupportsGraphics()) 96 { 97 /* Taking Main Dialog: */ 98 QIMainDialog *pMainDialog = machineWindowWrapper() && machineWindowWrapper()->machineWindow() ? 99 qobject_cast<QIMainDialog*>(machineWindowWrapper()->machineWindow()) : 0; 100 87 101 /* If this slot is invoked directly then use the passed size 88 102 * otherwise get the available size for the guest display. 89 103 * We assume here that the centralWidget() contains this view only 90 104 * and gives it all available space. */ 91 QSize sz(toSize.isValid() ? toSize : machineWindow()->centralWidget()->size()); 105 QSize newSize(toSize.isValid() ? toSize : pMainDialog ? pMainDialog->centralWidget()->size() : QSize()); 106 AssertMsg(newSize.isValid(), ("This size should be valid!\n")); 107 108 /* Subtracting frame in case we basing on machine view size: */ 92 109 if (!toSize.isValid()) 93 sz -= QSize(frameWidth() * 2, frameWidth() * 2); 94 /* Do not send out useless hints. */ 95 if ((sz.width() == mStoredConsoleSize.width()) && (sz.height() == mStoredConsoleSize.height())) 110 newSize -= QSize(frameWidth() * 2, frameWidth() * 2); 111 112 /* Do not send the same hints as we already have: */ 113 if ((newSize.width() == m_storedConsoleSize.width()) && (newSize.height() == m_storedConsoleSize.height())) 96 114 return; 115 97 116 /* We only actually send the hint if 98 117 * 1) the autoresize property is set to true and … … 102 121 * needed (e.g. the autoresize was just enabled and the console 103 122 * was resized while it was disabled). */ 104 if ( m_bIsGuestAutoresizeEnabled && (toSize.isValid() || mDoResize))123 if (toSize.isValid() || m_fShouldWeDoResize) 105 124 { 106 125 /* Remember the new size. */ 107 storeConsoleSize(sz.width(), sz.height()); 108 109 mConsole.GetDisplay().SetVideoModeHint(sz.width(), sz.height(), 0, 0); 126 m_storedConsoleSize = newSize; 127 128 /* Send new size-hint to the guest: */ 129 session().GetConsole().GetDisplay().SetVideoModeHint(newSize.width(), newSize.height(), 0, 0); 110 130 } 111 /* We have resized now... */ 112 mDoResize = false; 113 } 114 #endif 115 } 116 117 void UIMachineViewNormal::sltAdditionsStateChanged() 118 { 119 /* Base-class additions state-change-handler: */ 120 UIMachineView::sltAdditionsStateChanged(); 121 122 /* Enable/Disable guest auto-resizing depending on advanced graphics availablability: */ 123 setGuestAutoresizeEnabled(m_bIsGuestAutoresizeEnabled && uisession()->isGuestSupportsGraphics()); 131 /* We had requested resize now, rejecting accident requests: */ 132 m_fShouldWeDoResize = false; 133 } 134 } 135 136 /* If the desktop geometry is set automatically, this will update it: */ 137 void UIMachineViewNormal::sltDesktopResized() 138 { 139 calculateDesktopGeometry(); 124 140 } 125 141 126 142 void UIMachineViewNormal::prepareFilters() 127 143 { 128 /* Prepare base-class filters: */144 /* Base class filters: */ 129 145 UIMachineView::prepareFilters(); 130 146 131 /* Normal window filters: */ 132 qobject_cast<QMainWindow*>(machineWindowWrapper()->machineWindow())->menuBar()->installEventFilter(this); 147 /* Menu bar filters: */ 148 qobject_cast<QIMainDialog*>(machineWindowWrapper()->machineWindow())->menuBar()->installEventFilter(this); 149 } 150 151 void UIMachineViewNormal::prepareConsoleConnections() 152 { 153 /* Base class connections: */ 154 UIMachineView::prepareConsoleConnections(); 155 156 /* Guest additions state-change updater: */ 157 connect(uisession(), SIGNAL(sigAdditionsStateChange()), this, SLOT(sltAdditionsStateChanged())); 158 } 159 160 void UIMachineViewNormal::loadMachineViewSettings() 161 { 162 /* Base class settings: */ 163 UIMachineView::loadMachineViewSettings(); 164 165 /* Global settings: */ 166 { 167 /* Remember the desktop geometry and register for geometry 168 * change events for telling the guest about video modes we like: */ 169 QString desktopGeometry = vboxGlobal().settings().publicProperty("GUI/MaxGuestResolution"); 170 if ((desktopGeometry == QString::null) || (desktopGeometry == "auto")) 171 setDesktopGeometry(DesktopGeo_Automatic, 0, 0); 172 else if (desktopGeometry == "any") 173 setDesktopGeometry(DesktopGeo_Any, 0, 0); 174 else 175 { 176 int width = desktopGeometry.section(',', 0, 0).toInt(); 177 int height = desktopGeometry.section(',', 1, 1).toInt(); 178 setDesktopGeometry(DesktopGeo_Fixed, width, height); 179 } 180 connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(sltDesktopResized())); 181 } 133 182 } 134 183 … … 141 190 maybeRestrictMinimumSize(); 142 191 143 if ( uisession()->isGuestSupportsGraphics() && m_bIsGuestAutoresizeEnabled)192 if (m_bIsGuestAutoresizeEnabled && uisession()->isGuestSupportsGraphics()) 144 193 sltPerformGuestResize(); 145 194 } 146 195 } 147 196 148 void UIMachineViewNormal::normalizeGeometry(bool bAdjustPosition /* = false */) 197 QSize UIMachineViewNormal::desktopGeometry() const 198 { 199 QSize geometry; 200 switch (m_desktopGeometryType) 201 { 202 case DesktopGeo_Fixed: 203 case DesktopGeo_Automatic: 204 geometry = QSize(qMax(m_desktopGeometry.width(), m_storedConsoleSize.width()), 205 qMax(m_desktopGeometry.height(), m_storedConsoleSize.height())); 206 break; 207 case DesktopGeo_Any: 208 geometry = QSize(0, 0); 209 break; 210 default: 211 AssertMsgFailed(("Bad geometry type %d!\n", m_desktopGeometryType)); 212 } 213 return geometry; 214 } 215 216 void UIMachineViewNormal::normalizeGeometry(bool bAdjustPosition) 149 217 { 150 218 QWidget *pTopLevelWidget = window(); … … 182 250 availableGeo = dwt->availableGeometry(pTopLevelWidget->pos()); 183 251 184 frameGeo = VBoxGlobal::normalizeGeometry(frameGeo, availableGeo, mode() != VBoxDefs::SDLMode /* can Resize*/);252 frameGeo = VBoxGlobal::normalizeGeometry(frameGeo, availableGeo, mode() != VBoxDefs::SDLMode /* can resize? */); 185 253 } 186 254 … … 192 260 /* Finally, set the frame geometry */ 193 261 pTopLevelWidget->setGeometry(frameGeo.left() + dl, frameGeo.top() + dt, frameGeo.width() - dl - dr, frameGeo.height() - dt - db); 262 } 263 264 void UIMachineViewNormal::calculateDesktopGeometry() 265 { 266 /* This method should not get called until we have initially set up the m_desktopGeometryType: */ 267 Assert((m_desktopGeometryType != DesktopGeo_Invalid)); 268 /* If we are not doing automatic geometry calculation then there is nothing to do: */ 269 if (DesktopGeo_Automatic == m_desktopGeometryType) 270 { 271 /* Available geometry of the desktop. If the desktop is a single 272 * screen, this will exclude space taken up by desktop taskbars 273 * and things, but this is unfortunately not true for the more 274 * complex case of a desktop spanning multiple screens: */ 275 QRect desktop = availableGeometry(); 276 /* The area taken up by the machine window on the desktop, 277 * including window frame, title and menu bar and whatnot: */ 278 QRect frame = machineWindowWrapper()->machineWindow()->frameGeometry(); 279 /* The area taken up by the machine view, so excluding all decorations: */ 280 QRect window = geometry(); 281 /* To work out how big we can make the console window while still 282 * fitting on the desktop, we calculate desktop - frame + window. 283 * This works because the difference between frame and window 284 * (or at least its width and height) is a constant. */ 285 m_desktopGeometry = QSize(desktop.width() - frame.width() + window.width(), 286 desktop.height() - frame.height() + window.height()); 287 } 288 } 289 290 QRect UIMachineViewNormal::availableGeometry() 291 { 292 return machineWindowWrapper()->machineWindow()->isFullScreen() ? 293 QApplication::desktop()->screenGeometry(this) : 294 QApplication::desktop()->availableGeometry(this); 295 } 296 297 void UIMachineViewNormal::setDesktopGeometry(DesktopGeo geometry, int aWidth, int aHeight) 298 { 299 switch (geometry) 300 { 301 case DesktopGeo_Fixed: 302 m_desktopGeometryType = DesktopGeo_Fixed; 303 if (aWidth != 0 && aHeight != 0) 304 m_desktopGeometry = QSize(aWidth, aHeight); 305 else 306 m_desktopGeometry = QSize(0, 0); 307 storeConsoleSize(0, 0); 308 break; 309 case DesktopGeo_Automatic: 310 m_desktopGeometryType = DesktopGeo_Automatic; 311 m_desktopGeometry = QSize(0, 0); 312 storeConsoleSize(0, 0); 313 break; 314 case DesktopGeo_Any: 315 m_desktopGeometryType = DesktopGeo_Any; 316 m_desktopGeometry = QSize(0, 0); 317 break; 318 default: 319 AssertMsgFailed(("Invalid desktop geometry type %d\n", geometry)); 320 m_desktopGeometryType = DesktopGeo_Invalid; 321 } 322 } 323 324 void UIMachineViewNormal::storeConsoleSize(int iWidth, int iHeight) 325 { 326 m_storedConsoleSize = QSize(iWidth, iHeight); 194 327 } 195 328 … … 209 342 } 210 343 344 bool UIMachineViewNormal::event(QEvent *pEvent) 345 { 346 switch (pEvent->type()) 347 { 348 case VBoxDefs::ResizeEventType: 349 { 350 /* Some situations require initial VGA Resize Request 351 * to be ignored at all, leaving previous framebuffer, 352 * machine view and machine window sizes preserved: */ 353 if (uisession()->isGuestResizeIgnored()) 354 return true; 355 356 bool oldIgnoreMainwndResize = isMachineWindowResizeIgnored(); 357 setMachineWindowResizeIgnored(true); 358 359 UIResizeEvent *pResizeEvent = static_cast<UIResizeEvent*>(pEvent); 360 361 /* Store the new size to prevent unwanted resize hints being sent back. */ 362 storeConsoleSize(pResizeEvent->width(), pResizeEvent->height()); 363 364 /* Unfortunately restoreOverrideCursor() is broken in Qt 4.4.0 if WA_PaintOnScreen widgets are present. 365 * This is the case on linux with SDL. As workaround we save/restore the arrow cursor manually. 366 * See http://trolltech.com/developer/task-tracker/index_html?id=206165&method=entry for details. 367 * Moreover the current cursor, which could be set by the guest, should be restored after resize: */ 368 QCursor cursor; 369 if (uisession()->isHidingHostPointer()) 370 cursor = QCursor(Qt::BlankCursor); 371 else 372 cursor = viewport()->cursor(); 373 frameBuffer()->resizeEvent(pResizeEvent); 374 viewport()->setCursor(cursor); 375 376 #ifdef Q_WS_MAC 377 // TODO_NEW_CORE 378 // mDockIconPreview->setOriginalSize(pResizeEvent->width(), pResizeEvent->height()); 379 #endif /* Q_WS_MAC */ 380 381 /* This event appears in case of guest video was changed for somehow even without video resolution change. 382 * In this last case the host VM window will not be resized according this event and the host mouse cursor 383 * which was unset to default here will not be hidden in capture state. So it is necessary to perform 384 * updateMouseClipping() for the guest resize event if the mouse cursor was captured: */ 385 if (uisession()->isMouseCaptured()) 386 updateMouseClipping(); 387 388 /* Apply maximum size restriction: */ 389 setMaximumSize(sizeHint()); 390 391 /* May be we have to restrict minimum size? */ 392 maybeRestrictMinimumSize(); 393 394 /* Resize the guest canvas: */ 395 if (!isFrameBufferResizeIgnored()) 396 resize(pResizeEvent->width(), pResizeEvent->height()); 397 updateSliders(); 398 399 /* Let our toplevel widget calculate its sizeHint properly. */ 400 #ifdef Q_WS_X11 401 /* We use processEvents rather than sendPostedEvents & set the time out value to max cause on X11 otherwise 402 * the layout isn't calculated correctly. Dosn't find the bug in Qt, but this could be triggered through 403 * the async nature of the X11 window event system. */ 404 QCoreApplication::processEvents(QEventLoop::AllEvents, INT_MAX); 405 #else /* Q_WS_X11 */ 406 QCoreApplication::sendPostedEvents(0, QEvent::LayoutRequest); 407 #endif /* Q_WS_X11 */ 408 409 if (!isFrameBufferResizeIgnored()) 410 normalizeGeometry(true /* adjustPosition */); 411 412 /* Report to the VM thread that we finished resizing */ 413 session().GetConsole().GetDisplay().ResizeCompleted(0); 414 415 setMachineWindowResizeIgnored(oldIgnoreMainwndResize); 416 417 /* Make sure that all posted signals are processed: */ 418 qApp->processEvents(); 419 420 /* Emit a signal about guest was resized: */ 421 emit resizeHintDone(); 422 423 /* We also recalculate the desktop geometry if this is determined 424 * automatically. In fact, we only need this on the first resize, 425 * but it is done every time to keep the code simpler. */ 426 calculateDesktopGeometry(); 427 428 /* Enable frame-buffer resize watching: */ 429 if (isFrameBufferResizeIgnored()) 430 setFrameBufferResizeIgnored(false); 431 432 return true; 433 } 434 435 case QEvent::KeyPress: 436 case QEvent::KeyRelease: 437 { 438 QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(pEvent); 439 440 if (isHostKeyPressed() && pEvent->type() == QEvent::KeyPress) 441 { 442 if (pKeyEvent->key() == Qt::Key_Home) 443 { 444 /* In Qt4 it is not enough to just set the focus to menu-bar. 445 * So to get the menu-bar we have to send Qt::Key_Alt press/release events directly: */ 446 QKeyEvent e1(QEvent::KeyPress, Qt::Key_Alt, Qt::NoModifier); 447 QKeyEvent e2(QEvent::KeyRelease, Qt::Key_Alt, Qt::NoModifier); 448 QMenuBar *pMenuBar = machineWindowWrapper() && machineWindowWrapper()->machineWindow() ? 449 qobject_cast<QIMainDialog*>(machineWindowWrapper()->machineWindow())->menuBar() : 0; 450 QApplication::sendEvent(pMenuBar, &e1); 451 QApplication::sendEvent(pMenuBar, &e2); 452 } 453 else 454 pEvent->ignore(); 455 } 456 } 457 default: 458 break; 459 } 460 return UIMachineView::event(pEvent); 461 } 462 463 bool UIMachineViewNormal::eventFilter(QObject *pWatched, QEvent *pEvent) 464 { 465 /* Who are we watchin? */ 466 QIMainDialog *pMainDialog = machineWindowWrapper() && machineWindowWrapper()->machineWindow() ? 467 qobject_cast<QIMainDialog*>(machineWindowWrapper()->machineWindow()) : 0; 468 QMenuBar *pMenuBar = pMainDialog ? qobject_cast<QIMainDialog*>(pMainDialog)->menuBar() : 0; 469 470 if (pWatched != 0 && pWatched == pMainDialog) 471 { 472 switch (pEvent->type()) 473 { 474 case QEvent::Resize: 475 { 476 /* Set the "guest needs to resize" hint. 477 * This hint is acted upon when (and only when) the autoresize property is "true": */ 478 m_fShouldWeDoResize = uisession()->isGuestSupportsGraphics(); 479 if (!isMachineWindowResizeIgnored() && m_bIsGuestAutoresizeEnabled && uisession()->isGuestSupportsGraphics()) 480 QTimer::singleShot(300, this, SLOT(sltPerformGuestResize())); 481 break; 482 } 483 #if defined (Q_WS_WIN32) 484 # if defined (VBOX_GUI_USE_DDRAW) 485 case QEvent::Move: 486 { 487 /* Notification from our parent that it has moved. We need this in order 488 * to possibly adjust the direct screen blitting: */ 489 if (frameBuffer()) 490 frameBuffer()->moveEvent(static_cast<QMoveEvent*>(pEvent)); 491 break; 492 } 493 # endif 494 #endif /* defined (Q_WS_WIN32) */ 495 default: 496 break; 497 } 498 } 499 else if (pWatched != 0 && pWatched == pMenuBar) 500 { 501 /* Sometimes when we press ESC in the menu it brings the focus away (Qt bug?) 502 * causing no widget to have a focus, or holds the focus itself, instead of 503 * returning the focus to the console window. Here we fix this: */ 504 switch (pEvent->type()) 505 { 506 case QEvent::FocusOut: 507 { 508 if (qApp->focusWidget() == 0) 509 setFocus(); 510 break; 511 } 512 case QEvent::KeyPress: 513 { 514 QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(pEvent); 515 if (pKeyEvent->key() == Qt::Key_Escape && (pKeyEvent->modifiers() == Qt::NoModifier)) 516 if (pMenuBar->hasFocus()) 517 setFocus(); 518 break; 519 } 520 default: 521 break; 522 } 523 } 524 return UIMachineView::eventFilter(pWatched, pEvent); 525 } 526 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineViewNormal.h
r26773 r26878 31 31 Q_OBJECT; 32 32 33 signals: 34 35 /* Utility signals: */ 36 void resizeHintDone(); 37 33 38 protected: 39 40 /* Desktop geometry types: */ 41 enum DesktopGeo { DesktopGeo_Invalid = 0, DesktopGeo_Fixed, DesktopGeo_Automatic, DesktopGeo_Any }; 34 42 35 43 /* Normal machine view constructor/destructor: */ … … 48 56 49 57 /* Slot to perform guest resize: */ 50 void sltPerformGuestResize(const QSize &aSize = QSize()); 58 void sltPerformGuestResize(const QSize &size = QSize()); 59 60 /* Watch dog for desktop resizes: */ 61 void sltDesktopResized(); 51 62 52 63 private: 53 64 54 /* Prepare routines: */65 /* Prepare helpers: */ 55 66 void prepareFilters(); 67 void prepareConsoleConnections(); 68 void loadMachineViewSettings(); 56 69 57 /* Private setters: */ 70 /* Cleanup helpers: */ 71 //void saveMachineViewSettings() {} 72 //void cleanupConsoleConnections() {} 73 //cleanupFilters() {} 74 75 /* Hidden setters: */ 58 76 void setGuestAutoresizeEnabled(bool bEnabled); 59 77 78 /* Hidden getters: */ 79 QSize desktopGeometry() const; 80 60 81 /* Private helpers: */ 61 void normalizeGeometry(bool bAdjustPosition = false); 82 void normalizeGeometry(bool fAdjustPosition); 83 void calculateDesktopGeometry(); 84 QRect availableGeometry(); 85 void setDesktopGeometry(DesktopGeo geometry, int iWidth, int iHeight); 86 void storeConsoleSize(int iWidth, int iHeight); 62 87 void maybeRestrictMinimumSize(); 63 88 89 /* Event handlers: */ 90 bool event(QEvent *pEvent); 91 bool eventFilter(QObject *pWatched, QEvent *pEvent); 92 64 93 /* Private members: */ 94 DesktopGeo m_desktopGeometryType; 95 QSize m_desktopGeometry; 96 QSize m_storedConsoleSize; 65 97 bool m_bIsGuestAutoresizeEnabled : 1; 98 bool m_fShouldWeDoResize : 1; 66 99 67 100 /* Friend classes: */ -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.cpp
r26820 r26878 69 69 retranslateUi(); 70 70 71 /* Prepare normal machine view container: */ 72 prepareMachineViewContainer(); 73 71 74 /* Prepare normal machine view: */ 72 75 prepareMachineView(); … … 86 89 /* Save normal window settings: */ 87 90 saveWindowSettings(); 91 92 /* Cleanup normal machine view: */ 93 cleanupMachineView(); 88 94 89 95 /* Cleanup status-bar: */ … … 454 460 #endif 455 461 462 /* Set central widget: */ 463 setCentralWidget(new QWidget); 464 465 /* Set central widget layout: */ 466 centralWidget()->setLayout(m_pMachineViewContainer); 467 456 468 m_pMachineView = UIMachineView::create( this 457 469 , vboxGlobal().vmRenderMode() … … 461 473 , machineLogic()->visualStateType()); 462 474 463 setCentralWidget(m_pMachineView); 475 /* Add machine view into layout: */ 476 m_pMachineViewContainer->addWidget(m_pMachineView, 1, 1); 464 477 465 478 /* Setup machine view connections: */ … … 568 581 } 569 582 583 void UIMachineWindowNormal::cleanupMachineView() 584 { 585 /* Do not cleanup machine view if it is not present: */ 586 if (!machineView()) 587 return; 588 589 UIMachineView::destroy(m_pMachineView); 590 m_pMachineView = 0; 591 } 592 570 593 void UIMachineWindowNormal::cleanupStatusBar() 571 594 { -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/normal/UIMachineWindowNormal.h
r26815 r26878 92 92 void prepareStatusBar(); 93 93 void prepareConnections(); 94 void prepareMachineView(); 94 95 void loadWindowSettings(); 95 void prepareMachineView();96 96 97 97 /* Cleanup helpers: */ 98 //void cleanupMachineView() {}99 98 void saveWindowSettings(); 99 void cleanupMachineView(); 100 100 //void cleanupConnections() {} 101 101 void cleanupStatusBar();
Note:
See TracChangeset
for help on using the changeset viewer.