Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/gui/kernel/qapplication_x11.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    7575#include "qvarlengtharray.h"
    7676#include "qdebug.h"
    77 #include <private/qunicodetables_p.h>
    7877#include <private/qcrashhandler_p.h>
    7978#include <private/qcolor_p.h>
     
    214213
    215214    "DTWM_IS_RUNNING\0"
    216     "KDE_FULL_SESSION\0"
    217     "KWIN_RUNNING\0"
    218     "KWM_RUNNING\0"
    219     "GNOME_BACKGROUND_PROPERTIES\0"
    220215    "ENLIGHTENMENT_DESKTOP\0"
     216    "_DT_SAVE_MODE\0"
    221217    "_SGI_DESKS_MANAGER\0"
    222218
     
    279275    "_NET_SYSTEM_TRAY_VISUAL\0"
    280276
     277    "_NET_ACTIVE_WINDOW\0"
     278
    281279    // Property formats
    282280    "COMPOUND_TEXT\0"
     
    402400#endif
    403401
     402typedef bool(*QX11FilterFunction)(XEvent *event);
     403
     404Q_GLOBAL_STATIC(QList<QX11FilterFunction>, x11Filters)
     405
     406Q_GUI_EXPORT void qt_installX11EventFilter(QX11FilterFunction func)
     407{
     408    Q_ASSERT(func);
     409
     410    if (QList<QX11FilterFunction> *list = x11Filters())
     411        list->append(func);
     412}
     413
     414Q_GUI_EXPORT void qt_removeX11EventFilter(QX11FilterFunction func)
     415{
     416    Q_ASSERT(func);
     417
     418    if (QList<QX11FilterFunction> *list = x11Filters())
     419        list->removeOne(func);
     420}
     421
     422
    404423static bool qt_x11EventFilter(XEvent* ev)
    405424{
     
    407426    if (qApp->filterEvent(ev, &unused))
    408427        return true;
     428    if (const QList<QX11FilterFunction> *list = x11Filters()) {
     429        for (QList<QX11FilterFunction>::const_iterator it = list->constBegin(); it != list->constEnd(); ++it) {
     430            if ((*it)(ev))
     431                return true;
     432        }
     433    }
     434
    409435    return qApp->x11EventFilter(ev);
    410436}
     
    625651static int qt_x_errhandler(Display *dpy, XErrorEvent *err)
    626652{
     653    if (X11->display != dpy) {
     654        // only handle X errors for our display
     655        return 0;
     656    }
     657
    627658    switch (err->error_code) {
    628659    case BadAtom:
     
    632663                || err->resourceid == ATOM(_NET_SUPPORTED)
    633664                || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK)
    634                 || err->resourceid == ATOM(KDE_FULL_SESSION)
    635                 || err->resourceid == ATOM(KWIN_RUNNING)
    636665                || err->resourceid == ATOM(XdndProxy)
    637666                || err->resourceid == ATOM(XdndAware))) {
     
    665694        }
    666695        if (X11->ignore_badwindow)
    667             return 0;
    668         break;
    669 
    670     case BadMatch:
    671         if (err->request_code == 42 /* X_SetInputFocus */)
    672696            return 0;
    673697        break;
     
    710734        else if (err->request_code == X11->mitshm_major)
    711735            extensionName = "MIT-SHM";
     736#ifndef QT_NO_XKB
     737        else if(err->request_code == X11->xkb_major)
     738            extensionName = "XKEYBOARD";
     739#endif
    712740
    713741        char minor_str[256];
     
    16351663    X11->xinput_eventbase = 0;
    16361664    X11->xinput_errorbase = 0;
     1665
     1666    X11->use_xkb = false;
     1667    X11->xkb_major = 0;
     1668    X11->xkb_eventbase = 0;
     1669    X11->xkb_errorbase = 0;
    16371670
    16381671    // MIT-SHM
     
    21092142#endif // QT_NO_XINPUT
    21102143
     2144#ifndef QT_NO_XKB
     2145        int xkblibMajor = XkbMajorVersion;
     2146        int xkblibMinor = XkbMinorVersion;
     2147        X11->use_xkb = XkbQueryExtension(X11->display,
     2148                                         &X11->xkb_major,
     2149                                         &X11->xkb_eventbase,
     2150                                         &X11->xkb_errorbase,
     2151                                         &xkblibMajor,
     2152                                         &xkblibMinor);
     2153        if (X11->use_xkb) {
     2154            // If XKB is detected, set the GrabsUseXKBState option so input method
     2155            // compositions continue to work (ie. deadkeys)
     2156            unsigned int state = XkbPCF_GrabsUseXKBStateMask;
     2157            (void) XkbSetPerClientControls(X11->display, state, &state);
     2158
     2159            // select for group change events
     2160            XkbSelectEventDetails(X11->display,
     2161                                  XkbUseCoreKbd,
     2162                                  XkbStateNotify,
     2163                                  XkbAllStateComponentsMask,
     2164                                  XkbGroupStateMask);
     2165
     2166            // current group state is queried when creating the keymapper, no need to do it here
     2167        }
     2168#endif
     2169
     2170
    21112171#if !defined(QT_NO_FONTCONFIG)
    21122172        int dpi = 0;
     
    21232183        for (int s = 0; s < ScreenCount(X11->display); ++s) {
    21242184            int subpixel = FC_RGBA_UNKNOWN;
    2125 #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
     2185#if !defined(QT_NO_XRENDER) && (RENDER_MAJOR > 0 || RENDER_MINOR >= 6)
    21262186            if (X11->use_xrender) {
    21272187                int rsp = XRenderQuerySubpixelOrder(X11->display, s);
     
    21872247        QKeyMapper::changeKeyboard();
    21882248
    2189 #ifndef QT_NO_XKB
    2190         if (qt_keymapper_private()->useXKB) {
    2191             // If XKB is detected, set the GrabsUseXKBState option so input method
    2192             // compositions continue to work (ie. deadkeys)
    2193             unsigned int state = XkbPCF_GrabsUseXKBStateMask;
    2194             (void) XkbSetPerClientControls(X11->display, state, &state);
    2195         }
    2196 #endif // QT_NO_XKB
    2197 
    21982249        // Misc. initialization
    21992250#if 0 //disabled for now..
     
    22282279        X11->desktopVersion = 0;
    22292280
    2230         // See if the current window manager is using the freedesktop.org spec to give its name
    2231         Window windowManagerWindow = XNone;
    2232         Atom typeReturned;
    2233         int formatReturned;
    2234         unsigned long nitemsReturned;
    2235         unsigned long unused;
    2236         unsigned char *data = 0;
    2237         if (XGetWindowProperty(QX11Info::display(), QX11Info::appRootWindow(),
    2238                            ATOM(_NET_SUPPORTING_WM_CHECK),
    2239                            0, 1024, False, XA_WINDOW, &typeReturned,
    2240                            &formatReturned, &nitemsReturned, &unused, &data)
    2241               == Success) {
    2242             if (typeReturned == XA_WINDOW && formatReturned == 32)
    2243                 windowManagerWindow = *((Window*) data);
    2244             if (data)
     2281        Atom type;
     2282        int format;
     2283        unsigned long length, after;
     2284        uchar *data = 0;
     2285        int rc;
     2286
     2287        do {
     2288            if (!qgetenv("KDE_FULL_SESSION").isEmpty()) {
     2289                X11->desktopEnvironment = DE_KDE;
     2290                X11->desktopVersion = qgetenv("KDE_SESSION_VERSION").toInt();
     2291                break;
     2292            }
     2293
     2294            if (qgetenv("DESKTOP_SESSION") == "gnome") {
     2295                X11->desktopEnvironment = DE_GNOME;
     2296                break;
     2297            }
     2298
     2299            // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it
     2300            if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
     2301                X11->desktopEnvironment = DE_GNOME;
     2302                break;
     2303            }
     2304
     2305            rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE),
     2306                                    0, 2, False, XA_STRING, &type, &format, &length,
     2307                                    &after, &data);
     2308            if (rc == Success && length) {
     2309                if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) {
     2310                    // Pretend that xfce4 is gnome, as it uses the same libraries.
     2311                    // The detection above is stolen from xdg-open.
     2312                    X11->desktopEnvironment = DE_GNOME;
     2313                    break;
     2314                }
     2315
     2316                // We got the property but it wasn't xfce4. Free data before it gets overwritten.
    22452317                XFree(data);
    2246 
    2247             if (windowManagerWindow != XNone) {
    2248                 QString wmName;
    2249                 Atom utf8atom = ATOM(UTF8_STRING);
    2250                 if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
    2251                                        0, 1024, False, utf8atom, &typeReturned,
    2252                                        &formatReturned, &nitemsReturned, &unused, &data)
    2253                     == Success) {
    2254                     if (typeReturned == utf8atom && formatReturned == 8)
    2255                         wmName = QString::fromUtf8((const char*)data);
    2256                     if (data)
    2257                         XFree(data);
    2258                     if (wmName == QLatin1String("KWin"))
    2259                         X11->desktopEnvironment = DE_KDE;
    2260                     if (wmName == QLatin1String("Metacity"))
    2261                         X11->desktopEnvironment = DE_GNOME;
    2262                 }
    2263             }
    2264         }
    2265 
    2266         // Running a different/newer/older window manager?  Try some other things
    2267         if (X11->desktopEnvironment == DE_UNKNOWN){
    2268             Atom type;
    2269             int format;
    2270             unsigned long length, after;
    2271             uchar *data = 0;
    2272 
    2273             QString session = QString::fromLocal8Bit(qgetenv("DESKTOP_SESSION"));
    2274             if (session == QLatin1String("kde")) {
    2275                 X11->desktopEnvironment = DE_KDE;
    2276             } else if (session == QLatin1String("gnome") || session == QLatin1String("xfce")) {
    2277                 X11->desktopEnvironment = DE_GNOME;
    2278             } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
    2279                                           0, 1, False, AnyPropertyType, &type, &format, &length,
    2280                                    &after, &data) == Success && length) {
     2318                data = 0;
     2319            }
     2320
     2321            rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING),
     2322                                    0, 1, False, AnyPropertyType, &type, &format, &length,
     2323                                    &after, &data);
     2324            if (rc == Success && length) {
    22812325                // DTWM is running, meaning most likely CDE is running...
    22822326                X11->desktopEnvironment = DE_CDE;
    2283             } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
    2284                                           ATOM(GNOME_BACKGROUND_PROPERTIES), 0, 1, False, AnyPropertyType,
    2285                                           &type, &format, &length, &after, &data) == Success && length) {
    2286                 X11->desktopEnvironment = DE_GNOME;
    2287             } else if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
    2288                 X11->desktopEnvironment = DE_GNOME;
    2289             } else if ((XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KDE_FULL_SESSION),
    2290                                            0, 1, False, AnyPropertyType, &type, &format, &length, &after, &data) == Success
    2291                         && length)
    2292                        || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWIN_RUNNING),
    2293                                               0, 1, False, AnyPropertyType, &type, &format, &length,
    2294                                               &after, &data) == Success
    2295                            && length)
    2296                        || (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KWM_RUNNING),
    2297                                               0, 1, False, AnyPropertyType, &type, &format, &length,
    2298                                               &after, &data) == Success && length)) {
    2299                 X11->desktopEnvironment = DE_KDE;
    2300             } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_SGI_DESKS_MANAGER),
    2301                                           0, 1, False, XA_WINDOW, &type, &format, &length, &after, &data) == Success
    2302                        && length) {
     2327                break;
     2328            }
     2329
     2330            rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
     2331                                    ATOM(_SGI_DESKS_MANAGER), 0, 1, False, XA_WINDOW,
     2332                                    &type, &format, &length, &after, &data);
     2333            if (rc == Success && length) {
    23032334                X11->desktopEnvironment = DE_4DWM;
    2304             }
    2305             if (data)
    2306                 XFree((char *)data);
    2307         }
    2308 
    2309         if (X11->desktopEnvironment == DE_KDE)
    2310             X11->desktopVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt();
     2335                break;
     2336            }
     2337
     2338            if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(),
     2339                               ATOM(_NET_SUPPORTING_WM_CHECK),
     2340                               0, 1024, False, XA_WINDOW, &type,
     2341                               &format, &length, &after, &data) == Success) {
     2342                if (type == XA_WINDOW && format == 32) {
     2343                    Window windowManagerWindow = *((Window*) data);
     2344                    XFree(data);
     2345                    data = 0;
     2346
     2347                    if (windowManagerWindow != XNone) {
     2348                        Atom utf8atom = ATOM(UTF8_STRING);
     2349                        if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME),
     2350                                               0, 1024, False, utf8atom, &type,
     2351                                               &format, &length, &after, &data) == Success) {
     2352                            if (type == utf8atom && format == 8) {
     2353                                if (qstrcmp((const char *)data, "MCompositor") == 0)
     2354                                    X11->desktopEnvironment = DE_MEEGO_COMPOSITOR;
     2355                            }
     2356                        }
     2357                    }
     2358                }
     2359            }
     2360
     2361        } while(0);
     2362
     2363        if (data)
     2364            XFree((char *)data);
    23112365
    23122366#if !defined(QT_NO_STYLE_GTK)
     
    30533107                    X11->time = event->xclient.data.l[1];
    30543108                QWidget *amw = activeModalWidget();
     3109                if (amw && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus))
     3110                    amw = 0;
    30553111                if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) {
    30563112                    QWidget *p = amw->parentWidget();
     
    32513307        return 0;
    32523308    }
     3309#ifndef QT_NO_XKB
     3310    else if (X11->use_xkb && event->type == X11->xkb_eventbase) {
     3311        XkbAnyEvent *xkbevent = (XkbAnyEvent *) event;
     3312        switch (xkbevent->xkb_type) {
     3313        case XkbStateNotify:
     3314            {
     3315                XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent;
     3316                if ((xkbstateevent->changed & XkbGroupStateMask) != 0) {
     3317                    qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group;
     3318                    QKeyMapper::changeKeyboard();
     3319                }
     3320                break;
     3321            }
     3322        default:
     3323            break;
     3324        }
     3325    }
     3326#endif
    32533327
    32543328    if (!widget) {                                // don't know this windows
     
    36203694    case MapNotify:                                // window shown
    36213695        if (widget->isWindow()) {
     3696            // if we got a MapNotify when we were not waiting for it, it most
     3697            // likely means the user has already asked to hide the window before
     3698            // it ever being shown, so we try to withdraw a window after sending
     3699            // the QShowEvent.
     3700            bool pendingHide = widget->testAttribute(Qt::WA_WState_ExplicitShowHide) && widget->testAttribute(Qt::WA_WState_Hidden);
    36223701            widget->d_func()->topData()->waitingForMapNotify = 0;
    36233702
     
    36393718                }
    36403719            }
     3720            if (pendingHide) // hide the window
     3721                XWithdrawWindow(X11->display, widget->internalWinId(), widget->x11Info().screen());
    36413722        }
    36423723        break;
     
    36863767                QWidget *newparent = QWidget::find(event->xreparent.parent);
    36873768                if (! newparent || (newparent->windowType() == Qt::Desktop)) {
    3688                     // we dont' know about the new parent (or we've been
     3769                    // we don't know about the new parent (or we've been
    36893770                    // reparented to root), perhaps a window manager
    36903771                    // has been (re)started?  reset the focus model to unknown
     
    52465327        if (isVisible() && data->crect.size() != oldSize) {
    52475328            Q_ASSERT(d->extra->topextra);
    5248             QWidgetBackingStore *bs = d->extra->topextra->backingStore;
     5329            QWidgetBackingStore *bs = d->extra->topextra->backingStore.data();
    52495330            const bool hasStaticContents = bs && bs->hasStaticContents();
    52505331            // If we have a backing store with static contents, we have to disable the top-level
Note: See TracChangeset for help on using the changeset viewer.