Changeset 846 for trunk/src/gui/kernel/qapplication_x11.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/gui/kernel/qapplication_x11.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 75 75 #include "qvarlengtharray.h" 76 76 #include "qdebug.h" 77 #include <private/qunicodetables_p.h>78 77 #include <private/qcrashhandler_p.h> 79 78 #include <private/qcolor_p.h> … … 214 213 215 214 "DTWM_IS_RUNNING\0" 216 "KDE_FULL_SESSION\0"217 "KWIN_RUNNING\0"218 "KWM_RUNNING\0"219 "GNOME_BACKGROUND_PROPERTIES\0"220 215 "ENLIGHTENMENT_DESKTOP\0" 216 "_DT_SAVE_MODE\0" 221 217 "_SGI_DESKS_MANAGER\0" 222 218 … … 279 275 "_NET_SYSTEM_TRAY_VISUAL\0" 280 276 277 "_NET_ACTIVE_WINDOW\0" 278 281 279 // Property formats 282 280 "COMPOUND_TEXT\0" … … 402 400 #endif 403 401 402 typedef bool(*QX11FilterFunction)(XEvent *event); 403 404 Q_GLOBAL_STATIC(QList<QX11FilterFunction>, x11Filters) 405 406 Q_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 414 Q_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 404 423 static bool qt_x11EventFilter(XEvent* ev) 405 424 { … … 407 426 if (qApp->filterEvent(ev, &unused)) 408 427 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 409 435 return qApp->x11EventFilter(ev); 410 436 } … … 625 651 static int qt_x_errhandler(Display *dpy, XErrorEvent *err) 626 652 { 653 if (X11->display != dpy) { 654 // only handle X errors for our display 655 return 0; 656 } 657 627 658 switch (err->error_code) { 628 659 case BadAtom: … … 632 663 || err->resourceid == ATOM(_NET_SUPPORTED) 633 664 || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK) 634 || err->resourceid == ATOM(KDE_FULL_SESSION)635 || err->resourceid == ATOM(KWIN_RUNNING)636 665 || err->resourceid == ATOM(XdndProxy) 637 666 || err->resourceid == ATOM(XdndAware))) { … … 665 694 } 666 695 if (X11->ignore_badwindow) 667 return 0;668 break;669 670 case BadMatch:671 if (err->request_code == 42 /* X_SetInputFocus */)672 696 return 0; 673 697 break; … … 710 734 else if (err->request_code == X11->mitshm_major) 711 735 extensionName = "MIT-SHM"; 736 #ifndef QT_NO_XKB 737 else if(err->request_code == X11->xkb_major) 738 extensionName = "XKEYBOARD"; 739 #endif 712 740 713 741 char minor_str[256]; … … 1635 1663 X11->xinput_eventbase = 0; 1636 1664 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; 1637 1670 1638 1671 // MIT-SHM … … 2109 2142 #endif // QT_NO_XINPUT 2110 2143 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 2111 2171 #if !defined(QT_NO_FONTCONFIG) 2112 2172 int dpi = 0; … … 2123 2183 for (int s = 0; s < ScreenCount(X11->display); ++s) { 2124 2184 int subpixel = FC_RGBA_UNKNOWN; 2125 #if RENDER_MAJOR > 0 || RENDER_MINOR >= 62185 #if !defined(QT_NO_XRENDER) && (RENDER_MAJOR > 0 || RENDER_MINOR >= 6) 2126 2186 if (X11->use_xrender) { 2127 2187 int rsp = XRenderQuerySubpixelOrder(X11->display, s); … … 2187 2247 QKeyMapper::changeKeyboard(); 2188 2248 2189 #ifndef QT_NO_XKB2190 if (qt_keymapper_private()->useXKB) {2191 // If XKB is detected, set the GrabsUseXKBState option so input method2192 // compositions continue to work (ie. deadkeys)2193 unsigned int state = XkbPCF_GrabsUseXKBStateMask;2194 (void) XkbSetPerClientControls(X11->display, state, &state);2195 }2196 #endif // QT_NO_XKB2197 2198 2249 // Misc. initialization 2199 2250 #if 0 //disabled for now.. … … 2228 2279 X11->desktopVersion = 0; 2229 2280 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. 2245 2317 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) { 2281 2325 // DTWM is running, meaning most likely CDE is running... 2282 2326 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) { 2303 2334 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); 2311 2365 2312 2366 #if !defined(QT_NO_STYLE_GTK) … … 3053 3107 X11->time = event->xclient.data.l[1]; 3054 3108 QWidget *amw = activeModalWidget(); 3109 if (amw && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus)) 3110 amw = 0; 3055 3111 if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) { 3056 3112 QWidget *p = amw->parentWidget(); … … 3251 3307 return 0; 3252 3308 } 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 3253 3327 3254 3328 if (!widget) { // don't know this windows … … 3620 3694 case MapNotify: // window shown 3621 3695 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); 3622 3701 widget->d_func()->topData()->waitingForMapNotify = 0; 3623 3702 … … 3639 3718 } 3640 3719 } 3720 if (pendingHide) // hide the window 3721 XWithdrawWindow(X11->display, widget->internalWinId(), widget->x11Info().screen()); 3641 3722 } 3642 3723 break; … … 3686 3767 QWidget *newparent = QWidget::find(event->xreparent.parent); 3687 3768 if (! newparent || (newparent->windowType() == Qt::Desktop)) { 3688 // we don t'know about the new parent (or we've been3769 // we don't know about the new parent (or we've been 3689 3770 // reparented to root), perhaps a window manager 3690 3771 // has been (re)started? reset the focus model to unknown … … 5246 5327 if (isVisible() && data->crect.size() != oldSize) { 5247 5328 Q_ASSERT(d->extra->topextra); 5248 QWidgetBackingStore *bs = d->extra->topextra->backingStore ;5329 QWidgetBackingStore *bs = d->extra->topextra->backingStore.data(); 5249 5330 const bool hasStaticContents = bs && bs->hasStaticContents(); 5250 5331 // 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.