changeset 30 | 5dc02b23752f |
parent 19 | fcece45ef507 |
child 33 | 3e2da88830cd |
29:b72c6db6890b | 30:5dc02b23752f |
---|---|
211 "_QT_INPUT_ENCODING\0" |
211 "_QT_INPUT_ENCODING\0" |
212 |
212 |
213 "_MOTIF_WM_HINTS\0" |
213 "_MOTIF_WM_HINTS\0" |
214 |
214 |
215 "DTWM_IS_RUNNING\0" |
215 "DTWM_IS_RUNNING\0" |
216 "KDE_FULL_SESSION\0" |
|
217 "KWIN_RUNNING\0" |
|
218 "KWM_RUNNING\0" |
|
219 "GNOME_BACKGROUND_PROPERTIES\0" |
|
220 "ENLIGHTENMENT_DESKTOP\0" |
216 "ENLIGHTENMENT_DESKTOP\0" |
217 "_DT_SAVE_MODE\0" |
|
221 "_SGI_DESKS_MANAGER\0" |
218 "_SGI_DESKS_MANAGER\0" |
222 |
219 |
223 // EWMH (aka NETWM) |
220 // EWMH (aka NETWM) |
224 "_NET_SUPPORTED\0" |
221 "_NET_SUPPORTED\0" |
225 "_NET_VIRTUAL_ROOTS\0" |
222 "_NET_VIRTUAL_ROOTS\0" |
276 |
273 |
277 "_NET_WM_CM_S0\0" |
274 "_NET_WM_CM_S0\0" |
278 |
275 |
279 "_NET_SYSTEM_TRAY_VISUAL\0" |
276 "_NET_SYSTEM_TRAY_VISUAL\0" |
280 |
277 |
278 "_NET_ACTIVE_WINDOW\0" |
|
279 |
|
281 // Property formats |
280 // Property formats |
282 "COMPOUND_TEXT\0" |
281 "COMPOUND_TEXT\0" |
283 "TEXT\0" |
282 "TEXT\0" |
284 "UTF8_STRING\0" |
283 "UTF8_STRING\0" |
285 |
284 |
622 static int (*original_x_errhandler)(Display *dpy, XErrorEvent *); |
621 static int (*original_x_errhandler)(Display *dpy, XErrorEvent *); |
623 static int (*original_xio_errhandler)(Display *dpy); |
622 static int (*original_xio_errhandler)(Display *dpy); |
624 |
623 |
625 static int qt_x_errhandler(Display *dpy, XErrorEvent *err) |
624 static int qt_x_errhandler(Display *dpy, XErrorEvent *err) |
626 { |
625 { |
626 if (X11->display != dpy) { |
|
627 // only handle X errors for our display |
|
628 return 0; |
|
629 } |
|
630 |
|
627 switch (err->error_code) { |
631 switch (err->error_code) { |
628 case BadAtom: |
632 case BadAtom: |
629 if (err->request_code == 20 /* X_GetProperty */ |
633 if (err->request_code == 20 /* X_GetProperty */ |
630 && (err->resourceid == XA_RESOURCE_MANAGER |
634 && (err->resourceid == XA_RESOURCE_MANAGER |
631 || err->resourceid == XA_RGB_DEFAULT_MAP |
635 || err->resourceid == XA_RGB_DEFAULT_MAP |
632 || err->resourceid == ATOM(_NET_SUPPORTED) |
636 || err->resourceid == ATOM(_NET_SUPPORTED) |
633 || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK) |
637 || err->resourceid == ATOM(_NET_SUPPORTING_WM_CHECK) |
634 || err->resourceid == ATOM(KDE_FULL_SESSION) |
|
635 || err->resourceid == ATOM(KWIN_RUNNING) |
|
636 || err->resourceid == ATOM(XdndProxy) |
638 || err->resourceid == ATOM(XdndProxy) |
637 || err->resourceid == ATOM(XdndAware))) { |
639 || err->resourceid == ATOM(XdndAware))) { |
638 // Perhaps we're running under SECURITY reduction? :/ |
640 // Perhaps we're running under SECURITY reduction? :/ |
639 return 0; |
641 return 0; |
640 } |
642 } |
662 qDebug("xdndHandleBadwindow returned true"); |
664 qDebug("xdndHandleBadwindow returned true"); |
663 return 0; |
665 return 0; |
664 } |
666 } |
665 } |
667 } |
666 if (X11->ignore_badwindow) |
668 if (X11->ignore_badwindow) |
667 return 0; |
|
668 break; |
|
669 |
|
670 case BadMatch: |
|
671 if (err->request_code == 42 /* X_SetInputFocus */) |
|
672 return 0; |
669 return 0; |
673 break; |
670 break; |
674 |
671 |
675 default: |
672 default: |
676 #if !defined(QT_NO_XINPUT) |
673 #if !defined(QT_NO_XINPUT) |
707 extensionName = "RANDR"; |
704 extensionName = "RANDR"; |
708 else if (err->request_code == X11->xinput_major) |
705 else if (err->request_code == X11->xinput_major) |
709 extensionName = "XInputExtension"; |
706 extensionName = "XInputExtension"; |
710 else if (err->request_code == X11->mitshm_major) |
707 else if (err->request_code == X11->mitshm_major) |
711 extensionName = "MIT-SHM"; |
708 extensionName = "MIT-SHM"; |
709 #ifndef QT_NO_XKB |
|
710 else if(err->request_code == X11->xkb_major) |
|
711 extensionName = "XKEYBOARD"; |
|
712 #endif |
|
712 |
713 |
713 char minor_str[256]; |
714 char minor_str[256]; |
714 if (extensionName) { |
715 if (extensionName) { |
715 qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code); |
716 qsnprintf(buffer, 256, "%s.%d", extensionName, err->minor_code); |
716 XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256); |
717 XGetErrorDatabaseText(dpy, "XRequest", buffer, "", minor_str, 256); |
1632 // XInputExtension |
1633 // XInputExtension |
1633 X11->use_xinput = false; |
1634 X11->use_xinput = false; |
1634 X11->xinput_major = 0; |
1635 X11->xinput_major = 0; |
1635 X11->xinput_eventbase = 0; |
1636 X11->xinput_eventbase = 0; |
1636 X11->xinput_errorbase = 0; |
1637 X11->xinput_errorbase = 0; |
1638 |
|
1639 X11->use_xkb = false; |
|
1640 X11->xkb_major = 0; |
|
1641 X11->xkb_eventbase = 0; |
|
1642 X11->xkb_errorbase = 0; |
|
1637 |
1643 |
1638 // MIT-SHM |
1644 // MIT-SHM |
1639 X11->use_mitshm = false; |
1645 X11->use_mitshm = false; |
1640 X11->use_mitshm_pixmaps = false; |
1646 X11->use_mitshm_pixmaps = false; |
1641 X11->mitshm_major = 0; |
1647 X11->mitshm_major = 0; |
2106 X11->ptrXFreeDeviceList = XINPUT_LOAD(XFreeDeviceList); |
2112 X11->ptrXFreeDeviceList = XINPUT_LOAD(XFreeDeviceList); |
2107 X11->ptrXSelectExtensionEvent = XINPUT_LOAD(XSelectExtensionEvent); |
2113 X11->ptrXSelectExtensionEvent = XINPUT_LOAD(XSelectExtensionEvent); |
2108 } |
2114 } |
2109 #endif // QT_NO_XINPUT |
2115 #endif // QT_NO_XINPUT |
2110 |
2116 |
2117 #ifndef QT_NO_XKB |
|
2118 int xkblibMajor = XkbMajorVersion; |
|
2119 int xkblibMinor = XkbMinorVersion; |
|
2120 X11->use_xkb = XkbQueryExtension(X11->display, |
|
2121 &X11->xkb_major, |
|
2122 &X11->xkb_eventbase, |
|
2123 &X11->xkb_errorbase, |
|
2124 &xkblibMajor, |
|
2125 &xkblibMinor); |
|
2126 if (X11->use_xkb) { |
|
2127 // If XKB is detected, set the GrabsUseXKBState option so input method |
|
2128 // compositions continue to work (ie. deadkeys) |
|
2129 unsigned int state = XkbPCF_GrabsUseXKBStateMask; |
|
2130 (void) XkbSetPerClientControls(X11->display, state, &state); |
|
2131 |
|
2132 // select for group change events |
|
2133 XkbSelectEventDetails(X11->display, |
|
2134 XkbUseCoreKbd, |
|
2135 XkbStateNotify, |
|
2136 XkbAllStateComponentsMask, |
|
2137 XkbGroupStateMask); |
|
2138 |
|
2139 // current group state is queried when creating the keymapper, no need to do it here |
|
2140 } |
|
2141 #endif |
|
2142 |
|
2143 |
|
2111 #if !defined(QT_NO_FONTCONFIG) |
2144 #if !defined(QT_NO_FONTCONFIG) |
2112 int dpi = 0; |
2145 int dpi = 0; |
2113 getXDefault("Xft", FC_DPI, &dpi); |
2146 getXDefault("Xft", FC_DPI, &dpi); |
2114 if (dpi) { |
2147 if (dpi) { |
2115 for (int s = 0; s < ScreenCount(X11->display); ++s) { |
2148 for (int s = 0; s < ScreenCount(X11->display); ++s) { |
2184 #endif // QT_NO_XRENDER |
2217 #endif // QT_NO_XRENDER |
2185 |
2218 |
2186 // initialize key mapper |
2219 // initialize key mapper |
2187 QKeyMapper::changeKeyboard(); |
2220 QKeyMapper::changeKeyboard(); |
2188 |
2221 |
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 |
|
2198 // Misc. initialization |
2222 // Misc. initialization |
2199 #if 0 //disabled for now.. |
2223 #if 0 //disabled for now.. |
2200 QSegfaultHandler::initialize(priv->argv, priv->argc); |
2224 QSegfaultHandler::initialize(priv->argv, priv->argc); |
2201 #endif |
2225 #endif |
2202 QCursorData::initialize(); |
2226 QCursorData::initialize(); |
2225 X11->compositingManagerRunning = XGetSelectionOwner(X11->display, |
2249 X11->compositingManagerRunning = XGetSelectionOwner(X11->display, |
2226 ATOM(_NET_WM_CM_S0)); |
2250 ATOM(_NET_WM_CM_S0)); |
2227 X11->desktopEnvironment = DE_UNKNOWN; |
2251 X11->desktopEnvironment = DE_UNKNOWN; |
2228 X11->desktopVersion = 0; |
2252 X11->desktopVersion = 0; |
2229 |
2253 |
2230 // See if the current window manager is using the freedesktop.org spec to give its name |
2254 Atom type; |
2231 Window windowManagerWindow = XNone; |
2255 int format; |
2232 Atom typeReturned; |
2256 unsigned long length, after; |
2233 int formatReturned; |
2257 uchar *data = 0; |
2234 unsigned long nitemsReturned; |
2258 int rc; |
2235 unsigned long unused; |
2259 |
2236 unsigned char *data = 0; |
2260 do { |
2237 if (XGetWindowProperty(QX11Info::display(), QX11Info::appRootWindow(), |
2261 if (!qgetenv("KDE_FULL_SESSION").isEmpty()) { |
2238 ATOM(_NET_SUPPORTING_WM_CHECK), |
2262 X11->desktopEnvironment = DE_KDE; |
2239 0, 1024, False, XA_WINDOW, &typeReturned, |
2263 X11->desktopVersion = qgetenv("KDE_SESSION_VERSION").toInt(); |
2240 &formatReturned, &nitemsReturned, &unused, &data) |
2264 break; |
2241 == Success) { |
2265 } |
2242 if (typeReturned == XA_WINDOW && formatReturned == 32) |
2266 |
2243 windowManagerWindow = *((Window*) data); |
2267 if (qgetenv("DESKTOP_SESSION") == "gnome") { |
2244 if (data) |
2268 X11->desktopEnvironment = DE_GNOME; |
2269 break; |
|
2270 } |
|
2271 |
|
2272 // GNOME_DESKTOP_SESSION_ID is deprecated for some reason, but still check it |
|
2273 if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) { |
|
2274 X11->desktopEnvironment = DE_GNOME; |
|
2275 break; |
|
2276 } |
|
2277 |
|
2278 rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(_DT_SAVE_MODE), |
|
2279 0, 2, False, XA_STRING, &type, &format, &length, |
|
2280 &after, &data); |
|
2281 if (rc == Success && length) { |
|
2282 if (!strcmp(reinterpret_cast<char *>(data), "xfce4")) { |
|
2283 // Pretend that xfce4 is gnome, as it uses the same libraries. |
|
2284 // The detection above is stolen from xdg-open. |
|
2285 X11->desktopEnvironment = DE_GNOME; |
|
2286 break; |
|
2287 } |
|
2288 |
|
2289 // We got the property but it wasn't xfce4. Free data before it gets overwritten. |
|
2245 XFree(data); |
2290 XFree(data); |
2246 |
2291 data = 0; |
2247 if (windowManagerWindow != XNone) { |
2292 } |
2248 QString wmName; |
2293 |
2249 Atom utf8atom = ATOM(UTF8_STRING); |
2294 rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(DTWM_IS_RUNNING), |
2250 if (XGetWindowProperty(QX11Info::display(), windowManagerWindow, ATOM(_NET_WM_NAME), |
2295 0, 1, False, AnyPropertyType, &type, &format, &length, |
2251 0, 1024, False, utf8atom, &typeReturned, |
2296 &after, &data); |
2252 &formatReturned, &nitemsReturned, &unused, &data) |
2297 if (rc == Success && length) { |
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) { |
|
2281 // DTWM is running, meaning most likely CDE is running... |
2298 // DTWM is running, meaning most likely CDE is running... |
2282 X11->desktopEnvironment = DE_CDE; |
2299 X11->desktopEnvironment = DE_CDE; |
2283 } else if (XGetWindowProperty(X11->display, QX11Info::appRootWindow(), |
2300 break; |
2284 ATOM(GNOME_BACKGROUND_PROPERTIES), 0, 1, False, AnyPropertyType, |
2301 } |
2285 &type, &format, &length, &after, &data) == Success && length) { |
2302 |
2286 X11->desktopEnvironment = DE_GNOME; |
2303 rc = XGetWindowProperty(X11->display, QX11Info::appRootWindow(), |
2287 } else if (!qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) { |
2304 ATOM(_SGI_DESKS_MANAGER), 0, 1, False, XA_WINDOW, |
2288 X11->desktopEnvironment = DE_GNOME; |
2305 &type, &format, &length, &after, &data); |
2289 } else if ((XGetWindowProperty(X11->display, QX11Info::appRootWindow(), ATOM(KDE_FULL_SESSION), |
2306 if (rc == Success && length) { |
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) { |
|
2303 X11->desktopEnvironment = DE_4DWM; |
2307 X11->desktopEnvironment = DE_4DWM; |
2304 } |
2308 break; |
2305 if (data) |
2309 } |
2306 XFree((char *)data); |
2310 } while(0); |
2307 } |
2311 |
2308 |
2312 if (data) |
2309 if (X11->desktopEnvironment == DE_KDE) |
2313 XFree((char *)data); |
2310 X11->desktopVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); |
|
2311 |
2314 |
2312 #if !defined(QT_NO_STYLE_GTK) |
2315 #if !defined(QT_NO_STYLE_GTK) |
2313 if (X11->desktopEnvironment == DE_GNOME) { |
2316 if (X11->desktopEnvironment == DE_GNOME) { |
2314 static bool menusHaveIcons = QGtkStyle::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true); |
2317 static bool menusHaveIcons = QGtkStyle::getGConfBool(QLatin1String("/desktop/gnome/interface/menus_have_icons"), true); |
2315 QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons); |
2318 QApplication::setAttribute(Qt::AA_DontShowIconsInMenus, !menusHaveIcons); |
3050 } |
3053 } |
3051 else if (a == ATOM(WM_TAKE_FOCUS)) { |
3054 else if (a == ATOM(WM_TAKE_FOCUS)) { |
3052 if ((ulong) event->xclient.data.l[1] > X11->time) |
3055 if ((ulong) event->xclient.data.l[1] > X11->time) |
3053 X11->time = event->xclient.data.l[1]; |
3056 X11->time = event->xclient.data.l[1]; |
3054 QWidget *amw = activeModalWidget(); |
3057 QWidget *amw = activeModalWidget(); |
3058 if (amw && amw->testAttribute(Qt::WA_X11DoNotAcceptFocus)) |
|
3059 amw = 0; |
|
3055 if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) { |
3060 if (amw && !QApplicationPrivate::tryModalHelper(widget, 0)) { |
3056 QWidget *p = amw->parentWidget(); |
3061 QWidget *p = amw->parentWidget(); |
3057 while (p && p != widget) |
3062 while (p && p != widget) |
3058 p = p->parentWidget(); |
3063 p = p->parentWidget(); |
3059 if (!p || !X11->net_supported_list) |
3064 if (!p || !X11->net_supported_list) |
3248 XRefreshKeyboardMapping(&event->xmapping); |
3253 XRefreshKeyboardMapping(&event->xmapping); |
3249 |
3254 |
3250 QKeyMapper::changeKeyboard(); |
3255 QKeyMapper::changeKeyboard(); |
3251 return 0; |
3256 return 0; |
3252 } |
3257 } |
3258 #ifndef QT_NO_XKB |
|
3259 else if (X11->use_xkb && event->type == X11->xkb_eventbase) { |
|
3260 XkbAnyEvent *xkbevent = (XkbAnyEvent *) event; |
|
3261 switch (xkbevent->xkb_type) { |
|
3262 case XkbStateNotify: |
|
3263 { |
|
3264 XkbStateNotifyEvent *xkbstateevent = (XkbStateNotifyEvent *) xkbevent; |
|
3265 if ((xkbstateevent->changed & XkbGroupStateMask) != 0) { |
|
3266 qt_keymapper_private()->xkb_currentGroup = xkbstateevent->group; |
|
3267 QKeyMapper::changeKeyboard(); |
|
3268 } |
|
3269 break; |
|
3270 } |
|
3271 default: |
|
3272 break; |
|
3273 } |
|
3274 } |
|
3275 #endif |
|
3253 |
3276 |
3254 if (!widget) { // don't know this windows |
3277 if (!widget) { // don't know this windows |
3255 QWidget* popup = QApplication::activePopupWidget(); |
3278 QWidget* popup = QApplication::activePopupWidget(); |
3256 if (popup) { |
3279 if (popup) { |
3257 |
3280 |