Warning, file /plasma/khotkeys/kcm_hotkeys/helper_widgets/window_selector.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-only 0003 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org> 0004 */ 0005 0006 #include "helper_widgets/window_selector.h" 0007 0008 #include <QApplication> 0009 #include <QDebug> 0010 #include <QDesktopWidget> 0011 #include <QX11Info> 0012 0013 #include <X11/Xlib.h> 0014 #include <fixx11h.h> 0015 #include <xcb/xcb.h> 0016 0017 namespace KHotKeys 0018 { 0019 WindowSelector::WindowSelector(QObject *receiver_P, const char *slot_P) 0020 { 0021 connect(this, SIGNAL(selected_signal(WId)), receiver_P, slot_P); 0022 } 0023 0024 WindowSelector::~WindowSelector() 0025 { 0026 qApp->desktop()->releaseMouse(); 0027 QApplication::instance()->removeNativeEventFilter(this); 0028 } 0029 0030 void WindowSelector::select() 0031 { 0032 qApp->desktop()->grabMouse(QCursor(Qt::CrossCursor)); 0033 QApplication::instance()->installNativeEventFilter(this); 0034 } 0035 0036 bool WindowSelector::nativeEventFilter(const QByteArray &eventType, void *message, long *result) 0037 { 0038 Q_UNUSED(result) 0039 if (eventType != QByteArrayLiteral("xcb_generic_event_t")) { 0040 return false; 0041 } 0042 xcb_generic_event_t *event = reinterpret_cast<xcb_generic_event_t *>(message); 0043 if ((event->response_type & ~0x80) == XCB_BUTTON_PRESS) { 0044 xcb_button_press_event_t *e = reinterpret_cast<xcb_button_press_event_t *>(event); 0045 if (e->detail == XCB_BUTTON_INDEX_1) { 0046 if (WId window = findRealWindow(e->child)) { 0047 emit selected_signal(window); 0048 } 0049 deleteLater(); 0050 return true; 0051 } 0052 } 0053 return false; 0054 } 0055 0056 WId WindowSelector::findRealWindow(WId w, int depth) 0057 { 0058 if (depth > 5) 0059 return None; 0060 static Atom wm_state = XInternAtom(QX11Info::display(), "WM_STATE", False); 0061 Atom type; 0062 int format; 0063 unsigned long nitems, after; 0064 unsigned char *prop; 0065 if (XGetWindowProperty(QX11Info::display(), w, wm_state, 0, 0, False, AnyPropertyType, &type, &format, &nitems, &after, &prop) == Success) { 0066 if (prop != nullptr) 0067 XFree(prop); 0068 if (type != None) 0069 return w; 0070 } 0071 Window root, parent; 0072 Window *children; 0073 unsigned int nchildren; 0074 Window ret = None; 0075 if (XQueryTree(QX11Info::display(), w, &root, &parent, &children, &nchildren) != 0) { 0076 for (unsigned int i = 0; i < nchildren && ret == None; ++i) 0077 ret = findRealWindow(children[i], depth + 1); 0078 if (children != nullptr) 0079 XFree(children); 0080 } 0081 return ret; 0082 } 0083 0084 } // namespace KHotKeys