Merge remote-tracking branch 'origin/stable' into dev
Change-Id: Id13badc270db98806048753fd7fb658aa17f1ede
This commit is contained in:
commit
b5ab7ee0d7
49
config.tests/unix/mtdev/mtdev.c
Normal file
49
config.tests/unix/mtdev/mtdev.c
Normal file
@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Jolla Ltd, author: <robin.burchell@jollamobile.com>
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of the config.tests 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia 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.
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <mtdev.h>
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
mtdev m;
|
||||
mtdev_open(&m, 0);
|
||||
return 0;
|
||||
}
|
6
config.tests/unix/mtdev/mtdev.pro
Normal file
6
config.tests/unix/mtdev/mtdev.pro
Normal file
@ -0,0 +1,6 @@
|
||||
SOURCES = mtdev.c
|
||||
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG_PRIVATE += mtdev
|
||||
|
||||
CONFIG -= qt
|
24
configure
vendored
24
configure
vendored
@ -595,6 +595,7 @@ CFG_XVIDEO=auto
|
||||
CFG_XINERAMA=runtime
|
||||
CFG_XFIXES=runtime
|
||||
CFG_ZLIB=auto
|
||||
CFG_MTDEV=auto
|
||||
CFG_SQLITE=qt
|
||||
CFG_GIF=auto
|
||||
CFG_PNG=yes
|
||||
@ -1589,6 +1590,13 @@ while [ "$#" -gt 0 ]; do
|
||||
# No longer supported:
|
||||
#[ "$VAL" = "no" ] && CFG_LIBPNG=no
|
||||
;;
|
||||
mtdev)
|
||||
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
|
||||
CFG_MTDEV="$VAL"
|
||||
else
|
||||
UNKNOWN_OPT=yes
|
||||
fi
|
||||
;;
|
||||
sqlite)
|
||||
if [ "$VAL" = "system" ]; then
|
||||
CFG_SQLITE=system
|
||||
@ -2304,6 +2312,9 @@ Third Party Libraries:
|
||||
+ -system-zlib ....... Use zlib from the operating system.
|
||||
See http://www.gzip.org/zlib
|
||||
|
||||
-no-mtdev ......... Do not compile mtdev support.
|
||||
+ -mtdev ............. Enable mtdev support.
|
||||
|
||||
-no-gif ............ Do not compile GIF reading support.
|
||||
|
||||
-no-libpng ......... Do not compile PNG support.
|
||||
@ -4414,6 +4425,17 @@ if [ "$CFG_ZLIB" = "auto" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$CFG_MTDEV" != "no" ]; then
|
||||
if compileTest unix/mtdev "mtdev"; then
|
||||
CFG_MTDEV=yes
|
||||
else
|
||||
CFG_MTDEV=no
|
||||
fi
|
||||
fi
|
||||
if [ "$CFG_MTDEV" = "no" ]; then
|
||||
QMakeVar add DEFINES QT_NO_MTDEV
|
||||
fi
|
||||
|
||||
if [ "$CFG_LARGEFILE" = "auto" ]; then
|
||||
#Large files should be enabled for all Linux systems
|
||||
CFG_LARGEFILE=yes
|
||||
@ -5875,6 +5897,7 @@ elif [ "$CFG_ZLIB" = "system" ]; then
|
||||
QT_CONFIG="$QT_CONFIG system-zlib"
|
||||
fi
|
||||
|
||||
[ "$CFG_MTDEV" = "yes" ] && QT_CONFIG="$QT_CONFIG mtdev"
|
||||
[ "$CFG_NIS" = "yes" ] && QT_CONFIG="$QT_CONFIG nis"
|
||||
[ "$CFG_CUPS" = "yes" ] && QT_CONFIG="$QT_CONFIG cups"
|
||||
[ "$CFG_ICONV" = "yes" ] && QT_CONFIG="$QT_CONFIG iconv"
|
||||
@ -6772,6 +6795,7 @@ report_support " TDS .................." "$CFG_SQL_tds" plugin "plugin" yes "
|
||||
report_support " udev ..................." "$CFG_LIBUDEV"
|
||||
report_support " xkbcommon .............." "$CFG_XKBCOMMON" system "system library" qt "bundled copy"
|
||||
report_support " zlib ..................." "$CFG_ZLIB" system "system library" yes "bundled copy"
|
||||
report_support " mtdev .................." "$CFG_MTDEV" yes "system library"
|
||||
|
||||
echo
|
||||
|
||||
|
@ -507,7 +507,7 @@
|
||||
|
||||
\snippet graphicsview/diagramscene/diagramscene.cpp 5
|
||||
|
||||
\c DiagramTextItems emit a signal when they loose focus, which is
|
||||
\c DiagramTextItems emit a signal when they lose focus, which is
|
||||
connected to this slot. We remove the item if it has no text.
|
||||
If not, we would leak memory and confuse the user as the items
|
||||
will be edited when pressed on by the mouse.
|
||||
@ -715,7 +715,7 @@
|
||||
|
||||
\snippet graphicsview/diagramscene/diagramtextitem.cpp 2
|
||||
|
||||
\c DiagramScene uses the signal emitted when the text item looses
|
||||
\c DiagramScene uses the signal emitted when the text item loses
|
||||
focus to remove the item if it is empty, i.e., it contains no
|
||||
text.
|
||||
|
||||
|
@ -139,9 +139,41 @@ public class QtActivityDelegate
|
||||
if (m_fullScreen = enterFullScreen) {
|
||||
m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
try {
|
||||
int ui_flag_immersive_sticky = View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
|
||||
int ui_flag_layout_stable = View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_STABLE").getInt(null);
|
||||
int ui_flag_layout_hide_navigation = View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION").getInt(null);
|
||||
int ui_flag_layout_fullscreen = View.class.getDeclaredField("SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN").getInt(null);
|
||||
int ui_flag_hide_navigation = View.class.getDeclaredField("SYSTEM_UI_FLAG_HIDE_NAVIGATION").getInt(null);
|
||||
int ui_flag_fullscreen = View.class.getDeclaredField("SYSTEM_UI_FLAG_FULLSCREEN").getInt(null);
|
||||
|
||||
Method m = View.class.getMethod("setSystemUiVisibility", int.class);
|
||||
m.invoke(m_activity.getWindow().getDecorView(),
|
||||
ui_flag_layout_stable
|
||||
| ui_flag_layout_hide_navigation
|
||||
| ui_flag_layout_fullscreen
|
||||
| ui_flag_hide_navigation
|
||||
| ui_flag_fullscreen
|
||||
| ui_flag_immersive_sticky
|
||||
| View.INVISIBLE);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
|
||||
m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
try {
|
||||
int ui_flag_visible = View.class.getDeclaredField("SYSTEM_UI_FLAG_VISIBLE").getInt(null);
|
||||
Method m = View.class.getMethod("setSystemUiVisibility", int.class);
|
||||
m.invoke(m_activity.getWindow().getDecorView(),
|
||||
ui_flag_visible);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,6 +380,7 @@ public class QtActivityDelegate
|
||||
}
|
||||
|
||||
m_activity = activity;
|
||||
setActionBarVisibility(false);
|
||||
QtNative.setActivity(m_activity, this);
|
||||
QtNative.setClassLoader(classLoader);
|
||||
if (loaderParams.containsKey(STATIC_INIT_CLASSES_KEY)) {
|
||||
@ -412,7 +445,6 @@ public class QtActivityDelegate
|
||||
m_applicationParameters = loaderParams.getString(APPLICATION_PARAMETERS_KEY);
|
||||
else
|
||||
m_applicationParameters = "";
|
||||
setActionBarVisibility(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -696,6 +728,12 @@ public class QtActivityDelegate
|
||||
QtNative.updateApplicationState(ApplicationActive);
|
||||
QtNative.clearLostActions();
|
||||
QtNative.updateWindow();
|
||||
|
||||
if (m_fullScreen) {
|
||||
// Suspending the app clears the immersive mode, so we need to set it again.
|
||||
m_fullScreen = false; // Force the setFullScreen() call below to actually do something
|
||||
setFullScreen(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -816,8 +854,7 @@ public class QtActivityDelegate
|
||||
{
|
||||
m_opionsMenuIsVisible = true;
|
||||
boolean res = QtNative.onPrepareOptionsMenu(menu);
|
||||
if (!res || menu.size() == 0)
|
||||
setActionBarVisibility(false);
|
||||
setActionBarVisibility(res && menu.size() > 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -834,7 +871,6 @@ public class QtActivityDelegate
|
||||
|
||||
public void resetOptionsMenu()
|
||||
{
|
||||
setActionBarVisibility(true);
|
||||
if (Build.VERSION.SDK_INT > 10) {
|
||||
try {
|
||||
Activity.class.getMethod("invalidateOptionsMenu").invoke(m_activity);
|
||||
|
@ -32,6 +32,8 @@ import java.io.OutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -50,6 +52,7 @@ import android.content.ServiceConnection;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.AssetManager;
|
||||
@ -382,6 +385,9 @@ public class QtActivity extends Activity
|
||||
InputStream inputStream = assetsManager.open(source);
|
||||
OutputStream outputStream = new FileOutputStream(destinationFile);
|
||||
copyFile(inputStream, outputStream);
|
||||
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
private static void createBundledBinary(String source, String destination)
|
||||
@ -401,13 +407,66 @@ public class QtActivity extends Activity
|
||||
InputStream inputStream = new FileInputStream(source);
|
||||
OutputStream outputStream = new FileOutputStream(destinationFile);
|
||||
copyFile(inputStream, outputStream);
|
||||
|
||||
inputStream.close();
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
private void extractBundledPluginsAndImports(String localPrefix)
|
||||
private boolean cleanCacheIfNecessary(String pluginsPrefix, long packageVersion)
|
||||
{
|
||||
File versionFile = new File(pluginsPrefix + "cache.version");
|
||||
|
||||
long cacheVersion = 0;
|
||||
if (versionFile.exists() && versionFile.canRead()) {
|
||||
try {
|
||||
DataInputStream inputStream = new DataInputStream(new FileInputStream(versionFile));
|
||||
cacheVersion = inputStream.readLong();
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheVersion != packageVersion) {
|
||||
deleteRecursively(new File(pluginsPrefix));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void extractBundledPluginsAndImports(String pluginsPrefix)
|
||||
throws IOException
|
||||
{
|
||||
ArrayList<String> libs = new ArrayList<String>();
|
||||
|
||||
String dataDir = getApplicationInfo().dataDir + "/";
|
||||
|
||||
long packageVersion = -1;
|
||||
try {
|
||||
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
|
||||
packageVersion = packageInfo.lastUpdateTime;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!cleanCacheIfNecessary(pluginsPrefix, packageVersion))
|
||||
return;
|
||||
|
||||
{
|
||||
File versionFile = new File(pluginsPrefix + "cache.version");
|
||||
|
||||
File parentDirectory = versionFile.getParentFile();
|
||||
if (!parentDirectory.exists())
|
||||
parentDirectory.mkdirs();
|
||||
|
||||
versionFile.createNewFile();
|
||||
|
||||
DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(versionFile));
|
||||
outputStream.writeLong(packageVersion);
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
{
|
||||
String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY;
|
||||
java.util.Set<String> keys = m_activityInfo.metaData.keySet();
|
||||
@ -416,8 +475,8 @@ public class QtActivity extends Activity
|
||||
|
||||
for (String bundledImportBinary : list) {
|
||||
String[] split = bundledImportBinary.split(":");
|
||||
String sourceFileName = localPrefix + "lib/" + split[0];
|
||||
String destinationFileName = localPrefix + split[1];
|
||||
String sourceFileName = dataDir + "lib/" + split[0];
|
||||
String destinationFileName = pluginsPrefix + split[1];
|
||||
createBundledBinary(sourceFileName, destinationFileName);
|
||||
}
|
||||
}
|
||||
@ -431,7 +490,7 @@ public class QtActivity extends Activity
|
||||
for (String fileName : list) {
|
||||
String[] split = fileName.split(":");
|
||||
String sourceFileName = split[0];
|
||||
String destinationFileName = localPrefix + split[1];
|
||||
String destinationFileName = pluginsPrefix + split[1];
|
||||
copyAsset(sourceFileName, destinationFileName);
|
||||
}
|
||||
}
|
||||
@ -439,6 +498,45 @@ public class QtActivity extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteRecursively(File directory)
|
||||
{
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isDirectory())
|
||||
deleteRecursively(file);
|
||||
else
|
||||
file.delete();
|
||||
}
|
||||
|
||||
directory.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanOldCacheIfNecessary(String oldLocalPrefix, String localPrefix)
|
||||
{
|
||||
File newCache = new File(localPrefix);
|
||||
if (!newCache.exists()) {
|
||||
{
|
||||
File oldPluginsCache = new File(oldLocalPrefix + "plugins/");
|
||||
if (oldPluginsCache.exists() && oldPluginsCache.isDirectory())
|
||||
deleteRecursively(oldPluginsCache);
|
||||
}
|
||||
|
||||
{
|
||||
File oldImportsCache = new File(oldLocalPrefix + "imports/");
|
||||
if (oldImportsCache.exists() && oldImportsCache.isDirectory())
|
||||
deleteRecursively(oldImportsCache);
|
||||
}
|
||||
|
||||
{
|
||||
File oldQmlCache = new File(oldLocalPrefix + "qml/");
|
||||
if (oldQmlCache.exists() && oldQmlCache.isDirectory())
|
||||
deleteRecursively(oldQmlCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startApp(final boolean firstStart)
|
||||
{
|
||||
try {
|
||||
@ -464,11 +562,15 @@ public class QtActivity extends Activity
|
||||
if (m_activityInfo.metaData.containsKey("android.app.libs_prefix"))
|
||||
localPrefix = m_activityInfo.metaData.getString("android.app.libs_prefix");
|
||||
|
||||
String pluginsPrefix = localPrefix;
|
||||
|
||||
boolean bundlingQtLibs = false;
|
||||
if (m_activityInfo.metaData.containsKey("android.app.bundle_local_qt_libs")
|
||||
&& m_activityInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) {
|
||||
localPrefix = getApplicationInfo().dataDir + "/";
|
||||
extractBundledPluginsAndImports(localPrefix);
|
||||
pluginsPrefix = localPrefix + "qt-reserved-files/";
|
||||
cleanOldCacheIfNecessary(localPrefix, pluginsPrefix);
|
||||
extractBundledPluginsAndImports(pluginsPrefix);
|
||||
bundlingQtLibs = true;
|
||||
}
|
||||
|
||||
@ -484,8 +586,12 @@ public class QtActivity extends Activity
|
||||
if (m_activityInfo.metaData.containsKey("android.app.load_local_libs")) {
|
||||
String[] extraLibs = m_activityInfo.metaData.getString("android.app.load_local_libs").split(":");
|
||||
for (String lib : extraLibs) {
|
||||
if (lib.length() > 0)
|
||||
libraryList.add(localPrefix + lib);
|
||||
if (lib.length() > 0) {
|
||||
if (lib.startsWith("lib/"))
|
||||
libraryList.add(localPrefix + lib);
|
||||
else
|
||||
libraryList.add(pluginsPrefix + lib);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -513,9 +619,9 @@ public class QtActivity extends Activity
|
||||
}
|
||||
loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList);
|
||||
loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES
|
||||
+ "\tQML2_IMPORT_PATH=" + localPrefix + "/qml"
|
||||
+ "\tQML_IMPORT_PATH=" + localPrefix + "/imports"
|
||||
+ "\tQT_PLUGIN_PATH=" + localPrefix + "/plugins");
|
||||
+ "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml"
|
||||
+ "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports"
|
||||
+ "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins");
|
||||
|
||||
Intent intent = getIntent();
|
||||
if (intent != null) {
|
||||
|
@ -509,15 +509,14 @@
|
||||
delivery at a later time.
|
||||
|
||||
\value AutoConnection
|
||||
(default) If the signal is emitted from a different thread than the
|
||||
receiving object, the signal is queued, behaving as
|
||||
Qt::QueuedConnection. Otherwise, the slot is invoked directly,
|
||||
behaving as Qt::DirectConnection. The type of connection is
|
||||
\b (Default) If the receiver \l{QObject#Thread Affinity}{lives in} the
|
||||
thread that emits the signal, Qt::DirectConnection is used. Otherwise,
|
||||
Qt::QueuedConnection is used. The connection type is
|
||||
determined when the signal is emitted.
|
||||
|
||||
\value DirectConnection
|
||||
The slot is invoked immediately, when the signal is
|
||||
emitted.
|
||||
The slot is invoked immediately when the signal is
|
||||
emitted. The slot is executed in the signalling thread.
|
||||
|
||||
\value QueuedConnection
|
||||
The slot is invoked when control returns to the event loop
|
||||
@ -525,11 +524,10 @@
|
||||
receiver's thread.
|
||||
|
||||
\value BlockingQueuedConnection
|
||||
Same as QueuedConnection, except the current thread blocks
|
||||
until the slot returns. This connection type should only be
|
||||
used where the emitter and receiver are in different
|
||||
threads. \note Violating this rule can cause your
|
||||
application to deadlock.
|
||||
Same as Qt::QueuedConnection, except that the signalling thread blocks
|
||||
until the slot returns. This connection must \e not be used if the
|
||||
receiver lives in the signalling thread, or else the application
|
||||
will deadlock.
|
||||
|
||||
\value UniqueConnection
|
||||
This is a flag that can be combined with any one of the above
|
||||
|
@ -51,6 +51,10 @@
|
||||
#include <QtCore/QLocale>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
//Environment variable to allow tooling full control of file selectors
|
||||
@ -69,7 +73,7 @@ QFileSelectorPrivate::QFileSelectorPrivate()
|
||||
/*!
|
||||
\class QFileSelector
|
||||
\inmodule QtCore
|
||||
\brief QFileSelector provides a convenient way of selecting file variants
|
||||
\brief QFileSelector provides a convenient way of selecting file variants.
|
||||
\since 5.2
|
||||
|
||||
QFileSelector is a convenience for selecting file variants based on platform or device
|
||||
@ -77,6 +81,10 @@ QFileSelectorPrivate::QFileSelectorPrivate()
|
||||
different variants more easily in some circumstances, such as when the correct variant cannot
|
||||
be determined during the deploy step.
|
||||
|
||||
\section1 Using QFileSelector
|
||||
|
||||
If you always use the same file you do not need to use QFileSelector.
|
||||
|
||||
Consider the following example usage, where you want to use different settings files on
|
||||
different locales. You might select code between locales like this:
|
||||
|
||||
@ -115,7 +123,7 @@ QFileSelectorPrivate::QFileSelectorPrivate()
|
||||
QFile defaultsFile(selector.select("data/defaults.conf"));
|
||||
\endcode
|
||||
|
||||
The files to be selected are placed in directories named with a '+' and a selector name. In the above
|
||||
The files to be selected are placed in directories named with a \c'+' and a selector name. In the above
|
||||
example you could have the platform configurations selected by placing them in the following locations:
|
||||
\code
|
||||
data/defaults.conf
|
||||
@ -124,8 +132,6 @@ QFileSelectorPrivate::QFileSelectorPrivate()
|
||||
data/+ios/+en_GB/defaults.conf
|
||||
\endcode
|
||||
|
||||
If you always use the same file you do not need to use QFileSelector.
|
||||
|
||||
To find selected files, QFileSelector looks in the same directory as the base file. If there are
|
||||
any directories of the form +<selector> with an active selector, QFileSelector will prefer a file
|
||||
with the same file name from that directory over the base file. These directories can be nested to
|
||||
@ -138,33 +144,43 @@ QFileSelectorPrivate::QFileSelectorPrivate()
|
||||
With those files available, you would select a different file on android and blackberry platforms,
|
||||
but only if the locale was en_GB.
|
||||
|
||||
QFileSelector will not attempt to select if the base file does not exist. For error handling in
|
||||
the case no valid selectors are present, it is recommended to have a default or error-handling
|
||||
file in the base file location even if you expect selectors to be present for all deployments.
|
||||
|
||||
In a future version, some may be marked as deploy-time static and be moved during the
|
||||
deployment step as an optimization. As selectors come with a performance cost, it is
|
||||
recommended to avoid their use in circumstances involving performance-critical code.
|
||||
|
||||
\section1 Adding selectors
|
||||
|
||||
Selectors normally available are
|
||||
\list
|
||||
\li platform, one of: android, blackberry, ios, windows, osx, linux, generic_unix or unknown.
|
||||
\li platform, any of the following strings which match the platform the application is running
|
||||
on: android, blackberry, ios, mac, linux, wince, unix, windows.
|
||||
\li locale, same as QLocale::system().name().
|
||||
\endlist
|
||||
|
||||
Further selectors will be added from the QT_FILE_SELECTORS environment variable, which when
|
||||
set should be a set of colon (semi-colon on windows) separated selectors. Note that this
|
||||
variable will only be read once, selectors may not update if the variable changes while the
|
||||
application is running.
|
||||
Further selectors will be added from the \c QT_FILE_SELECTORS environment variable, which
|
||||
when set should be a set of comma separated selectors. Note that this variable will only be
|
||||
read once; selectors may not update if the variable changes while the application is running.
|
||||
The initial set of selectors are evaluated only once, on first use.
|
||||
|
||||
The initial set of selectors are evaluated only once, on first use. In a future
|
||||
version, some may be marked as deploy-time static and be moved during the deployment step as an
|
||||
optimization. As selectors come with a performance cost, it is recommended to avoid their use
|
||||
in circumstances involving performance-critical code.
|
||||
You can also add extra selectors at runtime for custom behavior. These will be used in any
|
||||
future calls to select(). If the extra selectors list has been changed, calls to select() will
|
||||
use the new list and may return differently.
|
||||
|
||||
Additionally you can add extra selectors at runtime to customize behavior further. These will
|
||||
be used in any future calls to select(). If the extra selectors list has been changed, calls to
|
||||
select() will use the new list and may return differently.
|
||||
\section1 Conflict resolution when multiple selectors apply
|
||||
|
||||
When multiple selectors could be applied to the same file, the first matching selector is chosen.
|
||||
The order selectors are checked in are:
|
||||
|
||||
1. Selectors set via setExtraSelectors(), in the order they are in the list
|
||||
2. Selectors in the QT_FILE_SELECTORS environment variable, from left to right
|
||||
3. Locale
|
||||
4. Platform
|
||||
\list 1
|
||||
\li Selectors set via setExtraSelectors(), in the order they are in the list
|
||||
\li Selectors in the \c QT_FILE_SELECTORS environment variable, from left to right
|
||||
\li Locale
|
||||
\li Platform
|
||||
\endlist
|
||||
|
||||
Here is an example involving multiple selectors matching at the same time. It uses platform
|
||||
selectors, plus an extra selector named "admin" is set by the application based on user
|
||||
@ -179,14 +195,11 @@ QFileSelectorPrivate::QFileSelectorPrivate()
|
||||
images/+admin/+linux/background.png
|
||||
\endcode
|
||||
|
||||
Because extra selectors are checked before platform the +admin/background.png will be chosen
|
||||
on windows when the admin selector is set, and +windows/background.png will be chosen on
|
||||
windows when the admin selector is not set. On linux, the +admin/+linux/background.png will be
|
||||
chosen when admin is set, and the +linux/background.png when it is not.
|
||||
Because extra selectors are checked before platform the \c{+admin/background.png} will be chosen
|
||||
on Windows when the admin selector is set, and \c{+windows/background.png} will be chosen on
|
||||
Windows when the admin selector is not set. On Linux, the \c{+admin/+linux/background.png} will be
|
||||
chosen when admin is set, and the \c{+linux/background.png} when it is not.
|
||||
|
||||
QFileSelector will not attempt to select if the base file does not exist. For error handling in
|
||||
the case no valid selectors are present, it is recommended to have a default or error-handling
|
||||
file in the base file location even if you expect selectors to be present for all deployments.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -876,7 +876,7 @@ struct CapabilitiesImpl<T, std::random_access_iterator_tag>
|
||||
template<typename T>
|
||||
struct ContainerAPI : CapabilitiesImpl<T>
|
||||
{
|
||||
static int size(const T *t) { return std::distance(t->begin(), t->end()); }
|
||||
static int size(const T *t) { return int(std::distance(t->begin(), t->end())); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -1102,8 +1102,8 @@ public:
|
||||
|
||||
template<class T>
|
||||
static int sizeImpl(const void *p)
|
||||
{ return std::distance(static_cast<const T*>(p)->begin(),
|
||||
static_cast<const T*>(p)->end()); }
|
||||
{ return int(std::distance(static_cast<const T*>(p)->begin(),
|
||||
static_cast<const T*>(p)->end())); }
|
||||
|
||||
template<class T>
|
||||
static void findImpl(const void *container, const void *p, void **iterator)
|
||||
|
@ -534,7 +534,7 @@
|
||||
Use std::lower_bound instead.
|
||||
|
||||
Performs a binary search of the range [\a begin, \a end) and
|
||||
returns the position of the first ocurrence of \a value. If no
|
||||
returns the position of the first occurrence of \a value. If no
|
||||
such item is found, returns the position where it should be
|
||||
inserted.
|
||||
|
||||
|
@ -262,7 +262,7 @@ public:
|
||||
inline const_iterator &operator-=(int j) { i-=j; return *this; }
|
||||
inline const_iterator operator+(int j) const { return const_iterator(i+j); }
|
||||
inline const_iterator operator-(int j) const { return const_iterator(i-j); }
|
||||
inline int operator-(const_iterator j) const { return i - j.i; }
|
||||
inline int operator-(const_iterator j) const { return int(i - j.i); }
|
||||
};
|
||||
friend class const_iterator;
|
||||
|
||||
|
@ -187,7 +187,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
|
||||
|
||||
The method systemTimeZoneId() returns the current system IANA time zone
|
||||
ID which on OSX and Linux will always be correct. On Windows this ID is
|
||||
translated from the the Windows system ID using an internal translation
|
||||
translated from the Windows system ID using an internal translation
|
||||
table and the user's selected country. As a consequence there is a small
|
||||
chance any Windows install may have IDs not known by Qt, in which case
|
||||
"UTC" will be returned.
|
||||
@ -773,7 +773,7 @@ QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
|
||||
/*!
|
||||
Returns the current system time zone IANA ID.
|
||||
|
||||
On Windows this ID is translated from the the Windows ID using an internal
|
||||
On Windows this ID is translated from the Windows ID using an internal
|
||||
translation table and the user's selected country. As a consequence there
|
||||
is a small chance any Windows install may have IDs not known by Qt, in
|
||||
which case "UTC" will be returned.
|
||||
|
@ -178,6 +178,7 @@ public:
|
||||
typedef QMultiHash<QString, SignalHook> SignalHookHash;
|
||||
typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
|
||||
typedef QHash<QByteArray, int> MatchRefCountHash;
|
||||
typedef QList<QDBusPendingCallPrivate*> PendingCallList;
|
||||
|
||||
struct WatchedServiceData {
|
||||
WatchedServiceData() : refcount(0) {}
|
||||
@ -316,6 +317,7 @@ public:
|
||||
MatchRefCountHash matchRefCounts;
|
||||
ObjectTreeNode rootNode;
|
||||
MetaObjectHash cachedMetaObjects;
|
||||
PendingCallList pendingCalls;
|
||||
|
||||
QMutex callDeliveryMutex;
|
||||
QDBusCallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex
|
||||
|
@ -1092,6 +1092,9 @@ void QDBusConnectionPrivate::closeConnection()
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
qDeleteAll(pendingCalls);
|
||||
|
||||
qDBusDebug() << this << "Disconnected";
|
||||
}
|
||||
|
||||
@ -1834,6 +1837,8 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call)
|
||||
|
||||
QMutexLocker locker(&call->mutex);
|
||||
|
||||
connection->pendingCalls.removeOne(call);
|
||||
|
||||
QDBusMessage &msg = call->replyMessage;
|
||||
if (call->pending) {
|
||||
// decode the message
|
||||
@ -2094,6 +2099,10 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM
|
||||
pcall->pending = pending;
|
||||
q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);
|
||||
|
||||
// DBus won't notify us when a peer disconnects so we need to track these ourselves
|
||||
if (mode == QDBusConnectionPrivate::PeerMode)
|
||||
pendingCalls.append(pcall);
|
||||
|
||||
return pcall;
|
||||
} else {
|
||||
// we're probably disconnected at this point
|
||||
|
@ -1313,6 +1313,8 @@ QAccessible::Id QAccessibleEvent::uniqueId() const
|
||||
if (!m_object)
|
||||
return m_uniqueId;
|
||||
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(m_object);
|
||||
if (!iface)
|
||||
return 0;
|
||||
if (m_child != -1)
|
||||
iface = iface->child(m_child);
|
||||
return QAccessible::uniqueId(iface);
|
||||
|
@ -1426,7 +1426,7 @@ qreal QImage::devicePixelRatio() const
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the the device pixel ratio for the image. This is the
|
||||
Sets the device pixel ratio for the image. This is the
|
||||
ratio between image pixels and device-independent pixels.
|
||||
|
||||
The default \a scaleFactor is 1.0. Setting it to something else has
|
||||
|
@ -665,7 +665,7 @@ qreal QPixmap::devicePixelRatio() const
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the the device pixel ratio for the pixmap. This is the
|
||||
Sets the device pixel ratio for the pixmap. This is the
|
||||
ratio between image pixels and device-independent pixels.
|
||||
|
||||
The default \a scaleFactor is 1.0. Setting it to something else has
|
||||
|
@ -160,7 +160,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const
|
||||
// proper metrics will be cached and used later.
|
||||
if (fontEngine->hasInternalCaching()) {
|
||||
QImage *locked = fontEngine->lockedAlphaMapForGlyph(glyph, subPixelPosition, format);
|
||||
if (locked)
|
||||
if (locked && !locked->isNull())
|
||||
fontEngine->unlockAlphaMapForGlyph();
|
||||
}
|
||||
|
||||
|
@ -954,12 +954,12 @@ void QTextEngine::shapeText(int item) const
|
||||
itemBoundaries.append(i);
|
||||
itemBoundaries.append(glyph_pos);
|
||||
|
||||
lastEngine = engineIdx;
|
||||
QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
|
||||
si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
|
||||
si.descent = qMax(actualFontEngine->descent(), si.descent);
|
||||
si.leading = qMax(actualFontEngine->leading(), si.leading);
|
||||
}
|
||||
lastEngine = engineIdx;
|
||||
if (QChar::isHighSurrogate(string[i]) && i + 1 < itemLength && QChar::isLowSurrogate(string[i + 1]))
|
||||
++i;
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ contains(QT_CONFIG, libudev) {
|
||||
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
|
||||
}
|
||||
|
||||
# DEFINES += USE_MTDEV
|
||||
contains(CONFIG, mtdev) {
|
||||
CONFIG += link_pkgconfig
|
||||
PKGCONFIG_PRIVATE += mtdev
|
||||
}
|
||||
|
||||
contains(DEFINES, USE_MTDEV): LIBS_PRIVATE += -lmtdev
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include <QtPlatformSupport/private/qdevicediscovery_p.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
extern "C" {
|
||||
#include <mtdev.h>
|
||||
}
|
||||
@ -164,7 +164,7 @@ static inline bool testBit(long bit, const long *array)
|
||||
|
||||
QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification, QObject *parent)
|
||||
: QObject(parent), m_notify(0), m_fd(-1), d(0)
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
, m_mtdev(0)
|
||||
#endif
|
||||
{
|
||||
@ -233,7 +233,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
m_mtdev = static_cast<mtdev *>(calloc(1, sizeof(mtdev)));
|
||||
int mtdeverr = mtdev_open(m_mtdev, m_fd);
|
||||
if (mtdeverr) {
|
||||
@ -245,7 +245,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
|
||||
|
||||
d = new QEvdevTouchScreenData(this, args);
|
||||
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
const char *mtdevStr = "(mtdev)";
|
||||
d->m_typeB = true;
|
||||
#else
|
||||
@ -329,7 +329,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &specification,
|
||||
|
||||
QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler()
|
||||
{
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
if (m_mtdev) {
|
||||
mtdev_close(m_mtdev);
|
||||
free(m_mtdev);
|
||||
@ -347,7 +347,7 @@ void QEvdevTouchScreenHandler::readData()
|
||||
::input_event buffer[32];
|
||||
int n = 0;
|
||||
for (; ;) {
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
int result = mtdev_get(m_mtdev, m_fd, buffer, sizeof(buffer) / sizeof(::input_event));
|
||||
if (result > 0)
|
||||
result *= sizeof(::input_event);
|
||||
|
@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSocketNotifier;
|
||||
class QEvdevTouchScreenData;
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
struct mtdev;
|
||||
#endif
|
||||
|
||||
@ -71,7 +71,7 @@ private:
|
||||
QSocketNotifier *m_notify;
|
||||
int m_fd;
|
||||
QEvdevTouchScreenData *d;
|
||||
#ifdef USE_MTDEV
|
||||
#if !defined(QT_NO_MTDEV)
|
||||
mtdev *m_mtdev;
|
||||
#endif
|
||||
};
|
||||
|
@ -1729,6 +1729,7 @@ QSpiActionArray AtSpiAdaptor::getActions(QAccessibleActionInterface *actionInter
|
||||
QSpiAction action;
|
||||
QStringList keyBindings;
|
||||
|
||||
action.name = actionName;
|
||||
action.description = actionInterface->localizedActionDescription(actionName);
|
||||
|
||||
keyBindings = actionInterface->keyBindingsForAction(actionName);
|
||||
|
@ -5,8 +5,9 @@ Single-touch devices reporting ABS_X and Y only are not supported
|
||||
by this plugin. Use tslib or evdevmouse instead.
|
||||
|
||||
The protocol type will be detected automatically.
|
||||
To enable libmtdev support uncomment the USE_MTDEV define in
|
||||
src/platformsupport/input/evdevtouch/evdevtouch.pri.
|
||||
|
||||
libmtdev is automatically detected based on library availability. To disable it,
|
||||
pass -no-mtdev to configure.
|
||||
|
||||
Tested with the following kernel drivers:
|
||||
bcm5974 (type A)
|
||||
|
@ -156,11 +156,11 @@ namespace QtAndroidMenu
|
||||
foreach (QAndroidPlatformMenuBar *menuBar, menuBars) {
|
||||
if (menuBar->parentWindow() == window) {
|
||||
visibleMenuBar = menuBar;
|
||||
resetMenuBar();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
resetMenuBar();
|
||||
}
|
||||
|
||||
void addMenuBar(QAndroidPlatformMenuBar *menuBar)
|
||||
|
@ -1342,11 +1342,6 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
{
|
||||
Q_UNUSED(replacementRange)
|
||||
|
||||
if (m_sendKeyEvent && m_composingText.isEmpty()) {
|
||||
// don't send input method events for simple text input (let handleKeyEvent send key events instead)
|
||||
return;
|
||||
}
|
||||
|
||||
QString commitString;
|
||||
if ([aString length]) {
|
||||
if ([aString isKindOfClass:[NSAttributedString class]]) {
|
||||
|
@ -400,7 +400,11 @@ bool QLinuxFbScreen::initialize()
|
||||
mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);
|
||||
|
||||
QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR");
|
||||
#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)
|
||||
bool hideCursor = false;
|
||||
#else
|
||||
bool hideCursor = true; // default to true to prevent the cursor showing up with the subclass on Android
|
||||
#endif
|
||||
if (hideCursorVal.isEmpty()) {
|
||||
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
|
||||
QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse));
|
||||
|
@ -2132,6 +2132,9 @@ bool useHelper(QPlatformTheme::DialogType type)
|
||||
break;
|
||||
#endif
|
||||
case QPlatformTheme::FontDialog:
|
||||
case QPlatformTheme::MessageDialog:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@ -2160,6 +2163,9 @@ QPlatformDialogHelper *createHelper(QPlatformTheme::DialogType type)
|
||||
break;
|
||||
#endif
|
||||
case QPlatformTheme::FontDialog:
|
||||
case QPlatformTheme::MessageDialog:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -262,12 +262,19 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||
, has_input_shape(false)
|
||||
, has_touch_without_mouse_emulation(false)
|
||||
, has_xkb(false)
|
||||
, debug_xinput_devices(false)
|
||||
, debug_xinput(false)
|
||||
, m_buttons(0)
|
||||
, m_focusWindow(0)
|
||||
, m_systemTrayTracker(0)
|
||||
{
|
||||
#ifdef XCB_USE_EGL
|
||||
EGLNativeDisplayType dpy = EGL_DEFAULT_DISPLAY;
|
||||
#elif defined(XCB_USE_XLIB)
|
||||
Display *dpy;
|
||||
#endif
|
||||
#ifdef XCB_USE_XLIB
|
||||
Display *dpy = XOpenDisplay(m_displayName.constData());
|
||||
dpy = XOpenDisplay(m_displayName.constData());
|
||||
if (dpy) {
|
||||
m_primaryScreen = DefaultScreen(dpy);
|
||||
m_connection = XGetXCBConnection(dpy);
|
||||
@ -276,7 +283,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
||||
m_xlib_display = dpy;
|
||||
}
|
||||
#else
|
||||
EGLNativeDisplayType dpy = EGL_DEFAULT_DISPLAY;
|
||||
m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen);
|
||||
#endif //XCB_USE_XLIB
|
||||
|
||||
@ -733,6 +739,8 @@ void QXcbConnection::handleButtonPress(xcb_generic_event_t *ev)
|
||||
// the rest we need to manage ourselves
|
||||
m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
|
||||
m_buttons |= translateMouseButton(event->detail);
|
||||
if (Q_UNLIKELY(debug_xinput))
|
||||
qDebug("xcb: pressed mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons));
|
||||
}
|
||||
|
||||
void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev)
|
||||
@ -743,6 +751,8 @@ void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev)
|
||||
// the rest we need to manage ourselves
|
||||
m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state);
|
||||
m_buttons &= ~translateMouseButton(event->detail);
|
||||
if (Q_UNLIKELY(debug_xinput))
|
||||
qDebug("xcb: released mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons));
|
||||
}
|
||||
|
||||
#ifndef QT_NO_XKB
|
||||
@ -798,6 +808,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
||||
handleButtonRelease(event);
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
|
||||
case XCB_MOTION_NOTIFY:
|
||||
if (Q_UNLIKELY(debug_xinput)) {
|
||||
xcb_motion_notify_event_t *mev = (xcb_motion_notify_event_t *)event;
|
||||
qDebug("xcb: moved mouse to %4d, %4d; button state %X", mev->event_x, mev->event_y, static_cast<unsigned int>(m_buttons));
|
||||
}
|
||||
#ifdef QT_NO_XKB
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state);
|
||||
#endif
|
||||
|
@ -572,6 +572,8 @@ private:
|
||||
bool has_input_shape;
|
||||
bool has_touch_without_mouse_emulation;
|
||||
bool has_xkb;
|
||||
bool debug_xinput_devices;
|
||||
bool debug_xinput;
|
||||
|
||||
Qt::MouseButtons m_buttons;
|
||||
|
||||
|
@ -44,10 +44,7 @@
|
||||
#include "qxcbwindow.h"
|
||||
#include "qtouchdevice.h"
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
//#define XI2_DEBUG
|
||||
#ifdef XI2_DEBUG
|
||||
#include <QDebug>
|
||||
#endif
|
||||
|
||||
#ifdef XCB_USE_XINPUT2
|
||||
|
||||
@ -73,6 +70,8 @@ struct XInput2DeviceData {
|
||||
|
||||
void QXcbConnection::initializeXInput2()
|
||||
{
|
||||
debug_xinput = qEnvironmentVariableIsSet("QT_XCB_DEBUG_XINPUT");
|
||||
debug_xinput_devices = qEnvironmentVariableIsSet("QT_XCB_DEBUG_XINPUT_DEVICES");
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
m_tabletData.clear();
|
||||
#endif
|
||||
@ -87,8 +86,11 @@ void QXcbConnection::initializeXInput2()
|
||||
m_xi2Enabled = true;
|
||||
}
|
||||
if (m_xi2Enabled) {
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug("XInput version %d.%d is supported", xiMajor, m_xi2Minor);
|
||||
if (Q_UNLIKELY(debug_xinput_devices))
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
qDebug("XInput version %d.%d is available and Qt supports 2.2 or greater", xiMajor, m_xi2Minor);
|
||||
#else
|
||||
qDebug("XInput version %d.%d is available and Qt supports 2.0", xiMajor, m_xi2Minor);
|
||||
#endif
|
||||
int deviceCount = 0;
|
||||
XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
|
||||
@ -96,9 +98,8 @@ void QXcbConnection::initializeXInput2()
|
||||
// Only non-master pointing devices are relevant here.
|
||||
if (devices[i].use != XISlavePointer)
|
||||
continue;
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug() << "input device "<< devices[i].name;
|
||||
#endif
|
||||
if (Q_UNLIKELY(debug_xinput_devices))
|
||||
qDebug() << "input device "<< devices[i].name;
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
TabletData tabletData;
|
||||
#endif
|
||||
@ -107,9 +108,8 @@ void QXcbConnection::initializeXInput2()
|
||||
case XIValuatorClass: {
|
||||
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(devices[i].classes[c]);
|
||||
const int valuatorAtom = qatom(vci->label);
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
|
||||
#endif
|
||||
if (Q_UNLIKELY(debug_xinput_devices))
|
||||
qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
if (valuatorAtom < QXcbAtom::NAtoms) {
|
||||
TabletData::ValuatorClassInfo info;
|
||||
@ -136,26 +136,23 @@ void QXcbConnection::initializeXInput2()
|
||||
tabletData.pointerType = QTabletEvent::Eraser;
|
||||
m_tabletData.append(tabletData);
|
||||
isTablet = true;
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
|
||||
#endif
|
||||
if (Q_UNLIKELY(debug_xinput_devices))
|
||||
qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
|
||||
}
|
||||
#endif // QT_NO_TABLETEVENT
|
||||
if (!isTablet) {
|
||||
XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
|
||||
#ifdef XI2_DEBUG
|
||||
if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
|
||||
qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
|
||||
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
|
||||
dev->qtTouchDevice->maximumTouchPoints());
|
||||
else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
|
||||
qDebug(" it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
|
||||
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
|
||||
dev->qtTouchDevice->maximumTouchPoints(),
|
||||
dev->size.width(), dev->size.height());
|
||||
#else
|
||||
Q_UNUSED(dev);
|
||||
#endif // XI2_DEBUG
|
||||
if (Q_UNLIKELY(debug_xinput_devices)) {
|
||||
if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
|
||||
qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
|
||||
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
|
||||
dev->qtTouchDevice->maximumTouchPoints());
|
||||
else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
|
||||
qDebug(" it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
|
||||
dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
|
||||
dev->qtTouchDevice->maximumTouchPoints(),
|
||||
dev->size.width(), dev->size.height());
|
||||
}
|
||||
}
|
||||
}
|
||||
XIFreeDeviceInfo(devices);
|
||||
@ -236,9 +233,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
|
||||
case XITouchClass: {
|
||||
XITouchClassInfo *tci = reinterpret_cast<XITouchClassInfo *>(classinfo);
|
||||
maxTouchPoints = tci->num_touches;
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug(" has touch class with mode %d", tci->mode);
|
||||
#endif
|
||||
if (Q_UNLIKELY(debug_xinput_devices))
|
||||
qDebug(" has touch class with mode %d", tci->mode);
|
||||
switch (tci->mode) {
|
||||
case XIModeRelative:
|
||||
type = QTouchDevice::TouchPad;
|
||||
@ -324,13 +320,11 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
#ifdef XCB_USE_XINPUT22
|
||||
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
|
||||
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug("XI2 event type %d seq %d detail %d pos 0x%X,0x%X %f,%f root pos %f,%f",
|
||||
event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail,
|
||||
xiDeviceEvent->event_x, xiDeviceEvent->event_y,
|
||||
fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
|
||||
fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) );
|
||||
#endif
|
||||
if (Q_UNLIKELY(debug_xinput))
|
||||
qDebug("XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f",
|
||||
event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail,
|
||||
fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
|
||||
fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) );
|
||||
|
||||
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
|
||||
XInput2DeviceData *dev = deviceForId(xiEvent->deviceid);
|
||||
@ -356,10 +350,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
double value;
|
||||
if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value))
|
||||
continue;
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug(" valuator %20s value %lf from range %lf -> %lf",
|
||||
atomName(vci->label).constData(), value, vci->min, vci->max );
|
||||
#endif
|
||||
if (Q_UNLIKELY(debug_xinput))
|
||||
qDebug(" valuator %20s value %lf from range %lf -> %lf",
|
||||
atomName(vci->label).constData(), value, vci->min, vci->max );
|
||||
if (vci->label == atom(QXcbAtom::RelX)) {
|
||||
nx = valuatorNormalized(value, vci);
|
||||
} else if (vci->label == atom(QXcbAtom::RelY)) {
|
||||
@ -435,10 +428,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
|
||||
touchPoint.area = QRectF(x - w/2, y - h/2, w, h);
|
||||
touchPoint.normalPosition = QPointF(nx, ny);
|
||||
|
||||
#ifdef XI2_DEBUG
|
||||
qDebug() << " tp " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition <<
|
||||
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
|
||||
#endif
|
||||
if (Q_UNLIKELY(debug_xinput))
|
||||
qDebug() << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition <<
|
||||
" area " << touchPoint.area << " pressure " << touchPoint.pressure;
|
||||
QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values());
|
||||
if (touchPoint.state == Qt::TouchPointReleased)
|
||||
// If a touchpoint was released, we can forget it, because the ID won't be reused.
|
||||
@ -560,6 +552,13 @@ void QXcbConnection::xi2ReportTabletEvent(const TabletData &tabletData, void *ev
|
||||
}
|
||||
}
|
||||
|
||||
if (Q_UNLIKELY(debug_xinput))
|
||||
qDebug("XI2 tablet event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f pressure %4.2lf tilt %d, %d rotation %6.2lf",
|
||||
ev->type, ev->sequenceNumber, ev->detail,
|
||||
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
|
||||
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
|
||||
pressure, xTilt, yTilt, rotation);
|
||||
|
||||
QWindowSystemInterface::handleTabletEvent(window, tabletData.down, local, global,
|
||||
QTabletEvent::Stylus, tabletData.pointerType,
|
||||
pressure, xTilt, yTilt, 0,
|
||||
|
@ -373,9 +373,9 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan
|
||||
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
|
||||
QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
|
||||
QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
|
||||
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(),
|
||||
Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(),
|
||||
Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
|
||||
|
||||
QDpi ldpi = logicalDpi();
|
||||
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), ldpi.first, ldpi.second);
|
||||
}
|
||||
|
||||
void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
|
||||
|
@ -1916,6 +1916,16 @@ bool CppCodeParser::matchProperty(InnerNode *parent)
|
||||
QString key = previousLexeme();
|
||||
QString value;
|
||||
|
||||
// Keywords with no associated values
|
||||
if (key == "CONSTANT") {
|
||||
property->setConstant();
|
||||
continue;
|
||||
}
|
||||
else if (key == "FINAL") {
|
||||
property->setFinal();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (match(Tok_Ident) || match(Tok_Number)) {
|
||||
value = previousLexeme();
|
||||
}
|
||||
@ -1966,7 +1976,7 @@ bool CppCodeParser::matchProperty(InnerNode *parent)
|
||||
if (ok)
|
||||
property->setRevision(revision);
|
||||
else
|
||||
parent->doc().location().warning(tr("Invalid revision number: %1").arg(value));
|
||||
location().warning(tr("Invalid revision number: %1").arg(value));
|
||||
} else if (key == "SCRIPTABLE") {
|
||||
QString v = value.toLower();
|
||||
if (v == "true")
|
||||
@ -1978,10 +1988,6 @@ bool CppCodeParser::matchProperty(InnerNode *parent)
|
||||
property->setRuntimeScrFunc(value);
|
||||
}
|
||||
}
|
||||
else if (key == "CONSTANT")
|
||||
property->setConstant();
|
||||
else if (key == "FINAL")
|
||||
property->setFinal();
|
||||
}
|
||||
match(Tok_RightParen);
|
||||
return true;
|
||||
@ -2061,7 +2067,11 @@ bool CppCodeParser::matchDeclList(InnerNode *parent)
|
||||
case Tok_Q_PROPERTY:
|
||||
case Tok_Q_PRIVATE_PROPERTY:
|
||||
case Tok_QDOC_PROPERTY:
|
||||
matchProperty(parent);
|
||||
if (!matchProperty(parent)) {
|
||||
location().warning(tr("Failed to parse token %1 in property declaration").arg(lexeme()));
|
||||
skipTo(Tok_RightParen);
|
||||
match(Tok_RightParen);
|
||||
}
|
||||
break;
|
||||
case Tok_Q_DECLARE_SEQUENTIAL_ITERATOR:
|
||||
readToken();
|
||||
|
@ -463,7 +463,7 @@
|
||||
|
||||
We get the model index that corresponds to the selection by calling
|
||||
\l{QItemSelectionModel::currentIndex()}{treeView->selectionModel()->currentIndex()}
|
||||
and we get the the field's string by using the model index. Then we just
|
||||
and we get the field's string by using the model index. Then we just
|
||||
calculate the item's \c hierarchyLevel. Top level items do not have parents
|
||||
and the \l{QAbstractItemModel::}{parent()} method will return a default
|
||||
constructed \l{QModelIndex}{QModelIndex()}. This is why we use the
|
||||
@ -548,7 +548,7 @@
|
||||
the underlying data. The data can be looked up by calling
|
||||
\l{QModelIndex::data()}{index.data()}. The delegate's
|
||||
\l{QAbstractItemDelegate::}{sizeHint()} method is used to obtain each
|
||||
star's dimensions, so the the cell will provide enough height and width to
|
||||
star's dimensions, so the cell will provide enough height and width to
|
||||
accommodate the stars.
|
||||
|
||||
Writing custom delegates is the right choice if you want to show your data
|
||||
|
@ -874,7 +874,7 @@ void QGraphicsSceneContextMenuEvent::setPos(const QPointF &pos)
|
||||
|
||||
/*!
|
||||
Returns the position of the mouse cursor in scene coordinates at the moment the
|
||||
the context menu was requested.
|
||||
context menu was requested.
|
||||
|
||||
\sa pos(), screenPos()
|
||||
*/
|
||||
@ -899,7 +899,7 @@ void QGraphicsSceneContextMenuEvent::setScenePos(const QPointF &pos)
|
||||
|
||||
/*!
|
||||
Returns the position of the mouse cursor in screen coordinates at the moment the
|
||||
the context menu was requested.
|
||||
context menu was requested.
|
||||
|
||||
\sa pos(), scenePos()
|
||||
*/
|
||||
|
@ -70,7 +70,7 @@ void q_createNativeChildrenAndSetParent(const QWidget *parentWidget)
|
||||
const QWidget *childWidget = qobject_cast<const QWidget *>(children.at(i));
|
||||
if (childWidget) { // should not be necessary
|
||||
if (childWidget->testAttribute(Qt::WA_NativeWindow)) {
|
||||
if (!childWidget->windowHandle())
|
||||
if (!childWidget->internalWinId())
|
||||
childWidget->winId();
|
||||
if (childWidget->windowHandle()) {
|
||||
QWindow *parentWindow = childWidget->nativeParentWidget()->windowHandle();
|
||||
|
@ -1116,7 +1116,7 @@ QStyleOptionToolBar::QStyleOptionToolBar(int version)
|
||||
|
||||
The order of the positions within a line starts at the top of a
|
||||
vertical line, and from the left within a horizontal line. The
|
||||
order of the positions for the lines is always from the the
|
||||
order of the positions for the lines is always from the
|
||||
parent widget's boundary edges.
|
||||
|
||||
\value Beginning The toolbar is located at the beginning of the line,
|
||||
|
@ -94,6 +94,8 @@ private slots:
|
||||
#ifndef QT_NO_DRAGANDDROP
|
||||
void tst_dnd();
|
||||
#endif
|
||||
|
||||
void tst_qtbug35600();
|
||||
};
|
||||
|
||||
void tst_QWidget_window::initTestCase()
|
||||
@ -568,5 +570,33 @@ void tst_QWidget_window::tst_dnd()
|
||||
}
|
||||
#endif
|
||||
|
||||
void tst_QWidget_window::tst_qtbug35600()
|
||||
{
|
||||
QWidget w;
|
||||
w.show();
|
||||
|
||||
QWidget *wA = new QWidget;
|
||||
QHBoxLayout *layoutA = new QHBoxLayout;
|
||||
|
||||
QWidget *wB = new QWidget;
|
||||
layoutA->addWidget(wB);
|
||||
|
||||
QWidget *wC = new QWidget;
|
||||
layoutA->addWidget(wC);
|
||||
|
||||
wA->setLayout(layoutA);
|
||||
|
||||
QWidget *wD = new QWidget;
|
||||
wD->setAttribute(Qt::WA_NativeWindow);
|
||||
wD->setParent(wB);
|
||||
|
||||
QWidget *wE = new QWidget(wC, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowTransparentForInput);
|
||||
wE->show();
|
||||
|
||||
wA->setParent(&w);
|
||||
|
||||
// QTBUG-35600: program may crash here or on exit
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QWidget_window)
|
||||
#include "tst_qwidget_window.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user