diff options
author | Donovan Baarda <abo@minkirri.apana.org.au> | 2014-10-15 14:07:20 +1100 |
---|---|---|
committer | Donovan Baarda <abo@minkirri.apana.org.au> | 2014-10-15 14:07:20 +1100 |
commit | dbd04e283082ab869a22abf03c4c6280b03935bb (patch) | |
tree | 3951c6f91f76047e655f35e04db4eecd576c49df /qxt-mini | |
parent | d880464fbe9180aefde94594330126e115066dc3 (diff) | |
parent | 051a2e4392bc75b246cc5cb897ae0bbb1f92042e (diff) |
Merge branch 'unstable' of https://github.com/opentrack/opentrack into dev/kalman
Conflicts:
ftnoir_filter_kalman/ftnoir_filter_kalman.h
Diffstat (limited to 'qxt-mini')
-rw-r--r-- | qxt-mini/plat/qxtglobalshortcut_mac.cpp | 456 | ||||
-rw-r--r-- | qxt-mini/plat/qxtglobalshortcut_x11.cpp | 470 | ||||
-rw-r--r-- | qxt-mini/qxtglobalshortcut.cpp | 448 | ||||
-rw-r--r-- | qxt-mini/qxtglobalshortcut.h | 128 |
4 files changed, 751 insertions, 751 deletions
diff --git a/qxt-mini/plat/qxtglobalshortcut_mac.cpp b/qxt-mini/plat/qxtglobalshortcut_mac.cpp index f43c773a..fbf86a94 100644 --- a/qxt-mini/plat/qxtglobalshortcut_mac.cpp +++ b/qxt-mini/plat/qxtglobalshortcut_mac.cpp @@ -1,4 +1,4 @@ -#include <Carbon/Carbon.h>
+#include <Carbon/Carbon.h> /**************************************************************************** ** Copyright (c) 2006 - 2011, the LibQxt project. ** See the Qxt AUTHORS file for a list of authors and copyright holders. @@ -29,235 +29,235 @@ ** <http://libqxt.org> <foundation@libqxt.org> *****************************************************************************/ -#include "qxtglobalshortcut_p.h"
-#include <QMap>
-#include <QHash>
-#include <QtDebug>
-#include <QApplication>
-
-typedef QPair<uint, uint> Identifier;
-static QMap<quint32, EventHotKeyRef> keyRefs;
-static QHash<Identifier, quint32> keyIDs;
-static quint32 hotKeySerial = 0;
-static bool qxt_mac_handler_installed = false;
-
-OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data)
-{
- Q_UNUSED(nextHandler);
- Q_UNUSED(data);
- if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed)
- {
- EventHotKeyID keyID;
- GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID);
- Identifier id = keyIDs.key(keyID.id);
+#include "qxtglobalshortcut_p.h" +#include <QMap> +#include <QHash> +#include <QtDebug> +#include <QApplication> + +typedef QPair<uint, uint> Identifier; +static QMap<quint32, EventHotKeyRef> keyRefs; +static QHash<Identifier, quint32> keyIDs; +static quint32 hotKeySerial = 0; +static bool qxt_mac_handler_installed = false; + +OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data) +{ + Q_UNUSED(nextHandler); + Q_UNUSED(data); + if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed) + { + EventHotKeyID keyID; + GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID); + Identifier id = keyIDs.key(keyID.id); if(id != Identifier()) - QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first);
- }
- return noErr;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
-{
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= shiftKey;
- if (modifiers & Qt::ControlModifier)
- native |= cmdKey;
- if (modifiers & Qt::AltModifier)
- native |= optionKey;
- if (modifiers & Qt::MetaModifier)
- native |= controlKey;
- if (modifiers & Qt::KeypadModifier)
- native |= kEventKeyModifierNumLockMask;
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
-{
- UTF16Char ch;
- // Constants found in NSEvent.h from AppKit.framework
- switch (key)
- {
- case Qt::Key_Return:
- return kVK_Return;
- case Qt::Key_Enter:
- return kVK_ANSI_KeypadEnter;
- case Qt::Key_Tab:
- return kVK_Tab;
- case Qt::Key_Space:
- return kVK_Space;
- case Qt::Key_Backspace:
- return kVK_Delete;
- case Qt::Key_Control:
- return kVK_Command;
- case Qt::Key_Shift:
- return kVK_Shift;
- case Qt::Key_CapsLock:
- return kVK_CapsLock;
- case Qt::Key_Option:
- return kVK_Option;
- case Qt::Key_Meta:
- return kVK_Control;
- case Qt::Key_F17:
- return kVK_F17;
- case Qt::Key_VolumeUp:
- return kVK_VolumeUp;
- case Qt::Key_VolumeDown:
- return kVK_VolumeDown;
- case Qt::Key_F18:
- return kVK_F18;
- case Qt::Key_F19:
- return kVK_F19;
- case Qt::Key_F20:
- return kVK_F20;
- case Qt::Key_F5:
- return kVK_F5;
- case Qt::Key_F6:
- return kVK_F6;
- case Qt::Key_F7:
- return kVK_F7;
- case Qt::Key_F3:
- return kVK_F3;
- case Qt::Key_F8:
- return kVK_F8;
- case Qt::Key_F9:
- return kVK_F9;
- case Qt::Key_F11:
- return kVK_F11;
- case Qt::Key_F13:
- return kVK_F13;
- case Qt::Key_F16:
- return kVK_F16;
- case Qt::Key_F14:
- return kVK_F14;
- case Qt::Key_F10:
- return kVK_F10;
- case Qt::Key_F12:
- return kVK_F12;
- case Qt::Key_F15:
- return kVK_F15;
- case Qt::Key_Help:
- return kVK_Help;
- case Qt::Key_Home:
- return kVK_Home;
- case Qt::Key_PageUp:
- return kVK_PageUp;
- case Qt::Key_Delete:
- return kVK_ForwardDelete;
- case Qt::Key_F4:
- return kVK_F4;
- case Qt::Key_End:
- return kVK_End;
- case Qt::Key_F2:
- return kVK_F2;
- case Qt::Key_PageDown:
- return kVK_PageDown;
- case Qt::Key_F1:
- return kVK_F1;
- case Qt::Key_Left:
- return kVK_LeftArrow;
- case Qt::Key_Right:
- return kVK_RightArrow;
- case Qt::Key_Down:
- return kVK_DownArrow;
- case Qt::Key_Up:
- return kVK_UpArrow;
- default:
- ;
- }
-
- if (key == Qt::Key_Escape) ch = 27;
- else if (key == Qt::Key_Return) ch = 13;
- else if (key == Qt::Key_Enter) ch = 3;
- else if (key == Qt::Key_Tab) ch = 9;
- else ch = key;
-
- CFDataRef currentLayoutData;
- TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
-
- if (currentKeyboard == NULL)
- return 0;
-
- currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
- CFRelease(currentKeyboard);
- if (currentLayoutData == NULL)
- return 0;
-
- UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData);
- UCKeyboardTypeHeader* table = header->keyboardTypeList;
-
- uint8_t *data = (uint8_t*)header;
- // God, would a little documentation for this shit kill you...
- for (quint32 i=0; i < header->keyboardTypeCount; i++)
- {
- UCKeyStateRecordsIndex* stateRec = 0;
- if (table[i].keyStateRecordsIndexOffset != 0)
- {
- stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset);
- if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0;
- }
-
- UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset);
- if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue;
-
- for (quint32 j=0; j < charTable->keyToCharTableCount; j++)
- {
- UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]);
- for (quint32 k=0; k < charTable->keyToCharTableSize; k++)
- {
- if (keyToChar[k] & kUCKeyOutputTestForIndexMask)
- {
- long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
- if (stateRec && idx < stateRec->keyStateRecordCount)
- {
- UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]);
- if (rec->stateZeroCharData == ch) return k;
- }
- }
- else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE)
- {
- if (keyToChar[k] == ch) return k;
- }
- } // for k
- } // for j
- } // for i
- return 0;
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- if (!qxt_mac_handler_installed)
- {
+ QxtGlobalShortcutPrivate::activateShortcut(id.second, id.first); + } + return noErr; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= shiftKey; + if (modifiers & Qt::ControlModifier) + native |= cmdKey; + if (modifiers & Qt::AltModifier) + native |= optionKey; + if (modifiers & Qt::MetaModifier) + native |= controlKey; + if (modifiers & Qt::KeypadModifier) + native |= kEventKeyModifierNumLockMask; + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + UTF16Char ch; + // Constants found in NSEvent.h from AppKit.framework + switch (key) + { + case Qt::Key_Return: + return kVK_Return; + case Qt::Key_Enter: + return kVK_ANSI_KeypadEnter; + case Qt::Key_Tab: + return kVK_Tab; + case Qt::Key_Space: + return kVK_Space; + case Qt::Key_Backspace: + return kVK_Delete; + case Qt::Key_Control: + return kVK_Command; + case Qt::Key_Shift: + return kVK_Shift; + case Qt::Key_CapsLock: + return kVK_CapsLock; + case Qt::Key_Option: + return kVK_Option; + case Qt::Key_Meta: + return kVK_Control; + case Qt::Key_F17: + return kVK_F17; + case Qt::Key_VolumeUp: + return kVK_VolumeUp; + case Qt::Key_VolumeDown: + return kVK_VolumeDown; + case Qt::Key_F18: + return kVK_F18; + case Qt::Key_F19: + return kVK_F19; + case Qt::Key_F20: + return kVK_F20; + case Qt::Key_F5: + return kVK_F5; + case Qt::Key_F6: + return kVK_F6; + case Qt::Key_F7: + return kVK_F7; + case Qt::Key_F3: + return kVK_F3; + case Qt::Key_F8: + return kVK_F8; + case Qt::Key_F9: + return kVK_F9; + case Qt::Key_F11: + return kVK_F11; + case Qt::Key_F13: + return kVK_F13; + case Qt::Key_F16: + return kVK_F16; + case Qt::Key_F14: + return kVK_F14; + case Qt::Key_F10: + return kVK_F10; + case Qt::Key_F12: + return kVK_F12; + case Qt::Key_F15: + return kVK_F15; + case Qt::Key_Help: + return kVK_Help; + case Qt::Key_Home: + return kVK_Home; + case Qt::Key_PageUp: + return kVK_PageUp; + case Qt::Key_Delete: + return kVK_ForwardDelete; + case Qt::Key_F4: + return kVK_F4; + case Qt::Key_End: + return kVK_End; + case Qt::Key_F2: + return kVK_F2; + case Qt::Key_PageDown: + return kVK_PageDown; + case Qt::Key_F1: + return kVK_F1; + case Qt::Key_Left: + return kVK_LeftArrow; + case Qt::Key_Right: + return kVK_RightArrow; + case Qt::Key_Down: + return kVK_DownArrow; + case Qt::Key_Up: + return kVK_UpArrow; + default: + ; + } + + if (key == Qt::Key_Escape) ch = 27; + else if (key == Qt::Key_Return) ch = 13; + else if (key == Qt::Key_Enter) ch = 3; + else if (key == Qt::Key_Tab) ch = 9; + else ch = key; + + CFDataRef currentLayoutData; + TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); + + if (currentKeyboard == NULL) + return 0; + + currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); + CFRelease(currentKeyboard); + if (currentLayoutData == NULL) + return 0; + + UCKeyboardLayout* header = (UCKeyboardLayout*)CFDataGetBytePtr(currentLayoutData); + UCKeyboardTypeHeader* table = header->keyboardTypeList; + + uint8_t *data = (uint8_t*)header; + // God, would a little documentation for this shit kill you... + for (quint32 i=0; i < header->keyboardTypeCount; i++) + { + UCKeyStateRecordsIndex* stateRec = 0; + if (table[i].keyStateRecordsIndexOffset != 0) + { + stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(data + table[i].keyStateRecordsIndexOffset); + if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0; + } + + UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(data + table[i].keyToCharTableIndexOffset); + if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue; + + for (quint32 j=0; j < charTable->keyToCharTableCount; j++) + { + UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(data + charTable->keyToCharTableOffsets[j]); + for (quint32 k=0; k < charTable->keyToCharTableSize; k++) + { + if (keyToChar[k] & kUCKeyOutputTestForIndexMask) + { + long idx = keyToChar[k] & kUCKeyOutputGetIndexMask; + if (stateRec && idx < stateRec->keyStateRecordCount) + { + UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(data + stateRec->keyStateRecordOffsets[idx]); + if (rec->stateZeroCharData == ch) return k; + } + } + else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE) + { + if (keyToChar[k] == ch) return k; + } + } // for k + } // for j + } // for i + return 0; +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + if (!qxt_mac_handler_installed) + { qxt_mac_handler_installed = true; - EventTypeSpec t;
- t.eventClass = kEventClassKeyboard;
- t.eventKind = kEventHotKeyPressed;
- InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL);
- }
-
- EventHotKeyID keyID;
- keyID.signature = 'cute';
- keyID.id = ++hotKeySerial;
-
- EventHotKeyRef ref = 0;
- bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref);
- if (rv)
- {
- keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id);
- keyRefs.insert(keyID.id, ref);
- }
- return rv;
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- Identifier id(nativeMods, nativeKey);
- if (!keyIDs.contains(id)) return false;
-
- EventHotKeyRef ref = keyRefs.take(keyIDs[id]);
- keyIDs.remove(id);
- return !UnregisterEventHotKey(ref);
-}
+ EventTypeSpec t; + t.eventClass = kEventClassKeyboard; + t.eventKind = kEventHotKeyPressed; + InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL); + } + + EventHotKeyID keyID; + keyID.signature = 'cute'; + keyID.id = ++hotKeySerial; + + EventHotKeyRef ref = 0; + bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref); + if (rv) + { + keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id); + keyRefs.insert(keyID.id, ref); + } + return rv; +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + Identifier id(nativeMods, nativeKey); + if (!keyIDs.contains(id)) return false; + + EventHotKeyRef ref = keyRefs.take(keyIDs[id]); + keyIDs.remove(id); + return !UnregisterEventHotKey(ref); +} bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType, void *message, long *result) { diff --git a/qxt-mini/plat/qxtglobalshortcut_x11.cpp b/qxt-mini/plat/qxtglobalshortcut_x11.cpp index 0c203dd8..f18f86db 100644 --- a/qxt-mini/plat/qxtglobalshortcut_x11.cpp +++ b/qxt-mini/plat/qxtglobalshortcut_x11.cpp @@ -1,235 +1,235 @@ -#include "../qxtglobalshortcut_p.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 <QVector>
-#include <QApplication>
-// include private header for great justice -sh 20131015
-#include <X11/Xlib.h>
-#include <xcb/xcb.h>
-#include "qplatformnativeinterface.h"
-
-namespace {
-
-const QVector<quint32> maskModifiers = QVector<quint32>()
- << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask);
-
-typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event);
-
-class QxtX11ErrorHandler {
-public:
- static bool error;
-
- static int qxtX11ErrorHandler(Display *display, XErrorEvent *event)
- {
- Q_UNUSED(display);
- switch (event->error_code)
- {
- case BadAccess:
- case BadValue:
- case BadWindow:
- if (event->request_code == 33 /* X_GrabKey */ ||
- event->request_code == 34 /* X_UngrabKey */)
- {
- error = true;
- //TODO:
- //char errstr[256];
- //XGetErrorText(dpy, err->error_code, errstr, 256);
- }
- }
- return 0;
- }
-
- QxtX11ErrorHandler()
- {
- error = false;
- m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler);
- }
-
- ~QxtX11ErrorHandler()
- {
- XSetErrorHandler(m_previousErrorHandler);
- }
-
-private:
- X11ErrorHandler m_previousErrorHandler;
-};
-
-bool QxtX11ErrorHandler::error = false;
-
-class QxtX11Data {
-public:
- QxtX11Data()
- {
-#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
- m_display = QX11Info::display();
-#else
- QPlatformNativeInterface *native = qApp->platformNativeInterface();
- void *display = native->nativeResourceForScreen(QByteArray("display"),
- QGuiApplication::primaryScreen());
- m_display = reinterpret_cast<Display *>(display);
-#endif
- }
-
- bool isValid()
- {
- return m_display != 0;
- }
-
- Display *display()
- {
- Q_ASSERT(isValid());
- return m_display;
- }
-
- Window rootWindow()
- {
- return DefaultRootWindow(display());
- }
-
- bool grabKey(quint32 keycode, quint32 modifiers, Window window)
- {
- QxtX11ErrorHandler errorHandler;
-
- for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) {
- XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True,
- GrabModeAsync, GrabModeAsync);
- }
-
- if (errorHandler.error) {
- ungrabKey(keycode, modifiers, window);
- return false;
- }
-
- return true;
- }
-
- bool ungrabKey(quint32 keycode, quint32 modifiers, Window window)
- {
- QxtX11ErrorHandler errorHandler;
-
- foreach (quint32 maskMods, maskModifiers) {
- XUngrabKey(display(), keycode, modifiers | maskMods, window);
- }
-
- return !errorHandler.error;
- }
-
-private:
- Display *m_display;
-};
-
-} // namespace
-
-#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
-bool QxtGlobalShortcutPrivate::eventFilter(void *message)
-{
- XEvent *event = static_cast<XEvent *>(message);
- if (event->type == KeyPress)
- {
- XKeyEvent *key = reinterpret_cast<XKeyEvent *>(event);
- unsigned int keycode = key->keycode;
- unsigned int keystate = key->state;
-#else
-bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
- void *message, long *result)
-{
- Q_UNUSED(result);
-
- xcb_key_press_event_t *kev = 0;
- if (eventType == "xcb_generic_event_t") {
- xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message);
- if ((ev->response_type & 127) == XCB_KEY_PRESS)
- kev = static_cast<xcb_key_press_event_t *>(message);
- }
-
- if (kev != 0) {
- unsigned int keycode = kev->detail;
- unsigned int keystate = 0;
- if(kev->state & XCB_MOD_MASK_1)
- keystate |= Mod1Mask;
- if(kev->state & XCB_MOD_MASK_CONTROL)
- keystate |= ControlMask;
- if(kev->state & XCB_MOD_MASK_4)
- keystate |= Mod4Mask;
- if(kev->state & XCB_MOD_MASK_SHIFT)
- keystate |= ShiftMask;
-#endif
- activateShortcut(keycode,
- // Mod1Mask == Alt, Mod4Mask == Meta
- keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask));
- }
- return false;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
-{
- // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask
- quint32 native = 0;
- if (modifiers & Qt::ShiftModifier)
- native |= ShiftMask;
- if (modifiers & Qt::ControlModifier)
- native |= ControlMask;
- if (modifiers & Qt::AltModifier)
- native |= Mod1Mask;
- if (modifiers & Qt::MetaModifier)
- native |= Mod4Mask;
-
- // TODO: resolve these?
- //if (modifiers & Qt::MetaModifier)
- //if (modifiers & Qt::KeypadModifier)
- //if (modifiers & Qt::GroupSwitchModifier)
- return native;
-}
-
-quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
-{
- QxtX11Data x11;
- if (!x11.isValid())
- return 0;
-
- KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data());
- if (keysym == NoSymbol)
- keysym = static_cast<ushort>(key);
-
- return XKeysymToKeycode(x11.display(), keysym);
-}
-
-bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtX11Data x11;
- return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow());
-}
-
-bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
-{
- QxtX11Data x11;
- return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow());
-}
+#include "../qxtglobalshortcut_p.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 <QVector> +#include <QApplication> +// include private header for great justice -sh 20131015 +#include <X11/Xlib.h> +#include <xcb/xcb.h> +#include "qplatformnativeinterface.h" + +namespace { + +const QVector<quint32> maskModifiers = QVector<quint32>() + << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask); + +typedef int (*X11ErrorHandler)(Display *display, XErrorEvent *event); + +class QxtX11ErrorHandler { +public: + static bool error; + + static int qxtX11ErrorHandler(Display *display, XErrorEvent *event) + { + Q_UNUSED(display); + switch (event->error_code) + { + case BadAccess: + case BadValue: + case BadWindow: + if (event->request_code == 33 /* X_GrabKey */ || + event->request_code == 34 /* X_UngrabKey */) + { + error = true; + //TODO: + //char errstr[256]; + //XGetErrorText(dpy, err->error_code, errstr, 256); + } + } + return 0; + } + + QxtX11ErrorHandler() + { + error = false; + m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler); + } + + ~QxtX11ErrorHandler() + { + XSetErrorHandler(m_previousErrorHandler); + } + +private: + X11ErrorHandler m_previousErrorHandler; +}; + +bool QxtX11ErrorHandler::error = false; + +class QxtX11Data { +public: + QxtX11Data() + { +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + m_display = QX11Info::display(); +#else + QPlatformNativeInterface *native = qApp->platformNativeInterface(); + void *display = native->nativeResourceForScreen(QByteArray("display"), + QGuiApplication::primaryScreen()); + m_display = reinterpret_cast<Display *>(display); +#endif + } + + bool isValid() + { + return m_display != 0; + } + + Display *display() + { + Q_ASSERT(isValid()); + return m_display; + } + + Window rootWindow() + { + return DefaultRootWindow(display()); + } + + bool grabKey(quint32 keycode, quint32 modifiers, Window window) + { + QxtX11ErrorHandler errorHandler; + + for (int i = 0; !errorHandler.error && i < maskModifiers.size(); ++i) { + XGrabKey(display(), keycode, modifiers | maskModifiers[i], window, True, + GrabModeAsync, GrabModeAsync); + } + + if (errorHandler.error) { + ungrabKey(keycode, modifiers, window); + return false; + } + + return true; + } + + bool ungrabKey(quint32 keycode, quint32 modifiers, Window window) + { + QxtX11ErrorHandler errorHandler; + + foreach (quint32 maskMods, maskModifiers) { + XUngrabKey(display(), keycode, modifiers | maskMods, window); + } + + return !errorHandler.error; + } + +private: + Display *m_display; +}; + +} // namespace + +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) +bool QxtGlobalShortcutPrivate::eventFilter(void *message) +{ + XEvent *event = static_cast<XEvent *>(message); + if (event->type == KeyPress) + { + XKeyEvent *key = reinterpret_cast<XKeyEvent *>(event); + unsigned int keycode = key->keycode; + unsigned int keystate = key->state; +#else +bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType, + void *message, long *result) +{ + Q_UNUSED(result); + + xcb_key_press_event_t *kev = 0; + if (eventType == "xcb_generic_event_t") { + xcb_generic_event_t *ev = static_cast<xcb_generic_event_t *>(message); + if ((ev->response_type & 127) == XCB_KEY_PRESS) + kev = static_cast<xcb_key_press_event_t *>(message); + } + + if (kev != 0) { + unsigned int keycode = kev->detail; + unsigned int keystate = 0; + if(kev->state & XCB_MOD_MASK_1) + keystate |= Mod1Mask; + if(kev->state & XCB_MOD_MASK_CONTROL) + keystate |= ControlMask; + if(kev->state & XCB_MOD_MASK_4) + keystate |= Mod4Mask; + if(kev->state & XCB_MOD_MASK_SHIFT) + keystate |= ShiftMask; +#endif + activateShortcut(keycode, + // Mod1Mask == Alt, Mod4Mask == Meta + keystate & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)); + } + return false; +} + +quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) +{ + // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask + quint32 native = 0; + if (modifiers & Qt::ShiftModifier) + native |= ShiftMask; + if (modifiers & Qt::ControlModifier) + native |= ControlMask; + if (modifiers & Qt::AltModifier) + native |= Mod1Mask; + if (modifiers & Qt::MetaModifier) + native |= Mod4Mask; + + // TODO: resolve these? + //if (modifiers & Qt::MetaModifier) + //if (modifiers & Qt::KeypadModifier) + //if (modifiers & Qt::GroupSwitchModifier) + return native; +} + +quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) +{ + QxtX11Data x11; + if (!x11.isValid()) + return 0; + + KeySym keysym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data()); + if (keysym == NoSymbol) + keysym = static_cast<ushort>(key); + + return XKeysymToKeycode(x11.display(), keysym); +} + +bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) +{ + QxtX11Data x11; + return x11.isValid() && x11.grabKey(nativeKey, nativeMods, x11.rootWindow()); +} + +bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) +{ + QxtX11Data x11; + return x11.isValid() && x11.ungrabKey(nativeKey, nativeMods, x11.rootWindow()); +} diff --git a/qxt-mini/qxtglobalshortcut.cpp b/qxt-mini/qxtglobalshortcut.cpp index 8515a6b2..45576d37 100644 --- a/qxt-mini/qxtglobalshortcut.cpp +++ b/qxt-mini/qxtglobalshortcut.cpp @@ -1,224 +1,224 @@ -#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)
-{
- if (shortcut.toString() == "") return false;
- 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);
- 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;
- 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();
- key = Qt::Key(0);
- mods = Qt::KeyboardModifiers(0);
- 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().key != 0)
- 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)
-{
- qxt_d().enabled = enabled;
-}
-
-/*!
- Sets the shortcut \a disabled.
-
- \sa enabled
- */
-void QxtGlobalShortcut::setDisabled(bool disabled)
-{
- qxt_d().enabled = !disabled;
-}
+#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) +{ + if (shortcut.toString() == "") return false; + 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); + 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; + 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(); + key = Qt::Key(0); + mods = Qt::KeyboardModifiers(0); + 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().key != 0) + 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) +{ + qxt_d().enabled = enabled; +} + +/*! + Sets the shortcut \a disabled. + + \sa enabled + */ +void QxtGlobalShortcut::setDisabled(bool disabled) +{ + qxt_d().enabled = !disabled; +} diff --git a/qxt-mini/qxtglobalshortcut.h b/qxt-mini/qxtglobalshortcut.h index a81942d2..641c07c9 100644 --- a/qxt-mini/qxtglobalshortcut.h +++ b/qxt-mini/qxtglobalshortcut.h @@ -1,64 +1,64 @@ -#ifndef 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>
-*****************************************************************************/
-
-#define QXTGLOBALSHORTCUT_H
-
-#include "qxtglobal.h"
-#include <QObject>
-#include <QKeySequence>
-class QxtGlobalShortcutPrivate;
-
-class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject
-{
- Q_OBJECT
- QXT_DECLARE_PRIVATE(QxtGlobalShortcut)
- Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
- Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
-
-public:
- explicit QxtGlobalShortcut(QObject* parent = 0);
- explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0);
- virtual ~QxtGlobalShortcut();
-
- QKeySequence shortcut() const;
- bool setShortcut(const QKeySequence& shortcut);
-
- bool isEnabled() const;
-
-public Q_SLOTS:
- void setEnabled(bool enabled = true);
- void setDisabled(bool disabled = true);
-
-Q_SIGNALS:
- void activated();
-};
-
-#endif // QXTGLOBALSHORTCUT_H
+#ifndef 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> +*****************************************************************************/ + +#define QXTGLOBALSHORTCUT_H + +#include "qxtglobal.h" +#include <QObject> +#include <QKeySequence> +class QxtGlobalShortcutPrivate; + +class QXT_GUI_EXPORT QxtGlobalShortcut : public QObject +{ + Q_OBJECT + QXT_DECLARE_PRIVATE(QxtGlobalShortcut) + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) + Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) + +public: + explicit QxtGlobalShortcut(QObject* parent = 0); + explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0); + virtual ~QxtGlobalShortcut(); + + QKeySequence shortcut() const; + bool setShortcut(const QKeySequence& shortcut); + + bool isEnabled() const; + +public Q_SLOTS: + void setEnabled(bool enabled = true); + void setDisabled(bool disabled = true); + +Q_SIGNALS: + void activated(); +}; + +#endif // QXTGLOBALSHORTCUT_H |