VirtualBox

Changeset 2708 in vbox for trunk/src


Ignore:
Timestamp:
May 18, 2007 12:58:15 PM (18 years ago)
Author:
vboxsync
Message:

FE/Qt: Implemented the "Show VM Window" functionality on X11.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h

    r2567 r2708  
    431431    static QString getFirstExistingDir (const QString &);
    432432
     433    static bool activateWindow (WId aWId, bool aSwitchDesktop = true);
     434
    433435signals:
    434436
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r2700 r2708  
    400400            return E_POINTER;
    401401
    402 #if defined (Q_WS_X11)
    403         /// @todo see the big comment in VBoxVMListBoxItem::switchTo()
    404         *canShow = FALSE;
    405 #else
     402        /* as long as there is VBoxConsoleView (which creates/destroys us), it
     403         * can be shown */
    406404        *canShow = TRUE;
    407 #endif
    408405        return S_OK;
    409406    }
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp

    r2567 r2708  
    4444#include <qprocess.h>
    4545
    46 #ifdef Q_WS_MAC
     46#if defined (Q_WS_MAC)
    4747#include <Carbon/Carbon.h> // for HIToolbox/InternetConfig
    4848#endif
    4949
    50 #ifdef Q_WS_WIN
     50#if defined (Q_WS_WIN)
    5151#include "shlobj.h"
    5252#include <qeventloop.h>
     53#endif
     54
     55#if defined (Q_WS_X11)
     56#undef BOOL /* typedef CARD8 BOOL in Xmd.h conflicts with #define BOOL PRBool
     57             * in COMDefs.h. A better fix would be to isolate X11-specific
     58             * stuff by placing XX* helpers below to a separate source file. */
     59#include <X11/X.h>
     60#include <X11/Xmd.h>
     61#include <X11/Xlib.h>
     62#include <X11/Xatom.h>
     63#define BOOL PRBool
    5364#endif
    5465
     
    27882799}
    27892800
     2801#if defined (Q_WS_X11)
     2802
     2803static char *XXGetProperty (Display *aDpy, Window aWnd,
     2804                            Atom aPropType, const char *aPropName)
     2805{
     2806    Atom propNameAtom = XInternAtom (aDpy, aPropName,
     2807                                     True /* only_if_exists */);
     2808    if (propNameAtom == None)
     2809        return NULL;
     2810
     2811    Atom actTypeAtom = None;
     2812    int actFmt = 0;
     2813    unsigned long nItems = 0;
     2814    unsigned long nBytesAfter = 0;
     2815    unsigned char *propVal = NULL;
     2816    int rc = XGetWindowProperty (aDpy, aWnd, propNameAtom,
     2817                                 0, LONG_MAX, False /* delete */,
     2818                                 aPropType, &actTypeAtom, &actFmt,
     2819                                 &nItems, &nBytesAfter, &propVal);
     2820    if (rc != Success)
     2821        return NULL;
     2822
     2823    return reinterpret_cast <char *> (propVal);
     2824}
     2825
     2826static Bool XXSendClientMessage (Display *aDpy, Window aWnd, const char *aMsg,
     2827                                 unsigned long aData0 = 0, unsigned long aData1 = 0,
     2828                                 unsigned long aData2 = 0, unsigned long aData3 = 0,
     2829                                 unsigned long aData4 = 0)
     2830{
     2831    Atom msgAtom = XInternAtom (aDpy, aMsg, True /* only_if_exists */);
     2832    if (msgAtom == None)
     2833        return False;
     2834
     2835    XEvent ev;
     2836
     2837    ev.xclient.type = ClientMessage;
     2838    ev.xclient.serial = 0;
     2839    ev.xclient.send_event = True;
     2840    ev.xclient.display = aDpy;
     2841    ev.xclient.window = aWnd;
     2842    ev.xclient.message_type = msgAtom;
     2843
     2844    /* always send as 32 bit for now */
     2845    ev.xclient.format = 32;
     2846    ev.xclient.data.l [0] = aData0;
     2847    ev.xclient.data.l [1] = aData1;
     2848    ev.xclient.data.l [2] = aData2;
     2849    ev.xclient.data.l [3] = aData3;
     2850    ev.xclient.data.l [4] = aData4;
     2851   
     2852    return XSendEvent (aDpy, DefaultRootWindow (aDpy), False,
     2853                       SubstructureRedirectMask, &ev) != 0;
     2854}
     2855
     2856#endif
     2857
     2858/**
     2859 * Activates the specified window. If necessary, the window will be
     2860 * de-iconified activation.
     2861 *
     2862 * @note On X11, it is implied that @a aWid represents a window of the same
     2863 * display the application was started on.
     2864 *
     2865 * @param aWId              Window ID to activate.       
     2866 * @param aSwitchDesktop    @c true to switch to the window's desktop before
     2867 *                          activation.
     2868 *
     2869 * @return @c true on success and @c false otherwise.
     2870 */
     2871/* static */
     2872bool VBoxGlobal::activateWindow (WId aWId, bool aSwitchDesktop /* = true */)
     2873{
     2874    bool result = true;
     2875
     2876#if defined (Q_WS_WIN32)
     2877
     2878    if (IsIconic (aWId))
     2879        result &= !!ShowWindow (aWId, SW_RESTORE);
     2880    else if (!IsWindowVisible (aWId))
     2881        result &= !!ShowWindow (aWId, SW_SHOW);
     2882
     2883    result &= !!SetForegroundWindow (aWId);
     2884
     2885#elif defined (Q_WS_X11)
     2886
     2887    Display *dpy = QPaintDevice::x11AppDisplay();
     2888
     2889    if (aSwitchDesktop)
     2890    {
     2891        /* try to find a desktop ID */
     2892        CARD32 *desktop = (CARD32 *) XXGetProperty (dpy, aWId, XA_CARDINAL,
     2893                                                    "_NET_WM_DESKTOP");
     2894        if (desktop == NULL)
     2895            desktop = (CARD32 *) XXGetProperty (dpy, aWId, XA_CARDINAL,
     2896                                                "_WIN_WORKSPACE");
     2897
     2898        if (desktop != NULL)
     2899        {
     2900            Bool ok = XXSendClientMessage (dpy, DefaultRootWindow (dpy),
     2901                                           "_NET_CURRENT_DESKTOP",
     2902                                           *desktop);
     2903            if (!ok)
     2904            {
     2905                LogWarningFunc (("Couldn't swith to desktop=%08X\n",
     2906                                 desktop));
     2907                result = false;
     2908            }
     2909            XFree (desktop);
     2910        }
     2911        else
     2912        {
     2913            LogWarningFunc (("Couldn't find a desktop ID for aWId=%08X\n",
     2914                             aWId));
     2915            result = false;
     2916        }
     2917    }
     2918
     2919    Bool ok = XXSendClientMessage (dpy, aWId, "_NET_ACTIVE_WINDOW");
     2920    result &= !!ok;
     2921
     2922    XRaiseWindow (dpy, aWId);
     2923
     2924#else
     2925
     2926    AssertFailed();
     2927    result = false;
     2928
     2929#endif
     2930
     2931    if (!result)
     2932        LogWarningFunc (("Couldn't activate aWId=%08X\n", aWId));
     2933
     2934    return result;
     2935}
    27902936
    27912937// Protected members
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxVMListBox.cpp

    r2567 r2708  
    3434#include <qfileinfo.h>
    3535
    36 #if defined (Q_WS_X11)
    37 # include <X11/Xlib.h>
    38 #elif defined (Q_WS_MAC)
     36/// @todo Remove? See @c todo in #switchTo() below.
     37#if defined (Q_WS_MAC)
    3938# include <Carbon/Carbon.h>
    4039#endif
    4140
    4241
    43 ////////////////////////////////////////////////////////////////////////////////
    4442// Helpers
    4543////////////////////////////////////////////////////////////////////////////////
     
    553551        return true;
    554552
    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;
     553#if defined (Q_WS_WIN32) || defined (Q_WS_X11)
     554
     555    return vboxGlobal().activateWindow (id, true);
    586556
    587557#elif defined (Q_WS_MAC)
Note: See TracChangeset for help on using the changeset viewer.

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