VirtualBox

Changeset 2540 in vbox for trunk


Ignore:
Timestamp:
May 8, 2007 4:06:27 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
20981
Message:

Main & All Frontends: Improved console window activation helper APIs (still no success on X11, works well on Win32, the old method of activation is disabled).

Location:
trunk/src/VBox
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxSDL/VBoxSDL.cpp

    r2463 r2540  
    3838#include <X11/cursorfont.h>      /* for XC_left_ptr */
    3939#include <X11/Xcursor/Xcursor.h>
     40#endif
     41
    4042#include <SDL_syswm.h>           /* for SDL_GetWMInfo() */
    41 #endif
    4243
    4344#include "VBoxSDL.h"
     
    506507        if (!canShow)
    507508            return E_POINTER;
    508         /* @todo return TRUE if gConsole is not NULL */
     509#if defined (__LINUX__)
     510        /// @todo see the big comment in Frontends/VirtualBox/src/VBoxVMListBoxItem::switchTo()
    509511        *canShow = FALSE;
     512#else
     513        SDL_SysWMinfo info;
     514        SDL_VERSION(&info.version);
     515        *canShow = !!SDL_GetWMInfo(&info);
     516#endif
    510517        return S_OK;
    511518    }
    512519
    513     STDMETHOD(OnShowWindow)()
    514     {
    515         /* @todo implement */
    516         return E_NOTIMPL;
     520    STDMETHOD(OnShowWindow) (ULONG64 *winId)
     521    {
     522        SDL_SysWMinfo info;
     523        SDL_VERSION(&info.version);
     524        if (SDL_GetWMInfo(&info))
     525        {
     526#if defined (__LINUX__)
     527            *winId = (ULONG64) info.info.x11.window;
     528#elif defined (__WIN__)
     529            *winId = (ULONG64) info.window;
     530#else
     531            AssertFailed();
     532            return E_FAIL;
     533#endif
     534            return S_OK;
     535        }
     536        AssertFailed();
     537        return E_FAIL;
    517538    }
    518539
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxVMListBox.h

    r1718 r2540  
    133133    ULONG snapshotCount() const { return mSnapshotCount; }
    134134
     135    /// @todo see comments in #switchTo() in VBoxVMListBox.cpp
     136#if 0
    135137    bool canSwitchTo() const { return mWinId != (WId) ~0; }
     138#endif
     139    bool canSwitchTo() const;
    136140    bool switchTo();
    137141
     
    161165
    162166    ULONG mPid;
     167    /// @todo see comments in #switchTo() in VBoxVMListBox.cpp
     168#if 0
    163169    WId mWinId;
     170#endif
    164171};
    165172
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r2463 r2540  
    280280    VBoxConsoleCallback (VBoxConsoleView *v) {
    281281#if defined (Q_WS_WIN)
    282         refcnt = 0;
    283 #endif
    284         view = v;
     282        mRefCnt = 0;
     283#endif
     284        mView = v;
    285285    }
    286286
     
    291291#if defined (Q_WS_WIN)
    292292    STDMETHOD_(ULONG, AddRef)() {
    293         return ::InterlockedIncrement (&refcnt);
     293        return ::InterlockedIncrement (&mRefCnt);
    294294    }
    295295    STDMETHOD_(ULONG, Release)()
    296296    {
    297         long cnt = ::InterlockedDecrement (&refcnt);
     297        long cnt = ::InterlockedDecrement (&mRefCnt);
    298298        if (cnt == 0)
    299299            delete this;
     
    322322                                          BYTE *shape)
    323323    {
    324         QApplication::postEvent (
    325             view, new MousePointerChangeEvent (visible, alpha, xhot, yhot,
    326                                                width, height,
    327                                                shape)
    328         );
     324        QApplication::postEvent (mView,
     325                                 new MousePointerChangeEvent (visible, alpha,
     326                                                              xhot, yhot,
     327                                                              width, height, shape));
    329328        return S_OK;
    330329    }
     
    332331    STDMETHOD(OnMouseCapabilityChange)(BOOL supportsAbsolute, BOOL needsHostCursor)
    333332    {
    334         QApplication::postEvent (view, new MouseCapabilityEvent (supportsAbsolute, needsHostCursor));
     333        QApplication::postEvent (mView,
     334                                 new MouseCapabilityEvent (supportsAbsolute,
     335                                                           needsHostCursor));
    335336        return S_OK;
    336337    }
     
    339340    {
    340341        LogFlowFunc (("machineState=%d\n", machineState));
    341         QApplication::postEvent (
    342             view, new StateChangeEvent ((CEnums::MachineState) machineState));
     342        QApplication::postEvent (mView,
     343                                 new StateChangeEvent (
     344                                     (CEnums::MachineState) machineState));
    343345        return S_OK;
    344346    }
     
    346348    STDMETHOD(OnAdditionsStateChange)()
    347349    {
    348         CGuest guest = view->console().GetGuest();
     350        CGuest guest = mView->console().GetGuest();
    349351        LogFlowFunc (("ver=%s, active=%d\n",
    350352                      guest.GetAdditionsVersion().latin1(),
     
    356358    STDMETHOD(OnKeyboardLedsChange)(BOOL fNumLock, BOOL fCapsLock, BOOL fScrollLock)
    357359    {
    358         QApplication::postEvent (
    359             view, new ModifierKeyChangeEvent (fNumLock, fCapsLock, fScrollLock));
     360        QApplication::postEvent (mView,
     361                                 new ModifierKeyChangeEvent (fNumLock, fCapsLock,
     362                                                             fScrollLock));
    360363        return S_OK;
    361364    }
     
    363366    STDMETHOD(OnRuntimeError)(BOOL fatal, IN_BSTRPARAM id, IN_BSTRPARAM message)
    364367    {
    365         QApplication::postEvent (
    366             view, new RuntimeErrorEvent (!!fatal, QString::fromUcs2 (id),
    367                                          QString::fromUcs2 (message)));
     368        QApplication::postEvent (mView,
     369                                 new RuntimeErrorEvent (!!fatal,
     370                                                        QString::fromUcs2 (id),
     371                                                        QString::fromUcs2 (message)));
    368372        return S_OK;
    369373    }
    370374
    371     STDMETHOD(OnCanShowWindow)(BOOL *canShow)
     375    STDMETHOD(OnCanShowWindow) (BOOL *canShow)
    372376    {
    373377        if (!canShow)
    374378            return E_POINTER;
    375         /* @todo return TRUE... */
     379
     380#if defined (Q_WS_X11)
     381        /// @todo see the big comment in VBoxVMListBoxItem::switchTo()
    376382        *canShow = FALSE;
     383#else
     384        *canShow = TRUE;
     385#endif
    377386        return S_OK;
    378387    }
    379388
    380     STDMETHOD(OnShowWindow)()
    381     {
    382         /* @todo implement */
    383         return E_NOTIMPL;
     389    STDMETHOD(OnShowWindow) (ULONG64 *winId)
     390    {
     391        if (!winId)
     392            return E_POINTER;
     393
     394        /* Return the ID of the top-level console window. */
     395        *winId = (ULONG64) mView->topLevelWidget()->winId();
     396
     397        return S_OK;
    384398    }
    385399
    386400protected:
    387401
    388     VBoxConsoleView *view;
     402    VBoxConsoleView *mView;
    389403
    390404#if defined (Q_WS_WIN)
    391405private:
    392     long refcnt;
     406    long mRefCnt;
    393407#endif
    394408};
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxVMListBox.cpp

    r2139 r2540  
    3434#include <qfileinfo.h>
    3535
    36 #if defined (Q_WS_MAC)
     36#if defined (Q_WS_X11)
     37# include <X11/Xlib.h>
     38#elif defined (Q_WS_MAC)
    3739# include <Carbon/Carbon.h>
    3840#endif
     
    4244// Helpers
    4345////////////////////////////////////////////////////////////////////////////////
     46
     47/// @todo Remove. See @c todo in #switchTo() below.
     48#if 0
    4449
    4550#if defined (Q_WS_WIN32)
     
    136141}
    137142
     143#endif
     144
    138145////////////////////////////////////////////////////////////////////////////////
    139146// VBoxVMListBoxItem class
     
    367374        {
    368375            mPid = mMachine.GetSessionPid();
     376    /// @todo Remove. See @c todo in #switchTo() below.
     377#if 0
    369378            mWinId = FindWindowIdFromPid (mPid);
     379#endif
    370380        }
    371381        else
    372382        {
    373383            mPid = (ULONG) ~0;
     384    /// @todo Remove. See @c todo in #switchTo() below.
     385#if 0
    374386            mWinId = (WId) ~0;
     387#endif
    375388        }
    376389    }
     
    393406
    394407        mPid = (ULONG) ~0;
     408    /// @todo Remove. See @c todo in #switchTo() below.
     409#if 0
    395410        mWinId = (WId) ~0;
     411#endif
    396412    }
    397413
     
    507523
    508524/**
     525 * Returns @a true if we can activate and bring the VM console window to
     526 * foreground, and @a false otherwise.
     527 */
     528bool VBoxVMListBoxItem::canSwitchTo() const
     529{
     530    return const_cast <CMachine &> (mMachine).CanShowConsoleWindow();
     531
     532    /// @todo Remove. See @c todo in #switchTo() below.
     533#if 0
     534    return mWinId != (WId) ~0;
     535#endif
     536}
     537
     538/**
    509539 * Tries to switch to the main window of the VM process.
    510540 *
     
    513543bool VBoxVMListBoxItem::switchTo()
    514544{
     545    WId id = (WId) mMachine.ShowConsoleWindow();
     546    AssertWrapperOk (mMachine);
     547    if (!mMachine.isOk())
     548        return false;
     549
     550    /* winId = 0 it means the console window has already done everything
     551     * necessary to implement the "show window" semantics. */
     552    if (id == 0)
     553        return true;
     554
     555#if defined (Q_WS_WIN32)
     556
     557    if (IsIconic (id))
     558        ShowWindow (id, SW_RESTORE);
     559    else if (!IsWindowVisible (id))
     560        ShowWindow (id, SW_SHOW);
     561
     562    return SetForegroundWindow (id);
     563
     564#elif defined (Q_WS_X11)
     565
     566    /// @todo I've tried XRaiseWindow, XConfigureWindow, XRestackWindows and
     567    /// XSetInputFocus here but couldn't get a useless result under
     568    /// metacity/Ubuntu-7.04.  XSetInputFocus works, but XRaiseWindow and
     569    /// friends don't -- when it comes to bringing the window represented by
     570    /// the given id (or its parent) to front, on top of all other top-level
     571    /// windows. As a result, we would get input focus to a possibly invisible
     572    /// (obscured by others) window!.. I've found one way to steal raise
     573    /// window events from Metacity and prevent it from applying focus
     574    /// stealing prevention (by settings override_redirect to True on the id's
     575    /// parent using using XChangeWindowAttributes), but the result didn't
     576    /// satisfy me: the raised console window started to behave like an
     577    /// always-on-top window until moved or minimized which is wrong. Also,
     578    /// there is little hope that this approach will work for other window
     579    /// managers with "strong" focus stealing prevention algorithms, so I
     580    /// decided to completely disable this feature on X11 -- Until someone has
     581    /// enough time to find an acceptable solution that will work constantly
     582    /// well under at least selected window managers, and will be simply
     583    /// disabled on those where it doesn't work.
     584
     585    return false;
     586
     587#elif defined (Q_WS_MAC)
     588
     589    /// @todo (r=dmik) Knut, everything you have to do here is to raise the
     590    /// given window over all other top-level windows and give it focus. Ah,
     591    /// and deiconify/show it first if it is minimized/hidden. I really hope
     592    /// it's better on Mac than on X11. If not, feel free to revert to the
     593    /// previous pid-based behavior.
     594
     595    return false;
     596
     597#endif
     598
     599    return false;
     600
     601    /// @todo Below is the old method of switching to the console window
     602    //  based on the process ID of the console process. It should go away
     603    //  after the new (callback-based) method is fully tested.
     604#if 0
     605
    515606    if (!canSwitchTo())
    516607        return false;
     
    575666
    576667    return false;
     668
     669#endif
    577670
    578671#endif
  • trunk/src/VBox/Frontends/VirtualBox/src/main.cpp

    r2354 r2540  
    135135
    136136    QIApplication a (argc, argv);
     137
     138    /* weird palette test */
     139#if 0
     140    QPalette pal = a.palette();
     141    pal.setColor (QColorGroup::Background, Qt::red);
     142    pal.setBrush (QColorGroup::Background,
     143                  QBrush (QColor(),
     144                          QPixmap::fromMimeSource ("about_16px.png")));
     145    a.setPalette (pal);
     146#endif
    137147
    138148#ifdef Q_WS_X11
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r2527 r2540  
    35463546 *  @note Locks this object for reading.
    35473547 */
    3548 HRESULT Console::onShowWindow (BOOL aCheck, BOOL *aCanShow)
     3548HRESULT Console::onShowWindow (BOOL aCheck, BOOL *aCanShow, ULONG64 *aWinId)
    35493549{
    35503550    AssertReturn (aCanShow, E_POINTER);
     3551    AssertReturn (aWinId, E_POINTER);
    35513552
    35523553    *aCanShow = FALSE;
     3554    *aWinId = 0;
    35533555
    35543556    AutoCaller autoCaller (this);
     
    35763578        while (it != mCallbacks.end())
    35773579        {
    3578             rc = (*it++)->OnShowWindow();
     3580            ULONG64 winId = 0;
     3581            rc = (*it++)->OnShowWindow (&winId);
     3582            AssertComRC (rc);
    35793583            if (FAILED (rc))
    35803584                return rc;
     3585            /* only one callback may return non-null winId */
     3586            Assert (*aWinId == 0 || winId == 0);
     3587            if (*aWinId == 0)
     3588                *aWinId = winId;
    35813589        }
    35823590    }
  • trunk/src/VBox/Main/MachineImpl.cpp

    r2463 r2540  
    23012301
    23022302    /* start with No */
    2303     aCanShow = FALSE;
     2303    *aCanShow = FALSE;
    23042304
    23052305    AutoCaller autoCaller (this);
     
    23222322        return S_OK;
    23232323
    2324     return directControl->OnShowWindow (TRUE /* aCheck */, aCanShow);
    2325 }
    2326 
    2327 STDMETHODIMP Machine::ShowConsoleWindow()
    2328 {
     2324    ULONG64 dummy;
     2325    return directControl->OnShowWindow (TRUE /* aCheck */, aCanShow, &dummy);
     2326}
     2327
     2328STDMETHODIMP Machine::ShowConsoleWindow (ULONG64 *aWinId)
     2329{
     2330    if (!aWinId)
     2331        return E_POINTER;
     2332
    23292333    AutoCaller autoCaller (this);
    23302334    AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
     
    23472351
    23482352    BOOL dummy;
    2349     return directControl->OnShowWindow (FALSE /* aCheck */, &dummy);
     2353    return directControl->OnShowWindow (FALSE /* aCheck */, &dummy, aWinId);
    23502354}
    23512355
  • trunk/src/VBox/Main/SessionImpl.cpp

    r2463 r2540  
    590590}
    591591
    592 STDMETHODIMP Session::OnShowWindow (BOOL aCheck, BOOL *aCanShow)
     592STDMETHODIMP Session::OnShowWindow (BOOL aCheck, BOOL *aCanShow, ULONG64 *aWinId)
    593593{
    594594    AutoCaller autoCaller (this);
     
    599599                  mType == SessionType_DirectSession, E_FAIL);
    600600
    601     return mConsole->onShowWindow (aCheck, aCanShow);
     601    return mConsole->onShowWindow (aCheck, aCanShow, aWinId);
    602602}
    603603
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r2519 r2540  
    25852585        <method name="showConsoleWindow">
    25862586            <desc>
    2587                 Returns @c true if the VM console process can activate the
    2588                 console window and bring it to foreground on the desktop of
    2589                 the host PC.
     2587                Activates the console window and brings it to foreground on
     2588                the desktop of the host PC. Many modern window managers on
     2589                many platforms implement some sort of focus stealing
     2590                prevention logic, so that it may be impossible to activate
     2591                a window without the help of the currently active
     2592                application. In this case, this method will return a non-zero
     2593                identifier that represents the top-level window of the VM
     2594                console process. The caller, if it represents a currently
     2595                active process, is responsible to use this identifier (in a
     2596                platform-dependent manner) to perform actual window
     2597                activation.
    25902598                <note>
    25912599                    This method will fail if a session for this machine is not
     
    25932601                </note>
    25942602            </desc>
     2603            <param name="winId" type="unsigned long long" dir="return">
     2604                <desc>
     2605                  Platform-dependent identifier of the top-level VM console
     2606                  window, or zero if this method has performed all actions
     2607                  necessary to implement the <i>show window</i> semantics for
     2608                  the given platform and/or VirtualBox front-end.
     2609                </desc>
     2610            </param>
    25952611        </method>
    25962612
     
    28192835                method should return a failure.
    28202836
     2837                Note that many modern window managers on many platforms
     2838                implement some sort of focus stealing prevention logic, so
     2839                that it may be impossible to activate a window without the
     2840                help of the currently active application (which is supposedly
     2841                an initiator of this notification). In this case, this method
     2842                must return a non-zero identifier that represents the
     2843                top-level window of the VM console process. The caller, if it
     2844                represents a currently active process, is responsible to use
     2845                this identifier (in a platform-dependent manner) to perform
     2846                actual window activation.
     2847
     2848                This method must set @a winId to zero if it has performed all
     2849                actions necessary to complete the request and the console
     2850                window is now active and in foreground, to indicate that no
     2851                further action is required on the caller's side.
     2852
    28212853                <note>
    28222854                    This notification is not designed to be implemented by
     
    28282860                </note>
    28292861            </desc>
     2862            <param name="winId" type="unsigned long long" dir="return">
     2863                <desc>
     2864                    Platform-dependent identifier of the top-level VM console
     2865                    window, or zero if this method has performed all actions
     2866                    necessary to implement the <i>show window</i> semantics for
     2867                    the given platform and/or this VirtualBox front-end.
     2868                </desc>
     2869            </param>
    28302870        </method>
    28312871
     
    74157455            <param name="check" type="boolean" dir="in"/>
    74167456            <param name="canShow" type="boolean" dir="out"/>
     7457            <param name="winId" type="unsigned long long" dir="out"/>
    74177458        </method>
    74187459
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r2527 r2540  
    199199    void onKeyboardLedsChange (bool fNumLock, bool fCapsLock, bool fScrollLock);
    200200    void onRuntimeError (BOOL aFatal, INPTR BSTR aErrorID, INPTR BSTR aMessage);
    201     HRESULT onShowWindow (BOOL aCheck, BOOL *aCanShow);
     201    HRESULT onShowWindow (BOOL aCheck, BOOL *aCanShow, ULONG64 *aWinId);
    202202
    203203    static const PDMDRVREG DrvStatusReg;
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r2463 r2540  
    115115    }
    116116
    117     STDMETHOD(OnShowWindow)()
    118     {
     117    STDMETHOD(OnShowWindow)(ULONG64 *winId)
     118    {
     119        if (winId)
     120            *winId = 0;
    119121        return S_OK;
    120122    }
  • trunk/src/VBox/Main/include/MachineImpl.h

    r2463 r2540  
    367367    STDMETHOD(RemoveSharedFolder) (INPTR BSTR aName);
    368368    STDMETHOD(CanShowConsoleWindow) (BOOL *aCanShow);
    369     STDMETHOD(ShowConsoleWindow)();
     369    STDMETHOD(ShowConsoleWindow) (ULONG64 *aWinId);
    370370
    371371    // public methods only for internal purposes
  • trunk/src/VBox/Main/include/SessionImpl.h

    r2463 r2540  
    102102    STDMETHOD(OnUSBDeviceAttach) (IUSBDevice *aDevice);
    103103    STDMETHOD(OnUSBDeviceDetach) (INPTR GUIDPARAM aId);
    104     STDMETHOD(OnShowWindow) (BOOL aCheck, BOOL *aCanShow);
     104    STDMETHOD(OnShowWindow) (BOOL aCheck, BOOL *aCanShow, ULONG64 *aWinId);
    105105
    106106    // for VirtualBoxSupportErrorInfoImpl
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette