123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- #include "qxtglobalshortcut.h"
- /****************************************************************************
- ** Copyright (c) 2006 - 2011, the LibQxt project.
- ** See the Qxt AUTHORS file for a list of authors and copyright holders.
- ** All rights reserved.
- **
- ** Redistribution and use in source and binary forms, with or without
- ** modification, are permitted provided that the following conditions are met:
- ** * Redistributions of source code must retain the above copyright
- ** notice, this list of conditions and the following disclaimer.
- ** * Redistributions in binary form must reproduce the above copyright
- ** notice, this list of conditions and the following disclaimer in the
- ** documentation and/or other materials provided with the distribution.
- ** * Neither the name of the LibQxt project nor the
- ** names of its contributors may be used to endorse or promote products
- ** derived from this software without specific prior written permission.
- **
- ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- ** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- ** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- ** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- **
- ** <http://libqxt.org> <foundation@libqxt.org>
- *****************************************************************************/
- #include "qxtglobalshortcut_p.h"
- #include <QAbstractEventDispatcher>
- #include <QtDebug>
- #ifndef Q_OS_MAC
- int QxtGlobalShortcutPrivate::ref = 0;
- # if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0;
- # endif
- #endif // Q_OS_MAC
- QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts;
- QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier)
- {
- #ifndef Q_OS_MAC
- if (ref == 0) {
- # if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter);
- # else
- QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
- #endif
- }
- ++ref;
- #endif // Q_OS_MAC
- }
- QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate()
- {
- #ifndef Q_OS_MAC
- --ref;
- if (ref == 0) {
- QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance();
- if (ed != 0) {
- # if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- ed->setEventFilter(prevEventFilter);
- # else
- ed->removeNativeEventFilter(this);
- # endif
- }
- }
- #endif // Q_OS_MAC
- }
- bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut)
- {
- Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
- key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]);
- mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods);
- if (enabled)
- return registerShortcut();
- else
- return false;
- }
- bool QxtGlobalShortcutPrivate::registerShortcut()
- {
- const quint32 nativeKey = nativeKeycode(key);
- const quint32 nativeMods = nativeModifiers(mods);
- const bool res = registerShortcut(nativeKey, nativeMods);
- if (res)
- shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p());
- else
- qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString();
- return res;
- }
- bool QxtGlobalShortcutPrivate::unsetShortcut()
- {
- bool res = false;
- if (enabled)
- res = unregisterShortcut();
- key = Qt::Key(0);
- mods = Qt::KeyboardModifiers(0);
- return res;
- }
- bool QxtGlobalShortcutPrivate::unregisterShortcut()
- {
- bool res = false;
- const quint32 nativeKey = nativeKeycode(key);
- const quint32 nativeMods = nativeModifiers(mods);
- if (shortcuts.value(qMakePair(nativeKey, nativeMods)) == &qxt_p())
- res = unregisterShortcut(nativeKey, nativeMods);
- if (res)
- shortcuts.remove(qMakePair(nativeKey, nativeMods));
- else
- qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString();
- return res;
- }
- void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
- {
- QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
- if (shortcut && shortcut->isEnabled())
- emit shortcut->activated();
- }
- /*!
- \class QxtGlobalShortcut
- \inmodule QxtWidgets
- \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey".
- A global shortcut triggers even if the application is not active. This
- makes it easy to implement applications that react to certain shortcuts
- still if some other application is active or if the application is for
- example minimized to the system tray.
- Example usage:
- \code
- QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
- connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
- shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
- \endcode
- \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication.
- */
- /*!
- \fn QxtGlobalShortcut::activated()
- This signal is emitted when the user types the shortcut's key sequence.
- \sa shortcut
- */
- /*!
- Constructs a new QxtGlobalShortcut with \a parent.
- */
- QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent)
- : QObject(parent)
- {
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
- }
- /*!
- Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
- */
- QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
- : QObject(parent)
- {
- QXT_INIT_PRIVATE(QxtGlobalShortcut);
- setShortcut(shortcut);
- }
- /*!
- Destructs the QxtGlobalShortcut.
- */
- QxtGlobalShortcut::~QxtGlobalShortcut()
- {
- if (qxt_d().enabled)
- qxt_d().unsetShortcut();
- }
- /*!
- \property QxtGlobalShortcut::shortcut
- \brief the shortcut key sequence
- \bold {Note:} Notice that corresponding key press and release events are not
- delivered for registered global shortcuts even if they are disabled.
- Also, comma separated key sequences are not supported.
- Only the first part is used:
- \code
- qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B"));
- Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A"));
- \endcode
- */
- QKeySequence QxtGlobalShortcut::shortcut() const
- {
- return QKeySequence(qxt_d().key | qxt_d().mods);
- }
- bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
- {
- if (qxt_d().key != 0)
- qxt_d().unsetShortcut();
- return qxt_d().setShortcut(shortcut);
- }
- /*!
- \property QxtGlobalShortcut::enabled
- \brief whether the shortcut is enabled
- A disabled shortcut does not get activated.
- The default value is \c true.
- \sa setDisabled()
- */
- bool QxtGlobalShortcut::isEnabled() const
- {
- return qxt_d().enabled;
- }
- void QxtGlobalShortcut::setEnabled(bool enabled)
- {
- if (qxt_d().key != 0)
- {
- if (enabled && !qxt_d().enabled)
- qxt_d().registerShortcut();
- else if (!enabled && qxt_d().enabled)
- qxt_d().unregisterShortcut();
- }
- qxt_d().enabled = enabled;
- }
- /*!
- Sets the shortcut \a disabled.
- \sa enabled
- */
- void QxtGlobalShortcut::setDisabled(bool disabled)
- {
- setEnabled(!disabled);
- }
|