diff options
Diffstat (limited to 'qxt-mini')
| -rw-r--r-- | qxt-mini/qxtglobalshortcut.cpp | 70 | ||||
| -rw-r--r-- | qxt-mini/qxtglobalshortcut_p.h | 8 | ||||
| -rw-r--r-- | qxt-mini/qxtglobalshortcut_x11.cpp | 25 | 
3 files changed, 66 insertions, 37 deletions
| diff --git a/qxt-mini/qxtglobalshortcut.cpp b/qxt-mini/qxtglobalshortcut.cpp index bf3ed33d..298472b5 100644 --- a/qxt-mini/qxtglobalshortcut.cpp +++ b/qxt-mini/qxtglobalshortcut.cpp @@ -30,36 +30,50 @@  *****************************************************************************/  #include "qxtglobalshortcut_p.h" + +#include "compat/util.hpp" +  #include <QAbstractEventDispatcher> -#include <QtDebug>  #include <QApplication> +#include <QtDebug> +#include <QtGlobal> -#ifndef Q_OS_MAC -int QxtGlobalShortcutPrivate::ref = 0; -#endif // Q_OS_MAC  QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts; -QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier) +struct QxtGlobalShortcutPrivate::event_filter_installer +{ +    static void ensure_event_filter(); +}; + +void QxtGlobalShortcutPrivate::event_filter_installer::ensure_event_filter()  {  #ifndef Q_OS_MAC -    if (ref == 0) { -        QAbstractEventDispatcher::instance()->installNativeEventFilter(this); +    QAbstractEventDispatcher* instance = QAbstractEventDispatcher::instance(); +    if (instance) +    { +        static QxtGlobalShortcutPrivate filter(QxtGlobalShortcutPrivate::tag {}); +        static bool installed = +            (instance->installNativeEventFilter(&filter), +             true); +        Q_UNUSED(installed);      } -    ++ref; -#endif // Q_OS_MAC +#endif +} + +QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate(QxtGlobalShortcutPrivate::tag) : +    enabled(false), key(Qt::Key(0)), mods(Qt::NoModifier) +{ +    qDebug() << "qxt-mini: adding event filter"; +} + +QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : +    enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier) +{ +    QxtGlobalShortcutPrivate::event_filter_installer::ensure_event_filter();  }  QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()  { -#ifndef Q_OS_MAC -    --ref; -    if (ref == 0) { -        QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance(qApp->thread()); -        if (ed != 0) { -            ed->removeNativeEventFilter(this); -        } -    } -#endif // Q_OS_MAC      unsetShortcut();  } @@ -76,11 +90,13 @@ bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)      const quint32 nativeMods = nativeModifiers(mods);      const bool res = registerShortcut(nativeKey, nativeMods);      if (res) +    {  #ifndef Q_OS_MAC          shortcuts.insertMulti(qMakePair(nativeKey, nativeMods), &qxt_p());  #else          shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());  #endif +    }      else          qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();      return res; @@ -102,10 +118,14 @@ bool QxtGlobalShortcutPrivate::unsetShortcut()      else          qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();  #else -    auto list = shortcuts.values(qMakePair(nativeKey, nativeMods)); +    using IT = decltype(shortcuts.end()); +    const auto pair = qMakePair(nativeKey, nativeMods); +    IT it = shortcuts.find(pair);      bool found = false; -    for (auto it = list.begin(); it != list.end(); it++) +    for (; it != shortcuts.end(); it++)      { +        if (it.key() != pair) // DO NOT REMOVE +            break;          if (*it == &qxt_p())          {              found = true; @@ -126,13 +146,17 @@ bool QxtGlobalShortcutPrivate::unsetShortcut()  void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)  {  #ifndef Q_OS_MAC -    auto list = shortcuts.values(qMakePair(nativeKey, nativeMods)); +    using IT = decltype(shortcuts.end()); +    const auto pair = qMakePair(nativeKey, nativeMods); +    IT it = shortcuts.find(pair); -    for (auto it = list.begin(); it != list.end(); it++) +    for (; it != shortcuts.end(); it++)      { +        if (it.key() != pair) // DO NOT REMOVE +            break;          auto ptr = *it;          if (ptr->isEnabled()) -            ptr->activated(); +            emit ptr->activated();      }  #else      QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods)); diff --git a/qxt-mini/qxtglobalshortcut_p.h b/qxt-mini/qxtglobalshortcut_p.h index 9eadbc7f..1835f956 100644 --- a/qxt-mini/qxtglobalshortcut_p.h +++ b/qxt-mini/qxtglobalshortcut_p.h @@ -53,13 +53,17 @@ public:      bool unsetShortcut();      static bool error; -    static int ref;      static bool eventFilter(void* message);      bool nativeEventFilter(const QByteArray & eventType, void * message, long * result) override;      static void activateShortcut(quint32 nativeKey, quint32 nativeMods);  private: +    struct event_filter_installer; +    friend struct event_filter_installer; +    struct tag {}; +    explicit QxtGlobalShortcutPrivate(tag); +      static quint32 nativeKeycode(Qt::Key keycode);      static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers); @@ -67,6 +71,8 @@ private:      static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);      static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts; + +    static void ensure_event_filter();  };  #endif // QXTGLOBALSHORTCUT_P_H diff --git a/qxt-mini/qxtglobalshortcut_x11.cpp b/qxt-mini/qxtglobalshortcut_x11.cpp index dad12b56..e04a782a 100644 --- a/qxt-mini/qxtglobalshortcut_x11.cpp +++ b/qxt-mini/qxtglobalshortcut_x11.cpp @@ -42,6 +42,8 @@  #include "qplatformnativeinterface.h"  #include "compat/util.hpp" +static constexpr quint32 AllMods = ShiftMask|LockMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask; +  typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event);  struct keybinding final @@ -99,13 +101,13 @@ bool keybinding::incf(quint32 code)      if (ret)      { -        qDebug() << "qxt-mini: registered keybinding" << code; +        //qDebug() << "qxt-mini: registered keybinding" << code;      }      k.refcnt++;      list.insert(code, k); -    qDebug() << "qxt-mini: incf: refcount for" << code << "now" << k.refcnt; +    //qDebug() << "qxt-mini: incf: refcount for" << code << "now" << k.refcnt;      return ret;  } @@ -128,11 +130,11 @@ bool keybinding::decf(quint32 code)      if (k.refcnt == 0)      {          list.erase(it); -        qDebug() << "qxt-mini: removed keybinding" << code; +        //qDebug() << "qxt-mini: removed keybinding" << code;          return true;      } -    qDebug() << "qxt-mini: decf: refcount for" << code << "now" << k.refcnt; +    //qDebug() << "qxt-mini: decf: refcount for" << code << "now" << k.refcnt;      return false;  } @@ -210,7 +212,7 @@ public:          {              QxtX11ErrorHandler errorHandler; -            XGrabKey(display(), keycode, AnyModifier, window, True, +            XGrabKey(display(), keycode, AllMods, window, True,                       GrabModeAsync, GrabModeAsync);              if (errorHandler.error) { @@ -227,7 +229,7 @@ public:          if (keybinding::decf(keycode))          {              QxtX11ErrorHandler errorHandler; -            XUngrabKey(display(), keycode, AnyModifier, window); +            XUngrabKey(display(), keycode, AllMods, window);              return !errorHandler.error;          }          return true; @@ -267,9 +269,7 @@ bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,              keystate |= AltGrMask;  #endif -        activateShortcut(keycode, -            // Mod1Mask == Alt, Mod4Mask == Meta -            keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask | Mod2Mask)); +        activateShortcut(keycode, keystate);      }      return false;  } @@ -296,6 +296,8 @@ quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifier      if (modifiers & Qt::KeypadModifier) // numlock          native |= Mod2Mask; +    native &= AllMods; +      return native;  } @@ -307,28 +309,25 @@ quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)      QByteArray tmp(QKeySequence(key).toString().toLatin1()); -      KeySym keysym = XStringToKeysym(tmp.data());      if (keysym == NoSymbol)          keysym = static_cast<ushort>(key);      const quint32 ret = XKeysymToKeycode(x11.display(), keysym); -    qDebug() << "key is" << key << QKeySequence(key).toString(QKeySequence::PortableText) << ret; +    //qDebug() << "key is" << key << QKeySequence(key).toString(QKeySequence::PortableText) << ret;      return ret;  }  bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, unused(quint32, nativeMods))  { -    qDebug() << "register" << nativeKey;      QxtX11Data x11;      return x11.isValid() && x11.grabKey(nativeKey, x11.rootWindow());  }  bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, unused(quint32, nativeMods))  { -    qDebug() << "unregister" << nativeKey;      QxtX11Data x11;      return x11.isValid() && x11.ungrabKey(nativeKey, x11.rootWindow());  } | 
