first commit
This commit is contained in:
commit
2ffce46245
|
|
@ -0,0 +1,20 @@
|
|||
kind: pipeline
|
||||
type: ssh
|
||||
name: default
|
||||
|
||||
server:
|
||||
host: 192.168.46.100:2223
|
||||
user: jessequ
|
||||
password:
|
||||
from_secret: password
|
||||
|
||||
workspace:
|
||||
path: /home/tmp
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
commands:
|
||||
- mkdir -p build/debug
|
||||
- cd build/debug
|
||||
- cmake -S ../.. -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_PREFIX_PATH:PATH=/home/jessequ/Qt/6.7.2/gcc_64
|
||||
- make
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
build/
|
||||
.vscode/
|
||||
|
||||
# ---> CMake
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# ---> C++
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# ---> C
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(qxtglobalshortcut VERSION 0.0.1)
|
||||
|
||||
# Library name
|
||||
set(bin qxtglobalshortcut)
|
||||
|
||||
# Public headers
|
||||
set(${bin}_public_headers
|
||||
src/qxtglobalshortcut.h
|
||||
)
|
||||
|
||||
# Source files common for all platforms
|
||||
set(${bin}_sources
|
||||
src/qxtglobalshortcut.cpp
|
||||
${${bin}_public_headers}
|
||||
)
|
||||
|
||||
# Files with Q_OBJECT macros to pass to moc utility
|
||||
set(${bin}_moc
|
||||
src/qxtglobalshortcut.h
|
||||
)
|
||||
|
||||
# Required pkg-config packages
|
||||
set(${bin}_pkg_config_requires)
|
||||
|
||||
include(cmake/cxx11.cmake)
|
||||
include(cmake/library.cmake)
|
||||
include(cmake/platform.cmake)
|
||||
include(cmake/qt.cmake)
|
||||
include(cmake/pkg-config.cmake)
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
Cross-platform library for handling system-wide shortcuts in Qt applications.
|
||||
|
||||
[](http://192.168.46.100:4080/jessequ/qxtglobalshortcut)
|
||||
|
||||
[API Reference](https://codedocs.xyz/hluk/qxtglobalshortcut/classQxtGlobalShortcut.html)
|
||||
|
||||
This code was originally part of [Qtx](https://bitbucket.org/libqxt/libqxt/wiki/Home) which is no longer maintained.
|
||||
|
||||
# Supported Platforms
|
||||
|
||||
- Windows
|
||||
- OS X
|
||||
- Linux/X11
|
||||
|
||||
# Requirements
|
||||
|
||||
- Compiler with C++11 support
|
||||
- Qt 6 or Qt 5
|
||||
- CMake 3.0.0 and later
|
||||
|
||||
# Build
|
||||
|
||||
To build the library without installation run:
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -S .. -DCMAKE_PREFIX_PATH:PATH=~/Qt/6.9.0/gcc_64
|
||||
make
|
||||
```
|
||||
|
||||
To build and install run:
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -S .. -DCMAKE_PREFIX_PATH:PATH=~/Qt/6.9.0/gcc_64 -DCMAKE_INSTALL_PREFIX=/usr/local
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
To build static library run:
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -S .. -DCMAKE_PREFIX_PATH:PATH=~/Qt/6.9.0/gcc_64 -DQXTGLOBALSHORTCUT_STATIC=ON
|
||||
make
|
||||
|
||||
```
|
||||
|
||||
# Use the Library
|
||||
|
||||
Directory "example" contains simple CMake project which uses the installed library.
|
||||
|
||||
To compile and run the example:
|
||||
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
mkdir example
|
||||
cd example
|
||||
cmake -S ../../example -DCMAKE_PREFIX_PATH:PATH=~/Qt/6.9.0/gcc_64
|
||||
make
|
||||
./qxtglobalshortcut_test
|
||||
```
|
||||
|
||||
If `cmake` prints error that it cannot find package for the library you have to specify
|
||||
it's install path. E.g.
|
||||
|
||||
```bash
|
||||
qxtglobalshortcut_DIR=/usr/local/lib/cmake/qxtglobalshortcut cmake .
|
||||
```
|
||||
|
||||
Alternatively you can add the path to `CMAKE_PREFIX_PATH` environment variable.
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
if (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 3.1)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
set(INSTALL_LIB_DIR "lib${LIB_SUFFIX}" CACHE PATH
|
||||
"Installation directory for libraries")
|
||||
set(INSTALL_BIN_DIR "bin" CACHE PATH
|
||||
"Installation directory for executables")
|
||||
set(INSTALL_INCLUDE_DIR "include/${bin}" CACHE PATH
|
||||
"Installation directory for header files")
|
||||
set(INSTALL_CMAKE_DIR "lib${LIB_SUFFIX}/cmake/${bin}" CACHE PATH
|
||||
"Installation directory for CMake files")
|
||||
|
||||
# Shared or static library
|
||||
option(CREATE_STATIC_LIBRARY "Create static library" OFF)
|
||||
if (CREATE_STATIC_LIBRARY)
|
||||
add_definitions( -DQXT_STATIC )
|
||||
set(libtype STATIC)
|
||||
else()
|
||||
set(libtype SHARED)
|
||||
endif()
|
||||
|
||||
add_library(${bin} ${libtype} ${${bin}_sources})
|
||||
set_target_properties(${bin} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
)
|
||||
|
||||
# Headers
|
||||
set(exports_dir "${CMAKE_CURRENT_BINARY_DIR}/exports")
|
||||
set(export_header "${exports_dir}/private/${bin}_export.h")
|
||||
set_target_properties(${bin} PROPERTIES
|
||||
PUBLIC_HEADER "${${bin}_public_headers}"
|
||||
PRIVATE_HEADER "${export_header}")
|
||||
|
||||
target_include_directories(${bin} INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
$<INSTALL_INTERFACE:include/${bin}>
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS ${bin} EXPORT ${bin}Targets
|
||||
RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin
|
||||
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib
|
||||
ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" COMPONENT lib
|
||||
PUBLIC_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT dev
|
||||
PRIVATE_HEADER DESTINATION "${INSTALL_INCLUDE_DIR}/private" COMPONENT dev
|
||||
)
|
||||
|
||||
# Generate and install CMake files for the library so `find_package(<Library>)` can be used with CMake.
|
||||
# For more info: https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#creating-packages
|
||||
include(GenerateExportHeader)
|
||||
generate_export_header(${bin} EXPORT_FILE_NAME "${export_header}")
|
||||
target_include_directories(${bin} PRIVATE "${exports_dir}")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${bin}ConfigVersion.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
|
||||
export(
|
||||
EXPORT ${bin}Targets
|
||||
FILE "${CMAKE_CURRENT_BINARY_DIR}/${bin}Targets.cmake"
|
||||
)
|
||||
configure_file(
|
||||
cmake/${bin}Config.cmake
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${bin}Config.cmake"
|
||||
COPYONLY
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT ${bin}Targets
|
||||
FILE
|
||||
${bin}Targets.cmake
|
||||
DESTINATION
|
||||
"${INSTALL_CMAKE_DIR}"
|
||||
COMPONENT
|
||||
dev
|
||||
)
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${bin}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${bin}ConfigVersion.cmake"
|
||||
DESTINATION
|
||||
"${INSTALL_CMAKE_DIR}"
|
||||
COMPONENT
|
||||
dev
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
set(PKG_CONFIG_REQUIRES "${${bin}_pkg_config_requires}")
|
||||
set(PKG_CONFIG_LIBDIR "\${prefix}/lib${LIB_SUFFIX}")
|
||||
set(PKG_CONFIG_INCLUDEDIR "\${prefix}/include/${bin}")
|
||||
set(PKG_CONFIG_LIBS "-L\${libdir} -l${bin}")
|
||||
set(PKG_CONFIG_CFLAGS "-I\${includedir}")
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/pkg-config.pc.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${bin}.pc"
|
||||
)
|
||||
|
||||
set(INSTALL_PKG_CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig"
|
||||
CACHE PATH "Installation directory for pkg-config files")
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${bin}.pc"
|
||||
DESTINATION
|
||||
"${INSTALL_PKG_CONFIG_DIR}"
|
||||
COMPONENT
|
||||
dev
|
||||
)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
find_package(X11)
|
||||
if (X11_FOUND)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/platform_x11.cmake)
|
||||
elseif (Q_WS_WIN OR WIN32)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/platform_win.cmake)
|
||||
elseif (Q_OS_MAC OR APPLE)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/platform_mac.cmake)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported platform! Supported are Windows, OS X, Linux/X11.")
|
||||
endif()
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
target_sources(${bin} PRIVATE src/qxtglobalshortcut_mac.cpp)
|
||||
|
||||
# On Macs we must ensure Carbon and Cocoa are linked
|
||||
#
|
||||
# We do this using a macro taken from:
|
||||
# http://stackoverflow.com/questions/12547624/cant-link-macos-frameworks-with-cmake?rq=1
|
||||
|
||||
#macro(ADD_FRAMEWORK fwname appname)
|
||||
# find_library(FRAMEWORK_${fwname}
|
||||
# NAMES ${fwname}
|
||||
# PATHS ${CMAKE_OSX_SYSROOT}/System/Library
|
||||
# PATH_SUFFIXES Frameworks
|
||||
# NO_DEFAULT_PATH)
|
||||
# if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
|
||||
# MESSAGE(ERROR ": Framework ${fwname} not found")
|
||||
# else()
|
||||
# TARGET_LINK_LIBRARIES(${appname} "${FRAMEWORK_${fwname}}/${fwname}")
|
||||
# MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
|
||||
# endif()
|
||||
#endmacro(ADD_FRAMEWORK)
|
||||
|
||||
#ADD_FRAMEWORK(Carbon ${bin})
|
||||
#ADD_FRAMEWORK(Cocoa ${bin})
|
||||
|
||||
set(MAC_LIBS)
|
||||
|
||||
FIND_LIBRARY( CARBON_LIBRARY Carbon )
|
||||
LIST( APPEND MAC_LIBS ${CARBON_LIBRARY} )
|
||||
|
||||
FIND_LIBRARY( COCOA_LIBRARY Cocoa )
|
||||
LIST( APPEND MAC_LIBS ${COCOA_LIBRARY} )
|
||||
|
||||
TARGET_LINK_LIBRARIES(${bin} ${MAC_LIBS})
|
||||
|
|
@ -0,0 +1 @@
|
|||
target_sources(${bin} PRIVATE src/qxtglobalshortcut_win.cpp)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
target_sources(${bin} PRIVATE src/qxtglobalshortcut_x11.cpp)
|
||||
target_include_directories(${bin} SYSTEM PRIVATE ${X11_INCLUDE_DIR})
|
||||
target_link_libraries(${bin} ${X11_LIBRARIES})
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
option(WITH_QT6 "Use Qt 6 (disable to use Qt 5 instead)" ON)
|
||||
|
||||
if (WITH_QT6)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/qt6.cmake)
|
||||
else()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/qt5.cmake)
|
||||
endif()
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
find_package(Qt5Widgets)
|
||||
if (NOT Qt5Widgets_FOUND)
|
||||
message(FATAL_ERROR "Qt 5 is unavailable. To compile with Qt 4 use -DWITH_QT5=OFF.")
|
||||
endif()
|
||||
message(STATUS "Building with Qt 5.")
|
||||
|
||||
include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
|
||||
target_link_libraries(${bin} Qt5::Widgets)
|
||||
|
||||
qt5_wrap_cpp(${bin}_mocced ${${bin}_moc})
|
||||
target_sources(${bin} PRIVATE ${${bin}_mocced})
|
||||
|
||||
set(${bin}_pkg_config_requires ${${bin}_pkg_config_requires} Qt5Widgets)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
find_package(Qt6 REQUIRED COMPONENTS Widgets)
|
||||
if (NOT Qt6_FOUND)
|
||||
message(FATAL_ERROR "Qt 6 is unavailable. To compile with Qt 5 use -DWITH_QT6=OFF.")
|
||||
endif()
|
||||
message(STATUS "Building with Qt 6.")
|
||||
|
||||
include_directories(${Qt6Gui_PRIVATE_INCLUDE_DIRS})
|
||||
target_link_libraries(${bin} Qt6::Widgets)
|
||||
|
||||
qt6_wrap_cpp(${bin}_mocced ${${bin}_moc})
|
||||
target_sources(${bin} PRIVATE ${${bin}_mocced})
|
||||
|
||||
set(${bin}_pkg_config_requires ${${bin}_pkg_config_requires} Qt6)
|
||||
|
|
@ -0,0 +1 @@
|
|||
include("${CMAKE_CURRENT_LIST_DIR}/qxtglobalshortcutTargets.cmake")
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
cmake_minimum_required(VERSION 2.8.8)
|
||||
project(qxtglobalshortcut_test)
|
||||
|
||||
find_package(qxtglobalshortcut REQUIRED)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets)
|
||||
|
||||
set(bin qxtglobalshortcut_test)
|
||||
add_executable(${bin} src/main.cpp)
|
||||
|
||||
target_link_libraries(${bin} qxtglobalshortcut)
|
||||
target_link_libraries(${bin} Qt6::Widgets)
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#include <QApplication>
|
||||
|
||||
#include <qxtglobalshortcut.h>
|
||||
|
||||
#include <QTextStream>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QTextStream out(stdout);
|
||||
QTextStream err(stderr);
|
||||
|
||||
const QKeySequence shortcut("Ctrl+Shift+T");
|
||||
const QxtGlobalShortcut globalShortcut(shortcut);
|
||||
|
||||
if ( !globalShortcut.isValid() ) {
|
||||
err << QString("Error: Failed to set shortcut %1")
|
||||
.arg(shortcut.toString()) << Qt::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
out << QString("Press shortcut %1 (or CTRL+C to exit)").arg(shortcut.toString()) << Qt::endl;
|
||||
|
||||
QObject::connect(
|
||||
&globalShortcut, &QxtGlobalShortcut::activated, &globalShortcut,
|
||||
[&]{
|
||||
out << QLatin1String("Shortcut pressed!") << Qt::endl;
|
||||
QApplication::quit();
|
||||
});
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Name: ${PROJECT_NAME}
|
||||
Description: ${PROJECT_DESCRIPTION}
|
||||
Version: ${PROJECT_VERSION}
|
||||
Requires: ${PKG_CONFIG_REQUIRES}
|
||||
|
||||
prefix=${CMAKE_INSTALL_PREFIX}
|
||||
includedir=${PKG_CONFIG_INCLUDEDIR}
|
||||
libdir=${PKG_CONFIG_LIBDIR}
|
||||
|
||||
Libs: ${PKG_CONFIG_LIBS}
|
||||
Cflags: ${PKG_CONFIG_CFLAGS}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
#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>
|
||||
|
||||
#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(QxtGlobalShortcut *q)
|
||||
: enabled(true)
|
||||
, key(Qt::Key(0))
|
||||
, mods(Qt::NoModifier)
|
||||
, nativeKey(0)
|
||||
, nativeMods(0)
|
||||
, registered(false)
|
||||
, q_ptr(q)
|
||||
{
|
||||
#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()
|
||||
{
|
||||
unsetShortcut();
|
||||
|
||||
#ifndef Q_OS_MAC
|
||||
--ref;
|
||||
if (ref == 0) {
|
||||
QAbstractEventDispatcher *ed = QAbstractEventDispatcher::instance();
|
||||
if (ed != nullptr) {
|
||||
# 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)
|
||||
{
|
||||
unsetShortcut();
|
||||
|
||||
const Qt::KeyboardModifiers allMods =
|
||||
Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier;
|
||||
const auto xkeyCode = static_cast<uint>( shortcut.isEmpty() ? 0 : shortcut[0] );
|
||||
// WORKAROUND: Qt has convert some keys to upper case which
|
||||
// breaks some shortcuts on some keyboard layouts.
|
||||
const uint keyCode = QChar::toLower(xkeyCode & ~allMods);
|
||||
|
||||
key = Qt::Key(keyCode);
|
||||
mods = Qt::KeyboardModifiers(xkeyCode & allMods);
|
||||
|
||||
nativeKey = nativeKeycode(key);
|
||||
nativeMods = nativeModifiers(mods);
|
||||
|
||||
registered = registerShortcut(nativeKey, nativeMods);
|
||||
if (registered)
|
||||
shortcuts.insert(qMakePair(nativeKey, nativeMods), q_ptr);
|
||||
|
||||
return registered;
|
||||
}
|
||||
|
||||
bool QxtGlobalShortcutPrivate::unsetShortcut()
|
||||
{
|
||||
if (registered
|
||||
&& shortcuts.value(qMakePair(nativeKey, nativeMods)) == q_ptr
|
||||
&& unregisterShortcut(nativeKey, nativeMods))
|
||||
{
|
||||
shortcuts.remove(qMakePair(nativeKey, nativeMods));
|
||||
registered = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods)
|
||||
{
|
||||
QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods));
|
||||
if (shortcut && shortcut->isEnabled())
|
||||
emit shortcut->activated(shortcut);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QxtGlobalShortcut
|
||||
\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
|
||||
*/
|
||||
|
||||
/*!
|
||||
\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)
|
||||
, d_ptr(new QxtGlobalShortcutPrivate(this))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new QxtGlobalShortcut with \a shortcut and \a parent.
|
||||
*/
|
||||
QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent)
|
||||
: QxtGlobalShortcut(parent)
|
||||
{
|
||||
setShortcut(shortcut);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destructs the QxtGlobalShortcut.
|
||||
*/
|
||||
QxtGlobalShortcut::~QxtGlobalShortcut()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QxtGlobalShortcut::shortcut
|
||||
\brief the shortcut key sequence
|
||||
|
||||
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
|
||||
|
||||
\sa setShortcut()
|
||||
*/
|
||||
QKeySequence QxtGlobalShortcut::shortcut() const
|
||||
{
|
||||
return QKeySequence( static_cast<int>(d_ptr->key | d_ptr->mods) );
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QxtGlobalShortcut::shortcut
|
||||
\brief sets the shortcut key sequence
|
||||
|
||||
\sa shortcut()
|
||||
*/
|
||||
bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut)
|
||||
{
|
||||
return d_ptr->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 setEnabled(), setDisabled()
|
||||
*/
|
||||
bool QxtGlobalShortcut::isEnabled() const
|
||||
{
|
||||
return d_ptr->enabled;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QxtGlobalShortcut::valid
|
||||
\brief whether the shortcut was successfully set up
|
||||
*/
|
||||
bool QxtGlobalShortcut::isValid() const
|
||||
{
|
||||
return d_ptr->registered;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the shortcut \a enabled.
|
||||
|
||||
\sa enabled
|
||||
*/
|
||||
void QxtGlobalShortcut::setEnabled(bool enabled)
|
||||
{
|
||||
d_ptr->enabled = enabled;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the shortcut \a disabled.
|
||||
|
||||
\sa enabled
|
||||
*/
|
||||
void QxtGlobalShortcut::setDisabled(bool disabled)
|
||||
{
|
||||
d_ptr->enabled = !disabled;
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
#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 "private/qxtglobalshortcut_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QKeySequence>
|
||||
|
||||
class QxtGlobalShortcutPrivate;
|
||||
|
||||
class QXTGLOBALSHORTCUT_EXPORT QxtGlobalShortcut : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
|
||||
Q_PROPERTY(bool valid READ isValid)
|
||||
Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut)
|
||||
|
||||
public:
|
||||
explicit QxtGlobalShortcut(QObject* parent = nullptr);
|
||||
explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = nullptr);
|
||||
~QxtGlobalShortcut();
|
||||
|
||||
QKeySequence shortcut() const;
|
||||
bool setShortcut(const QKeySequence& shortcut);
|
||||
|
||||
bool isEnabled() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setEnabled(bool enabled = true);
|
||||
void setDisabled(bool disabled = true);
|
||||
|
||||
Q_SIGNALS:
|
||||
void activated(QxtGlobalShortcut *self);
|
||||
|
||||
private:
|
||||
friend class QxtGlobalShortcutPrivate;
|
||||
QxtGlobalShortcutPrivate *d_ptr;
|
||||
};
|
||||
|
||||
#endif // QXTGLOBALSHORTCUT_H
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
#include <Carbon/Carbon.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 <QMap>
|
||||
#include <QHash>
|
||||
#include <QtDebug>
|
||||
#include <QApplication>
|
||||
|
||||
using Identifier = QPair<uint, uint>;
|
||||
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, nullptr, sizeof(keyID), nullptr, &keyID);
|
||||
Identifier id = keyIDs.key(keyID.id);
|
||||
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;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
// This is only here to get it to compile on OSX
|
||||
bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
|
||||
void * message, qintptr * result)
|
||||
{
|
||||
Q_UNUSED(result);
|
||||
Q_UNUSED(message);
|
||||
Q_UNUSED(eventType);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
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 == nullptr)
|
||||
return 0;
|
||||
|
||||
currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
|
||||
CFRelease(currentKeyboard);
|
||||
if (currentLayoutData == nullptr){//Japanese or Chinese always return null
|
||||
currentKeyboard = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
currentLayoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
|
||||
if(!currentLayoutData)
|
||||
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
|
||||
|
||||
// The code above fails to translate keys like semicolon with Qt 5.7.1.
|
||||
// Last resort is to try mapping the rest of the keys directly.
|
||||
switch (key)
|
||||
{
|
||||
case Qt::Key_A:
|
||||
return kVK_ANSI_A;
|
||||
case Qt::Key_S:
|
||||
return kVK_ANSI_S;
|
||||
case Qt::Key_D:
|
||||
return kVK_ANSI_D;
|
||||
case Qt::Key_F:
|
||||
return kVK_ANSI_F;
|
||||
case Qt::Key_H:
|
||||
return kVK_ANSI_H;
|
||||
case Qt::Key_G:
|
||||
return kVK_ANSI_G;
|
||||
case Qt::Key_Z:
|
||||
return kVK_ANSI_Z;
|
||||
case Qt::Key_X:
|
||||
return kVK_ANSI_X;
|
||||
case Qt::Key_C:
|
||||
return kVK_ANSI_C;
|
||||
case Qt::Key_V:
|
||||
return kVK_ANSI_V;
|
||||
case Qt::Key_B:
|
||||
return kVK_ANSI_B;
|
||||
case Qt::Key_Q:
|
||||
return kVK_ANSI_Q;
|
||||
case Qt::Key_W:
|
||||
return kVK_ANSI_W;
|
||||
case Qt::Key_E:
|
||||
return kVK_ANSI_E;
|
||||
case Qt::Key_R:
|
||||
return kVK_ANSI_R;
|
||||
case Qt::Key_Y:
|
||||
return kVK_ANSI_Y;
|
||||
case Qt::Key_T:
|
||||
return kVK_ANSI_T;
|
||||
case Qt::Key_1:
|
||||
return kVK_ANSI_1;
|
||||
case Qt::Key_2:
|
||||
return kVK_ANSI_2;
|
||||
case Qt::Key_3:
|
||||
return kVK_ANSI_3;
|
||||
case Qt::Key_4:
|
||||
return kVK_ANSI_4;
|
||||
case Qt::Key_6:
|
||||
return kVK_ANSI_6;
|
||||
case Qt::Key_5:
|
||||
return kVK_ANSI_5;
|
||||
case Qt::Key_Equal:
|
||||
return kVK_ANSI_Equal;
|
||||
case Qt::Key_9:
|
||||
return kVK_ANSI_9;
|
||||
case Qt::Key_7:
|
||||
return kVK_ANSI_7;
|
||||
case Qt::Key_Minus:
|
||||
return kVK_ANSI_Minus;
|
||||
case Qt::Key_8:
|
||||
return kVK_ANSI_8;
|
||||
case Qt::Key_0:
|
||||
return kVK_ANSI_0;
|
||||
case Qt::Key_BracketRight:
|
||||
return kVK_ANSI_RightBracket;
|
||||
case Qt::Key_O:
|
||||
return kVK_ANSI_O;
|
||||
case Qt::Key_U:
|
||||
return kVK_ANSI_U;
|
||||
case Qt::Key_BracketLeft:
|
||||
return kVK_ANSI_LeftBracket;
|
||||
case Qt::Key_I:
|
||||
return kVK_ANSI_I;
|
||||
case Qt::Key_P:
|
||||
return kVK_ANSI_P;
|
||||
case Qt::Key_L:
|
||||
return kVK_ANSI_L;
|
||||
case Qt::Key_J:
|
||||
return kVK_ANSI_J;
|
||||
case Qt::Key_QuoteDbl:
|
||||
return kVK_ANSI_Quote;
|
||||
case Qt::Key_K:
|
||||
return kVK_ANSI_K;
|
||||
case Qt::Key_Semicolon:
|
||||
return kVK_ANSI_Semicolon;
|
||||
case Qt::Key_Backslash:
|
||||
return kVK_ANSI_Backslash;
|
||||
case Qt::Key_Comma:
|
||||
return kVK_ANSI_Comma;
|
||||
case Qt::Key_Slash:
|
||||
return kVK_ANSI_Slash;
|
||||
case Qt::Key_N:
|
||||
return kVK_ANSI_N;
|
||||
case Qt::Key_M:
|
||||
return kVK_ANSI_M;
|
||||
case Qt::Key_Period:
|
||||
return kVK_ANSI_Period;
|
||||
case Qt::Key_Dead_Grave:
|
||||
return kVK_ANSI_Grave;
|
||||
case Qt::Key_Asterisk:
|
||||
return kVK_ANSI_KeypadMultiply;
|
||||
case Qt::Key_Plus:
|
||||
return kVK_ANSI_KeypadPlus;
|
||||
case Qt::Key_Clear:
|
||||
return kVK_ANSI_KeypadClear;
|
||||
case Qt::Key_Escape:
|
||||
return kVK_Escape;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
|
||||
{
|
||||
if (!qxt_mac_handler_installed)
|
||||
{
|
||||
EventTypeSpec t;
|
||||
t.eventClass = kEventClassKeyboard;
|
||||
t.eventKind = kEventHotKeyPressed;
|
||||
InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, nullptr, nullptr);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef 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>
|
||||
*****************************************************************************/
|
||||
|
||||
#define QXTGLOBALSHORTCUT_P_H
|
||||
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QHash>
|
||||
|
||||
class QKeySequence;
|
||||
class QxtGlobalShortcut;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QAbstractNativeEventFilter>
|
||||
#endif
|
||||
|
||||
class QxtGlobalShortcutPrivate
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
: public QAbstractNativeEventFilter
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
explicit QxtGlobalShortcutPrivate(QxtGlobalShortcut *q);
|
||||
~QxtGlobalShortcutPrivate();
|
||||
|
||||
bool enabled;
|
||||
Qt::Key key;
|
||||
Qt::KeyboardModifiers mods;
|
||||
quint32 nativeKey;
|
||||
quint32 nativeMods;
|
||||
bool registered;
|
||||
|
||||
bool setShortcut(const QKeySequence& shortcut);
|
||||
bool unsetShortcut();
|
||||
|
||||
# ifndef Q_OS_MAC
|
||||
static int ref;
|
||||
# endif // Q_OS_MAC
|
||||
|
||||
# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
# ifndef Q_OS_MAC
|
||||
static QAbstractEventDispatcher::EventFilter prevEventFilter;
|
||||
static bool eventFilter(void* message);
|
||||
# endif // Q_OS_MAC
|
||||
# else
|
||||
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
|
||||
# endif // QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
|
||||
static void activateShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||
|
||||
private:
|
||||
QxtGlobalShortcut *q_ptr;
|
||||
|
||||
static quint32 nativeKeycode(Qt::Key keycode);
|
||||
static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers);
|
||||
|
||||
static bool registerShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||
static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods);
|
||||
|
||||
static QHash<QPair<quint32, quint32>, QxtGlobalShortcut*> shortcuts;
|
||||
};
|
||||
|
||||
#endif // QXTGLOBALSHORTCUT_P_H
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
#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 <qt_windows.h>
|
||||
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
bool QxtGlobalShortcutPrivate::eventFilter(void* message)
|
||||
{
|
||||
#else
|
||||
bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray & eventType,
|
||||
void * message, qintptr * result)
|
||||
{
|
||||
Q_UNUSED(eventType);
|
||||
Q_UNUSED(result);
|
||||
#endif
|
||||
MSG* msg = static_cast<MSG*>(message);
|
||||
if (msg->message == WM_HOTKEY)
|
||||
{
|
||||
const quint32 keycode = HIWORD(msg->lParam);
|
||||
const quint32 modifiers = LOWORD(msg->lParam);
|
||||
activateShortcut(keycode, modifiers);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers)
|
||||
{
|
||||
// MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN
|
||||
quint32 native = 0;
|
||||
if (modifiers & Qt::ShiftModifier)
|
||||
native |= MOD_SHIFT;
|
||||
if (modifiers & Qt::ControlModifier)
|
||||
native |= MOD_CONTROL;
|
||||
if (modifiers & Qt::AltModifier)
|
||||
native |= MOD_ALT;
|
||||
if (modifiers & Qt::MetaModifier)
|
||||
native |= MOD_WIN;
|
||||
// TODO: resolve these?
|
||||
//if (modifiers & Qt::KeypadModifier)
|
||||
//if (modifiers & Qt::GroupSwitchModifier)
|
||||
return native;
|
||||
}
|
||||
|
||||
quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key)
|
||||
{
|
||||
// Here is list of keys that presumably work on most keyboard layouts.
|
||||
// Default branch is for keys that can change with keyboard layout.
|
||||
switch (key)
|
||||
{
|
||||
case Qt::Key_Escape:
|
||||
return VK_ESCAPE;
|
||||
case Qt::Key_Tab:
|
||||
case Qt::Key_Backtab:
|
||||
return VK_TAB;
|
||||
case Qt::Key_Backspace:
|
||||
return VK_BACK;
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
return VK_RETURN;
|
||||
case Qt::Key_Insert:
|
||||
return VK_INSERT;
|
||||
case Qt::Key_Delete:
|
||||
return VK_DELETE;
|
||||
case Qt::Key_Pause:
|
||||
return VK_PAUSE;
|
||||
case Qt::Key_Print:
|
||||
return VK_PRINT;
|
||||
case Qt::Key_Clear:
|
||||
return VK_CLEAR;
|
||||
case Qt::Key_Home:
|
||||
return VK_HOME;
|
||||
case Qt::Key_End:
|
||||
return VK_END;
|
||||
case Qt::Key_Left:
|
||||
return VK_LEFT;
|
||||
case Qt::Key_Up:
|
||||
return VK_UP;
|
||||
case Qt::Key_Right:
|
||||
return VK_RIGHT;
|
||||
case Qt::Key_Down:
|
||||
return VK_DOWN;
|
||||
case Qt::Key_PageUp:
|
||||
return VK_PRIOR;
|
||||
case Qt::Key_PageDown:
|
||||
return VK_NEXT;
|
||||
case Qt::Key_F1:
|
||||
return VK_F1;
|
||||
case Qt::Key_F2:
|
||||
return VK_F2;
|
||||
case Qt::Key_F3:
|
||||
return VK_F3;
|
||||
case Qt::Key_F4:
|
||||
return VK_F4;
|
||||
case Qt::Key_F5:
|
||||
return VK_F5;
|
||||
case Qt::Key_F6:
|
||||
return VK_F6;
|
||||
case Qt::Key_F7:
|
||||
return VK_F7;
|
||||
case Qt::Key_F8:
|
||||
return VK_F8;
|
||||
case Qt::Key_F9:
|
||||
return VK_F9;
|
||||
case Qt::Key_F10:
|
||||
return VK_F10;
|
||||
case Qt::Key_F11:
|
||||
return VK_F11;
|
||||
case Qt::Key_F12:
|
||||
return VK_F12;
|
||||
case Qt::Key_F13:
|
||||
return VK_F13;
|
||||
case Qt::Key_F14:
|
||||
return VK_F14;
|
||||
case Qt::Key_F15:
|
||||
return VK_F15;
|
||||
case Qt::Key_F16:
|
||||
return VK_F16;
|
||||
case Qt::Key_F17:
|
||||
return VK_F17;
|
||||
case Qt::Key_F18:
|
||||
return VK_F18;
|
||||
case Qt::Key_F19:
|
||||
return VK_F19;
|
||||
case Qt::Key_F20:
|
||||
return VK_F20;
|
||||
case Qt::Key_F21:
|
||||
return VK_F21;
|
||||
case Qt::Key_F22:
|
||||
return VK_F22;
|
||||
case Qt::Key_F23:
|
||||
return VK_F23;
|
||||
case Qt::Key_F24:
|
||||
return VK_F24;
|
||||
case Qt::Key_Space:
|
||||
return VK_SPACE;
|
||||
case Qt::Key_Asterisk:
|
||||
return VK_MULTIPLY;
|
||||
case Qt::Key_Plus:
|
||||
return VK_ADD;
|
||||
case Qt::Key_Minus:
|
||||
return VK_SUBTRACT;
|
||||
case Qt::Key_Slash:
|
||||
return VK_DIVIDE;
|
||||
case Qt::Key_MediaNext:
|
||||
return VK_MEDIA_NEXT_TRACK;
|
||||
case Qt::Key_MediaPrevious:
|
||||
return VK_MEDIA_PREV_TRACK;
|
||||
case Qt::Key_MediaPlay:
|
||||
return VK_MEDIA_PLAY_PAUSE;
|
||||
case Qt::Key_MediaStop:
|
||||
return VK_MEDIA_STOP;
|
||||
// couldn't find those in VK_*
|
||||
//case Qt::Key_MediaLast:
|
||||
//case Qt::Key_MediaRecord:
|
||||
case Qt::Key_VolumeDown:
|
||||
return VK_VOLUME_DOWN;
|
||||
case Qt::Key_VolumeUp:
|
||||
return VK_VOLUME_UP;
|
||||
case Qt::Key_VolumeMute:
|
||||
return VK_VOLUME_MUTE;
|
||||
|
||||
default:
|
||||
// Try to get virtual key from current keyboard layout or US.
|
||||
const HKL layout = GetKeyboardLayout(0);
|
||||
int vk = VkKeyScanEx(key, layout);
|
||||
if (vk == -1) {
|
||||
const HKL layoutUs = GetKeyboardLayout(0x409);
|
||||
vk = VkKeyScanEx(key, layoutUs);
|
||||
}
|
||||
return vk == -1 ? 0 : vk;
|
||||
}
|
||||
}
|
||||
|
||||
bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods)
|
||||
{
|
||||
return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey);
|
||||
}
|
||||
|
||||
bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods)
|
||||
{
|
||||
return UnregisterHotKey(0, nativeMods ^ nativeKey);
|
||||
}
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
#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>
|
||||
*****************************************************************************/
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
# include <QX11Info>
|
||||
#else
|
||||
# include <QApplication>
|
||||
# include <qpa/qplatformnativeinterface.h>
|
||||
# include <xcb/xcb.h>
|
||||
#endif
|
||||
#include <QVector>
|
||||
#include <QWidget>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#include "xcbkeyboard.h"
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Creates first invisible application window
|
||||
* so X11 key press events can be received.
|
||||
*
|
||||
* This is used for Cinnamon and KDE.
|
||||
*/
|
||||
void createFirstWindow()
|
||||
{
|
||||
static QWidget *w = nullptr;
|
||||
if (!w) {
|
||||
// Try hard so the window is not visible.
|
||||
|
||||
// Tool tips won't show in taskbar.
|
||||
w = new QWidget(nullptr, Qt::ToolTip);
|
||||
|
||||
// Move out of screen (if it's not possible to show the window minimized).
|
||||
w->resize(1, 1);
|
||||
w->move(-100000, -100000);
|
||||
|
||||
// Show and hide quickly.
|
||||
w->showMinimized();
|
||||
w->hide();
|
||||
}
|
||||
}
|
||||
|
||||
QVector<quint32> maskModifiers()
|
||||
{
|
||||
return QVector<quint32>() << 0 << Mod2Mask << LockMask << (Mod2Mask | LockMask);
|
||||
}
|
||||
|
||||
using X11ErrorHandler = int (*)(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()
|
||||
: m_previousErrorHandler(nullptr)
|
||||
{
|
||||
error = false;
|
||||
m_previousErrorHandler = XSetErrorHandler(qxtX11ErrorHandler);
|
||||
}
|
||||
|
||||
~QxtX11ErrorHandler()
|
||||
{
|
||||
XSetErrorHandler(m_previousErrorHandler);
|
||||
}
|
||||
|
||||
private:
|
||||
X11ErrorHandler m_previousErrorHandler;
|
||||
};
|
||||
|
||||
bool QxtX11ErrorHandler::error = false;
|
||||
|
||||
class QxtX11Data {
|
||||
public:
|
||||
QxtX11Data()
|
||||
: m_display(nullptr)
|
||||
{
|
||||
createFirstWindow();
|
||||
|
||||
#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() const
|
||||
{
|
||||
return m_display != nullptr;
|
||||
}
|
||||
|
||||
Display *display()
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return m_display;
|
||||
}
|
||||
|
||||
Window rootWindow()
|
||||
{
|
||||
return DefaultRootWindow(display());
|
||||
}
|
||||
|
||||
bool grabKey(quint32 keycode, quint32 modifiers, Window window)
|
||||
{
|
||||
QxtX11ErrorHandler errorHandler;
|
||||
|
||||
for (const auto maskMods : maskModifiers()) {
|
||||
XGrabKey(display(), static_cast<int>(keycode), modifiers | maskMods, window, True,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
if (errorHandler.error)
|
||||
break;
|
||||
}
|
||||
|
||||
if (errorHandler.error) {
|
||||
ungrabKey(keycode, modifiers, window);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ungrabKey(quint32 keycode, quint32 modifiers, Window window)
|
||||
{
|
||||
QxtX11ErrorHandler errorHandler;
|
||||
|
||||
for (const auto maskMods : maskModifiers()) {
|
||||
XUngrabKey(display(), static_cast<int>(keycode), modifiers | maskMods, window);
|
||||
}
|
||||
|
||||
return !errorHandler.error;
|
||||
}
|
||||
|
||||
private:
|
||||
Display *m_display;
|
||||
};
|
||||
|
||||
KeySym qtKeyToXKeySym(Qt::Key key)
|
||||
{
|
||||
const auto keySym = XStringToKeysym(QKeySequence(key).toString().toLatin1().data());
|
||||
if (keySym != NoSymbol)
|
||||
return keySym;
|
||||
|
||||
for (int i = 0; KeyTbl[i] != 0; i += 2) {
|
||||
if (KeyTbl[i + 1] == key)
|
||||
return KeyTbl[i];
|
||||
}
|
||||
|
||||
return static_cast<ushort>(key);
|
||||
}
|
||||
|
||||
} // 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, qintptr * result)
|
||||
{
|
||||
Q_UNUSED(result);
|
||||
|
||||
xcb_key_press_event_t *kev = nullptr;
|
||||
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 != nullptr) {
|
||||
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;
|
||||
|
||||
const KeySym keysym = qtKeyToXKeySym(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());
|
||||
}
|
||||
|
|
@ -0,0 +1,571 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
// Following definitions and table are taken from
|
||||
// "qt5/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp".
|
||||
|
||||
#include <Qt>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#ifndef XK_ISO_Left_Tab
|
||||
#define XK_ISO_Left_Tab 0xFE20
|
||||
#endif
|
||||
|
||||
#ifndef XK_dead_hook
|
||||
#define XK_dead_hook 0xFE61
|
||||
#endif
|
||||
|
||||
#ifndef XK_dead_horn
|
||||
#define XK_dead_horn 0xFE62
|
||||
#endif
|
||||
|
||||
#ifndef XK_Codeinput
|
||||
#define XK_Codeinput 0xFF37
|
||||
#endif
|
||||
|
||||
#ifndef XK_Kanji_Bangou
|
||||
#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */
|
||||
#endif
|
||||
|
||||
// Fix old X libraries
|
||||
#ifndef XK_KP_Home
|
||||
#define XK_KP_Home 0xFF95
|
||||
#endif
|
||||
#ifndef XK_KP_Left
|
||||
#define XK_KP_Left 0xFF96
|
||||
#endif
|
||||
#ifndef XK_KP_Up
|
||||
#define XK_KP_Up 0xFF97
|
||||
#endif
|
||||
#ifndef XK_KP_Right
|
||||
#define XK_KP_Right 0xFF98
|
||||
#endif
|
||||
#ifndef XK_KP_Down
|
||||
#define XK_KP_Down 0xFF99
|
||||
#endif
|
||||
#ifndef XK_KP_Prior
|
||||
#define XK_KP_Prior 0xFF9A
|
||||
#endif
|
||||
#ifndef XK_KP_Next
|
||||
#define XK_KP_Next 0xFF9B
|
||||
#endif
|
||||
#ifndef XK_KP_End
|
||||
#define XK_KP_End 0xFF9C
|
||||
#endif
|
||||
#ifndef XK_KP_Insert
|
||||
#define XK_KP_Insert 0xFF9E
|
||||
#endif
|
||||
#ifndef XK_KP_Delete
|
||||
#define XK_KP_Delete 0xFF9F
|
||||
#endif
|
||||
|
||||
// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
|
||||
// multimedia keys. They are included here as not every system has them.
|
||||
#define XF86XK_MonBrightnessUp 0x1008FF02
|
||||
#define XF86XK_MonBrightnessDown 0x1008FF03
|
||||
#define XF86XK_KbdLightOnOff 0x1008FF04
|
||||
#define XF86XK_KbdBrightnessUp 0x1008FF05
|
||||
#define XF86XK_KbdBrightnessDown 0x1008FF06
|
||||
#define XF86XK_Standby 0x1008FF10
|
||||
#define XF86XK_AudioLowerVolume 0x1008FF11
|
||||
#define XF86XK_AudioMute 0x1008FF12
|
||||
#define XF86XK_AudioRaiseVolume 0x1008FF13
|
||||
#define XF86XK_AudioPlay 0x1008FF14
|
||||
#define XF86XK_AudioStop 0x1008FF15
|
||||
#define XF86XK_AudioPrev 0x1008FF16
|
||||
#define XF86XK_AudioNext 0x1008FF17
|
||||
#define XF86XK_HomePage 0x1008FF18
|
||||
#define XF86XK_Mail 0x1008FF19
|
||||
#define XF86XK_Start 0x1008FF1A
|
||||
#define XF86XK_Search 0x1008FF1B
|
||||
#define XF86XK_AudioRecord 0x1008FF1C
|
||||
#define XF86XK_Calculator 0x1008FF1D
|
||||
#define XF86XK_Memo 0x1008FF1E
|
||||
#define XF86XK_ToDoList 0x1008FF1F
|
||||
#define XF86XK_Calendar 0x1008FF20
|
||||
#define XF86XK_PowerDown 0x1008FF21
|
||||
#define XF86XK_ContrastAdjust 0x1008FF22
|
||||
#define XF86XK_Back 0x1008FF26
|
||||
#define XF86XK_Forward 0x1008FF27
|
||||
#define XF86XK_Stop 0x1008FF28
|
||||
#define XF86XK_Refresh 0x1008FF29
|
||||
#define XF86XK_PowerOff 0x1008FF2A
|
||||
#define XF86XK_WakeUp 0x1008FF2B
|
||||
#define XF86XK_Eject 0x1008FF2C
|
||||
#define XF86XK_ScreenSaver 0x1008FF2D
|
||||
#define XF86XK_WWW 0x1008FF2E
|
||||
#define XF86XK_Sleep 0x1008FF2F
|
||||
#define XF86XK_Favorites 0x1008FF30
|
||||
#define XF86XK_AudioPause 0x1008FF31
|
||||
#define XF86XK_AudioMedia 0x1008FF32
|
||||
#define XF86XK_MyComputer 0x1008FF33
|
||||
#define XF86XK_LightBulb 0x1008FF35
|
||||
#define XF86XK_Shop 0x1008FF36
|
||||
#define XF86XK_History 0x1008FF37
|
||||
#define XF86XK_OpenURL 0x1008FF38
|
||||
#define XF86XK_AddFavorite 0x1008FF39
|
||||
#define XF86XK_HotLinks 0x1008FF3A
|
||||
#define XF86XK_BrightnessAdjust 0x1008FF3B
|
||||
#define XF86XK_Finance 0x1008FF3C
|
||||
#define XF86XK_Community 0x1008FF3D
|
||||
#define XF86XK_AudioRewind 0x1008FF3E
|
||||
#define XF86XK_BackForward 0x1008FF3F
|
||||
#define XF86XK_Launch0 0x1008FF40
|
||||
#define XF86XK_Launch1 0x1008FF41
|
||||
#define XF86XK_Launch2 0x1008FF42
|
||||
#define XF86XK_Launch3 0x1008FF43
|
||||
#define XF86XK_Launch4 0x1008FF44
|
||||
#define XF86XK_Launch5 0x1008FF45
|
||||
#define XF86XK_Launch6 0x1008FF46
|
||||
#define XF86XK_Launch7 0x1008FF47
|
||||
#define XF86XK_Launch8 0x1008FF48
|
||||
#define XF86XK_Launch9 0x1008FF49
|
||||
#define XF86XK_LaunchA 0x1008FF4A
|
||||
#define XF86XK_LaunchB 0x1008FF4B
|
||||
#define XF86XK_LaunchC 0x1008FF4C
|
||||
#define XF86XK_LaunchD 0x1008FF4D
|
||||
#define XF86XK_LaunchE 0x1008FF4E
|
||||
#define XF86XK_LaunchF 0x1008FF4F
|
||||
#define XF86XK_ApplicationLeft 0x1008FF50
|
||||
#define XF86XK_ApplicationRight 0x1008FF51
|
||||
#define XF86XK_Book 0x1008FF52
|
||||
#define XF86XK_CD 0x1008FF53
|
||||
#define XF86XK_Calculater 0x1008FF54
|
||||
#define XF86XK_Clear 0x1008FF55
|
||||
#define XF86XK_ClearGrab 0x1008FE21
|
||||
#define XF86XK_Close 0x1008FF56
|
||||
#define XF86XK_Copy 0x1008FF57
|
||||
#define XF86XK_Cut 0x1008FF58
|
||||
#define XF86XK_Display 0x1008FF59
|
||||
#define XF86XK_DOS 0x1008FF5A
|
||||
#define XF86XK_Documents 0x1008FF5B
|
||||
#define XF86XK_Excel 0x1008FF5C
|
||||
#define XF86XK_Explorer 0x1008FF5D
|
||||
#define XF86XK_Game 0x1008FF5E
|
||||
#define XF86XK_Go 0x1008FF5F
|
||||
#define XF86XK_iTouch 0x1008FF60
|
||||
#define XF86XK_LogOff 0x1008FF61
|
||||
#define XF86XK_Market 0x1008FF62
|
||||
#define XF86XK_Meeting 0x1008FF63
|
||||
#define XF86XK_MenuKB 0x1008FF65
|
||||
#define XF86XK_MenuPB 0x1008FF66
|
||||
#define XF86XK_MySites 0x1008FF67
|
||||
#define XF86XK_New 0x1008FF68
|
||||
#define XF86XK_News 0x1008FF69
|
||||
#define XF86XK_OfficeHome 0x1008FF6A
|
||||
#define XF86XK_Open 0x1008FF6B
|
||||
#define XF86XK_Option 0x1008FF6C
|
||||
#define XF86XK_Paste 0x1008FF6D
|
||||
#define XF86XK_Phone 0x1008FF6E
|
||||
#define XF86XK_Reply 0x1008FF72
|
||||
#define XF86XK_Reload 0x1008FF73
|
||||
#define XF86XK_RotateWindows 0x1008FF74
|
||||
#define XF86XK_RotationPB 0x1008FF75
|
||||
#define XF86XK_RotationKB 0x1008FF76
|
||||
#define XF86XK_Save 0x1008FF77
|
||||
#define XF86XK_Send 0x1008FF7B
|
||||
#define XF86XK_Spell 0x1008FF7C
|
||||
#define XF86XK_SplitScreen 0x1008FF7D
|
||||
#define XF86XK_Support 0x1008FF7E
|
||||
#define XF86XK_TaskPane 0x1008FF7F
|
||||
#define XF86XK_Terminal 0x1008FF80
|
||||
#define XF86XK_Tools 0x1008FF81
|
||||
#define XF86XK_Travel 0x1008FF82
|
||||
#define XF86XK_Video 0x1008FF87
|
||||
#define XF86XK_Word 0x1008FF89
|
||||
#define XF86XK_Xfer 0x1008FF8A
|
||||
#define XF86XK_ZoomIn 0x1008FF8B
|
||||
#define XF86XK_ZoomOut 0x1008FF8C
|
||||
#define XF86XK_Away 0x1008FF8D
|
||||
#define XF86XK_Messenger 0x1008FF8E
|
||||
#define XF86XK_WebCam 0x1008FF8F
|
||||
#define XF86XK_MailForward 0x1008FF90
|
||||
#define XF86XK_Pictures 0x1008FF91
|
||||
#define XF86XK_Music 0x1008FF92
|
||||
#define XF86XK_Battery 0x1008FF93
|
||||
#define XF86XK_Bluetooth 0x1008FF94
|
||||
#define XF86XK_WLAN 0x1008FF95
|
||||
#define XF86XK_UWB 0x1008FF96
|
||||
#define XF86XK_AudioForward 0x1008FF97
|
||||
#define XF86XK_AudioRepeat 0x1008FF98
|
||||
#define XF86XK_AudioRandomPlay 0x1008FF99
|
||||
#define XF86XK_Subtitle 0x1008FF9A
|
||||
#define XF86XK_AudioCycleTrack 0x1008FF9B
|
||||
#define XF86XK_Time 0x1008FF9F
|
||||
#define XF86XK_Select 0x1008FFA0
|
||||
#define XF86XK_View 0x1008FFA1
|
||||
#define XF86XK_TopMenu 0x1008FFA2
|
||||
#define XF86XK_Red 0x1008FFA3
|
||||
#define XF86XK_Green 0x1008FFA4
|
||||
#define XF86XK_Yellow 0x1008FFA5
|
||||
#define XF86XK_Blue 0x1008FFA6
|
||||
#define XF86XK_Suspend 0x1008FFA7
|
||||
#define XF86XK_Hibernate 0x1008FFA8
|
||||
#define XF86XK_TouchpadToggle 0x1008FFA9
|
||||
#define XF86XK_TouchpadOn 0x1008FFB0
|
||||
#define XF86XK_TouchpadOff 0x1008FFB1
|
||||
#define XF86XK_AudioMicMute 0x1008FFB2
|
||||
|
||||
|
||||
// end of XF86keysyms.h
|
||||
|
||||
// keyboard mapping table
|
||||
static const unsigned int KeyTbl[] = {
|
||||
|
||||
// misc keys
|
||||
|
||||
XK_Escape, Qt::Key_Escape,
|
||||
XK_Tab, Qt::Key_Tab,
|
||||
XK_ISO_Left_Tab, Qt::Key_Backtab,
|
||||
XK_BackSpace, Qt::Key_Backspace,
|
||||
XK_Return, Qt::Key_Return,
|
||||
XK_Insert, Qt::Key_Insert,
|
||||
XK_Delete, Qt::Key_Delete,
|
||||
XK_Clear, Qt::Key_Delete,
|
||||
XK_Pause, Qt::Key_Pause,
|
||||
XK_Print, Qt::Key_Print,
|
||||
0x1005FF60, Qt::Key_SysReq, // hardcoded Sun SysReq
|
||||
0x1007ff00, Qt::Key_SysReq, // hardcoded X386 SysReq
|
||||
|
||||
// cursor movement
|
||||
|
||||
XK_Home, Qt::Key_Home,
|
||||
XK_End, Qt::Key_End,
|
||||
XK_Left, Qt::Key_Left,
|
||||
XK_Up, Qt::Key_Up,
|
||||
XK_Right, Qt::Key_Right,
|
||||
XK_Down, Qt::Key_Down,
|
||||
XK_Prior, Qt::Key_PageUp,
|
||||
XK_Next, Qt::Key_PageDown,
|
||||
|
||||
// modifiers
|
||||
|
||||
XK_Shift_L, Qt::Key_Shift,
|
||||
XK_Shift_R, Qt::Key_Shift,
|
||||
XK_Shift_Lock, Qt::Key_Shift,
|
||||
XK_Control_L, Qt::Key_Control,
|
||||
XK_Control_R, Qt::Key_Control,
|
||||
XK_Meta_L, Qt::Key_Meta,
|
||||
XK_Meta_R, Qt::Key_Meta,
|
||||
XK_Alt_L, Qt::Key_Alt,
|
||||
XK_Alt_R, Qt::Key_Alt,
|
||||
XK_Caps_Lock, Qt::Key_CapsLock,
|
||||
XK_Num_Lock, Qt::Key_NumLock,
|
||||
XK_Scroll_Lock, Qt::Key_ScrollLock,
|
||||
XK_Super_L, Qt::Key_Super_L,
|
||||
XK_Super_R, Qt::Key_Super_R,
|
||||
XK_Menu, Qt::Key_Menu,
|
||||
XK_Hyper_L, Qt::Key_Hyper_L,
|
||||
XK_Hyper_R, Qt::Key_Hyper_R,
|
||||
XK_Help, Qt::Key_Help,
|
||||
0x1000FF74, Qt::Key_Backtab, // hardcoded HP backtab
|
||||
0x1005FF10, Qt::Key_F11, // hardcoded Sun F36 (labeled F11)
|
||||
0x1005FF11, Qt::Key_F12, // hardcoded Sun F37 (labeled F12)
|
||||
|
||||
// numeric and function keypad keys
|
||||
|
||||
XK_KP_Space, Qt::Key_Space,
|
||||
XK_KP_Tab, Qt::Key_Tab,
|
||||
XK_KP_Enter, Qt::Key_Enter,
|
||||
//XK_KP_F1, Qt::Key_F1,
|
||||
//XK_KP_F2, Qt::Key_F2,
|
||||
//XK_KP_F3, Qt::Key_F3,
|
||||
//XK_KP_F4, Qt::Key_F4,
|
||||
XK_KP_Home, Qt::Key_Home,
|
||||
XK_KP_Left, Qt::Key_Left,
|
||||
XK_KP_Up, Qt::Key_Up,
|
||||
XK_KP_Right, Qt::Key_Right,
|
||||
XK_KP_Down, Qt::Key_Down,
|
||||
XK_KP_Prior, Qt::Key_PageUp,
|
||||
XK_KP_Next, Qt::Key_PageDown,
|
||||
XK_KP_End, Qt::Key_End,
|
||||
XK_KP_Begin, Qt::Key_Clear,
|
||||
XK_KP_Insert, Qt::Key_Insert,
|
||||
XK_KP_Delete, Qt::Key_Delete,
|
||||
XK_KP_Equal, Qt::Key_Equal,
|
||||
XK_KP_Multiply, Qt::Key_Asterisk,
|
||||
XK_KP_Add, Qt::Key_Plus,
|
||||
XK_KP_Separator, Qt::Key_Comma,
|
||||
XK_KP_Subtract, Qt::Key_Minus,
|
||||
XK_KP_Decimal, Qt::Key_Period,
|
||||
XK_KP_Divide, Qt::Key_Slash,
|
||||
|
||||
// International input method support keys
|
||||
|
||||
// International & multi-key character composition
|
||||
XK_ISO_Level3_Shift, Qt::Key_AltGr,
|
||||
XK_Multi_key, Qt::Key_Multi_key,
|
||||
XK_Codeinput, Qt::Key_Codeinput,
|
||||
XK_SingleCandidate, Qt::Key_SingleCandidate,
|
||||
XK_MultipleCandidate, Qt::Key_MultipleCandidate,
|
||||
XK_PreviousCandidate, Qt::Key_PreviousCandidate,
|
||||
|
||||
// Misc Functions
|
||||
XK_Mode_switch, Qt::Key_Mode_switch,
|
||||
XK_script_switch, Qt::Key_Mode_switch,
|
||||
|
||||
// Japanese keyboard support
|
||||
XK_Kanji, Qt::Key_Kanji,
|
||||
XK_Muhenkan, Qt::Key_Muhenkan,
|
||||
//XK_Henkan_Mode, Qt::Key_Henkan_Mode,
|
||||
XK_Henkan_Mode, Qt::Key_Henkan,
|
||||
XK_Henkan, Qt::Key_Henkan,
|
||||
XK_Romaji, Qt::Key_Romaji,
|
||||
XK_Hiragana, Qt::Key_Hiragana,
|
||||
XK_Katakana, Qt::Key_Katakana,
|
||||
XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
|
||||
XK_Zenkaku, Qt::Key_Zenkaku,
|
||||
XK_Hankaku, Qt::Key_Hankaku,
|
||||
XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
|
||||
XK_Touroku, Qt::Key_Touroku,
|
||||
XK_Massyo, Qt::Key_Massyo,
|
||||
XK_Kana_Lock, Qt::Key_Kana_Lock,
|
||||
XK_Kana_Shift, Qt::Key_Kana_Shift,
|
||||
XK_Eisu_Shift, Qt::Key_Eisu_Shift,
|
||||
XK_Eisu_toggle, Qt::Key_Eisu_toggle,
|
||||
//XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
|
||||
//XK_Zen_Koho, Qt::Key_Zen_Koho,
|
||||
//XK_Mae_Koho, Qt::Key_Mae_Koho,
|
||||
XK_Kanji_Bangou, Qt::Key_Codeinput,
|
||||
XK_Zen_Koho, Qt::Key_MultipleCandidate,
|
||||
XK_Mae_Koho, Qt::Key_PreviousCandidate,
|
||||
|
||||
#ifdef XK_KOREAN
|
||||
// Korean keyboard support
|
||||
XK_Hangul, Qt::Key_Hangul,
|
||||
XK_Hangul_Start, Qt::Key_Hangul_Start,
|
||||
XK_Hangul_End, Qt::Key_Hangul_End,
|
||||
XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
|
||||
XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
|
||||
XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
|
||||
//XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
|
||||
XK_Hangul_Codeinput, Qt::Key_Codeinput,
|
||||
XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
|
||||
XK_Hangul_Banja, Qt::Key_Hangul_Banja,
|
||||
XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
|
||||
XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
|
||||
//XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
|
||||
//XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
|
||||
//XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
|
||||
XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
|
||||
XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
|
||||
XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
|
||||
XK_Hangul_Special, Qt::Key_Hangul_Special,
|
||||
//XK_Hangul_switch, Qt::Key_Hangul_switch,
|
||||
XK_Hangul_switch, Qt::Key_Mode_switch,
|
||||
#endif // XK_KOREAN
|
||||
|
||||
// dead keys
|
||||
XK_dead_grave, Qt::Key_Dead_Grave,
|
||||
XK_dead_acute, Qt::Key_Dead_Acute,
|
||||
XK_dead_circumflex, Qt::Key_Dead_Circumflex,
|
||||
XK_dead_tilde, Qt::Key_Dead_Tilde,
|
||||
XK_dead_macron, Qt::Key_Dead_Macron,
|
||||
XK_dead_breve, Qt::Key_Dead_Breve,
|
||||
XK_dead_abovedot, Qt::Key_Dead_Abovedot,
|
||||
XK_dead_diaeresis, Qt::Key_Dead_Diaeresis,
|
||||
XK_dead_abovering, Qt::Key_Dead_Abovering,
|
||||
XK_dead_doubleacute, Qt::Key_Dead_Doubleacute,
|
||||
XK_dead_caron, Qt::Key_Dead_Caron,
|
||||
XK_dead_cedilla, Qt::Key_Dead_Cedilla,
|
||||
XK_dead_ogonek, Qt::Key_Dead_Ogonek,
|
||||
XK_dead_iota, Qt::Key_Dead_Iota,
|
||||
XK_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
|
||||
XK_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
|
||||
XK_dead_belowdot, Qt::Key_Dead_Belowdot,
|
||||
XK_dead_hook, Qt::Key_Dead_Hook,
|
||||
XK_dead_horn, Qt::Key_Dead_Horn,
|
||||
|
||||
// Special keys from X.org - This include multimedia keys,
|
||||
// wireless/bluetooth/uwb keys, special launcher keys, etc.
|
||||
XF86XK_Back, Qt::Key_Back,
|
||||
XF86XK_Forward, Qt::Key_Forward,
|
||||
XF86XK_Stop, Qt::Key_Stop,
|
||||
XF86XK_Refresh, Qt::Key_Refresh,
|
||||
XF86XK_Favorites, Qt::Key_Favorites,
|
||||
XF86XK_AudioMedia, Qt::Key_LaunchMedia,
|
||||
XF86XK_OpenURL, Qt::Key_OpenUrl,
|
||||
XF86XK_HomePage, Qt::Key_HomePage,
|
||||
XF86XK_Search, Qt::Key_Search,
|
||||
XF86XK_AudioLowerVolume, Qt::Key_VolumeDown,
|
||||
XF86XK_AudioMute, Qt::Key_VolumeMute,
|
||||
XF86XK_AudioRaiseVolume, Qt::Key_VolumeUp,
|
||||
XF86XK_AudioPlay, Qt::Key_MediaPlay,
|
||||
XF86XK_AudioStop, Qt::Key_MediaStop,
|
||||
XF86XK_AudioPrev, Qt::Key_MediaPrevious,
|
||||
XF86XK_AudioNext, Qt::Key_MediaNext,
|
||||
XF86XK_AudioRecord, Qt::Key_MediaRecord,
|
||||
XF86XK_AudioPause, Qt::Key_MediaPause,
|
||||
XF86XK_Mail, Qt::Key_LaunchMail,
|
||||
XF86XK_MyComputer, Qt::Key_Launch0, // ### Qt 6: remap properly
|
||||
XF86XK_Calculator, Qt::Key_Launch1,
|
||||
XF86XK_Memo, Qt::Key_Memo,
|
||||
XF86XK_ToDoList, Qt::Key_ToDoList,
|
||||
XF86XK_Calendar, Qt::Key_Calendar,
|
||||
XF86XK_PowerDown, Qt::Key_PowerDown,
|
||||
XF86XK_ContrastAdjust, Qt::Key_ContrastAdjust,
|
||||
XF86XK_Standby, Qt::Key_Standby,
|
||||
XF86XK_MonBrightnessUp, Qt::Key_MonBrightnessUp,
|
||||
XF86XK_MonBrightnessDown, Qt::Key_MonBrightnessDown,
|
||||
XF86XK_KbdLightOnOff, Qt::Key_KeyboardLightOnOff,
|
||||
XF86XK_KbdBrightnessUp, Qt::Key_KeyboardBrightnessUp,
|
||||
XF86XK_KbdBrightnessDown, Qt::Key_KeyboardBrightnessDown,
|
||||
XF86XK_PowerOff, Qt::Key_PowerOff,
|
||||
XF86XK_WakeUp, Qt::Key_WakeUp,
|
||||
XF86XK_Eject, Qt::Key_Eject,
|
||||
XF86XK_ScreenSaver, Qt::Key_ScreenSaver,
|
||||
XF86XK_WWW, Qt::Key_WWW,
|
||||
XF86XK_Sleep, Qt::Key_Sleep,
|
||||
XF86XK_LightBulb, Qt::Key_LightBulb,
|
||||
XF86XK_Shop, Qt::Key_Shop,
|
||||
XF86XK_History, Qt::Key_History,
|
||||
XF86XK_AddFavorite, Qt::Key_AddFavorite,
|
||||
XF86XK_HotLinks, Qt::Key_HotLinks,
|
||||
XF86XK_BrightnessAdjust, Qt::Key_BrightnessAdjust,
|
||||
XF86XK_Finance, Qt::Key_Finance,
|
||||
XF86XK_Community, Qt::Key_Community,
|
||||
XF86XK_AudioRewind, Qt::Key_AudioRewind,
|
||||
XF86XK_BackForward, Qt::Key_BackForward,
|
||||
XF86XK_ApplicationLeft, Qt::Key_ApplicationLeft,
|
||||
XF86XK_ApplicationRight, Qt::Key_ApplicationRight,
|
||||
XF86XK_Book, Qt::Key_Book,
|
||||
XF86XK_CD, Qt::Key_CD,
|
||||
XF86XK_Calculater, Qt::Key_Calculator,
|
||||
XF86XK_Clear, Qt::Key_Clear,
|
||||
XF86XK_ClearGrab, Qt::Key_ClearGrab,
|
||||
XF86XK_Close, Qt::Key_Close,
|
||||
XF86XK_Copy, Qt::Key_Copy,
|
||||
XF86XK_Cut, Qt::Key_Cut,
|
||||
XF86XK_Display, Qt::Key_Display,
|
||||
XF86XK_DOS, Qt::Key_DOS,
|
||||
XF86XK_Documents, Qt::Key_Documents,
|
||||
XF86XK_Excel, Qt::Key_Excel,
|
||||
XF86XK_Explorer, Qt::Key_Explorer,
|
||||
XF86XK_Game, Qt::Key_Game,
|
||||
XF86XK_Go, Qt::Key_Go,
|
||||
XF86XK_iTouch, Qt::Key_iTouch,
|
||||
XF86XK_LogOff, Qt::Key_LogOff,
|
||||
XF86XK_Market, Qt::Key_Market,
|
||||
XF86XK_Meeting, Qt::Key_Meeting,
|
||||
XF86XK_MenuKB, Qt::Key_MenuKB,
|
||||
XF86XK_MenuPB, Qt::Key_MenuPB,
|
||||
XF86XK_MySites, Qt::Key_MySites,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_New, Qt::Key_New,
|
||||
#endif
|
||||
XF86XK_News, Qt::Key_News,
|
||||
XF86XK_OfficeHome, Qt::Key_OfficeHome,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_Open, Qt::Key_Open,
|
||||
#endif
|
||||
XF86XK_Option, Qt::Key_Option,
|
||||
XF86XK_Paste, Qt::Key_Paste,
|
||||
XF86XK_Phone, Qt::Key_Phone,
|
||||
XF86XK_Reply, Qt::Key_Reply,
|
||||
XF86XK_Reload, Qt::Key_Reload,
|
||||
XF86XK_RotateWindows, Qt::Key_RotateWindows,
|
||||
XF86XK_RotationPB, Qt::Key_RotationPB,
|
||||
XF86XK_RotationKB, Qt::Key_RotationKB,
|
||||
XF86XK_Save, Qt::Key_Save,
|
||||
XF86XK_Send, Qt::Key_Send,
|
||||
XF86XK_Spell, Qt::Key_Spell,
|
||||
XF86XK_SplitScreen, Qt::Key_SplitScreen,
|
||||
XF86XK_Support, Qt::Key_Support,
|
||||
XF86XK_TaskPane, Qt::Key_TaskPane,
|
||||
XF86XK_Terminal, Qt::Key_Terminal,
|
||||
XF86XK_Tools, Qt::Key_Tools,
|
||||
XF86XK_Travel, Qt::Key_Travel,
|
||||
XF86XK_Video, Qt::Key_Video,
|
||||
XF86XK_Word, Qt::Key_Word,
|
||||
XF86XK_Xfer, Qt::Key_Xfer,
|
||||
XF86XK_ZoomIn, Qt::Key_ZoomIn,
|
||||
XF86XK_ZoomOut, Qt::Key_ZoomOut,
|
||||
XF86XK_Away, Qt::Key_Away,
|
||||
XF86XK_Messenger, Qt::Key_Messenger,
|
||||
XF86XK_WebCam, Qt::Key_WebCam,
|
||||
XF86XK_MailForward, Qt::Key_MailForward,
|
||||
XF86XK_Pictures, Qt::Key_Pictures,
|
||||
XF86XK_Music, Qt::Key_Music,
|
||||
XF86XK_Battery, Qt::Key_Battery,
|
||||
XF86XK_Bluetooth, Qt::Key_Bluetooth,
|
||||
XF86XK_WLAN, Qt::Key_WLAN,
|
||||
XF86XK_UWB, Qt::Key_UWB,
|
||||
XF86XK_AudioForward, Qt::Key_AudioForward,
|
||||
XF86XK_AudioRepeat, Qt::Key_AudioRepeat,
|
||||
XF86XK_AudioRandomPlay, Qt::Key_AudioRandomPlay,
|
||||
XF86XK_Subtitle, Qt::Key_Subtitle,
|
||||
XF86XK_AudioCycleTrack, Qt::Key_AudioCycleTrack,
|
||||
XF86XK_Time, Qt::Key_Time,
|
||||
XF86XK_Select, Qt::Key_Select,
|
||||
XF86XK_View, Qt::Key_View,
|
||||
XF86XK_TopMenu, Qt::Key_TopMenu,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_Red, Qt::Key_Red,
|
||||
XF86XK_Green, Qt::Key_Green,
|
||||
XF86XK_Yellow, Qt::Key_Yellow,
|
||||
XF86XK_Blue, Qt::Key_Blue,
|
||||
#endif
|
||||
XF86XK_Bluetooth, Qt::Key_Bluetooth,
|
||||
XF86XK_Suspend, Qt::Key_Suspend,
|
||||
XF86XK_Hibernate, Qt::Key_Hibernate,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_TouchpadToggle, Qt::Key_TouchpadToggle,
|
||||
XF86XK_TouchpadOn, Qt::Key_TouchpadOn,
|
||||
XF86XK_TouchpadOff, Qt::Key_TouchpadOff,
|
||||
XF86XK_AudioMicMute, Qt::Key_MicMute,
|
||||
#endif
|
||||
XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 6: remap properly
|
||||
XF86XK_Launch1, Qt::Key_Launch3,
|
||||
XF86XK_Launch2, Qt::Key_Launch4,
|
||||
XF86XK_Launch3, Qt::Key_Launch5,
|
||||
XF86XK_Launch4, Qt::Key_Launch6,
|
||||
XF86XK_Launch5, Qt::Key_Launch7,
|
||||
XF86XK_Launch6, Qt::Key_Launch8,
|
||||
XF86XK_Launch7, Qt::Key_Launch9,
|
||||
XF86XK_Launch8, Qt::Key_LaunchA,
|
||||
XF86XK_Launch9, Qt::Key_LaunchB,
|
||||
XF86XK_LaunchA, Qt::Key_LaunchC,
|
||||
XF86XK_LaunchB, Qt::Key_LaunchD,
|
||||
XF86XK_LaunchC, Qt::Key_LaunchE,
|
||||
XF86XK_LaunchD, Qt::Key_LaunchF,
|
||||
XF86XK_LaunchE, Qt::Key_LaunchG,
|
||||
XF86XK_LaunchF, Qt::Key_LaunchH,
|
||||
|
||||
0, 0
|
||||
};
|
||||
Loading…
Reference in New Issue