diff options
24 files changed, 586 insertions, 18 deletions
diff --git a/.gitignore b/.gitignore index 4906f241ec..5edd8fbc80 100644 --- a/.gitignore +++ b/.gitignore @@ -93,8 +93,10 @@ bin/qmlconv* bin/qmldebugger* bin/qml* bin/qttracereplay* +bin/qt.conf configure.cache config.status +config.summary mkspecs/default mkspecs/qconfig.pri mkspecs/qdevice.pri diff --git a/mkspecs/common/android/qplatformdefs.h b/mkspecs/common/android/qplatformdefs.h new file mode 100644 index 0000000000..c6a8497552 --- /dev/null +++ b/mkspecs/common/android/qplatformdefs.h @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Collabora Ltd, author <robin.burchell@collabora.co.uk> +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +// Get Qt defines/settings + +#include "qglobal.h" + +// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs + +// 1) need to reset default environment if _BSD_SOURCE is defined +// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0 +// 3) it seems older glibc need this to include the X/Open stuff + +#include <unistd.h> + +// We are hot - unistd.h should have turned on the specific APIs we requested + +#include <features.h> +#include <pthread.h> +#include <dirent.h> +#include <fcntl.h> +#include <grp.h> +#include <pwd.h> +#include <signal.h> +#include <dlfcn.h> + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/ipc.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#ifndef QT_NO_IPV6IFNAME +#include <net/if.h> +#endif + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#define QT_STATBUF struct stat +#define QT_STATBUF4TSTAT struct stat +#define QT_STAT ::stat +#define QT_FSTAT ::fstat +#define QT_LSTAT ::lstat +#define QT_OPEN ::open +#define QT_TRUNCATE ::truncate +#define QT_FTRUNCATE ::ftruncate +#define QT_LSEEK ::lseek + +#define QT_FOPEN ::fopen +#define QT_FSEEK ::fseek +#define QT_FTELL ::ftell +#define QT_FGETPOS ::fgetpos +#define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap +#define QT_FPOS_T fpos_t +#define QT_OFF_T long + +#define QT_STAT_REG S_IFREG +#define QT_STAT_DIR S_IFDIR +#define QT_STAT_MASK S_IFMT +#define QT_STAT_LNK S_IFLNK +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind +#define QT_FILENO fileno +#define QT_CLOSE ::close +#define QT_READ ::read +#define QT_WRITE ::write +#define QT_ACCESS ::access +#define QT_GETCWD ::getcwd +#define QT_CHDIR ::chdir +#define QT_MKDIR ::mkdir +#define QT_RMDIR ::rmdir +#define QT_OPEN_LARGEFILE O_LARGEFILE +#define QT_OPEN_RDONLY O_RDONLY +#define QT_OPEN_WRONLY O_WRONLY +#define QT_OPEN_RDWR O_RDWR +#define QT_OPEN_CREAT O_CREAT +#define QT_OPEN_TRUNC O_TRUNC +#define QT_OPEN_APPEND O_APPEND + +// Directory iteration +#define QT_DIR DIR + + +#define QT_OPENDIR ::opendir +#define QT_CLOSEDIR ::closedir + +#if defined(QT_LARGEFILE_SUPPORT) \ + && defined(QT_USE_XOPEN_LFS_EXTENSIONS) \ + && !defined(QT_NO_READDIR64) +#define QT_DIRENT struct dirent64 +#define QT_READDIR ::readdir64 +#define QT_READDIR_R ::readdir64_r +#else +#define QT_DIRENT struct dirent +#define QT_READDIR ::readdir +#define QT_READDIR_R ::readdir_r +#endif + +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind + + +#define QT_SIGNAL_RETTYPE void +#define QT_SIGNAL_ARGS int +#define QT_SIGNAL_IGNORE SIG_IGN + +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +#define QT_SOCKLEN_T socklen_t +#else +#define QT_SOCKLEN_T int +#endif + +#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500) +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf +#endif + + +#endif // QPLATFORMDEFS_H diff --git a/mkspecs/common/linux-android.conf b/mkspecs/common/linux-android.conf new file mode 100644 index 0000000000..5b6427c9cc --- /dev/null +++ b/mkspecs/common/linux-android.conf @@ -0,0 +1,120 @@ +MAKEFILE_GENERATOR = UNIX +TARGET_PLATFORM = unix +TEMPLATE = app +QMAKE_INCREMENTAL_STYLE = sublib + +include(linux.conf) +include(gcc-base-unix.conf) + +CONFIG = qt warn_on release link_prl +QT = core gui +DEFINES += Q_OS_LINUX_ANDROID +DEFINES += QT_NO_PRINTER QT_NO_PRINTDIALOG +QT_QPA_DEFAULT_PLATFORM = minimal + +NDK_ROOT = $$(ANDROID_NDK_ROOT) +isEmpty(NDK_ROOT): error("$ANDROID_NDK_ROOT is empty, please set it to something like ~/android/ndk-r7c") + +NDK_HOST = $$(ANDROID_NDK_HOST) +isEmpty(NDK_HOST): error("$ANDROID_NDK_HOST is empty, please set it to something like linux-x86 or darwin-x86") + +ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM) +isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = android-5 + +NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) +isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = 4.4.3 + +!contains(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION + +NDK_TOOLCHAIN = $$ANDROID_NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION +NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST + +CONFIG += $$ANDROID_PLATFORM $$ANDROID_TARGET_ARCH +ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ +ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr + +# used to compile platform plugins for android-4 and android-5 +QMAKE_ANDROID_PLATFORM_INCDIR = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/usr/include +QMAKE_ANDROID_PLATFORM_LIBDIR = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/usr/lib + +ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl$$ANDROID_CXXSTL_SUFFIX/gnu-libstdc++/libs/$$ANDROID_TARGET_ARCH +ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl$$ANDROID_CXXSTL_SUFFIX/gnu-libstdc++/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include + +# modifications to g++.conf +QMAKE_CC = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-gcc + +QMAKE_CFLAGS_WARN_ON = -Wall -Wextra +QMAKE_CFLAGS_WARN_OFF = -Wno-psabi + +QMAKE_CFLAGS_SHLIB = -fPIC +QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden + +QMAKE_CXX = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-g++ +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -DQT_NO_QWS_TRANSFORMED +QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD +QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden + +QMAKE_LINK = $$QMAKE_CXX +QMAKE_LINK_SHLIB = $$QMAKE_LINK + +# modifications to linux.conf +QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-ar cqs +QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-objcopy +QMAKE_STRIP = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-strip +QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$ANDROID_NDK_TOOLS_PREFIX-ranlib + +QMAKE_INCDIR = $$ANDROID_PLATFORM_PATH/include $$ANDROID_SOURCES_CXX_STL_INCDIR +QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$ANDROID_PLATFORM_PATH/lib +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = +QMAKE_INCDIR_OPENGL = +QMAKE_INCDIR_OPENGL_ES1 = +QMAKE_LIBDIR_OPENGL_ES1 = +QMAKE_INCDIR_OPENGL_ES2 = +QMAKE_LIBDIR_OPENGL_ES2 = + +contains(ANDROID_TARGET_ARCH, x86): LIBGCC_PATH_FULL = $$system($$QMAKE_CC -print-libgcc-file-name) + else: LIBGCC_PATH_FULL = $$system($$QMAKE_CC -mthumb-interwork -print-libgcc-file-name) + +QMAKE_LINK = $$QMAKE_CXX +QMAKE_LINK_SHLIB = $$QMAKE_CXX +QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH -L$$dirname(LIBGCC_PATH_FULL) -Wl,-rpath-link=$$ANDROID_PLATFORM_PATH/lib +QMAKE_LFLAGS_APP = +QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared + +contains(NDK_ROOT, ".*r[56].*") { + !contains(ANDROID_PLATFORM, ".*android-[458].*") { + message("Your NDK-version is out-dated. A work-around is enabled. Consider updating your NDK (workarounds are required until r6(a))") + QMAKE_LFLAGS_SHLIB += $$ANDROID_PLATFORM_PATH/lib/crtbegin_so.o $$ANDROID_PLATFORM_PATH/lib/crtend_so.o + } +} + +QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_SONAME = +QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined +QMAKE_LFLAGS_RPATH = -Wl,-rpath= + +# TODO: -lgnustl_static was -lstdc++, but that leads to undefined reference to +# std::__throw_bad_alloc during configure. +QMAKE_LIBS = -lsupc++ -llog -lz -lm -ldl -lc -lgcc -lgnustl_static +QMAKE_LIBS_X11 = +QMAKE_LIBS_X11SM = +QMAKE_LIBS_QT_THREAD = +QMAKE_LIBS_QT_OPENGL = +QMAKE_LIBS_QTOPIA = +QMAKE_LIBS_THREAD = +QMAKE_LIBS_OPENGL = +QMAKE_LIBS_OPENGL_QT = +QMAKE_LIBS_OPENGL_ES1 = -lGLESv1_CM +QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 $$QMAKE_LIBS + +load(qt_config) + diff --git a/mkspecs/unsupported/linux-android-armeabi-g++/qmake.conf b/mkspecs/unsupported/linux-android-armeabi-g++/qmake.conf new file mode 100644 index 0000000000..ef5594e3a4 --- /dev/null +++ b/mkspecs/unsupported/linux-android-armeabi-g++/qmake.conf @@ -0,0 +1,15 @@ +# +# qmake configuration for building with android-g++ for ARMv5 +# + +ANDROID_TARGET_ARCH = armeabi +ANDROID_ARCHITECTURE = arm +ANDROID_NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi +ANDROID_NDK_TOOLS_PREFIX = arm-linux-androideabi + +include(../../common/linux-android.conf) + +QMAKE_CFLAGS = -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack +QMAKE_CFLAGS_RELEASE = -g -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 +QMAKE_CFLAGS_DEBUG = -g -marm -O0 -fno-omit-frame-pointer + diff --git a/mkspecs/unsupported/linux-android-armeabi-g++/qplatformdefs.h b/mkspecs/unsupported/linux-android-armeabi-g++/qplatformdefs.h new file mode 100644 index 0000000000..ff3730b246 --- /dev/null +++ b/mkspecs/unsupported/linux-android-armeabi-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Collabora Ltd, author <robin.burchell@collabora.co.uk> +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../common/android/qplatformdefs.h" diff --git a/mkspecs/unsupported/linux-android-armeabi-v7a-g++/qmake.conf b/mkspecs/unsupported/linux-android-armeabi-v7a-g++/qmake.conf new file mode 100644 index 0000000000..91e0c4cb72 --- /dev/null +++ b/mkspecs/unsupported/linux-android-armeabi-v7a-g++/qmake.conf @@ -0,0 +1,15 @@ +# +# qmake configuration for building with android-g++ for ARMv7 +# + +ANDROID_TARGET_ARCH = armeabi-v7a +ANDROID_ARCHITECTURE = arm +ANDROID_NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi +ANDROID_NDK_TOOLS_PREFIX = arm-linux-androideabi + +include(../../common/linux-android.conf) + +QMAKE_CFLAGS = -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack +QMAKE_CFLAGS_RELEASE = -g -mthumb -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 +QMAKE_CFLAGS_DEBUG = -g -marm -O0 -fno-omit-frame-pointer + diff --git a/mkspecs/unsupported/linux-android-armeabi-v7a-g++/qplatformdefs.h b/mkspecs/unsupported/linux-android-armeabi-v7a-g++/qplatformdefs.h new file mode 100644 index 0000000000..ff3730b246 --- /dev/null +++ b/mkspecs/unsupported/linux-android-armeabi-v7a-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Collabora Ltd, author <robin.burchell@collabora.co.uk> +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../common/android/qplatformdefs.h" diff --git a/mkspecs/unsupported/linux-android-x86-g++/qmake.conf b/mkspecs/unsupported/linux-android-x86-g++/qmake.conf new file mode 100644 index 0000000000..9550e1ae46 --- /dev/null +++ b/mkspecs/unsupported/linux-android-x86-g++/qmake.conf @@ -0,0 +1,15 @@ +# +# qmake configuration for building with android-g++ for x86 +# + +ANDROID_TARGET_ARCH = x86 +ANDROID_ARCHITECTURE = x86 +ANDROID_NDK_TOOLCHAIN_PREFIX = x86 +ANDROID_NDK_TOOLS_PREFIX = i686-android-linux + +include(../../common/linux-android.conf) + +QMAKE_CFLAGS = -ffunction-sections -funwind-tables -O2 -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack +QMAKE_CFLAGS_RELEASE = -g -O2 +QMAKE_CFLAGS_DEBUG = -g + diff --git a/mkspecs/unsupported/linux-android-x86-g++/qplatformdefs.h b/mkspecs/unsupported/linux-android-x86-g++/qplatformdefs.h new file mode 100644 index 0000000000..ff3730b246 --- /dev/null +++ b/mkspecs/unsupported/linux-android-x86-g++/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Collabora Ltd, author <robin.burchell@collabora.co.uk> +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../common/android/qplatformdefs.h" diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a3d9c1f2ab..a27a8558cd 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1098,6 +1098,7 @@ bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArra void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) { switch(e->type) { + case QWindowSystemInterfacePrivate::FrameStrutMouse: case QWindowSystemInterfacePrivate::Mouse: QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e)); break; @@ -1179,9 +1180,10 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo QEvent::Type type; // move first Qt::MouseButtons stateChange = e->buttons ^ buttons; + const bool frameStrut = e->type == QWindowSystemInterfacePrivate::FrameStrutMouse; if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) { QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent = - new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->localPos, e->globalPos, e->buttons, e->modifiers); + new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers); QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop stateChange = Qt::NoButton; } @@ -1204,7 +1206,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo bool doubleClick = false; if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) { - type = QEvent::MouseMove; + type = frameStrut ? QEvent::NonClientAreaMouseMove : QEvent::MouseMove; QGuiApplicationPrivate::lastCursorPosition = globalPoint; if (qAbs(globalPoint.x() - mousePressX) > mouse_double_click_distance|| qAbs(globalPoint.y() - mousePressY) > mouse_double_click_distance) @@ -1226,14 +1228,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo if (button & e->buttons) { ulong doubleClickInterval = static_cast<ulong>(qApp->styleHints()->mouseDoubleClickInterval()); doubleClick = e->timestamp - mousePressTime < doubleClickInterval && button == mousePressButton; - type = QEvent::MouseButtonPress; + type = frameStrut ? QEvent::NonClientAreaMouseButtonPress : QEvent::MouseButtonPress; mousePressTime = e->timestamp; mousePressButton = button; const QPoint point = QGuiApplicationPrivate::lastCursorPosition.toPoint(); mousePressX = point.x(); mousePressY = point.y(); } else { - type = QEvent::MouseButtonRelease; + type = frameStrut ? QEvent::NonClientAreaMouseButtonRelease : QEvent::MouseButtonRelease; } } @@ -1253,7 +1255,9 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo cursor->pointerEvent(ev); #endif QGuiApplication::sendSpontaneousEvent(window, &ev); - if (!e->synthetic && !ev.isAccepted() && qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) { + if (!e->synthetic && !ev.isAccepted() + && !frameStrut + && qApp->testAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents)) { if (!m_fakeTouchDevice) { m_fakeTouchDevice = new QTouchDevice; QWindowSystemInterface::registerTouchDevice(m_fakeTouchDevice); @@ -1287,7 +1291,8 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo } if (doubleClick) { mousePressButton = Qt::NoButton; - QMouseEvent dblClickEvent(QEvent::MouseButtonDblClick, localPoint, localPoint, globalPoint, + const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick; + QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint, button, buttons, e->modifiers); dblClickEvent.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent); diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index cded1fe316..a6a519e6fd 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -122,6 +122,9 @@ public: virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner); + virtual void setFrameStrutEventsEnabled(bool enabled); + virtual bool frameStrutEventsEnabled() const; + protected: QScopedPointer<QPlatformWindowPrivate> d_ptr; private: diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index d2ec6833b0..3c2246cf00 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -374,6 +374,29 @@ bool QPlatformWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) } /*! + Reimplement this method to set whether frame strut events + should be sent to \a enabled. + + \sa frameStrutEventsEnabled +*/ + +void QPlatformWindow::setFrameStrutEventsEnabled(bool enabled) +{ + if (enabled) + qWarning("This plugin does not support frame strut events."); +} + +/*! + Reimplement this method to return whether + frame strut events are enabled. +*/ + +bool QPlatformWindow::frameStrutEventsEnabled() const +{ + return false; +} + +/*! \class QPlatformWindow \since 4.8 \internal diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp index c707d4eea2..139df98daf 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp +++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp @@ -149,6 +149,21 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } +void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +{ + const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); + handleFrameStrutMouseEvent(w, time, local, global, b, mods); +} + +void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) +{ + QWindowSystemInterfacePrivate::MouseEvent * e = + new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, + QWindowSystemInterfacePrivate::FrameStrutMouse, + local, global, b, mods); + QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); +} + bool QWindowSystemInterface::tryHandleSynchronousShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) { diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h index 34587f67d8..b55f3e3f33 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa.h @@ -68,6 +68,8 @@ class Q_GUI_EXPORT QWindowSystemInterface public: static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); + static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); + static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier); static bool tryHandleSynchronousShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1); diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h index 919a7de39b..8fb0652eb6 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h @@ -60,6 +60,7 @@ public: ActivatedWindow, WindowStateChanged, Mouse, + FrameStrutMouse, Wheel, Key, Touch, @@ -156,6 +157,9 @@ public: MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b) { } + MouseEvent(QWindow * w, ulong time, EventType t, const QPointF & local, const QPointF & global, + Qt::MouseButtons b, Qt::KeyboardModifiers mods) + : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b) { } QPointF localPos; QPointF globalPos; Qt::MouseButtons buttons; diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 3344a87f12..1dfb45d7ff 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -214,11 +214,8 @@ void QQnxWindow::setGeometry(const QRect &rect) QWindowSystemInterface::handleSynchronousGeometryChange(window(), rect); // Now move all children. - QPoint offset; if (!oldGeometry.isEmpty()) { - offset = rect.topLeft(); - offset -= oldGeometry.topLeft(); - + const QPoint offset = rect.topLeft() - oldGeometry.topLeft(); Q_FOREACH (QQnxWindow *childWindow, m_childWindows) childWindow->setOffset(offset); } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 891753215d..ba32369c03 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -817,9 +817,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, #endif case QtWindows::ExposeEvent: return platformWindow->handleWmPaint(hwnd, message, wParam, lParam); + case QtWindows::NonClientMouseEvent: + if (platformWindow->frameStrutEventsEnabled()) + return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + break; case QtWindows::MouseWheelEvent: case QtWindows::MouseEvent: - case QtWindows::NonClientMouseEvent: case QtWindows::LeaveEvent: return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); case QtWindows::TouchEvent: diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index eb7d2912bb..e9a2b5c19d 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qwindowsmousehandler.h" +#include "qwindowskeymapper.h" #include "qwindowscontext.h" #include "qwindowswindow.h" #include "qwindowsintegration.h" @@ -130,14 +131,37 @@ QWindowsMouseHandler::QWindowsMouseHandler() : { } +Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons() +{ + Qt::MouseButtons result = 0; + const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON); + if (GetAsyncKeyState(VK_LBUTTON) < 0) + result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton; + if (GetAsyncKeyState(VK_RBUTTON) < 0) + result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton; + if (GetAsyncKeyState(VK_MBUTTON) < 0) + result |= Qt::MidButton; + return result; +} + bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { - if (et & QtWindows::NonClientEventFlag) - return false; if (et == QtWindows::MouseWheelEvent) return translateMouseWheelEvent(window, hwnd, msg, result); + + const QPoint winEventPosition(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + if (et & QtWindows::NonClientEventFlag) { + const QPoint globalPosition = winEventPosition; + const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition); + const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons(); + QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition, + globalPosition, buttons, + QWindowsKeyMapper::queryKeyboardModifiers()); + return false; // Allow further event processing (dragging of windows). + } + *result = 0; if (msg.message == WM_MOUSELEAVE) { // When moving out of a child, MouseMove within parent is received first @@ -161,7 +185,6 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, return true; } } - const QPoint client(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); // Enter new window: track to generate leave event. if (m_windowUnderMouse != window) { // The tracking on m_windowUnderMouse might still be active and @@ -186,9 +209,11 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd, qWarning("TrackMouseEvent failed."); #endif // !Q_OS_WINCE } - QWindowSystemInterface::handleMouseEvent(window, client, - QWindowsGeometryHint::mapToGlobal(hwnd, client), - keyStateToMouseButtons((int)msg.wParam)); + const QPoint clientPosition = winEventPosition; + QWindowSystemInterface::handleMouseEvent(window, clientPosition, + QWindowsGeometryHint::mapToGlobal(hwnd, clientPosition), + keyStateToMouseButtons((int)msg.wParam), + QWindowsKeyMapper::queryKeyboardModifiers()); return true; } diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h index a978840d67..e3d329e872 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.h +++ b/src/plugins/platforms/windows/qwindowsmousehandler.h @@ -70,6 +70,7 @@ public: static inline Qt::KeyboardModifiers keyStateToModifiers(int); static inline int mouseButtonsToKeyState(Qt::MouseButtons); + static Qt::MouseButtons queryMouseButtons(); QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); } private: diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 7fa43e03e6..b553c15864 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1489,6 +1489,15 @@ bool QWindowsWindow::startSystemResize(const QPoint &, Qt::Corner corner) return true; } +void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled) +{ + if (enabled) { + setFlag(FrameStrutEventsEnabled); + } else { + clearFlag(FrameStrutEventsEnabled); + } +} + #ifndef Q_OS_WINCE // maybe available on some SDKs revisit WM_GETMINMAXINFO void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const { diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 182bef78e4..475982aba4 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -123,7 +123,8 @@ public: OpenGLDoubleBuffered = 0x20, OpenGlPixelFormatInitialized = 0x40, BlockedByModal = 0x80, - SizeGripOperation = 0x100 + SizeGripOperation = 0x100, + FrameStrutEventsEnabled = 0x200 }; struct WindowData @@ -178,6 +179,9 @@ public: virtual bool startSystemResize(const QPoint &pos, Qt::Corner corner); + void setFrameStrutEventsEnabled(bool enabled); + bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); } + Qt::WindowState windowState_sys() const; Qt::WindowStates windowStates_sys() const; diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index f8a5178be5..1b076d1801 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -137,6 +137,13 @@ bool QWidgetWindow::event(QEvent *event) handleMouseEvent(static_cast<QMouseEvent *>(event)); return true; + case QEvent::NonClientAreaMouseMove: + case QEvent::NonClientAreaMouseButtonPress: + case QEvent::NonClientAreaMouseButtonRelease: + case QEvent::NonClientAreaMouseButtonDblClick: + handleNonClientAreaMouseEvent(static_cast<QMouseEvent *>(event)); + return true; + case QEvent::TouchBegin: case QEvent::TouchUpdate: case QEvent::TouchEnd: @@ -208,6 +215,11 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) } } +void QWidgetWindow::handleNonClientAreaMouseEvent(QMouseEvent *e) +{ + QApplication::sendSpontaneousEvent(m_widget, e); +} + void QWidgetWindow::handleMouseEvent(QMouseEvent *event) { if (qApp->d_func()->inPopupMode()) { diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h index 8afa3f33cd..5750a05d40 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa_p.h +++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h @@ -74,6 +74,7 @@ protected: void handleEnterLeaveEvent(QEvent *); void handleKeyEvent(QKeyEvent *); void handleMouseEvent(QMouseEvent *); + void handleNonClientAreaMouseEvent(QMouseEvent *); void handleTouchEvent(QTouchEvent *); void handleMoveEvent(QMoveEvent *); void handleResizeEvent(QResizeEvent *); diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index be216ecf9f..551549f97e 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -48,12 +48,14 @@ #include <qdrawutil.h> #include <qevent.h> #include <qfontmetrics.h> +#include <qwindow.h> #include <qmainwindow.h> #include <qrubberband.h> #include <qstylepainter.h> #include <qtoolbutton.h> #include <qdebug.h> +#include <qpa/qplatformwindow.h> #include <private/qwidgetresizehandler_p.h> #include "qdockwidget_p.h" @@ -1052,6 +1054,11 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect } } + if (unplug && floating && nativeDeco) + if (const QWindow *window = q->windowHandle()) + if (QPlatformWindow *platformWindow = window->handle()) + platformWindow->setFrameStrutEventsEnabled(true); + resizer->setActive(QWidgetResizeHandler::Resize, !unplug && floating && !nativeDeco); } |