diff options
author | Jonathan White <support@dmapps.us> | 2021-02-28 17:28:27 +0300 |
---|---|---|
committer | Jonathan White <support@dmapps.us> | 2021-05-30 15:44:09 +0300 |
commit | 0c57c7a67bec2b817450e1e6f5880339eb755621 (patch) | |
tree | e55fe5e1c8b6b4a5e97d2949811596ac346aa049 | |
parent | 215ca536d023182c76701ae78ea806cb3268f148 (diff) |
Auto-Type: Allow selection of modal dialogs on X11
* Fix #5958 - Modal dialogs do not have WM_STATE set even though they are a valid top-level window with a valid name. In this case, we need to poll for WM_TRANSIENT_FOR which returns the top level window the dialog is a child of.
-rw-r--r-- | src/autotype/xcb/AutoTypeXCB.cpp | 22 | ||||
-rw-r--r-- | src/autotype/xcb/AutoTypeXCB.h | 3 |
2 files changed, 18 insertions, 7 deletions
diff --git a/src/autotype/xcb/AutoTypeXCB.cpp b/src/autotype/xcb/AutoTypeXCB.cpp index d2d757b4e..2f320f73b 100644 --- a/src/autotype/xcb/AutoTypeXCB.cpp +++ b/src/autotype/xcb/AutoTypeXCB.cpp @@ -39,6 +39,8 @@ AutoTypePlatformX11::AutoTypePlatformX11() m_atomString = XInternAtom(m_dpy, "STRING", True); m_atomUtf8String = XInternAtom(m_dpy, "UTF8_STRING", True); m_atomNetActiveWindow = XInternAtom(m_dpy, "_NET_ACTIVE_WINDOW", True); + m_atomTransientFor = XInternAtom(m_dpy, "WM_TRANSIENT_FOR", True); + m_atomWindow = XInternAtom(m_dpy, "WINDOW", True); m_classBlacklist << "desktop_window" << "gnome-panel"; // Gnome @@ -373,23 +375,31 @@ QStringList AutoTypePlatformX11::windowTitlesRecursive(Window window) bool AutoTypePlatformX11::isTopLevelWindow(Window window) { + bool result = false; + Atom type = None; int format; unsigned long nitems; unsigned long after; - unsigned char* data = Q_NULLPTR; + unsigned char* data = nullptr; + + // Check if the window has WM_STATE atom and it is not Withdrawn int retVal = XGetWindowProperty( m_dpy, window, m_atomWmState, 0, 2, False, m_atomWmState, &type, &format, &nitems, &after, &data); - bool result = false; - if (retVal == 0 && data) { if (type == m_atomWmState && format == 32 && nitems > 0) { - qint32 state = static_cast<qint32>(*data); - result = (state != WithdrawnState); + result = (static_cast<quint32>(*data) != WithdrawnState); } - XFree(data); + } else { + // See if this is a transient window without WM_STATE + retVal = XGetWindowProperty( + m_dpy, window, m_atomTransientFor, 0, 1, False, m_atomWindow, &type, &format, &nitems, &after, &data); + if (retVal == 0 && data) { + result = true; + XFree(data); + } } return result; diff --git a/src/autotype/xcb/AutoTypeXCB.h b/src/autotype/xcb/AutoTypeXCB.h index 221d2ba7b..327359d3c 100644 --- a/src/autotype/xcb/AutoTypeXCB.h +++ b/src/autotype/xcb/AutoTypeXCB.h @@ -77,7 +77,6 @@ private: void updateKeymap(); bool isRemapKeycodeValid(); int AddKeysym(KeySym keysym); - void AddModifier(KeySym keysym); void SendKeyEvent(unsigned keycode, bool press); void SendModifiers(unsigned int mask, bool press); int GetKeycode(KeySym keysym, unsigned int* mask); @@ -93,6 +92,8 @@ private: Atom m_atomString; Atom m_atomUtf8String; Atom m_atomNetActiveWindow; + Atom m_atomTransientFor; + Atom m_atomWindow; QSet<QString> m_classBlacklist; Qt::Key m_currentGlobalKey; Qt::KeyboardModifiers m_currentGlobalModifiers; |