summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java140
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java3
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtLayout.java3
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java14
-rw-r--r--src/gui/image/qimage.cpp4
-rw-r--r--src/gui/image/qpicture.cpp3
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/image/qpixmap_raster.cpp3
-rw-r--r--src/gui/kernel/kernel.pri8
-rw-r--r--src/gui/kernel/qcursor.cpp18
-rw-r--r--src/gui/kernel/qguiapplication.cpp16
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp230
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h484
-rw-r--r--src/gui/kernel/qopenglwindow.cpp5
-rw-r--r--src/gui/kernel/qpaintdevicewindow.cpp6
-rw-r--r--src/gui/kernel/qplatformintegration.cpp8
-rw-r--r--src/gui/kernel/qplatformscreen.cpp81
-rw-r--r--src/gui/kernel/qplatformscreen.h12
-rw-r--r--src/gui/kernel/qplatformwindow.cpp73
-rw-r--r--src/gui/kernel/qplatformwindow.h9
-rw-r--r--src/gui/kernel/qrasterwindow.cpp2
-rw-r--r--src/gui/kernel/qscreen.cpp31
-rw-r--r--src/gui/kernel/qscreen.h1
-rw-r--r--src/gui/kernel/qscreen_p.h25
-rw-r--r--src/gui/kernel/qsimpledrag.cpp42
-rw-r--r--src/gui/kernel/qsimpledrag_p.h8
-rw-r--r--src/gui/kernel/qwindow.cpp51
-rw-r--r--src/gui/kernel/qwindow_p.h1
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp72
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h7
-rw-r--r--src/gui/opengl/qopenglpaintdevice.cpp3
-rw-r--r--src/gui/painting/qbackingstore.cpp49
-rw-r--r--src/gui/painting/qpaintdevice.cpp9
-rw-r--r--src/gui/painting/qpaintdevice.h8
-rw-r--r--src/gui/painting/qpainter.cpp10
-rw-r--r--src/gui/painting/qpainter_p.h2
-rw-r--r--src/gui/painting/qpdf.cpp3
-rw-r--r--src/gui/text/qstatictext.cpp3
-rw-r--r--src/gui/text/qtextimagehandler.cpp4
-rw-r--r--src/opengl/qgl.cpp4
-rw-r--r--src/opengl/qglframebufferobject.cpp3
-rw-r--r--src/opengl/qglpaintdevice.cpp2
-rw-r--r--src/opengl/qglpixelbuffer.cpp3
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp27
-rw-r--r--src/plugins/platforms/android/androidjnimain.h3
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp19
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp3
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm33
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm3
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp40
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h8
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp40
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp24
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeimage.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsscaling.cpp71
-rw-r--r--src/plugins/platforms/windows/qwindowsscaling.h106
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp49
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h14
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp110
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h30
-rw-r--r--src/plugins/platforms/windows/windows.pri2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp46
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp10
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp61
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h18
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp64
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h9
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp213
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h6
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp28
-rw-r--r--src/widgets/kernel/qwidget.cpp24
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp3
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm4
-rw-r--r--src/widgets/styles/qwindowsstyle_p_p.h2
-rw-r--r--src/widgets/widgets/qlabel.cpp2
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp57
-rw-r--r--tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp1
-rw-r--r--tests/auto/gui/text/qtexttable/tst_qtexttable.cpp2
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp13
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp17
-rw-r--r--tests/manual/highdpi/dragwidget.cpp223
-rw-r--r--tests/manual/highdpi/dragwidget.h68
-rw-r--r--tests/manual/highdpi/highdpi.pro13
-rw-r--r--tests/manual/highdpi/main.cpp520
95 files changed, 2469 insertions, 1049 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
index 12ae8a65d8..ff0032d623 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -265,6 +265,25 @@ public class ExtractStyle {
final int defaultBackgroundColor;
final int defaultTextColor;
+ // wrapper for accessing a TypedArray with style values and
+ // retrieving either device-indpendent pixel values or device
+ // pixel valies, depending on if useDevicePixels below is set
+ Boolean m_useDevicePixels;
+ // ### should possibly return float
+ int getTypedArraDimensionSize(TypedArray a, int index, int defValue)
+ {
+ if (m_useDevicePixels)
+ return a.getDimensionPixelSize(index, defValue);
+ return (int) a.getDimension(index, (float)defValue);
+ }
+
+ int getTypedArraDimensionOffset(TypedArray a, int index, int defValue)
+ {
+ if (m_useDevicePixels)
+ return a.getDimensionPixelOffset(index, defValue);
+ return (int) a.getDimension(index, (float)defValue);
+ }
+
class SimpleJsonWriter
{
private OutputStreamWriter m_writer;
@@ -1180,19 +1199,19 @@ public class ExtractStyle {
if (attr == View_background)
json.put("View_background", getDrawable(a.getDrawable(attr), styleName + "_View_background", null));
else if (attr == View_padding)
- json.put("View_padding", a.getDimensionPixelSize(attr, -1));
+ json.put("View_padding", getTypedArraDimensionSize(a, attr, -1));
else if (attr == View_paddingLeft)
- json.put("View_paddingLeft", a.getDimensionPixelSize(attr, -1));
+ json.put("View_paddingLeft", getTypedArraDimensionSize(a, attr, -1));
else if (attr == View_paddingTop)
- json.put("View_paddingTop", a.getDimensionPixelSize(attr, -1));
+ json.put("View_paddingTop", getTypedArraDimensionSize(a, attr, -1));
else if (attr == View_paddingRight)
- json.put("View_paddingRight", a.getDimensionPixelSize(attr, -1));
+ json.put("View_paddingRight", getTypedArraDimensionSize(a, attr, -1));
else if (attr == View_paddingBottom)
- json.put("View_paddingBottom", a.getDimensionPixelSize(attr, -1));
+ json.put("View_paddingBottom", getTypedArraDimensionSize(a, attr, -1));
else if (attr == View_scrollX)
- json.put("View_paddingBottom", a.getDimensionPixelOffset(attr, 0));
+ json.put("View_paddingBottom", getTypedArraDimensionOffset(a, attr, 0));
else if (attr == View_scrollY)
- json.put("View_scrollY", a.getDimensionPixelOffset(attr, 0));
+ json.put("View_scrollY", getTypedArraDimensionOffset(a, attr, 0));
else if (attr == View_id)
json.put("View_id", a.getResourceId(attr, -1));
else if (attr == View_tag)
@@ -1232,7 +1251,7 @@ public class ExtractStyle {
else if (attr == View_scrollbarDefaultDelayBeforeFade)
json.put("View_scrollbarDefaultDelayBeforeFade", a.getInt(attr, 0));
else if (attr == View_scrollbarSize)
- json.put("View_scrollbarSize", a.getDimensionPixelSize(attr, -1));
+ json.put("View_scrollbarSize", getTypedArraDimensionSize(a, attr, -1));
else if (attr == View_scrollbarThumbHorizontal)
json.put("View_scrollbarThumbHorizontal", getDrawable(a.getDrawable(attr), styleName + "_View_scrollbarThumbHorizontal", null));
else if (attr == View_scrollbarThumbVertical)
@@ -1256,17 +1275,17 @@ public class ExtractStyle {
else if (attr == View_nextFocusDown)
json.put("View_nextFocusDown", a.getResourceId(attr, -1));
else if (attr == View_minWidth)
- json.put("View_minWidth", a.getDimensionPixelSize(attr, 0));
+ json.put("View_minWidth", getTypedArraDimensionSize(a, attr, 0));
else if (attr == View_minHeight)
- json.put("View_minHeight", a.getDimensionPixelSize(attr, 0));
+ json.put("View_minHeight", getTypedArraDimensionSize(a, attr, 0));
else if (attr == View_onClick)
json.put("View_onClick", a.getString(attr));
else if (attr == View_overScrollMode)
json.put("View_overScrollMode", a.getInt(attr, 1));
else if (attr == View_paddingStart)
- json.put("View_paddingStart", a.getDimensionPixelSize(attr, 0));
+ json.put("View_paddingStart", getTypedArraDimensionSize(a, attr, 0));
else if (attr == View_paddingEnd)
- json.put("View_paddingEnd", a.getDimensionPixelSize(attr, 0));
+ json.put("View_paddingEnd", getTypedArraDimensionSize(a, attr, 0));
}
a.recycle();
} catch (Exception e) {
@@ -1293,7 +1312,7 @@ public class ExtractStyle {
else if (attr == TextAppearance_textColorLink)
json.put("TextAppearance_textColorLink", getColorStateList(a.getColorStateList(attr)));
else if (attr == TextAppearance_textSize)
- json.put("TextAppearance_textSize", a.getDimensionPixelSize(attr, 15));
+ json.put("TextAppearance_textSize", getTypedArraDimensionSize(a, attr, 15));
else if (attr == TextAppearance_typeface)
json.put("TextAppearance_typeface", a.getInt(attr, -1));
else if (attr == TextAppearance_textStyle)
@@ -1354,7 +1373,7 @@ public class ExtractStyle {
else if (attr == TextAppearance_textColorLink)
textColorLink = appearance.getColorStateList(attr);
else if (attr == TextAppearance_textSize)
- textSize = appearance.getDimensionPixelSize(attr, textSize);
+ textSize = getTypedArraDimensionSize(appearance, attr, textSize);
else if (attr == TextAppearance_typeface)
typefaceIndex = appearance.getInt(attr, -1);
else if (attr == TextAppearance_textStyle)
@@ -1407,7 +1426,7 @@ public class ExtractStyle {
else if (attr == TextView_drawableEnd)
json.put("TextView_drawableEnd", getDrawable(a.getDrawable(attr), styleName + "_TextView_drawableEnd", null));
else if (attr == TextView_drawablePadding)
- json.put("TextView_drawablePadding", a.getDimensionPixelSize(attr, 0));
+ json.put("TextView_drawablePadding", getTypedArraDimensionSize(a, attr, 0));
else if (attr == TextView_textCursorDrawable) {
try {
json.put("TextView_textCursorDrawable", getDrawable(a.getDrawable(attr), styleName + "_TextView_textCursorDrawable", null));
@@ -1421,27 +1440,27 @@ public class ExtractStyle {
}else if (attr == TextView_maxLines)
json.put("TextView_maxLines", a.getInt(attr, -1));
else if (attr == TextView_maxHeight)
- json.put("TextView_maxHeight", a.getDimensionPixelSize(attr, -1));
+ json.put("TextView_maxHeight", getTypedArraDimensionSize(a, attr, -1));
else if (attr == TextView_lines)
json.put("TextView_lines", a.getInt(attr, -1));
else if (attr == TextView_height)
- json.put("TextView_height", a.getDimensionPixelSize(attr, -1));
+ json.put("TextView_height", getTypedArraDimensionSize(a, attr, -1));
else if (attr == TextView_minLines)
json.put("TextView_minLines", a.getInt(attr, -1));
else if (attr == TextView_minHeight)
- json.put("TextView_minHeight", a.getDimensionPixelSize(attr, -1));
+ json.put("TextView_minHeight", getTypedArraDimensionSize(a, attr, -1));
else if (attr == TextView_maxEms)
json.put("TextView_maxEms", a.getInt(attr, -1));
else if (attr == TextView_maxWidth)
- json.put("TextView_maxWidth", a.getDimensionPixelSize(attr, -1));
+ json.put("TextView_maxWidth", getTypedArraDimensionSize(a, attr, -1));
else if (attr == TextView_ems)
json.put("TextView_ems", a.getInt(attr, -1));
else if (attr == TextView_width)
- json.put("TextView_width", a.getDimensionPixelSize(attr, -1));
+ json.put("TextView_width", getTypedArraDimensionSize(a, attr, -1));
else if (attr == TextView_minEms)
json.put("TextView_minEms", a.getInt(attr, -1));
else if (attr == TextView_minWidth)
- json.put("TextView_minWidth", a.getDimensionPixelSize(attr, -1));
+ json.put("TextView_minWidth", getTypedArraDimensionSize(a, attr, -1));
else if (attr == TextView_gravity)
json.put("TextView_gravity", a.getInt(attr, -1));
else if (attr == TextView_hint)
@@ -1485,7 +1504,7 @@ public class ExtractStyle {
else if (attr == TextView_textColorLink)
textColorLink = a.getColorStateList(attr);
else if (attr == TextView_textSize)
- textSize = a.getDimensionPixelSize(attr, textSize);
+ textSize = getTypedArraDimensionSize(a, attr, textSize);
else if (attr == TextView_typeface)
typefaceIndex = a.getInt(attr, typefaceIndex);
else if (attr == TextView_textStyle)
@@ -1493,7 +1512,7 @@ public class ExtractStyle {
else if (attr == TextView_password)
json.put("TextView_password", a.getBoolean(attr,false));
else if (attr == TextView_lineSpacingExtra)
- json.put("TextView_lineSpacingExtra", a.getDimensionPixelSize(attr, 0));
+ json.put("TextView_lineSpacingExtra", getTypedArraDimensionSize(a, attr, 0));
else if (attr == TextView_lineSpacingMultiplier)
json.put("TextView_lineSpacingMultiplier", a.getFloat(attr, 1.0f));
else if (attr == TextView_inputType)
@@ -1588,8 +1607,8 @@ public class ExtractStyle {
json.put("ImageView_baselineAlignBottom", a.getBoolean(ImageView_baselineAlignBottom, false));
json.put("ImageView_adjustViewBounds", a.getBoolean(ImageView_adjustViewBounds, false));
- json.put("ImageView_maxWidth", a.getDimensionPixelSize(ImageView_maxWidth, Integer.MAX_VALUE));
- json.put("ImageView_maxHeight", a.getDimensionPixelSize(ImageView_maxHeight, Integer.MAX_VALUE));
+ json.put("ImageView_maxWidth", getTypedArraDimensionSize(a, ImageView_maxWidth, Integer.MAX_VALUE));
+ json.put("ImageView_maxHeight", getTypedArraDimensionSize(a, ImageView_maxHeight, Integer.MAX_VALUE));
int index = a.getInt(ImageView_scaleType, -1);
if (index >= 0)
json.put("ImageView_scaleType", sScaleTypeArray[index]);
@@ -1646,10 +1665,10 @@ public class ExtractStyle {
int mMaxWidth = 48;
int mMinHeight = 24;
int mMaxHeight = 48;
- mMinWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minWidth"), mMinWidth);
- mMaxWidth = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxWidth"), mMaxWidth);
- mMinHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_minHeight"), mMinHeight);
- mMaxHeight = a.getDimensionPixelSize(getField(styleableClass, "ProgressBar_maxHeight"), mMaxHeight);
+ mMinWidth = getTypedArraDimensionSize(a, getField(styleableClass, "ProgressBar_minWidth"), mMinWidth);
+ mMaxWidth = getTypedArraDimensionSize(a, getField(styleableClass, "ProgressBar_maxWidth"), mMaxWidth);
+ mMinHeight = getTypedArraDimensionSize(a, getField(styleableClass, "ProgressBar_minHeight"), mMinHeight);
+ mMaxHeight = getTypedArraDimensionSize(a, getField(styleableClass, "ProgressBar_maxHeight"), mMaxHeight);
json.put("ProgressBar_indeterminateDuration", a.getInt(getField(styleableClass, "ProgressBar_indeterminateDuration"), 4000));
json.put("ProgressBar_minWidth", mMinWidth);
@@ -1737,9 +1756,9 @@ public class ExtractStyle {
json.put("Switch_textOn", a.getText(getField(styleableClass, "Switch_textOn")));
json.put("Switch_textOff", a.getText(getField(styleableClass, "Switch_textOff")));
- json.put("Switch_switchMinWidth", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchMinWidth"), 0));
- json.put("Switch_switchPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchPadding"), 0));
- json.put("Switch_thumbTextPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_thumbTextPadding"), 0));
+ json.put("Switch_switchMinWidth", getTypedArraDimensionSize(a, getField(styleableClass, "Switch_switchMinWidth"), 0));
+ json.put("Switch_switchPadding", getTypedArraDimensionSize(a, getField(styleableClass, "Switch_switchPadding"), 0));
+ json.put("Switch_thumbTextPadding", getTypedArraDimensionSize(a, getField(styleableClass, "Switch_thumbTextPadding"), 0));
if (Build.VERSION.SDK_INT >= 21) {
json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true));
@@ -1834,7 +1853,7 @@ public class ExtractStyle {
if (divider != null)
json.put("ListView_divider", getDrawable(divider, styleName + "_ListView_divider", null));
- json.put("ListView_dividerHeight", a.getDimensionPixelSize(getField(styleableClass, "ListView_dividerHeight"), 0));
+ json.put("ListView_dividerHeight", getTypedArraDimensionSize(a, getField(styleableClass, "ListView_dividerHeight"), 0));
a.recycle();
writer.name(styleName).value(json);
@@ -1905,7 +1924,7 @@ public class ExtractStyle {
if (d != null)
json.put("ActionBar_divider", getDrawable(d, styleName + "_ActionBar_divider", null));
- json.put("ActionBar_itemPadding", a.getDimensionPixelSize(getField(styleableClass, "ActionBar_itemPadding"), 0));
+ json.put("ActionBar_itemPadding", getTypedArraDimensionSize(a, getField(styleableClass, "ActionBar_itemPadding"), 0));
a.recycle();
writer.name(styleName).value(json);
@@ -1928,7 +1947,7 @@ public class ExtractStyle {
if (d != null)
json.put("LinearLayout_divider", getDrawable(d, styleName + "_LinearLayout_divider", null));
json.put("LinearLayout_showDividers", a.getInt(getField(styleableClass, "LinearLayout_showDividers"), 0));
- json.put("LinearLayout_dividerPadding", a.getDimensionPixelSize(getField(styleableClass, "LinearLayout_dividerPadding"), 0));
+ json.put("LinearLayout_dividerPadding", getTypedArraDimensionSize(a, getField(styleableClass, "LinearLayout_dividerPadding"), 0));
a.recycle();
writer.name(styleName).value(json);
@@ -1981,29 +2000,11 @@ public class ExtractStyle {
return json;
}
- public ExtractStyle(Context context, String extractPath)
+ public void extractStyleToJson(String path)
{
-// Log.i(MinistroService.TAG, "Extract " + extractPath);
- m_extractPath = extractPath + "/";
- new File(m_extractPath).mkdirs();
-// MinistroActivity.nativeChmode(m_extractPath, 0755);
- m_context = context;
- m_theme = context.getTheme();
- TypedArray array = m_theme.obtainStyledAttributes(new int[]{
- android.R.attr.colorBackground,
- android.R.attr.textColorPrimary,
- android.R.attr.textColor
- });
- defaultBackgroundColor = array.getColor(0, 0);
- int textColor = array.getColor(1, 0xFFFFFF);
- if (textColor == 0xFFFFFF)
- textColor = array.getColor(2, 0xFFFFFF);
- defaultTextColor = textColor;
- array.recycle();
-
try
{
- SimpleJsonWriter jsonWriter = new SimpleJsonWriter(m_extractPath+"style.json");
+ SimpleJsonWriter jsonWriter = new SimpleJsonWriter(path);
jsonWriter.beginObject();
try {
jsonWriter.name("defaultStyle").value(extractDefaultPalette());
@@ -2047,4 +2048,33 @@ public class ExtractStyle {
e.printStackTrace();
}
}
+
+ public ExtractStyle(Context context, String extractPath)
+ {
+// Log.i(MinistroService.TAG, "Extract " + extractPath);
+ m_extractPath = extractPath + "/";
+ new File(m_extractPath).mkdirs();
+// MinistroActivity.nativeChmode(m_extractPath, 0755);
+ m_context = context;
+ m_theme = context.getTheme();
+ TypedArray array = m_theme.obtainStyledAttributes(new int[]{
+ android.R.attr.colorBackground,
+ android.R.attr.textColorPrimary,
+ android.R.attr.textColor
+ });
+ defaultBackgroundColor = array.getColor(0, 0);
+ int textColor = array.getColor(1, 0xFFFFFF);
+ if (textColor == 0xFFFFFF)
+ textColor = array.getColor(2, 0xFFFFFF);
+ defaultTextColor = textColor;
+ array.recycle();
+
+ // Write two versions of the style file
+ // style.json with values in device pixels
+ // style_dip.json with values in device independent pixels
+ m_useDevicePixels = false; // ### write device-independent pixels only for now
+ extractStyleToJson(m_extractPath + "style.json");
+ m_useDevicePixels = false;
+ extractStyleToJson(m_extractPath + "style_dip.json");
+ }
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index d6cd49f44c..18fa2f8fde 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -786,7 +786,8 @@ public class QtActivityDelegate
m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
QtNative.setApplicationDisplayMetrics(metrics.widthPixels, metrics.heightPixels,
0, 0,
- metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
+ metrics.xdpi, metrics.ydpi,
+ metrics.scaledDensity, metrics.density);
}
m_layout = new QtLayout(m_activity);
m_editText = new QtEditText(m_activity, this);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
index 09fef4a705..8f2d656bcc 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
@@ -64,7 +64,8 @@ public class QtLayout extends ViewGroup
DisplayMetrics metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
- metrics.heightPixels, w, h, metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
+ metrics.heightPixels, w, h, metrics.xdpi, metrics.ydpi,
+ metrics.scaledDensity, metrics.density);
}
@Override
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 80f7fb5c85..b7363e5d87 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -72,6 +72,7 @@ public class QtNative
private static double m_displayMetricsXDpi = .0;
private static double m_displayMetricsYDpi = .0;
private static double m_displayMetricsScaledDensity = 1.0;
+ private static double m_displayMetricsDensity = 1.0;
private static int m_oldx, m_oldy;
private static final int m_moveThreshold = 0;
private static ClipboardManager m_clipboardManager = null;
@@ -215,7 +216,8 @@ public class QtNative
m_displayMetricsDesktopHeightPixels,
m_displayMetricsXDpi,
m_displayMetricsYDpi,
- m_displayMetricsScaledDensity);
+ m_displayMetricsScaledDensity,
+ m_displayMetricsDensity);
if (params.length() > 0 && !params.startsWith("\t"))
params = "\t" + params;
startQtApplication(f.getAbsolutePath() + params, environment);
@@ -230,7 +232,8 @@ public class QtNative
int desktopHeightPixels,
double XDpi,
double YDpi,
- double scaledDensity)
+ double scaledDensity,
+ double density)
{
/* Fix buggy dpi report */
if (XDpi < android.util.DisplayMetrics.DENSITY_LOW)
@@ -246,7 +249,8 @@ public class QtNative
desktopHeightPixels,
XDpi,
YDpi,
- scaledDensity);
+ scaledDensity,
+ density);
} else {
m_displayMetricsScreenWidthPixels = screenWidthPixels;
m_displayMetricsScreenHeightPixels = screenHeightPixels;
@@ -255,6 +259,7 @@ public class QtNative
m_displayMetricsXDpi = XDpi;
m_displayMetricsYDpi = YDpi;
m_displayMetricsScaledDensity = scaledDensity;
+ m_displayMetricsDensity = density;
}
}
}
@@ -596,7 +601,8 @@ public class QtNative
int desktopHeightPixels,
double XDpi,
double YDpi,
- double scaledDensity);
+ double scaledDensity,
+ double density);
public static native void handleOrientationChanged(int newRotation, int nativeOrientation);
// screen methods
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 3c192a237e..7aeba45b3b 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -3891,6 +3891,10 @@ int QImage::metric(PaintDeviceMetric metric) const
return d->devicePixelRatio;
break;
+ case PdmDevicePixelRatioScaled:
+ return d->devicePixelRatio * QPaintDevice::devicePixelRatioFScale;
+ break;
+
default:
qWarning("QImage::metric(): Unhandled metric type %d", metric);
break;
diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp
index b63be19153..02a510ce29 100644
--- a/src/gui/image/qpicture.cpp
+++ b/src/gui/image/qpicture.cpp
@@ -961,6 +961,9 @@ int QPicture::metric(PaintDeviceMetric m) const
case PdmDevicePixelRatio:
val = 1;
break;
+ case PdmDevicePixelRatioScaled:
+ val = 1 * QPaintDevice::devicePixelRatioFScale;
+ break;
default:
val = 0;
qWarning("QPicture::metric: Invalid metric command");
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index f24cbc3db9..92f87b6ea9 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -115,6 +115,8 @@ int QBlittablePlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) con
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
return devicePixelRatio();
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return devicePixelRatio() * QPaintDevice::devicePixelRatioFScale;
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 9c8835a7a0..6d4e90a6c4 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -288,6 +288,9 @@ int QRasterPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
return qt_defaultDpiY();
case QPaintDevice::PdmDevicePixelRatio:
return image.devicePixelRatio();
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return image.devicePixelRatio() * QPaintDevice::devicePixelRatioFScale;
+
default:
qWarning("QRasterPlatformPixmap::metric(): Unhandled metric type %d", metric);
break;
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index af6a417608..73a5a7b6ab 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -75,7 +75,9 @@ HEADERS += \
kernel/qplatformgraphicsbuffer.h \
kernel/qplatformgraphicsbufferhelper.h \
kernel/qinputdevicemanager_p.h \
- kernel/qinputdevicemanager_p_p.h
+ kernel/qinputdevicemanager_p_p.h \
+ kernel/qhighdpiscaling_p.h
+
SOURCES += \
kernel/qgenericpluginfactory.cpp \
@@ -131,7 +133,9 @@ SOURCES += \
kernel/qrasterwindow.cpp \
kernel/qplatformgraphicsbuffer.cpp \
kernel/qplatformgraphicsbufferhelper.cpp \
- kernel/qinputdevicemanager.cpp
+ kernel/qinputdevicemanager.cpp \
+ kernel/qhighdpiscaling.cpp
+
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 6ed750eda1..d52ecb7a68 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -43,6 +43,7 @@
#include <qpa/qplatformcursor.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -177,9 +178,14 @@ QT_BEGIN_NAMESPACE
*/
QPoint QCursor::pos(const QScreen *screen)
{
- if (screen)
- if (const QPlatformCursor *cursor = screen->handle()->cursor())
- return cursor->pos();
+ if (screen) {
+ if (const QPlatformCursor *cursor = screen->handle()->cursor()) {
+ QPlatformScreen *ps = screen->handle();
+ QPoint nativePos = cursor->pos();
+ ps = ps->screenForPosition(nativePos);
+ return QHighDpi::fromNativePixels(nativePos, ps->screen());
+ }
+ }
return QGuiApplicationPrivate::lastCursorPosition.toPoint();
}
@@ -231,12 +237,12 @@ void QCursor::setPos(QScreen *screen, int x, int y)
{
if (screen) {
if (QPlatformCursor *cursor = screen->handle()->cursor()) {
- const QPoint pos = QPoint(x, y);
+ const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
// Need to check, since some X servers generate null mouse move
// events, causing looping in applications which call setPos() on
// every mouse move event.
- if (pos != cursor->pos())
- cursor->setPos(pos);
+ if (devicePos != cursor->pos())
+ cursor->setPos(devicePos);
}
}
}
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 024578ccdd..7866f65b7e 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -959,8 +959,10 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
QList<QScreen *>::const_iterator end = screens.constEnd();
while (screen != end) {
- if ((*screen)->geometry().contains(pos))
- return (*screen)->handle()->topLevelAt(pos);
+ if ((*screen)->geometry().contains(pos)) {
+ const QPoint devicePosition = QHighDpi::toNativePixels(pos, *screen);
+ return (*screen)->handle()->topLevelAt(devicePosition);
+ }
++screen;
}
return 0;
@@ -1116,6 +1118,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
// this flag.
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+
+ QHighDpiScaling::initHighDPiScaling();
+
// Load the platform integration
QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
@@ -1820,7 +1825,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
points << point;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, window, &type);
QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
@@ -2030,6 +2035,11 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
window->d_func()->setTopLevelScreen(screen, false /* recreate */);
else // Fall back to default behavior, and try to find some appropriate screen
window->setScreen(0);
+ // we may have changed scaling, so trigger resize event if needed
+ if (window->handle()) {
+ QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect());
+ processGeometryChangeEvent(&gce);
+ }
}
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
new file mode 100644
index 0000000000..be127a54f3
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module 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 "qhighdpiscaling_p.h"
+#include "qguiapplication.h"
+#include "qscreen.h"
+#include "qplatformintegration.h"
+#include "private/qscreen_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcScaling, "qt.scaling");
+
+static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
+static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR";
+static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR";
+
+static inline qreal initialScaleFactor()
+{
+
+ qreal result = 1;
+ if (qEnvironmentVariableIsSet(scaleFactorEnvVar)) {
+ bool ok;
+ const qreal f = qgetenv(scaleFactorEnvVar).toDouble(&ok);
+ if (ok && f > 0) {
+ qCDebug(lcScaling) << "Apply " << scaleFactorEnvVar << f;
+ result = f;
+ }
+ } else {
+ if (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar)) {
+ qWarning() << "Warning:" << legacyDevicePixelEnvVar << "is deprecated. Instead use:";
+ qWarning() << " " << scaleFactorEnvVar << "to set the application global scale factor.";
+ qWarning() << " " << autoScreenEnvVar << "to enable platform plugin controlled per-screen factors.";
+
+ int dpr = qEnvironmentVariableIntValue(legacyDevicePixelEnvVar);
+ if (dpr > 0)
+ result = dpr;
+ }
+ }
+ return result;
+}
+
+/*!
+ \class QHighDpiScaling
+ \since 5.6
+ \internal
+ \preliminary
+ \ingroup qpa
+
+ \brief Collection of utility functions for UI scaling.
+*/
+
+
+qreal QHighDpiScaling::m_factor;
+
+bool QHighDpiScaling::m_active; //"overall active" - is there any scale factor set.
+bool QHighDpiScaling::m_perScreenActive; // different screens may have different scale
+bool QHighDpiScaling::m_usePixelDensity; // use scale factor from platform plugin
+
+void QHighDpiScaling::initHighDPiScaling()
+{
+ m_factor = initialScaleFactor();
+ bool usePlatformPluginPixelDensity = qEnvironmentVariableIsSet(autoScreenEnvVar)
+ || qgetenv(legacyDevicePixelEnvVar).toLower() == "auto";
+
+ // m_active below is "overall active" - is there any scale factor set.
+ m_active = !qFuzzyCompare(m_factor, qreal(1)) || usePlatformPluginPixelDensity;
+ m_usePixelDensity = usePlatformPluginPixelDensity;
+ m_perScreenActive = m_usePixelDensity;
+}
+
+/*
+ Sets the global scale factor which is applied to all windows.
+*/
+void QHighDpiScaling::setGlobalFactor(qreal factor)
+{
+ if (qFuzzyCompare(factor, QHighDpiScaling::m_factor))
+ return;
+ if (!QGuiApplication::allWindows().isEmpty()) {
+ qWarning() << Q_FUNC_INFO << "QHighDpiScaling::setFactor: Should only be called when no windows exist.";
+ }
+
+ QHighDpiScaling::m_active = !qFuzzyCompare(factor, qreal(1));
+ QHighDpiScaling::m_factor = QHighDpiScaling::m_active ? factor : qreal(1);
+ Q_FOREACH (QScreen *screen, QGuiApplication::screens())
+ screen->d_func()->updateHighDpi();
+}
+
+static const char *scaleFactorProperty = "_q_scaleFactor";
+
+/*
+ Sets a per-screen scale factor.
+*/
+void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
+{
+ m_active = true;
+ m_perScreenActive = true;
+ screen->setProperty(scaleFactorProperty, QVariant(factor));
+}
+
+/*
+
+QPoint QXcbScreen::mapToNative(const QPoint &pos) const
+{
+ const int dpr = int(devicePixelRatio());
+ return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft();
+}
+
+QPoint QXcbScreen::mapFromNative(const QPoint &pos) const
+{
+ const int dpr = int(devicePixelRatio());
+ return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft();
+}
+
+
+ */
+
+
+QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) * scaleFactor + topLeft;
+}
+
+QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) / scaleFactor + topLeft;
+}
+
+qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
+{
+ qreal factor = qreal(1.0);
+ if (m_perScreenActive && screen) {
+ if (m_usePixelDensity)
+ factor *= screen->pixelDensity();
+ QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
+ if (screenFactor.isValid())
+ factor *= screenFactor.toReal();
+ }
+ return factor;
+}
+
+qreal QHighDpiScaling::factor(const QScreen *screen)
+{
+ // Fast path for when scaling in Qt is not used at all.
+ if (!m_active)
+ return qreal(1.0);
+
+ // The effective factor for a given screen is the product of the
+ // screen and global sub-factors
+ qreal factor = m_factor;
+ if (screen)
+ factor *= screenSubfactor(screen->handle());
+ return factor;
+}
+
+qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen)
+{
+ if (!m_active)
+ return qreal(1.0);
+
+ return m_factor * screenSubfactor(platformScreen);
+}
+
+qreal QHighDpiScaling::factor(const QWindow *window)
+{
+ if (!m_active || !window)
+ return qreal(1.0);
+
+ return factor(window->screen());
+}
+
+QPoint QHighDpiScaling::origin(const QScreen *screen)
+{
+ return screen->geometry().topLeft();
+}
+
+QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
+{
+ return platformScreen->geometry().topLeft();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
new file mode 100644
index 0000000000..8347214823
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -0,0 +1,484 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module 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$
+**
+****************************************************************************/
+
+#ifndef QHIGHDPISCALING_P_H
+#define QHIGHDPISCALING_P_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qmargins.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qloggingcategory.h>
+#include <QtGui/qregion.h>
+#include <QtGui/qscreen.h>
+#include <QtGui/qwindow.h>
+
+// This file implmements utility functions for high-dpi scaling on operating
+// systems that do not provide native scaling support.
+//
+// The functions support creating a logical device-independent
+// coordinate system which is related to the device pixel coordinate
+// through a scaling factor.
+//
+// Several scaling factors can be set:
+// - A process-global scale factor
+// - the QT_SCALE_FACTOR environment variable.
+// - QHighDpiScaling::setFactor(factor);
+// - A per-window scale factor
+// - QHighDpiScaling::setWindowFactor(window, factor);
+//
+// With these functions in use most of the Qt API will then operate in
+// the device-independent coordinate system. For example, setting
+// the scale factor to 2.0 will make Qt see half of the "device"
+// window geometry. Desktop and event geometry will be scaled
+// to match.
+//
+// Integer scaling factors work best. Glitch-free graphics at non-integer
+// scaling factors can not be guaranteed.
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcScaling);
+
+class QScreen;
+class QPlatformScreen;
+
+class Q_GUI_EXPORT QHighDpiScaling {
+public:
+ static void initHighDPiScaling();
+ static void setGlobalFactor(qreal factor);
+ static void setScreenFactor(QScreen *window, qreal factor);
+
+ static bool isActive() { return m_active; }
+ static qreal factor(const QWindow *window);
+ static qreal factor(const QScreen *screen);
+ static qreal factor(const QPlatformScreen *platformScreen);
+ static QPoint origin(const QScreen *screen);
+ static QPoint origin(const QPlatformScreen *platformScreen);
+ static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
+ static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
+private:
+ static qreal screenSubfactor(const QPlatformScreen *screen);
+
+ static qreal m_factor;
+ static bool m_active;
+ static bool m_perScreenActive;
+ static bool m_usePixelDensity;
+};
+
+// Coordinate system conversion functions:
+// QHighDpi::fromNativePixels : from physical(screen/backing) to logical pixels
+// QHighDpi::toNativePixels : from logical to physical pixels
+
+namespace QHighDpi {
+
+// inline QRect fromNativeGeometry(const QRect &pixelRect, const QPlatformScreen *platformScreen)
+// {
+// return QRect(pixelRect.topLeft(), pixelRect.size() / QHighDpiScaling::factor(platformScreen));
+// }
+
+// inline QRect toNativeGeometry(const QRect &pointRect, const QPlatformScreen *platformScreen)
+// {
+// return QRect(pointRect.topLeft(), pointRect.size() * QHighDpiScaling::factor(platformScreen));
+// }
+
+inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
+{
+ return (pos - origin) / scaleFactor + origin;
+}
+
+inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin)
+{
+ return (pos - origin) * scaleFactor + origin;
+}
+
+inline QPoint fromNative(const QPoint &pos, qreal scaleFactor)
+{
+ return pos / scaleFactor;
+}
+
+inline QPoint toNative(const QPoint &pos, qreal scaleFactor)
+{
+ return pos * scaleFactor;
+}
+
+inline QSize fromNative(const QSize &size, qreal scaleFactor)
+{
+ return size / scaleFactor; // TODO: ### round up ###
+}
+
+inline QSize toNative(const QSize &size, qreal scaleFactor)
+{
+ return size * scaleFactor;
+}
+
+inline QRect fromNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
+{
+ return QRect(fromNative(rect.topLeft(), scaleFactor, origin), fromNative(rect.size(), scaleFactor));
+}
+
+inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin)
+{
+ return QRect(toNative(rect.topLeft(), scaleFactor, origin), toNative(rect.size(), scaleFactor));
+
+}
+
+inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
+{
+ return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin);
+}
+
+inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen)
+{
+ return QRect(nativeScreenGeometry.topLeft(), fromNative(nativeScreenGeometry.size(), QHighDpiScaling::factor(screen)));
+}
+
+inline QPoint fromNativeLocalPosition(const QPoint &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos / scaleFactor;
+}
+
+inline QPoint toNativeLocalPosition(const QPoint &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos * scaleFactor;
+}
+
+inline QPointF fromNativeLocalPosition(const QPointF &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos / scaleFactor;
+}
+
+inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return pos * scaleFactor;
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
+ const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(platformScreen);
+ const QPoint origin = QHighDpiScaling::origin(platformScreen);
+ return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin),
+ fromNative(pixelRect.size(), scaleFactor));
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(screen);
+ const QPoint origin = QHighDpiScaling::origin(screen);
+ return QRect(toNative(pointRect.topLeft(), scaleFactor, origin),
+ toNative(pointRect.size(), scaleFactor));
+}
+
+inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return fromNativePixels(pixelRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor));
+ }
+}
+
+inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen)
+{
+ //########
+ return toNativePixels(pointRect.toRect(), screen);
+}
+
+inline QRect toNativePixels(const QRect &pointRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return toNativePixels(pointRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor));
+ }
+}
+
+inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen)
+{
+ //########
+ return fromNativePixels(pixelRect.toRect(), screen);
+}
+
+inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return fromNativePixels(pixelRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
+ }
+}
+
+inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen()) {
+ return toNativePixels(pointRect, window->screen());
+ } else {
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
+ }
+}
+
+inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window)
+{
+ return pixelSize / QHighDpiScaling::factor(window);
+}
+
+inline QSize toNativePixels(const QSize &pointSize, const QWindow *window)
+{
+ return pointSize * QHighDpiScaling::factor(window);
+}
+
+inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window)
+{
+ return pixelSize / QHighDpiScaling::factor(window);
+}
+
+inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window)
+{
+ return pointSize * QHighDpiScaling::factor(window);
+}
+
+inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen)
+{
+ return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return fromNativePixels(pixelPoint, window->screen());
+ else
+ return pixelPoint / QHighDpiScaling::factor(window);
+}
+
+inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen)
+{
+ return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen));
+}
+
+inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return toNativePixels(pointPoint, window->screen());
+ else
+ return pointPoint * QHighDpiScaling::factor(window);
+}
+
+inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen)
+{
+ return fromNativePixels(pixelPoint.toPoint(), screen); //###############
+}
+
+inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return fromNativePixels(pixelPoint, window->screen());
+ else
+ return pixelPoint / QHighDpiScaling::factor(window);
+}
+
+inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen)
+{
+ return toNativePixels(pointPoint.toPoint(), screen); //###########
+}
+
+inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window)
+{
+ if (window && window->isTopLevel() && window->screen())
+ return toNativePixels(pointPoint, window->screen());
+ else
+ return pointPoint * QHighDpiScaling::factor(window);
+}
+
+inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor,
+ pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor);
+}
+
+inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor(window);
+ return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor,
+ pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor);
+}
+#if 1
+ //############## expose regions need special handling
+inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelRegion;
+
+ qreal scaleFactor = QHighDpiScaling::factor(window);
+ QRegion pointRegion;
+ foreach (const QRect &rect, pixelRegion.rects())
+ pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor),
+ fromNative(rect.size(), scaleFactor));
+ return pointRegion;
+}
+
+inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointRegion;
+
+ qreal scaleFactor = QHighDpiScaling::factor(window);
+ QRegion pixelRegon;
+ foreach (const QRect &rect, pointRegion.rects())
+ pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor),
+ toNative(rect.size(), scaleFactor));
+ return pixelRegon;
+}
+#endif
+// Any T that has operator/()
+template <typename T>
+T fromNativePixels(const T &pixelValue, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValue;
+
+ return pixelValue / QHighDpiScaling::factor(window);
+
+}
+
+ //##### ?????
+template <typename T>
+T fromNativePixels(const T &pixelValue, const QScreen *screen)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValue;
+
+ return pixelValue / QHighDpiScaling::factor(screen);
+
+}
+
+// Any T that has operator*()
+template <typename T>
+T toNativePixels(const T &pointValue, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValue;
+
+ return pointValue * QHighDpiScaling::factor(window);
+}
+
+template <typename T>
+T toNativePixels(const T &pointValue, const QScreen *screen)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValue;
+
+ return pointValue * QHighDpiScaling::factor(screen);
+}
+
+
+// Any QVector<T> where T has operator/()
+template <typename T>
+QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValues;
+
+ QVector<T> pointValues;
+ foreach (const T& pixelValue, pixelValues)
+ pointValues.append(pixelValue / QHighDpiScaling::factor(window));
+ return pointValues;
+}
+
+// Any QVector<T> where T has operator*()
+template <typename T>
+QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValues;
+
+ QVector<T> pixelValues;
+ foreach (const T& pointValue, pointValues)
+ pixelValues.append(pointValue * QHighDpiScaling::factor(window));
+ return pixelValues;
+}
+
+#if 0
+// Any QPair<T, U> where T and U has operator/()
+template <typename T, typename U>
+QPair<T, U> fromNativePixels(const QPair<T, U> &pixelPair, const QWindow *window)
+{
+ return qMakePair(fromNativePixels(pixelPair.first, window),
+ fromNativePixels(pixelPair.second, window));
+}
+
+// Any QPair<T, U> where T and U has operator*()
+template <typename T, typename U>
+QPair<T, U> toNativePixels(const QPair<T, U> &pointPair, const QWindow *window)
+{
+ return qMakePair(QHighDpi::toNativePixels(pointPair.first, window),
+ QHighDpi::toNativePixels(pointPair.second, window));
+}
+#endif
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
index b2025faaf1..3a1126d318 100644
--- a/src/gui/kernel/qopenglwindow.cpp
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -664,15 +664,10 @@ int QOpenGLWindow::metric(PaintDeviceMetric metric) const
if (d->paintDevice)
return d->paintDevice->depth();
break;
- case PdmDevicePixelRatio:
- if (d->paintDevice)
- return devicePixelRatio();
- break;
default:
break;
}
return QPaintDeviceWindow::metric(metric);
-
}
/*!
diff --git a/src/gui/kernel/qpaintdevicewindow.cpp b/src/gui/kernel/qpaintdevicewindow.cpp
index ff661d017d..3ce83a0ad7 100644
--- a/src/gui/kernel/qpaintdevicewindow.cpp
+++ b/src/gui/kernel/qpaintdevicewindow.cpp
@@ -155,8 +155,10 @@ int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const
return qRound(screen->physicalDotsPerInchY());
break;
case PdmDevicePixelRatio:
- if (screen)
- return screen->devicePixelRatio();
+ return int(QWindow::devicePixelRatio());
+ break;
+ case PdmDevicePixelRatioScaled:
+ return int(QWindow::devicePixelRatio() * devicePixelRatioFScale);
break;
default:
break;
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 4d973d47a5..e935907a62 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -39,7 +39,6 @@
#include <qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
-#include <qpa/qplatformscreen_p.h>
#include <private/qdnd_p.h>
#include <private/qsimpledrag_p.h>
@@ -450,7 +449,7 @@ QList<int> QPlatformIntegration::possibleKeys(const QKeyEvent *) const
void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
{
QScreen *screen = new QScreen(ps);
- ps->d_func()->screen = screen;
+
if (isPrimary) {
QGuiApplicationPrivate::screen_list.prepend(screen);
} else {
@@ -469,8 +468,9 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary)
*/
void QPlatformIntegration::destroyScreen(QPlatformScreen *screen)
{
- QGuiApplicationPrivate::screen_list.removeOne(screen->d_func()->screen);
- delete screen->d_func()->screen;
+ QScreen *qScreen = screen->screen();
+ QGuiApplicationPrivate::screen_list.removeOne(qScreen);
+ delete qScreen;
delete screen;
}
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index edf546799f..3a4adbc436 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -40,6 +40,7 @@
#include <qpa/qplatformintegration.h>
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -97,6 +98,32 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
}
/*!
+ Find the sibling screen corresponding to \a globalPos.
+
+ Returns this screen if no suitable screen is found at the position.
+ */
+const QPlatformScreen *QPlatformScreen::screenForPosition(const QPoint &point) const
+{
+ QPlatformScreen *that = const_cast<QPlatformScreen*>(this);
+ return that->screenForPosition(point);
+}
+
+/*!
+ \overload
+ */
+QPlatformScreen *QPlatformScreen::screenForPosition(const QPoint &point)
+{
+ if (!geometry().contains(point)) {
+ Q_FOREACH (QPlatformScreen* screen, virtualSiblings()) {
+ if (screen->geometry().contains(point))
+ return screen;
+ }
+ }
+ return this;
+}
+
+
+/*!
Returns a list of all the platform screens that are part of the same
virtual desktop.
@@ -156,11 +183,13 @@ QDpi QPlatformScreen::logicalDpi() const
}
/*!
- Reimplement this function in subclass to return the device pixel
- ratio for the screen. This is the ratio between physical pixels
- and device-independent pixels.
+ Reimplement this function in subclass to return the device pixel ratio
+ for the screen. This is the ratio between physical pixels and the
+ device-independent pixels of the windowing system. The default
+ implementation returns 1.0.
- \sa QPlatformWindow::devicePixelRatio();
+ \sa QPlatformWindow::devicePixelRatio()
+ \sa QPlatformScreen::pixelDensity()
*/
qreal QPlatformScreen::devicePixelRatio() const
{
@@ -168,6 +197,26 @@ qreal QPlatformScreen::devicePixelRatio() const
}
/*!
+ Reimplement this function in subclass to return the pixel density of the
+ screen. This is the scale factor needed to make a low-dpi application
+ usable on this screen. The default implementation returns 1.0. In
+ addition the platform integration must return true for the PlatformScreenPixelDensity
+ Capability for this value to have an effect.
+
+ Returning something else than 1 from this function causes Qt to
+ apply the scale factor to the application's coordinate system.
+ This is different from devicePixelRatio, which reports a scale
+ factor already applied by the windowing system. A platform plugin
+ typically implements one (or none) of these two functions.
+
+ \sa QPlatformWindow::devicePixelRatio()
+*/
+qreal QPlatformScreen::pixelDensity() const
+{
+ return 1.0;
+}
+
+/*!
Reimplement this function in subclass to return the vertical refresh rate
of the screen, in Hz.
@@ -290,8 +339,8 @@ void QPlatformScreen::resizeMaximizedWindows()
// 'screen()' still has the old geometry info while 'this' has the new geometry info
const QRect oldGeometry = screen()->geometry();
const QRect oldAvailableGeometry = screen()->availableGeometry();
- const QRect newGeometry = geometry();
- const QRect newAvailableGeometry = availableGeometry();
+ const QRect newGeometry = deviceIndependentGeometry();
+ const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft());
// make sure maximized and fullscreen windows are updated
for (int i = 0; i < windows.size(); ++i) {
@@ -393,6 +442,26 @@ QRect QPlatformScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation
return rect;
}
+QRect QPlatformScreen::deviceIndependentGeometry() const
+{
+ qreal scaleFactor = QHighDpiScaling::factor(this);
+ QRect nativeGeometry = geometry();
+ return QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor));
+}
+
+
+QRect QPlatformScreen::screenGeometry() const
+{
+ qreal scaleFactor = QHighDpiScaling::factor(this);
+ QRect geometry = screen()->geometry();
+ return QRect(geometry.topLeft(), QHighDpi::toNative(geometry.size(), scaleFactor));
+}
+
+QRect QPlatformScreen::screenAvailableGeometry() const
+{
+ return QHighDpi::toNativePixels(screen()->availableGeometry(), this);
+}
+
/*!
Returns a hint about this screen's subpixel layout structure.
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index 551cb788c9..0bd0b77751 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -96,6 +96,7 @@ public:
virtual QSizeF physicalSize() const;
virtual QDpi logicalDpi() const;
virtual qreal devicePixelRatio() const;
+ virtual qreal pixelDensity() const;
virtual qreal refreshRate() const;
@@ -105,6 +106,8 @@ public:
virtual QWindow *topLevelAt(const QPoint &point) const;
virtual QList<QPlatformScreen *> virtualSiblings() const;
+ const QPlatformScreen *screenForPosition(const QPoint &point) const;
+ QPlatformScreen *screenForPosition(const QPoint &point);
QScreen *screen() const;
@@ -121,6 +124,13 @@ public:
static QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target);
static QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect);
+ // The platform screen's geometry in device independent coordinates
+ QRect deviceIndependentGeometry() const;
+
+ // Accessors for QScreen geometry in native coordinates. Platform plugins should use these
+ // instead of accessing QScreen directly.
+ QRect screenGeometry() const;
+ QRect screenAvailableGeometry() const;
protected:
void resizeMaximizedWindows();
@@ -129,7 +139,7 @@ protected:
private:
Q_DISABLE_COPY(QPlatformScreen)
- friend class QPlatformIntegration;
+ friend class QScreenPrivate;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 114fcf8062..34a1fabc76 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -39,8 +39,10 @@
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/qwindow.h>
#include <QtGui/qscreen.h>
+#include <private/qhighdpiscaling_p.h>
#include <private/qwindow_p.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -481,13 +483,25 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &
QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const
{
QPlatformScreen *currentScreen = screen();
- if (!parent() && currentScreen && !currentScreen->geometry().intersects(newGeometry)) {
+ QPlatformScreen *fallback = currentScreen;
+ QPoint center = newGeometry.center();
+ if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) {
Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
- if (screen->geometry().intersects(newGeometry))
+ if (screen->geometry().contains(center))
return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
}
}
- return currentScreen;
+ return fallback;
+}
+
+/*!
+ Returns a size with both dimentions bounded to [0, QWINDOWSIZE_MAX]
+*/
+QSize QPlatformWindow::constrainWindowSize(const QSize &size)
+{
+ return size.expandedTo(QSize(0, 0)).boundedTo(QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
}
/*!
@@ -565,7 +579,7 @@ void QPlatformWindow::invalidateSurface()
QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
- QRect rect(initialGeometry);
+ QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
if (rect.width() == 0) {
const int minWidth = w->minimumWidth();
rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
@@ -593,7 +607,7 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
}
}
}
- return rect;
+ return QHighDpi::toNativePixels(rect, w);
}
/*!
@@ -627,6 +641,55 @@ void QPlatformWindow::requestUpdate()
}
/*!
+ Returns the QWindow minimum size.
+*/
+QSize QPlatformWindow::windowMinimumSize() const
+{
+ return QHighDpi::toNativePixels(constrainWindowSize(window()->minimumSize()), window());
+}
+
+/*!
+ Returns the QWindow maximum size.
+*/
+QSize QPlatformWindow::windowMaximumSize() const
+{
+ return QHighDpi::toNativePixels(constrainWindowSize(window()->maximumSize()), window());
+}
+
+/*!
+ Returns the QWindow base size.
+*/
+QSize QPlatformWindow::windowBaseSize() const
+{
+ return QHighDpi::toNativePixels(window()->baseSize(), window());
+}
+
+/*!
+ Returns the QWindow size increment.
+*/
+QSize QPlatformWindow::windowSizeIncrement() const
+{
+ QSize increment = window()->sizeIncrement();
+ if (!QHighDpiScaling::isActive())
+ return increment;
+
+ // Normalize the increment. If not set the increment can be
+ // (-1, -1) or (0, 0). Make that (1, 1) which is scalable.
+ if (increment.isEmpty())
+ increment = QSize(1, 1);
+
+ return QHighDpi::toNativePixels(increment, window());
+}
+
+/*!
+ Returns the QWindow geometry.
+*/
+QRect QPlatformWindow::windowGeometry() const
+{
+ return QHighDpi::toNativePixels(window()->geometry(), window());
+}
+
+/*!
\class QPlatformWindow
\since 4.8
\internal
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index c7c1efdc58..c1f2a4bdf1 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -130,9 +130,18 @@ public:
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
virtual void requestUpdate();
+
+ // Window property accessors. Platform plugins should use these
+ // instead of accessing QWindow directly.
+ QSize windowMinimumSize() const;
+ QSize windowMaximumSize() const;
+ QSize windowBaseSize() const;
+ QSize windowSizeIncrement() const;
+ QRect windowGeometry() const;
protected:
static QString formatWindowTitle(const QString &title, const QString &separator);
QPlatformScreen *screenForGeometry(const QRect &newGeometry) const;
+ static QSize constrainWindowSize(const QSize &size);
QScopedPointer<QPlatformWindowPrivate> d_ptr;
private:
diff --git a/src/gui/kernel/qrasterwindow.cpp b/src/gui/kernel/qrasterwindow.cpp
index c04eb71420..fc1739ca0e 100644
--- a/src/gui/kernel/qrasterwindow.cpp
+++ b/src/gui/kernel/qrasterwindow.cpp
@@ -108,8 +108,6 @@ int QRasterWindow::metric(PaintDeviceMetric metric) const
switch (metric) {
case PdmDepth:
return d->backingstore->paintDevice()->depth();
- case PdmDevicePixelRatio:
- return d->backingstore->paintDevice()->devicePixelRatio();
default:
break;
}
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 5785722918..af88a44957 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -36,6 +36,7 @@
#include "qpixmap.h"
#include "qguiapplication_p.h"
#include <qpa/qplatformscreen.h>
+#include <qpa/qplatformscreen_p.h>
#include <QtCore/QDebug>
#include <QtCore/private/qobject_p.h>
@@ -63,11 +64,37 @@ QT_BEGIN_NAMESPACE
*/
QScreen::QScreen(QPlatformScreen *screen)
- : QObject(*new QScreenPrivate(screen), 0)
+ : QObject(*new QScreenPrivate(), 0)
{
+ Q_D(QScreen);
+ d->setPlatformScreen(screen);
+}
+
+void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
+{
+ Q_Q(QScreen);
+ platformScreen = screen;
+ platformScreen->d_func()->screen = q;
+ orientation = platformScreen->orientation();
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+ logicalDpi = platformScreen->logicalDpi();
+ refreshRate = platformScreen->refreshRate();
+ // safeguard ourselves against buggy platform behavior...
+ if (refreshRate < 1.0)
+ refreshRate = 60.0;
+
+ updatePrimaryOrientation();
+
+ filteredOrientation = orientation;
+ if (filteredOrientation == Qt::PrimaryOrientation)
+ filteredOrientation = primaryOrientation;
+
+ updateHighDpi();
}
+
/*!
Destroys the screen.
*/
@@ -259,7 +286,7 @@ qreal QScreen::logicalDotsPerInch() const
qreal QScreen::devicePixelRatio() const
{
Q_D(const QScreen);
- return d->platformScreen->devicePixelRatio();
+ return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor(this);
}
/*!
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index f60fafcf63..a6018128e2 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -154,6 +154,7 @@ private:
friend class QGuiApplicationPrivate;
friend class QPlatformIntegration;
friend class QPlatformScreen;
+ friend class QHighDpiScaling;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h
index d341b71932..4492eddd45 100644
--- a/src/gui/kernel/qscreen_p.h
+++ b/src/gui/kernel/qscreen_p.h
@@ -47,6 +47,7 @@
#include <QtGui/qscreen.h>
#include <qpa/qplatformscreen.h>
+#include "qhighdpiscaling_p.h"
#include <QtCore/private/qobject_p.h>
@@ -54,25 +55,19 @@ QT_BEGIN_NAMESPACE
class QScreenPrivate : public QObjectPrivate
{
+ Q_DECLARE_PUBLIC(QScreen)
public:
- QScreenPrivate(QPlatformScreen *screen)
- : platformScreen(screen)
+ QScreenPrivate()
+ : platformScreen(0)
, orientationUpdateMask(0)
{
- orientation = platformScreen->orientation();
- geometry = platformScreen->geometry();
- availableGeometry = platformScreen->availableGeometry();
- logicalDpi = platformScreen->logicalDpi();
- refreshRate = platformScreen->refreshRate();
- // safeguard ourselves against buggy platform behavior...
- if (refreshRate < 1.0)
- refreshRate = 60.0;
-
- updatePrimaryOrientation();
+ }
- filteredOrientation = orientation;
- if (filteredOrientation == Qt::PrimaryOrientation)
- filteredOrientation = primaryOrientation;
+ void setPlatformScreen(QPlatformScreen *screen);
+ void updateHighDpi()
+ {
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
}
void updatePrimaryOrientation();
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index b850f53014..162dbfee20 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -55,6 +55,7 @@
#include <private/qdnd_p.h>
#include <private/qshapedpixmapdndwindow_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -106,6 +107,12 @@ void QBasicDrag::disableEventFilter()
qApp->removeEventFilter(this);
}
+
+static inline QPoint getNativeMousePos(QEvent *e, QObject *o)
+{
+ return QHighDpi::toNativePixels(static_cast<QMouseEvent *>(e)->globalPos(), qobject_cast<QWindow*>(o));
+}
+
bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
{
Q_UNUSED(o);
@@ -139,19 +146,21 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
}
case QEvent::MouseMove:
- move(static_cast<QMouseEvent *>(e));
+ {
+ QPoint nativePosition = getNativeMousePos(e, o);
+ move(nativePosition);
return true; // Eat all mouse events
-
+ }
case QEvent::MouseButtonRelease:
disableEventFilter();
if (canDrop()) {
- drop(static_cast<QMouseEvent *>(e));
+ QPoint nativePosition = getNativeMousePos(e, o);
+ drop(nativePosition);
} else {
cancel();
}
exitDndEventLoop();
return true; // Eat all mouse events
-
case QEvent::MouseButtonPress:
case QEvent::MouseButtonDblClick:
case QEvent::Wheel:
@@ -227,13 +236,13 @@ void QBasicDrag::cancel()
m_drag_icon_window->setVisible(false);
}
-void QBasicDrag::move(const QMouseEvent *e)
+void QBasicDrag::move(const QPoint &globalPos)
{
if (m_drag)
- m_drag_icon_window->updateGeometry(e->globalPos());
+ m_drag_icon_window->updateGeometry(globalPos);
}
-void QBasicDrag::drop(const QMouseEvent *)
+void QBasicDrag::drop(const QPoint &)
{
disableEventFilter();
restoreCursor();
@@ -330,14 +339,15 @@ void QSimpleDrag::cancel()
}
}
-void QSimpleDrag::move(const QMouseEvent *me)
+void QSimpleDrag::move(const QPoint &globalPos)
{
- QBasicDrag::move(me);
- QWindow *window = topLevelAt(me->globalPos());
+ //### not high-DPI aware
+ QBasicDrag::move(globalPos);
+ QWindow *window = topLevelAt(globalPos);
if (!window)
return;
- const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPoint pos = globalPos - window->geometry().topLeft();
const QPlatformDragQtResponse qt_response =
QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions());
@@ -345,14 +355,16 @@ void QSimpleDrag::move(const QMouseEvent *me)
setCanDrop(qt_response.isAccepted());
}
-void QSimpleDrag::drop(const QMouseEvent *me)
+void QSimpleDrag::drop(const QPoint &globalPos)
{
- QBasicDrag::drop(me);
- QWindow *window = topLevelAt(me->globalPos());
+ //### not high-DPI aware
+
+ QBasicDrag::drop(globalPos);
+ QWindow *window = topLevelAt(globalPos);
if (!window)
return;
- const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPoint pos = globalPos - window->geometry().topLeft();
const QPlatformDropQtResponse response =
QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions());
if (response.isAccepted()) {
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 7812f8b863..728ae7bd15 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -73,8 +73,8 @@ protected:
virtual void startDrag();
virtual void cancel();
- virtual void move(const QMouseEvent *me);
- virtual void drop(const QMouseEvent *me);
+ virtual void move(const QPoint &globalPos) = 0;
+ virtual void drop(const QPoint &globalPos) = 0;
virtual void endDrag();
QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; }
@@ -111,8 +111,8 @@ public:
protected:
virtual void startDrag() Q_DECL_OVERRIDE;
virtual void cancel() Q_DECL_OVERRIDE;
- virtual void move(const QMouseEvent *me) Q_DECL_OVERRIDE;
- virtual void drop(const QMouseEvent *me) Q_DECL_OVERRIDE;
+ virtual void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
+ virtual void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
private:
QWindow *m_current_window;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index e697efe31c..4465a9aeb4 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -47,6 +47,7 @@
#ifndef QT_NO_ACCESSIBILITY
# include "qaccessible.h"
#endif
+#include "qhighdpiscaling_p.h"
#include <private/qevent_p.h>
@@ -1085,13 +1086,13 @@ qreal QWindow::devicePixelRatio() const
{
Q_D(const QWindow);
- // If there is no platform window, do the second best thing and
- // return the app global devicePixelRatio. This is the highest
- // devicePixelRatio found on the system screens, and will be
- // correct for single-display systems (a very common case).
+ // If there is no platform window use the app global devicePixelRatio,
+ // which is the the highest devicePixelRatio found on the system
+ // screens, and will be correct for single-display systems (a very common case).
if (!d->platformWindow)
return qApp->devicePixelRatio();
- return d->platformWindow->devicePixelRatio();
+
+ return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this);
}
/*!
@@ -1431,7 +1432,13 @@ void QWindow::setGeometry(const QRect &rect)
d->positionPolicy = QWindowPrivate::WindowFrameExclusive;
if (d->platformWindow) {
- d->platformWindow->setGeometry(rect);
+ QRect nativeRect;
+ QScreen *newScreen = d->screenForGeometry(rect);
+ if (newScreen && isTopLevel())
+ nativeRect = QHighDpi::toNativePixels(rect, newScreen);
+ else
+ nativeRect = QHighDpi::toNativePixels(rect, this);
+ d->platformWindow->setGeometry(nativeRect);
} else {
d->geometry = rect;
@@ -1446,6 +1453,26 @@ void QWindow::setGeometry(const QRect &rect)
}
}
+//######### This logic duplicated three times!!!!!
+// equivalent to QPlatformWindow::screenForGeometry, but in platform independent coordinates
+QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry)
+{
+ Q_Q(QWindow);
+ QScreen *currentScreen = q->screen();
+ QScreen *fallback = currentScreen;
+ QPoint center = newGeometry.center();
+ if (!q->parent() && currentScreen && !currentScreen->geometry().contains(center)) {
+ Q_FOREACH (QScreen* screen, currentScreen->virtualSiblings()) {
+ if (screen->geometry().contains(center))
+ return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
+ }
+ }
+ return fallback;
+}
+
+
/*!
Returns the geometry of the window, excluding its window frame.
@@ -1455,7 +1482,7 @@ QRect QWindow::geometry() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->geometry();
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this);
return d->geometry;
}
@@ -1468,7 +1495,7 @@ QMargins QWindow::frameMargins() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->frameMargins();
+ return QHighDpi::fromNativePixels(d->platformWindow->frameMargins(), this);
return QMargins();
}
@@ -1482,7 +1509,7 @@ QRect QWindow::frameGeometry() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins m = frameMargins();
- return d->platformWindow->geometry().adjusted(-m.left(), -m.top(), m.right(), m.bottom());
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this).adjusted(-m.left(), -m.top(), m.right(), m.bottom());
}
return d->geometry;
}
@@ -1499,7 +1526,7 @@ QPoint QWindow::framePosition() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins margins = frameMargins();
- return d->platformWindow->geometry().topLeft() - QPoint(margins.left(), margins.top());
+ return QHighDpi::fromNativePixels(d->platformWindow->geometry().topLeft(), this) - QPoint(margins.left(), margins.top());
}
return d->geometry.topLeft();
}
@@ -1515,7 +1542,7 @@ void QWindow::setFramePosition(const QPoint &point)
d->positionPolicy = QWindowPrivate::WindowFrameInclusive;
d->positionAutomatic = false;
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(point, size()));
+ d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(point, size()), this));
} else {
d->geometry.moveTopLeft(point);
}
@@ -1575,7 +1602,7 @@ void QWindow::resize(const QSize &newSize)
{
Q_D(QWindow);
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(position(), newSize));
+ d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(position(), newSize), this));
} else {
const QSize oldSize = d->geometry.size();
d->geometry.setSize(newSize);
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 4fc63acf28..23a6d800c0 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -136,6 +136,7 @@ public:
void connectToScreen(QScreen *topLevelScreen);
void disconnectFromScreen();
void emitScreenChangedRecursion(QScreen *newScreen);
+ QScreen *screenForGeometry(const QRect &rect);
virtual void clearFocusObject();
virtual QRectF closestAcceptableGeometry(const QRectF &rect) const;
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 823387b702..6f01f9a466 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -40,6 +40,7 @@
#include <qpa/qplatformdrag.h>
#include <qpa/qplatformintegration.h>
#include <qdebug.h>
+#include "qhighdpiscaling_p.h"
QT_BEGIN_NAMESPACE
@@ -139,7 +140,7 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState
*/
void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect)
{
- QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect, oldRect);
+ QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, QHighDpi::fromNativePixels(newRect, tlw), QHighDpi::fromNativePixels(oldRect, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -168,7 +169,7 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const
Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
- new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source);
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -185,7 +186,7 @@ void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timest
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
QWindowSystemInterfacePrivate::FrameStrutMouse,
- local, global, b, mods, source);
+ QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -366,14 +367,14 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Simple case: vertical deltas only:
if (angleDelta.y() != 0 && angleDelta.x() == 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
// Simple case: horizontal deltas only:
if (angleDelta.y() == 0 && angleDelta.x() != 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
@@ -381,12 +382,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Both horizontal and vertical deltas: Send two wheel events.
// The first event contains the Qt 5 pixel and angle delta as points,
// and in addition the Qt 4 compatibility vertical angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
// The second event contains null pixel and angle points and the
// Qt 4 compatibility horizontal angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -449,7 +450,10 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
handleTouchEvent(w, time, device, points, mods);
}
-QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type)
+QList<QTouchEvent::TouchPoint>
+ QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
+ const QWindow *window,
+ QEvent::Type *type)
{
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates states;
@@ -464,16 +468,16 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
p.setState(point->state);
const QPointF screenPos = point->area.center();
- p.setScreenPos(screenPos);
- p.setScreenRect(point->area);
+ p.setScreenPos(QHighDpi::fromNativePixels(screenPos, window));
+ p.setScreenRect(QHighDpi::fromNativePixels(point->area, window));
// The local pos and rect are not set, they will be calculated
// when the event gets processed by QGuiApplication.
- p.setNormalizedPos(point->normalPosition);
- p.setVelocity(point->velocity);
+ p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window));
+ p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window));
p.setFlags(point->flags);
- p.setRawScreenPositions(point->rawPositions);
+ p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window));
touchPoints.append(p);
++point;
@@ -491,6 +495,27 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
return touchPoints;
}
+QList<QWindowSystemInterface::TouchPoint>
+ QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
+ const QWindow *window)
+{
+ QList<QWindowSystemInterface::TouchPoint> newList;
+ newList.reserve(pointList.size());
+ foreach (const QTouchEvent::TouchPoint &pt, pointList) {
+ QWindowSystemInterface::TouchPoint p;
+ p.id = pt.id();
+ p.flags = pt.flags();
+ p.normalPosition = QHighDpi::toNativeLocalPosition(pt.normalizedPos(), window);
+ p.area = QHighDpi::toNativePixels(pt.screenRect(), window);
+ p.pressure = pt.pressure();
+ p.state = pt.state();
+ p.velocity = pt.velocity();
+ p.rawPositions = pt.rawScreenPositions();
+ newList.append(p);
+ }
+ return newList;
+}
+
void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTouchDevice *device,
const QList<TouchPoint> &points, Qt::KeyboardModifiers mods)
{
@@ -501,7 +526,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo
return;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, tlw, &type);
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods);
@@ -534,14 +559,14 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::
void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry)
{
QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
- new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry);
+ new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft()));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY)
{
QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e =
- new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY);
+ new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); // ### tja
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -560,7 +585,7 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{
- QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
+ QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -645,12 +670,12 @@ int QWindowSystemInterface::windowSystemEventsQueued()
#ifndef QT_NO_DRAGANDDROP
QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrag(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrag(w, dropData, QHighDpi::fromNativeLocalPosition(p, w) ,supportedActions);
}
QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrop(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrop(w, dropData, QHighDpi::fromNativeLocalPosition(p, w),supportedActions);
}
#endif // QT_NO_DRAGANDDROP
@@ -684,8 +709,11 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, cons
Qt::KeyboardModifiers modifiers)
{
QWindowSystemInterfacePrivate::TabletEvent *e =
- new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure,
- xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+ new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp,
+ QHighDpi::fromNativeLocalPosition(local, w),
+ QHighDpi::fromNativePixels(global, w),
+ device, pointerType, buttons, pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -837,7 +865,6 @@ Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int
return QWindowSystemInterface::tryHandleShortcutEventToObject(o, timestamp, k, mods, text, autorep, count);
}
-
Q_GUI_EXPORT void qt_handleTouchEvent(QWindow *w, QTouchDevice *device,
const QList<QTouchEvent::TouchPoint> &points,
Qt::KeyboardModifiers mods = Qt::NoModifier)
@@ -882,4 +909,5 @@ bool QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowS
return true;
}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 7160971305..cbc3bad7cd 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -488,7 +488,12 @@ public:
static QWaitCondition eventsFlushed;
static QMutex flushEventMutex;
- static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type);
+ static QList<QTouchEvent::TouchPoint>
+ fromNativeTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points,
+ const QWindow *window, QEvent::Type *type = Q_NULLPTR);
+ static QList<QWindowSystemInterface::TouchPoint>
+ toNativeTouchPoints(const QList<QTouchEvent::TouchPoint>& pointList,
+ const QWindow *window);
static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler);
static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler);
diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp
index e509b26a95..62e016c475 100644
--- a/src/gui/opengl/qopenglpaintdevice.cpp
+++ b/src/gui/opengl/qopenglpaintdevice.cpp
@@ -275,6 +275,9 @@ int QOpenGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
return qRound(d_ptr->dpmy * 0.0254);
case PdmDevicePixelRatio:
return d_ptr->devicePixelRatio;
+ case PdmDevicePixelRatioScaled:
+ return d_ptr->devicePixelRatio * QPaintDevice::devicePixelRatioFScale;
+
default:
qWarning("QOpenGLPaintDevice::metric() - metric %d not known", metric);
return 0;
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 19074e4c47..7b0a4e2ed4 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -38,22 +38,26 @@
#include <qpa/qplatformintegration.h>
#include <qscreen.h>
#include <qdebug.h>
+#include <qscopedpointer.h>
#include <private/qguiapplication_p.h>
#include <private/qwindow_p.h>
+#include <private/qhighdpiscaling_p.h>
+
QT_BEGIN_NAMESPACE
class QBackingStorePrivate
{
public:
QBackingStorePrivate(QWindow *w)
- : window(w)
+ : window(w), highDpiBackingstore(0)
{
}
QWindow *window;
QPlatformBackingStore *platformBackingStore;
+ QScopedPointer<QImage> highDpiBackingstore;
QRegion staticContents;
QSize size;
};
@@ -102,7 +106,7 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
}
#endif
- d_ptr->platformBackingStore->flush(win, region, offset);
+ d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset);
}
/*!
@@ -112,7 +116,12 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
*/
QPaintDevice *QBackingStore::paintDevice()
{
- return d_ptr->platformBackingStore->paintDevice();
+ QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+
+ if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image)
+ return d_ptr->highDpiBackingstore.data();
+
+ return device;
}
/*!
@@ -150,7 +159,35 @@ QWindow* QBackingStore::window() const
void QBackingStore::beginPaint(const QRegion &region)
{
- d_ptr->platformBackingStore->beginPaint(region);
+ if (d_ptr->highDpiBackingstore &&
+ d_ptr->highDpiBackingstore->devicePixelRatio() != d_ptr->window->devicePixelRatio())
+ resize(size());
+
+ // When QtGui is applying a high-dpi scale factor the backing store
+ // creates a "large" backing store image. This image needs to be
+ // painted on as a high-dpi image, which is done by setting
+ // devicePixelRatio. Do this on a separate image instance that shares
+ // the image data to avoid having the new devicePxielRatio be propagated
+ // back to the platform plugin.
+ QPaintDevice *device = d_ptr->platformBackingStore->paintDevice();
+ if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) {
+ QImage *source = reinterpret_cast<QImage *>(device);
+ const bool needsNewImage = d_ptr->highDpiBackingstore.isNull()
+ || source->data_ptr() != d_ptr->highDpiBackingstore->data_ptr()
+ || source->size() != d_ptr->highDpiBackingstore->size()
+ || source->devicePixelRatio() != d_ptr->highDpiBackingstore->devicePixelRatio();
+ if (needsNewImage) {
+ qCDebug(lcScaling) << "QBackingStore::beginPaint new backingstore for" << d_ptr->window;
+ qCDebug(lcScaling) << " source size" << source->size() << "dpr" << source->devicePixelRatio();
+ d_ptr->highDpiBackingstore.reset(
+ new QImage(source->bits(), source->width(), source->height(), source->format()));
+ qreal targetDevicePixelRatio = d_ptr->window->devicePixelRatio();
+ d_ptr->highDpiBackingstore->setDevicePixelRatio(targetDevicePixelRatio);
+ qCDebug(lcScaling) <<" destination size" << d_ptr->highDpiBackingstore->size()
+ << "dpr" << targetDevicePixelRatio;
+ }
+ }
+ d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window));
}
/*!
@@ -171,7 +208,7 @@ void QBackingStore::endPaint()
void QBackingStore::resize(const QSize &size)
{
d_ptr->size = size;
- d_ptr->platformBackingStore->resize(size, d_ptr->staticContents);
+ d_ptr->platformBackingStore->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents);
}
/*!
@@ -194,7 +231,7 @@ bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
Q_UNUSED(dx);
Q_UNUSED(dy);
- return d_ptr->platformBackingStore->scroll(area, dx, dy);
+ return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window));
}
void QBackingStore::setStaticContents(const QRegion &region)
diff --git a/src/gui/painting/qpaintdevice.cpp b/src/gui/painting/qpaintdevice.cpp
index bbf8e8f170..27d4bbcfd7 100644
--- a/src/gui/painting/qpaintdevice.cpp
+++ b/src/gui/painting/qpaintdevice.cpp
@@ -41,6 +41,8 @@ QPaintDevice::QPaintDevice() Q_DECL_NOEXCEPT
painters = 0;
}
+qreal QPaintDevice::devicePixelRatioFScale = 10000000.0;
+
QPaintDevice::~QPaintDevice()
{
if (paintingActive())
@@ -79,7 +81,13 @@ Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice
int QPaintDevice::metric(PaintDeviceMetric m) const
{
+ // Fallback: A subclass has not implemented PdmDevicePixelRatioScaled but might
+ // have implemented PdmDevicePixelRatio.
+ if (m == PdmDevicePixelRatioScaled)
+ return this->metric(PdmDevicePixelRatio) * devicePixelRatioFScale;
+
qWarning("QPaintDevice::metrics: Device has no metric information");
+
if (m == PdmDpiX) {
return 72;
} else if (m == PdmDpiY) {
@@ -95,4 +103,5 @@ int QPaintDevice::metric(PaintDeviceMetric m) const
}
}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpaintdevice.h b/src/gui/painting/qpaintdevice.h
index 4eb972786b..b699956e99 100644
--- a/src/gui/painting/qpaintdevice.h
+++ b/src/gui/painting/qpaintdevice.h
@@ -58,7 +58,8 @@ public:
PdmDpiY,
PdmPhysicalDpiX,
PdmPhysicalDpiY,
- PdmDevicePixelRatio
+ PdmDevicePixelRatio,
+ PdmDevicePixelRatioScaled
};
virtual ~QPaintDevice();
@@ -76,9 +77,13 @@ public:
int physicalDpiX() const { return metric(PdmPhysicalDpiX); }
int physicalDpiY() const { return metric(PdmPhysicalDpiY); }
int devicePixelRatio() const { return metric(PdmDevicePixelRatio); }
+ qreal devicePixelRatioF() const { return metric(PdmDevicePixelRatioScaled) / devicePixelRatioFScale; }
int colorCount() const { return metric(PdmNumColors); }
int depth() const { return metric(PdmDepth); }
+ // ### Classes that are not QPaintDevice subclasses are implementing metric(),
+ // ### and need to access this constant. Add it here as a static constant for now
+ static qreal devicePixelRatioFScale;
protected:
QPaintDevice() Q_DECL_NOEXCEPT;
virtual int metric(PaintDeviceMetric metric) const;
@@ -87,7 +92,6 @@ protected:
virtual QPainter *sharedPainter() const;
ushort painters; // refcount
-
private:
Q_DISABLE_COPY(QPaintDevice)
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index c17ea9c878..99a9f823a1 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -219,18 +219,18 @@ QTransform QPainterPrivate::viewTransform() const
return QTransform();
}
-int QPainterPrivate::effectiveDevicePixelRatio() const
+qreal QPainterPrivate::effectiveDevicePixelRatio() const
{
// Special cases for devices that does not support PdmDevicePixelRatio go here:
if (device->devType() == QInternal::Printer)
- return 1;
+ return qreal(1);
- return qMax(1, device->metric(QPaintDevice::PdmDevicePixelRatio));
+ return qMax(qreal(1), device->devicePixelRatioF());
}
QTransform QPainterPrivate::hidpiScaleTransform() const
{
- int devicePixelRatio = effectiveDevicePixelRatio();
+ const qreal devicePixelRatio = effectiveDevicePixelRatio();
return QTransform::fromScale(devicePixelRatio, devicePixelRatio);
}
@@ -5110,7 +5110,7 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
x += d->state->matrix.dx();
y += d->state->matrix.dy();
}
- int scale = pm.devicePixelRatio();
+ qreal scale = pm.devicePixelRatio();
d->engine->drawPixmap(QRectF(x, y, w / scale, h / scale), pm, QRectF(0, 0, w, h));
}
}
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 3ea4e35b8d..e8b675365f 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -240,7 +240,7 @@ public:
}
QTransform viewTransform() const;
- int effectiveDevicePixelRatio() const;
+ qreal effectiveDevicePixelRatio() const;
QTransform hidpiScaleTransform() const;
static bool attachPainterPrivate(QPainter *q, QPaintDevice *pdev);
void detachPainterPrivate(QPainter *q);
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 6ea0800538..011094b56b 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1318,6 +1318,9 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
case QPaintDevice::PdmDevicePixelRatio:
val = 1;
break;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ val = 1 * QPaintDevice::devicePixelRatioFScale;
+ break;
default:
qWarning("QPdfWriter::metric: Invalid metric command");
return 0;
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index 5d31ab9711..f03895a16e 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -558,6 +558,9 @@ namespace {
case PdmDevicePixelRatio:
val = 1;
break;
+ case PdmDevicePixelRatioScaled:
+ val = devicePixelRatioFScale;
+ break;
default:
val = 0;
qWarning("DrawTextItemDevice::metric: Invalid metric command");
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index e85890baf2..1ba2cb31ca 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -256,10 +256,10 @@ void QTextImageHandler::drawObject(QPainter *p, const QRectF &rect, QTextDocumen
const QTextImageFormat imageFormat = format.toImageFormat();
if (QCoreApplication::instance()->thread() != QThread::currentThread()) {
- const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatio());
+ const QImage image = getImage(doc, imageFormat, p->device()->devicePixelRatioF());
p->drawImage(rect, image, image.rect());
} else {
- const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatio());
+ const QPixmap pixmap = getPixmap(doc, imageFormat, p->device()->devicePixelRatioF());
p->drawPixmap(rect, pixmap, pixmap.rect());
}
}
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 5aec058532..ad99d3707f 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -4494,7 +4494,7 @@ QImage QGLWidget::grabFrameBuffer(bool withAlpha)
{
makeCurrent();
QImage res;
- qreal pixelRatio = devicePixelRatio();
+ qreal pixelRatio = devicePixelRatioF();
int w = pixelRatio * width();
int h = pixelRatio * height();
if (format().rgba())
@@ -4907,7 +4907,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
GLdouble win_x = 0, win_y = 0, win_z = 0;
qgluProject(x, y, z, &model[0], &proj[0], &view[0],
&win_x, &win_y, &win_z);
- const int dpr = d->glcx->device()->devicePixelRatio();
+ const int dpr = d->glcx->device()->devicePixelRatioF();
win_x /= dpr;
win_y /= dpr;
win_y = height - win_y; // y is inverted
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 3479fccf58..8a03f9a0b7 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -1285,6 +1285,9 @@ int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
case QPaintDevice::PdmDevicePixelRatio:
return 1;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return 1 * QPaintDevice::devicePixelRatioFScale;
+
default:
qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
break;
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
index 89cf01d8ec..16f1a3830e 100644
--- a/src/opengl/qglpaintdevice.cpp
+++ b/src/opengl/qglpaintdevice.cpp
@@ -62,6 +62,8 @@ int QGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
}
case PdmDevicePixelRatio:
return 1;
+ case PdmDevicePixelRatioScaled:
+ return 1 * QPaintDevice::devicePixelRatioFScale;
default:
qWarning("QGLPaintDevice::metric() - metric %d not known", metric);
return 0;
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index 49d2df9e1d..a9e3f15f9e 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -458,6 +458,9 @@ int QGLPixelBuffer::metric(PaintDeviceMetric metric) const
case QPaintDevice::PdmDevicePixelRatio:
return 1;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return QPaintDevice::devicePixelRatioFScale;
+
default:
qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n", metric);
break;
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 19ab051162..184fc58cf0 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -55,6 +55,7 @@
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <qpa/qwindowsysteminterface.h>
@@ -109,6 +110,8 @@ static QAndroidPlatformIntegration *m_androidPlatformIntegration = nullptr;
static int m_desktopWidthPixels = 0;
static int m_desktopHeightPixels = 0;
static double m_scaledDensity = 0;
+static double m_density = 1.0;
+static bool m_highDpiScalingEnabled = true;
static volatile bool m_pauseApplication;
@@ -157,6 +160,21 @@ namespace QtAndroid
return m_scaledDensity;
}
+ double density()
+ {
+ return m_density;
+ }
+
+ bool highDpiScalingEnabled()
+ {
+ return m_highDpiScalingEnabled;
+ }
+
+ double pixelDensity()
+ {
+ return QtAndroid::highDpiScalingEnabled() ? m_density : 1.0;
+ }
+
JavaVM *javaVM()
{
return m_javaVM;
@@ -541,7 +559,8 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface,
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
jint widthPixels, jint heightPixels,
jint desktopWidthPixels, jint desktopHeightPixels,
- jdouble xdpi, jdouble ydpi, jdouble scaledDensity)
+ jdouble xdpi, jdouble ydpi,
+ jdouble scaledDensity, jdouble density)
{
// Android does not give us the correct screen size for immersive mode, but
// the surface does have the right size
@@ -552,6 +571,10 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
m_desktopWidthPixels = desktopWidthPixels;
m_desktopHeightPixels = desktopHeightPixels;
m_scaledDensity = scaledDensity;
+ m_density = density;
+
+ if (m_highDpiScalingEnabled)
+ QHighDpiScaling::setGlobalFactor(density);
if (!m_androidPlatformIntegration) {
QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,
@@ -677,7 +700,7 @@ static JNINativeMethod methods[] = {
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
{"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin},
{"terminateQt", "()V", (void *)terminateQt},
- {"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics},
+ {"setDisplayMetrics", "(IIIIDDDD)V", (void *)setDisplayMetrics},
{"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
{"updateWindow", "()V", (void *)updateWindow},
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index 4d037f4b74..f8eca17393 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -71,6 +71,9 @@ namespace QtAndroid
int desktopWidthPixels();
int desktopHeightPixels();
double scaledDensity();
+ double density();
+ bool highDpiScalingEnabled();
+ double pixelDensity();
JavaVM *javaVM();
AAssetManager *assetManager();
jclass applicationClass();
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 7a509e4d61..76c0bfa75d 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -52,6 +52,7 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QWindow>
#include <QtGui/private/qwindow_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -81,8 +82,10 @@ private:
QAndroidPlatformScreen::QAndroidPlatformScreen():QObject(),QPlatformScreen()
{
- m_availableGeometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
- m_size = QSize(QAndroidPlatformIntegration::m_defaultScreenWidth, QAndroidPlatformIntegration::m_defaultScreenHeight);
+ m_availableGeometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth,
+ QAndroidPlatformIntegration::m_defaultGeometryHeight);
+ m_size = QSize(QAndroidPlatformIntegration::m_defaultScreenWidth,
+ QAndroidPlatformIntegration::m_defaultScreenHeight);
// Raster only apps should set QT_ANDROID_RASTER_IMAGE_DEPTH to 16
// is way much faster than 32
if (qEnvironmentVariableIntValue("QT_ANDROID_RASTER_IMAGE_DEPTH") == 16) {
@@ -109,6 +112,16 @@ QAndroidPlatformScreen::~QAndroidPlatformScreen()
}
}
+QRect QAndroidPlatformScreen::geometry() const
+{
+ return QRect(QPoint(), m_size);
+}
+
+QRect QAndroidPlatformScreen::availableGeometry() const
+{
+ return m_availableGeometry;
+}
+
QWindow *QAndroidPlatformScreen::topWindow() const
{
foreach (QAndroidPlatformWindow *w, m_windowStack)
@@ -378,7 +391,7 @@ void QAndroidPlatformScreen::doRedraw()
QDpi QAndroidPlatformScreen::logicalDpi() const
{
- qreal lDpi = QtAndroid::scaledDensity() * 72;
+ qreal lDpi = 72;
return QDpi(lDpi, lDpi);
}
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
index 403d6036f0..f1e3effb25 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -58,8 +58,8 @@ public:
QAndroidPlatformScreen();
~QAndroidPlatformScreen();
- QRect geometry() const { return QRect(QPoint(), m_size); }
- QRect availableGeometry() const { return m_availableGeometry; }
+ QRect geometry() const;
+ QRect availableGeometry() const;
int depth() const { return m_depth; }
QImage::Format format() const { return m_format; }
QSizeF physicalSize() const { return m_physicalSize; }
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 3e2ae7c939..1bfec1df8c 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -31,6 +31,7 @@
**
****************************************************************************/
+#include "androidjnimain.h"
#include "androidjnimenu.h"
#include "qandroidplatformtheme.h"
#include "qandroidplatformmenubar.h"
@@ -245,7 +246,7 @@ static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette)
// Font size (in pixels)
attributeIterator = item.find(QLatin1String("TextAppearance_textSize"));
if (attributeIterator != item.constEnd())
- font.setPixelSize(int(attributeIterator.value().toDouble()));
+ font.setPixelSize(int(attributeIterator.value().toDouble() / QtAndroid::pixelDensity()));
// Font style
attributeIterator = item.find(QLatin1String("TextAppearance_textStyle"));
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 6a4f7ed8ee..cd8af5092a 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -54,6 +54,7 @@ QPaintDevice *QCocoaBackingStore::paintDevice()
// Receate the backing store buffer if the effective buffer size has changed,
// either due to a window resize or devicePixelRatio change.
QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio;
+
if (m_qImage.size() != effectiveBufferSize) {
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index e5fedcd051..c61d6580fa 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -606,7 +606,7 @@ void QCocoaWindow::show(bool becauseOfAncestor)
&& !m_hiddenByClipping) { // ... NOR clipped
if (m_isNSWindowChild) {
m_hiddenByAncestor = false;
- setCocoaGeometry(window()->geometry());
+ setCocoaGeometry(windowGeometry());
}
if (!m_hiddenByClipping) { // setCocoaGeometry() can change the clipping status
[m_nsWindow orderFront:nil];
@@ -645,7 +645,7 @@ void QCocoaWindow::setVisible(bool visible)
if (parentCocoaWindow) {
// The parent window might have moved while this window was hidden,
// update the window geometry if there is a parent.
- setGeometry(window()->geometry());
+ setGeometry(windowGeometry());
if (window()->type() == Qt::Popup) {
// QTBUG-30266: a window should not be resizable while a transient popup is open
@@ -864,8 +864,8 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags)
// no-WindowMaximizeButtonHint windows. From a Qt perspective it migth be expected
// that the button would be removed in the latter case, but disabling it is more
// in line with the platform style guidelines.
- bool fixedSizeNoZoom = (window()->minimumSize().isValid() && window()->maximumSize().isValid()
- && window()->minimumSize() == window()->maximumSize());
+ bool fixedSizeNoZoom = (windowMinimumSize().isValid() && windowMaximumSize().isValid()
+ && windowMinimumSize() == windowMaximumSize());
bool customizeNoZoom = ((flags & Qt::CustomizeWindowHint) && !(flags & Qt::WindowMaximizeButtonHint));
[[m_nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:!(fixedSizeNoZoom || customizeNoZoom)];
}
@@ -1054,20 +1054,20 @@ void QCocoaWindow::propagateSizeHints()
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::propagateSizeHints" << this;
- qDebug() << " min/max " << window()->minimumSize() << window()->maximumSize();
- qDebug() << "size increment" << window()->sizeIncrement();
- qDebug() << " basesize" << window()->baseSize();
- qDebug() << " geometry" << geometry();
+ qDebug() << " min/max " << windowMinimumSize() << windowMaximumSize();
+ qDebug() << "size increment" << windowSizeIncrement();
+ qDebug() << " basesize" << windowBaseSize();
+ qDebug() << " geometry" << windowGeometry();
#endif
// Set the minimum content size.
- const QSize minimumSize = window()->minimumSize();
+ const QSize minimumSize = windowMinimumSize();
if (!minimumSize.isValid()) // minimumSize is (-1, -1) when not set. Make that (0, 0) for Cocoa.
[m_nsWindow setContentMinSize : NSMakeSize(0.0, 0.0)];
[m_nsWindow setContentMinSize : NSMakeSize(minimumSize.width(), minimumSize.height())];
// Set the maximum content size.
- const QSize maximumSize = window()->maximumSize();
+ const QSize maximumSize = windowMaximumSize();
[m_nsWindow setContentMaxSize : NSMakeSize(maximumSize.width(), maximumSize.height())];
// The window may end up with a fixed size; in this case the zoom button should be disabled.
@@ -1075,13 +1075,14 @@ void QCocoaWindow::propagateSizeHints()
// sizeIncrement is observed to take values of (-1, -1) and (0, 0) for windows that should be
// resizable and that have no specific size increment set. Cocoa expects (1.0, 1.0) in this case.
- if (!window()->sizeIncrement().isEmpty())
- [m_nsWindow setResizeIncrements : qt_mac_toNSSize(window()->sizeIncrement())];
+ const QSize sizeIncrement = windowSizeIncrement();
+ if (!sizeIncrement.isEmpty())
+ [m_nsWindow setResizeIncrements : qt_mac_toNSSize(sizeIncrement)];
else
[m_nsWindow setResizeIncrements : NSMakeSize(1.0, 1.0)];
QRect rect = geometry();
- QSize baseSize = window()->baseSize();
+ QSize baseSize = windowBaseSize();
if (!baseSize.isNull() && baseSize.isValid()) {
[m_nsWindow setFrame:NSMakeRect(rect.x(), rect.y(), baseSize.width(), baseSize.height()) display:YES];
}
@@ -1327,7 +1328,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
| NSWindowCollectionBehaviorFullScreenAuxiliary;
m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
m_nsWindow.collectionBehavior = collectionBehavior;
- setCocoaGeometry(window()->geometry());
+ setCocoaGeometry(windowGeometry());
QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
if (siblings.contains(this)) {
@@ -1341,7 +1342,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
} else {
// Child windows have no NSWindow, link the NSViews instead.
[m_parentCocoaWindow->m_contentView addSubview : m_contentView];
- QRect rect = window()->geometry();
+ QRect rect = windowGeometry();
// Prevent setting a (0,0) window size; causes opengl context
// "Invalid Drawable" warnings.
if (rect.isNull())
@@ -1393,7 +1394,7 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
{
QMacAutoReleasePool pool;
- QRect rect = initialGeometry(window(), window()->geometry(), defaultWindowWidth, defaultWindowHeight);
+ QRect rect = initialGeometry(window(), windowGeometry(), defaultWindowWidth, defaultWindowHeight);
NSRect frame = qt_mac_flipRect(rect);
Qt::WindowType type = window()->type();
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index cb3e6e2cc5..d4552eade4 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -211,6 +211,9 @@ int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
case QPaintDevice::PdmDevicePixelRatio:
val = 1;
break;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ val = 1 * QPaintDevice::devicePixelRatioFScale;
+ break;
default:
val = 0;
qWarning("QPrinter::metric: Invalid metric command");
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
index fee9ad88fa..bc6590ef64 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -113,6 +113,9 @@ int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric)
case QPaintDevice::PdmDevicePixelRatio:
return 1;
break;
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ return 1 * devicePixelRatioFScale;
+ break;
case QPaintDevice::PdmWidthMM:
case QPaintDevice::PdmHeightMM:
return -1;
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 16c278d9df..3f19e4401a 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -35,10 +35,10 @@
#include "qwindowswindow.h"
#include "qwindowsnativeimage.h"
#include "qwindowscontext.h"
-#include "qwindowsscaling.h"
#include <QtGui/QWindow>
#include <QtGui/QPainter>
+#include <private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
@@ -68,10 +68,12 @@ QPaintDevice *QWindowsBackingStore::paintDevice()
return &m_image->image();
}
-void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoint &offset)
+void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
+ const QPoint &offset)
{
Q_ASSERT(window);
+ const QRect br = region.boundingRect();
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br;
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
@@ -81,9 +83,8 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin
const Qt::WindowFlags flags = window->flags();
if ((flags & Qt::FramelessWindowHint) && QWindowsWindow::setWindowLayered(rw->handle(), flags, hasAlpha, rw->opacity()) && hasAlpha) {
// Windows with alpha: Use blend function to update.
- const QMargins marginsDP = rw->frameMarginsDp();
- const QRect r = rw->geometryDp() + marginsDP;
- const QPoint frameOffset(marginsDP.left(), marginsDP.top());
+ QRect r = QHighDpi::toNativePixels(window->frameGeometry(), window);
+ QPoint frameOffset(QHighDpi::toNativePixels(QPoint(window->frameMargins().left(), window->frameMargins().top()), window));
QRect dirtyRect = br.translated(offset + frameOffset);
SIZE size = {r.width(), r.height()};
@@ -127,15 +128,14 @@ void QWindowsBackingStore::flushDp(QWindow *window, const QRect &br, const QPoin
}
}
-void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip)
+void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
{
- const QSize size = sizeDip * QWindowsScaling::factor();
if (m_image.isNull() || m_image->image().size() != size) {
#ifndef QT_NO_DEBUG_OUTPUT
if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) {
qCDebug(lcQpaBackingStore)
- << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << sizeDip << ' '
- << regionDip << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
+ << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region
+ << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
}
#endif
const QImage::Format format = window()->format().hasAlpha() ?
@@ -144,10 +144,10 @@ void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip
QWindowsNativeImage *oldwni = m_image.data();
QWindowsNativeImage *newwni = new QWindowsNativeImage(size.width(), size.height(), format);
- if (oldwni && !regionDip.isEmpty()) {
+ if (oldwni && !region.isEmpty()) {
const QImage &oldimg(oldwni->image());
QImage &newimg(newwni->image());
- QRegion staticRegion = QWindowsScaling::mapToNative(regionDip);
+ QRegion staticRegion(region);
staticRegion &= QRect(0, 0, oldimg.width(), oldimg.height());
staticRegion &= QRect(0, 0, newimg.width(), newimg.height());
QPainter painter(&newimg);
@@ -156,38 +156,36 @@ void QWindowsBackingStore::resize(const QSize &sizeDip, const QRegion &regionDip
painter.drawImage(rect, oldimg, rect);
}
- if (QWindowsScaling::isActive())
- newwni->setDevicePixelRatio(QWindowsScaling::factor());
m_image.reset(newwni);
}
}
Q_GUI_EXPORT void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
-bool QWindowsBackingStore::scroll(const QRegion &areaDip, int dxDip, int dyDip)
+bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy)
{
if (m_image.isNull() || m_image->image().isNull())
return false;
- const QPoint dp = QPoint(dxDip, dyDip) * QWindowsScaling::factor();
- const QVector<QRect> rects = areaDip.rects();
+ const QVector<QRect> rects = area.rects();
+ const QPoint offset(dx, dy);
for (int i = 0; i < rects.size(); ++i)
- qt_scrollRectInImage(m_image->image(), QWindowsScaling::mapToNative(rects.at(i)), dp);
+ qt_scrollRectInImage(m_image->image(), rects.at(i), offset);
return true;
}
-void QWindowsBackingStore::beginPaint(const QRegion &regionDip)
+void QWindowsBackingStore::beginPaint(const QRegion &region)
{
if (QWindowsContext::verbose > 1)
- qCDebug(lcQpaBackingStore) <<__FUNCTION__ << regionDip;
+ qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region;
if (m_image->image().hasAlphaChannel()) {
QPainter p(&m_image->image());
p.setCompositionMode(QPainter::CompositionMode_Source);
const QColor blank = Qt::transparent;
- foreach (const QRect &r, regionDip.rects())
- p.fillRect(QWindowsScaling::mapToNative(r), blank);
+ foreach (const QRect &r, region.rects())
+ p.fillRect(r, blank);
}
}
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
index 41ad29babc..4badcf1b09 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.h
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -35,7 +35,6 @@
#define QWINDOWSBACKINGSTORE_H
#include "qtwindows_additional.h"
-#include "qwindowsscaling.h"
#include <qpa/qplatformbackingstore.h>
#include <QtCore/QScopedPointer>
@@ -53,12 +52,7 @@ public:
~QWindowsBackingStore();
QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE
- {
- flushDp(window, QWindowsScaling::mapToNative(region.boundingRect()),
- offset * QWindowsScaling::factor());
- }
- void flushDp(QWindow *window, const QRect &boundingRect, const QPoint &offset);
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
void resize(const QSize &size, const QRegion &r) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index a532e92397..27323a2fd6 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -51,7 +51,6 @@
#endif
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
-#include "qwindowsscaling.h"
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
@@ -1228,9 +1227,7 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg)
}
}
- QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered,
- pos / QWindowsScaling::factor(),
- globalPos / QWindowsScaling::factor(),
+ QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
QWindowsKeyMapper::queryKeyboardModifiers());
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 5f443f2675..1fbef61029 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -36,7 +36,6 @@
#include "qwindowscontext.h"
#include "qwindowswindow.h"
#include "qwindowsscreen.h"
-#include "qwindowsscaling.h"
#include <QtGui/QBitmap>
#include <QtGui/QImage>
@@ -646,13 +645,12 @@ QWindowsCursor::CursorState QWindowsCursor::cursorState()
QPoint QWindowsCursor::pos() const
{
- return mousePosition() / QWindowsScaling::factor();
+ return mousePosition();
}
void QWindowsCursor::setPos(const QPoint &pos)
{
- const QPoint posDp = pos * QWindowsScaling::factor();
- SetCursorPos(posDp.x() , posDp.y());
+ SetCursorPos(pos.x() , pos.y());
}
/*!
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index e10add9c7c..1e693641ca 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -33,7 +33,7 @@
#include "qwindowsdrag.h"
#include "qwindowscontext.h"
-#include "qwindowsscaling.h"
+#include "qwindowsscreen.h"
#ifndef QT_NO_CLIPBOARD
# include "qwindowsclipboard.h"
#endif
@@ -43,7 +43,6 @@
#include "qwindowswindow.h"
#include "qwindowsmousehandler.h"
#include "qwindowscursor.h"
-#include "qwindowsscaling.h"
#include <QtGui/QMouseEvent>
#include <QtGui/QPixmap>
@@ -52,6 +51,7 @@
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface_p.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtCore/QDebug>
#include <QtCore/QBuffer>
@@ -280,6 +280,13 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
}
#endif // !QT_NO_DEBUG_OUTPUT
+static qreal dragScaleFactor()
+{
+ const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
+ const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition());
+ return screen ? QHighDpiScaling::factor(screen) : qreal(1);
+}
+
/*!
\brief Blend custom pixmap with cursors.
*/
@@ -289,19 +296,22 @@ void QWindowsOleDropSource::createCursors()
const QDrag *drag = m_drag->currentDrag();
const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- const int scaleFactor = QWindowsScaling::factor();
- const QSize pixmapSizeDp = pixmap.size() * scaleFactor;
+
+ const qreal scaleFactor = dragScaleFactor();
const bool scalePixmap = hasPixmap
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
- const QPixmap drawPixmap = scalePixmap
- ? pixmap.scaled(pixmapSizeDp, Qt::KeepAspectRatio, Qt::SmoothTransformation) : pixmap;
-
+ const QPixmap scaledPixmap = scalePixmap
+ ? pixmap.scaled((QSizeF(pixmap.size()) * scaleFactor).toSize(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation)
+ : pixmap;
Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
int actionCount = int(sizeof(actions) / sizeof(actions[0]));
if (!hasPixmap)
--actionCount; // No Qt::IgnoreAction unless pixmap
- const QPoint hotSpot = drag->hotSpot() * scaleFactor;
+ const QPoint hotSpot = scalePixmap
+ ? (QPointF(drag->hotSpot()) * scaleFactor).toPoint()
+ : drag->hotSpot();
for (int cnum = 0; cnum < actionCount; ++cnum) {
const Qt::DropAction action = actions[cnum];
QPixmap cursorPixmap = drag->dragCursor(action);
@@ -321,14 +331,14 @@ void QWindowsOleDropSource::createCursors()
if (hasPixmap) {
const int x1 = qMin(-hotSpot.x(), 0);
- const int x2 = qMax(pixmapSizeDp.width() - hotSpot.x(), cursorPixmap.width());
+ const int x2 = qMax(scaledPixmap.width() - hotSpot.x(), cursorPixmap.width());
const int y1 = qMin(-hotSpot.y(), 0);
- const int y2 = qMax(pixmapSizeDp.height() - hotSpot.y(), cursorPixmap.height());
+ const int y2 = qMax(scaledPixmap.height() - hotSpot.y(), cursorPixmap.height());
QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1);
newCursor.fill(Qt::transparent);
QPainter p(&newCursor);
const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
- p.drawPixmap(pmDest, drawPixmap);
+ p.drawPixmap(pmDest, scaledPixmap);
p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap);
newPixmap = newCursor;
newHotSpot = QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y()));
@@ -454,7 +464,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
if (!m_touchDragWindow)
m_touchDragWindow = new QWindowsDragCursorWindow;
m_touchDragWindow->setPixmap(e.pixmap);
- m_touchDragWindow->setFramePosition((QWindowsCursor::mousePosition() - e.hotSpot) / QWindowsScaling::factor());
+ m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot);
if (!m_touchDragWindow->isVisible())
m_touchDragWindow->show();
break;
@@ -530,9 +540,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
const QPlatformDragQtResponse response =
- QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(),
- m_lastPoint / QWindowsScaling::factor(),
- actions);
+ QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
m_answerRect = response.answerRect();
const Qt::DropAction action = response.acceptedAction();
@@ -625,7 +633,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
const QPlatformDropQtResponse response =
QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(),
- m_lastPoint / QWindowsScaling::factor(),
+ m_lastPoint,
translateToQDragDropActions(m_chosenEffect));
if (response.isAccepted()) {
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 0cce171340..485b876fc7 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -36,7 +36,6 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowsmousehandler.h"
-#include "qwindowsscaling.h"
#include <QtCore/QDebug>
#include <QtCore/QObject>
@@ -243,10 +242,9 @@ void QWindowsInputContext::cursorRectChanged()
if (!m_compositionContext.hwnd)
return;
const QInputMethod *inputMethod = QGuiApplication::inputMethod();
- const QRect cursorRectangleDip = inputMethod->cursorRectangle().toRect();
- if (!cursorRectangleDip.isValid())
+ const QRect cursorRectangle = inputMethod->cursorRectangle().toRect();
+ if (!cursorRectangle.isValid())
return;
- const QRect cursorRectangle = QWindowsScaling::mapToNative(cursorRectangleDip);
qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 9b0f126241..05c7e6b240 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -33,7 +33,6 @@
****************************************************************************/
#include "qwindowsintegration.h"
-#include "qwindowsscaling.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#include "qwindowsopenglcontext.h"
@@ -64,6 +63,7 @@
# include "qwindowssessionmanager.h"
#endif
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qpa/qplatforminputcontextfactory_p.h>
#include <QtCore/private/qeventdispatcher_win_p.h>
@@ -223,12 +223,8 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
m_context.setProcessDpiAwareness(dpiAwareness);
dpiAwarenessSet = true;
}
- // Determine suitable scale factor, don't mix Windows and Qt scaling
- if (dpiAwareness != QtWindows::ProcessDpiUnaware)
- QWindowsScaling::setFactor(QWindowsScaling::determineUiScaleFactor());
qCDebug(lcQpaWindows)
- << __FUNCTION__ << "DpiAwareness=" << dpiAwareness <<",Scaling="
- << QWindowsScaling::factor();
+ << __FUNCTION__ << "DpiAwareness=" << dpiAwareness;
QTouchDevice *touchDevice = m_context.touchDevice();
if (touchDevice) {
@@ -307,7 +303,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
{
QWindowsWindowData requested;
requested.flags = window->flags();
- requested.geometry = QWindowsScaling::mapToNative(window->geometry());
+ requested.geometry = QHighDpi::toNativePixels(window->geometry(), window);
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
if (customMarginsV.isValid())
@@ -327,7 +323,7 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
window->setFlags(obtained.flags);
// Trigger geometry change signals of QWindow.
if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
- QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry));
+ QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
}
return obtained;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index d47c7df9e0..3636bb7893 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -35,12 +35,12 @@
#include "qwindowscontext.h"
#include "qwindowswindow.h"
#include "qwindowsguieventdispatcher.h"
-#include "qwindowsscaling.h"
#include "qwindowsinputcontext.h"
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QKeyEvent>
#if defined(WM_APPCOMMAND)
@@ -792,10 +792,12 @@ static void showSystemMenu(QWindow* w)
#undef enabled
#undef disabled
#endif // !Q_OS_WINCE
- const QPoint topLeft = topLevel->geometry().topLeft() * QWindowsScaling::factor();
+ const QPoint pos = QHighDpi::toNativePixels(topLevel->geometry().topLeft(), topLevel);
const int ret = TrackPopupMenuEx(menu,
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
- topLeft.x(), topLeft.y(), topLevelHwnd, 0);
+ pos.x(), pos.y(),
+ topLevelHwnd,
+ 0);
if (ret)
qWindowsWndProc(topLevelHwnd, WM_SYSCOMMAND, ret, 0);
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index db635b602b..a8aea05fd8 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -211,10 +211,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
const QPoint globalPosition = winEventPosition;
const QPoint clientPosition = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPosition);
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
- QWindowSystemInterface::handleFrameStrutMouseEvent(window,
- clientPosition / QWindowsScaling::factor(),
- globalPosition / QWindowsScaling::factor(),
- buttons,
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
+ globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
return false; // Allow further event processing (dragging of windows).
@@ -279,7 +277,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// ChildWindowFromPointEx() may not find the Qt window (failing with ERROR_ACCESS_DENIED)
if (!currentWindowUnderMouse) {
const QRect clientRect(QPoint(0, 0), window->size());
- if (clientRect.contains(winEventPosition / QWindowsScaling::factor()))
+ if (clientRect.contains(winEventPosition))
currentWindowUnderMouse = window;
}
@@ -366,10 +364,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
m_windowUnderMouse = currentWindowUnderMouse;
}
- QWindowSystemInterface::handleMouseEvent(window,
- winEventPosition / QWindowsScaling::factor(),
- globalPosition / QWindowsScaling::factor(),
- buttons,
+ QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers(),
source);
m_previousCaptureWindow = hasCapture ? window : 0;
@@ -404,11 +399,9 @@ static void redirectWheelEvent(QWindow *window, const QPoint &globalPos, int del
}
if (handleEvent) {
- const QPoint posDip = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos) / QWindowsScaling::factor();
QWindowSystemInterface::handleWheelEvent(receiver,
- posDip, globalPos / QWindowsScaling::factor(),
- delta / QWindowsScaling::factor(),
- orientation, mods);
+ QWindowsGeometryHint::mapFromGlobal(receiver, globalPos),
+ globalPos, delta, orientation, mods);
}
}
@@ -495,7 +488,6 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND hwnd,
Q_ASSERT(QWindowsContext::user32dll.getTouchInputInfo);
QWindowsContext::user32dll.getTouchInputInfo((HANDLE) msg.lParam, msg.wParam, winTouchInputs.data(), sizeof(TOUCHINPUT));
- const qreal screenPosFactor = 0.01 / qreal(QWindowsScaling::factor());
for (int i = 0; i < winTouchPointCount; ++i) {
const TOUCHINPUT &winTouchInput = winTouchInputs[i];
int id = m_touchInputIDToTouchPointID.value(winTouchInput.dwID, -1);
@@ -509,9 +501,9 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND hwnd,
if (m_lastTouchPositions.contains(id))
touchPoint.normalPosition = m_lastTouchPositions.value(id);
- const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) * screenPosFactor;
+ const QPointF screenPos = QPointF(winTouchInput.x, winTouchInput.y) / qreal(100.);
if (winTouchInput.dwMask & TOUCHINPUTMASKF_CONTACTAREA)
- touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) * screenPosFactor);
+ touchPoint.area.setSize(QSizeF(winTouchInput.cxContact, winTouchInput.cyContact) / qreal(100.));
touchPoint.area.moveCenter(screenPos);
QPointF normalPosition = QPointF(screenPos.x() / screenGeometry.width(),
screenPos.y() / screenGeometry.height());
diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h
index 6f9ce93ef0..80a1de1ea5 100644
--- a/src/plugins/platforms/windows/qwindowsnativeimage.h
+++ b/src/plugins/platforms/windows/qwindowsnativeimage.h
@@ -57,8 +57,6 @@ public:
HDC hdc() const { return m_hdc; }
- void setDevicePixelRatio(qreal scaleFactor) { m_image.setDevicePixelRatio(scaleFactor); }
-
static QImage::Format systemFormat();
private:
diff --git a/src/plugins/platforms/windows/qwindowsscaling.cpp b/src/plugins/platforms/windows/qwindowsscaling.cpp
deleted file mode 100644
index 6ab7f254fd..0000000000
--- a/src/plugins/platforms/windows/qwindowsscaling.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwindowsscaling.h"
-#include "qwindowsscreen.h"
-
-#include <QtCore/QDebug>
-#include <QtCore/QCoreApplication>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QWindowsScaling
- \brief Windows scaling utilities
-
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-int QWindowsScaling::m_factor = 1;
-
-static const char devicePixelRatioEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
-
-// Suggest a scale factor by checking monitor sizes.
-int QWindowsScaling::determineUiScaleFactor()
-{
- if (!qEnvironmentVariableIsSet(devicePixelRatioEnvVar))
- return 1;
- const QByteArray envDevicePixelRatioEnv = qgetenv(devicePixelRatioEnvVar);
- // Auto: Suggest a scale factor by checking monitor resolution.
- if (envDevicePixelRatioEnv == "auto") {
- const int maxResolution = QWindowsScreen::maxMonitorHorizResolution();
- return maxResolution > 180 ? maxResolution / 96 : 1;
- }
- // Get factor from environment
- bool ok = false;
- const int envFactor = envDevicePixelRatioEnv.toInt(&ok);
- return ok && envFactor > 0 ? envFactor : 1;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscaling.h b/src/plugins/platforms/windows/qwindowsscaling.h
deleted file mode 100644
index 39e554bbe2..0000000000
--- a/src/plugins/platforms/windows/qwindowsscaling.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWSSCALING_H
-#define QWINDOWSSCALING_H
-
-#include <QtGui/QRegion>
-#include <QtCore/QVector>
-#include <QtCore/QRect>
-
-QT_BEGIN_NAMESPACE
-
-enum
-#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_CC_MSVC)
- : int
-#endif
-{ QWINDOWSIZE_MAX = 16777215 };
-
-class QWindowsScaling {
-public:
- static bool isActive() { return m_factor > 1; }
- static int factor() { return m_factor; }
- static void setFactor(int factor) { m_factor = factor; }
- static int determineUiScaleFactor();
-
- // Scaling helpers for size constraints.
- static int mapToNativeConstrained(int qt)
- { return m_factor != 1 && qt > 0 && qt < QWINDOWSIZE_MAX ? qt * m_factor : qt; }
-
- static int mapFromNativeConstrained(int dp)
- { return m_factor != 1 && dp > 0 && dp < QWINDOWSIZE_MAX ? dp / m_factor : dp; }
-
- static QSize mapToNativeConstrained(const QSize &qt)
- { return QSize(mapToNativeConstrained(qt.width()), mapToNativeConstrained(qt.height())); }
-
- static QRect mapToNative(const QRect &qRect)
- {
- return QRect(qRect.x() * m_factor, qRect.y() * m_factor, qRect.width() * m_factor, qRect.height() * m_factor);
- }
-
- static QRect mapFromNative(const QRect &dp)
- {
- return isActive() ?
- QRect(dp.x() / m_factor, dp.y() / m_factor, (dp.width() + 1) / m_factor, (dp.height() + 1) / m_factor) :
- dp;
- }
-
- static QRegion mapToNative(const QRegion &regionQt)
- {
- if (!QWindowsScaling::isActive() || regionQt.isEmpty())
- return regionQt;
-
- QRegion result;
- foreach (const QRect &rectQt, regionQt.rects())
- result += QWindowsScaling::mapToNative(rectQt);
- return result;
- }
-
- static QRegion mapFromNative(const QRegion &regionDp)
- {
- if (!QWindowsScaling::isActive() || regionDp.isEmpty())
- return regionDp;
-
- QRegion result;
- foreach (const QRect &rectDp, regionDp.rects())
- result += QWindowsScaling::mapFromNative(rectDp);
- return result;
- }
-
-private:
- static int m_factor;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWSSCALING_H
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 7756c77001..7f3bb96503 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -43,6 +43,7 @@
#include <QtGui/QPixmap>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QScreen>
#include <QtCore/QDebug>
@@ -116,12 +117,14 @@ static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data)
HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL);
#endif
if (hdc) {
+ if (!QHighDpiScaling::isActive()) { // Assume 96 DPI to get fonts right when scaling.
#ifndef Q_OS_WINCE
- const QDpi dpi = monitorDPI(hMonitor);
- data->dpi = dpi.first ? dpi : deviceDPI(hdc);
+ const QDpi dpi = monitorDPI(hMonitor);
+ data->dpi = dpi.first ? dpi : deviceDPI(hdc);
#else
- data->dpi = deviceDPI(hdc);
+ data->dpi = deviceDPI(hdc);
#endif
+ }
data->depth = GetDeviceCaps(hdc, BITSPIXEL);
data->format = data->depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
data->physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
@@ -218,36 +221,14 @@ QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
{
}
-BOOL QT_WIN_CALLBACK monitorResolutionEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM p)
-{
- QWindowsScreenData data;
- if (monitorData(hMonitor, &data)) {
- int *maxHorizResolution = reinterpret_cast<int *>(p);
- const int horizResolution = qRound(data.dpi.first);
- if (horizResolution > *maxHorizResolution)
- *maxHorizResolution = horizResolution;
- }
- return TRUE;
-}
-
-int QWindowsScreen::maxMonitorHorizResolution()
-{
- int result = 0;
- EnumDisplayMonitors(0, 0, monitorResolutionEnumCallback, (LPARAM)&result);
- return result;
-}
-
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
-QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const
+QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
RECT r;
HWND hwnd = window ? (HWND)window : GetDesktopWindow();
GetClientRect(hwnd, &r);
- const int x = qX * QWindowsScaling::factor();
- const int y = qY * QWindowsScaling::factor();
- int width = qWidth * QWindowsScaling::factor();
- int height = qHeight * QWindowsScaling::factor();
+
if (width < 0) width = r.right - r.left;
if (height < 0) height = r.bottom - r.top;
@@ -271,10 +252,6 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q
DeleteObject(bitmap);
ReleaseDC(0, display_dc);
- if (QWindowsScaling::isActive()) {
- const qreal factor = 1.0 / qreal(QWindowsScaling::factor());
- return pixmap.transformed(QTransform::fromScale(factor, factor));
- }
return pixmap;
}
@@ -285,7 +262,7 @@ QPixmap QWindowsScreen::grabWindow(WId window, int qX, int qY, int qWidth, int q
QWindow *QWindowsScreen::topLevelAt(const QPoint &point) const
{
QWindow *result = 0;
- if (QWindow *child = QWindowsScreen::windowAt(point * QWindowsScaling::factor(), CWP_SKIPINVISIBLE))
+ if (QWindow *child = QWindowsScreen::windowAt(point, CWP_SKIPINVISIBLE))
result = QWindowsWindow::topLevelOf(child);
qCDebug(lcQpaWindows) <<__FUNCTION__ << point << result;
return result;
@@ -313,6 +290,12 @@ QWindowsScreen *QWindowsScreen::screenOf(const QWindow *w)
return 0;
}
+qreal QWindowsScreen::pixelDensity() const
+{
+ const qreal physicalDpi = m_data.geometry.width() / m_data.physicalSizeMM.width() * qreal(25.4);
+ return qRound(physicalDpi / 96);
+}
+
/*!
\brief Determine siblings in a virtual desktop system.
@@ -542,7 +525,7 @@ void QWindowsScreenManager::clearScreens()
const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
{
foreach (QWindowsScreen *scr, m_screens) {
- if (scr->geometryDp().contains(p))
+ if (scr->geometry().contains(p))
return scr;
}
return Q_NULLPTR;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 7352c45777..67e7ff644b 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -34,7 +34,6 @@
#ifndef QWINDOWSSCREEN_H
#define QWINDOWSSCREEN_H
-#include "qwindowsscaling.h"
#include "qtwindowsglobal.h"
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
@@ -82,16 +81,14 @@ public:
static QWindowsScreen *screenOf(const QWindow *w = 0);
- QRect geometryDp() const { return m_data.geometry; }
- QRect geometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(geometryDp()); }
- QRect availableGeometryDp() const { return m_data.availableGeometry; }
- QRect availableGeometry() const Q_DECL_OVERRIDE { return QWindowsScaling::mapFromNative(availableGeometryDp()); }
+ QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
+ QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; }
int depth() const Q_DECL_OVERRIDE { return m_data.depth; }
QImage::Format format() const Q_DECL_OVERRIDE { return m_data.format; }
QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_data.physicalSizeMM; }
- QDpi logicalDpi() const Q_DECL_OVERRIDE
- { return QDpi(m_data.dpi.first / QWindowsScaling::factor(), m_data.dpi.second / QWindowsScaling::factor()); }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE { return QWindowsScaling::factor(); }
+ QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_data.dpi; }
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
+ qreal devicePixelRatio() const Q_DECL_OVERRIDE { return 1.0; }
qreal refreshRate() const Q_DECL_OVERRIDE { return m_data.refreshRateHz; }
QString name() const Q_DECL_OVERRIDE { return m_data.name; }
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_data.orientation; }
@@ -112,7 +109,6 @@ public:
#endif // !QT_NO_CURSOR
const QWindowsScreenData &data() const { return m_data; }
- static int maxMonitorHorizResolution();
private:
QWindowsScreenData m_data;
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 7b871be015..05bddec530 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qwindowstabletsupport.h"
-#include "qwindowsscaling.h"
#ifndef QT_NO_TABLETEVENT
@@ -399,8 +398,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
// in which case we snap the position to the mouse position.
// It seems there is no way to find out the mode programmatically, the LOGCONTEXT orgX/Y/Ext
// area is always the virtual desktop.
- const QRect virtualDesktopArea
- = QWindowsScaling::mapToNative(QGuiApplication::primaryScreen()->virtualGeometry());
+ const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount
<< "target:" << QGuiApplicationPrivate::tabletPressTarget;
@@ -420,7 +418,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
QPoint globalPos = globalPosF.toPoint();
// Get Mouse Position and compare to tablet info
- QPoint mouseLocation = QWindowsCursor::mousePosition();
+ const QPoint mouseLocation = QWindowsCursor::mousePosition();
// Positions should be almost the same if we are in absolute
// mode. If they are not, use the mouse location.
@@ -475,9 +473,7 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
<< tiltY << "tanP:" << tangentialPressure << "rotation:" << rotation;
}
- const QPointF localPosDip = QPointF(localPos / QWindowsScaling::factor());
- const QPointF globalPosDip = globalPosF / qreal(QWindowsScaling::factor());
- QWindowSystemInterface::handleTabletEvent(target, localPosDip, globalPosDip,
+ QWindowSystemInterface::handleTabletEvent(target, QPointF(localPos), globalPosF,
currentDevice, currentPointer,
static_cast<Qt::MouseButtons>(packet.pkButtons),
pressureNew, tiltX, tiltY,
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index d3f67e9eaa..873052973e 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -43,7 +43,6 @@
#include "qwindowsintegration.h"
#include "qt_windows.h"
#include "qwindowsfontdatabase.h"
-#include "qwindowsscaling.h"
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
# include "winuser.h"
@@ -68,6 +67,7 @@
#include <QtGui/QPainter>
#include <QtGui/QPixmapCache>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
#include <private/qsystemlibrary_p.h>
#include <algorithm>
@@ -495,7 +495,8 @@ static QPixmap loadIconFromShell32(int resourceId, QSizeF size)
QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
{
- const int scaleFactor = QWindowsScaling::factor();
+ const QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ const int scaleFactor = primaryScreen ? qRound(QHighDpiScaling::factor(primaryScreen)) : 1;
const QSizeF pixmapSize = size * scaleFactor;
int resourceId = -1;
LPCTSTR iconName = 0;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 543c08135f..d6677bb228 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -36,7 +36,6 @@
#include "qwindowscontext.h"
#include "qwindowsdrag.h"
#include "qwindowsscreen.h"
-#include "qwindowsscaling.h"
#include "qwindowsintegration.h"
#include "qwindowsopenglcontext.h"
#ifdef QT_NO_CURSOR
@@ -49,8 +48,9 @@
#include <QtGui/QRegion>
#include <QtGui/QOpenGLContext>
#include <private/qsystemlibrary_p.h>
-#include <private/qwindow_p.h>
+#include <private/qwindow_p.h> // QWINDOWSIZE_MAX
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtCore/QDebug>
@@ -169,7 +169,7 @@ static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point)
const QWindowsScreen *screen = screenManager.screens().size() == 1
? screenManager.screens().first() : screenManager.screenAtDp(point);
if (screen)
- return screen->availableGeometryDp().topLeft() - screen->geometryDp().topLeft();
+ return screen->availableGeometry().topLeft() - screen->geometry().topLeft();
#else
Q_UNUSED(hwnd)
Q_UNUSED(point)
@@ -608,9 +608,7 @@ QWindowsWindowData
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
- const QRect geometryDip = QWindowsScaling::mapFromNative(data.geometry);
- QRect fixedGeometryDip = QPlatformWindow::initialGeometry(w, geometryDip, defaultWindowWidth, defaultWindowHeight);
- const QRect rect = fixedGeometryDip != geometryDip ? QWindowsScaling::mapToNative(fixedGeometryDip) : data.geometry;
+ const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry, defaultWindowWidth, defaultWindowHeight);
if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
title = topLevel ? qAppName() : w->objectName();
@@ -718,8 +716,8 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang
*/
QWindowsGeometryHint::QWindowsGeometryHint(const QWindow *w, const QMargins &cm) :
- minimumSize(QWindowsScaling::mapToNativeConstrained(w->minimumSize())),
- maximumSize(QWindowsScaling::mapToNativeConstrained(w->maximumSize())),
+ minimumSize(QHighDpi::toNativePixelsConstrained(w->minimumSize(), w)),
+ maximumSize(QHighDpi::toNativePixelsConstrained(w->maximumSize(), w)),
customMargins(cm)
{
}
@@ -953,8 +951,7 @@ void QWindowsWindow::fireExpose(const QRegion &region, bool force)
clearFlag(Exposed);
else
setFlag(Exposed);
- QWindowSystemInterface::handleExposeEvent(window(),
- QWindowsScaling::mapFromNative(region));
+ QWindowSystemInterface::handleExposeEvent(window(), region);
}
static inline QWindow *findTransientChild(const QWindow *parent)
@@ -1134,7 +1131,7 @@ bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const
return m_data.embedded;
}
-QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const
+QPoint QWindowsWindow::mapToGlobal(const QPoint &pos) const
{
if (m_data.hwnd)
return QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos);
@@ -1142,7 +1139,7 @@ QPoint QWindowsWindow::mapToGlobalDp(const QPoint &pos) const
return pos;
}
-QPoint QWindowsWindow::mapFromGlobalDp(const QPoint &pos) const
+QPoint QWindowsWindow::mapFromGlobal(const QPoint &pos) const
{
if (m_data.hwnd)
return QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos);
@@ -1323,22 +1320,22 @@ static QRect normalFrameGeometry(HWND hwnd)
return QRect();
}
-QRect QWindowsWindow::normalGeometryDp() const
+QRect QWindowsWindow::normalGeometry() const
{
// Check for fake 'fullscreen' mode.
const bool fakeFullScreen = m_savedFrameGeometry.isValid() && window()->windowState() == Qt::WindowFullScreen;
const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
- const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMarginsDp();
+ const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins();
return frame.isValid() ? frame.marginsRemoved(margins) : frame;
}
-void QWindowsWindow::setGeometryDp(const QRect &rectIn)
+void QWindowsWindow::setGeometry(const QRect &rectIn)
{
QRect rect = rectIn;
// This means it is a call from QWindow::setFramePosition() and
// the coordinates include the frame (size is still the contents rectangle).
if (QWindowsGeometryHint::positionIncludesFrame(window())) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
}
if (m_windowState == Qt::WindowMinimized)
@@ -1407,9 +1404,8 @@ void QWindowsWindow::handleGeometryChange()
return;
const QRect previousGeometry = m_data.geometry;
m_data.geometry = geometry_sys();
- const QRect geometryDip = QWindowsScaling::mapFromNative(m_data.geometry);
- QPlatformWindow::setGeometry(geometryDip);
- QWindowSystemInterface::handleGeometryChange(window(), geometryDip);
+ QPlatformWindow::setGeometry(m_data.geometry);
+ QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
// QTBUG-32121: OpenGL/normal windows (with exception of ANGLE) do not receive
// expose events when shrinking, synthesize.
if (!testFlag(OpenGL_ES2) && isExposed()
@@ -1417,7 +1413,7 @@ void QWindowsWindow::handleGeometryChange()
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
}
if (previousGeometry.topLeft() != m_data.geometry.topLeft()) {
- QPlatformScreen *newScreen = screenForGeometry(geometryDip);
+ QPlatformScreen *newScreen = screenForGeometry(m_data.geometry);
if (newScreen != screen())
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
@@ -1429,7 +1425,7 @@ void QWindowsWindow::handleGeometryChange()
void QWindowsWindow::setGeometry_sys(const QRect &rect) const
{
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
const QRect frameGeometry = rect + margins;
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window()
@@ -1468,7 +1464,7 @@ QRect QWindowsWindow::frameGeometry_sys() const
QRect QWindowsWindow::geometry_sys() const
{
- return frameGeometry_sys().marginsRemoved(frameMarginsDp());
+ return frameGeometry_sys().marginsRemoved(frameMargins());
}
/*!
@@ -1540,7 +1536,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
<< m_data.flags << "\n to: " << flags;
- const QRect oldGeometry = geometryDp();
+ const QRect oldGeometry = geometry();
if (m_data.flags != flags) {
m_data.flags = flags;
if (m_data.hwnd) {
@@ -1626,8 +1622,9 @@ void QWindowsWindow::setWindowState(Qt::WindowState state)
bool QWindowsWindow::isFullScreen_sys() const
{
- return window()->isTopLevel()
- && geometry_sys() == QWindowsScaling::mapToNative(window()->screen()->geometry());
+ const QWindow *w = window();
+ return w->isTopLevel()
+ && geometry_sys() == QHighDpi::toNativePixels(w->screen()->geometry(), w);
}
/*!
@@ -1697,15 +1694,14 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
// Use geometry of QWindow::screen() within creation or the virtual screen the
// window is in (QTBUG-31166, QTBUG-30724).
const QScreen *screen = window()->screen();
- const QRect rDip = screen->geometry();
- const QRect r = QWindowsScaling::mapToNative(rDip);
+ const QRect r = QHighDpi::toNativePixels(screen->geometry(), window());
const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
setFlag(SynchronousGeometryChangeEvent);
SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
if (!wasSync)
clearFlag(SynchronousGeometryChangeEvent);
- QWindowSystemInterface::handleGeometryChange(window(), rDip);
+ QWindowSystemInterface::handleGeometryChange(window(), r);
QWindowSystemInterface::flushWindowSystemEvents();
} else if (newState != Qt::WindowMinimized) {
// Restore saved state.
@@ -1804,7 +1800,7 @@ void QWindowsWindow::propagateSizeHints()
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
-bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp)
+bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &margins)
{
#ifndef Q_OS_WINCE
if (!qWindow->isTopLevel()) // Implement hasHeightForWidth().
@@ -1812,26 +1808,20 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam);
if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE)))
return false;
- const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y,
- windowPos->cx, windowPos->cy);
- const qreal factor = QWindowsScaling::factor();
- const QRect suggestedGeometryDp = suggestedFrameGeometryDp - marginsDp;
- const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor,
- QSizeF(suggestedGeometryDp.size()) / factor);
+ const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
+ windowPos->cx, windowPos->cy);
+ const QRect suggestedGeometry = suggestedFrameGeometry - margins;
const QRectF correctedGeometryF =
qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(suggestedGeometry);
if (!correctedGeometryF.isValid())
return false;
- const QRect correctedFrameGeometryDp
- = QRectF(correctedGeometryF.topLeft() * factor,
- correctedGeometryF.size() * factor).toRect()
- + marginsDp;
- if (correctedFrameGeometryDp == suggestedFrameGeometryDp)
+ const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
+ if (correctedFrameGeometry == suggestedFrameGeometry)
return false;
- windowPos->x = correctedFrameGeometryDp.left();
- windowPos->y = correctedFrameGeometryDp.top();
- windowPos->cx = correctedFrameGeometryDp.width();
- windowPos->cy = correctedFrameGeometryDp.height();
+ windowPos->x = correctedFrameGeometry.left();
+ windowPos->y = correctedFrameGeometry.top();
+ windowPos->cx = correctedFrameGeometry.width();
+ windowPos->cy = correctedFrameGeometry.height();
return true;
#else // !Q_OS_WINCE
Q_UNUSED(message)
@@ -1841,11 +1831,11 @@ bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *
bool QWindowsWindow::handleGeometryChanging(MSG *message) const
{
- const QMargins marginsDp = window()->isTopLevel() ? frameMarginsDp() : QMargins();
- return QWindowsWindow::handleGeometryChangingMessage(message, window(), marginsDp);
+ const QMargins margins = window()->isTopLevel() ? frameMargins() : QMargins();
+ return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
}
-QMargins QWindowsWindow::frameMarginsDp() const
+QMargins QWindowsWindow::frameMargins() const
{
// Frames are invalidated by style changes (window state, flags).
// As they are also required for geometry calculations in resize
@@ -1892,17 +1882,17 @@ static inline void addRectToWinRegion(const QRect &rect, HRGN *winRegion)
}
}
-static HRGN qRegionToWinRegion(const QRegion &regionDip)
+static HRGN qRegionToWinRegion(const QRegion &region)
{
- const QVector<QRect> rects = regionDip.rects();
+ const QVector<QRect> rects = region.rects();
if (rects.isEmpty())
return NULL;
const int rectCount = rects.size();
if (rectCount == 1)
- return createRectRegion(QWindowsScaling::mapToNative(regionDip.boundingRect()));
- HRGN hRegion = createRectRegion(QWindowsScaling::mapToNative(rects.front()));
+ return createRectRegion(region.boundingRect());
+ HRGN hRegion = createRectRegion(rects.front());
for (int i = 1; i < rectCount; ++i)
- addRectToWinRegion(QWindowsScaling::mapToNative(rects.at(i)), &hRegion);
+ addRectToWinRegion(rects.at(i), &hRegion);
return hRegion;
}
@@ -1916,7 +1906,7 @@ void QWindowsWindow::setMask(const QRegion &region)
// Mask is in client area coordinates, so offset it in case we have a frame
if (window()->isTopLevel()) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
OffsetRgn(winRegion, margins.left(), margins.top());
}
@@ -2053,23 +2043,23 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
|| (m_data.flags & Qt::FramelessWindowHint)) {
return false;
}
- const QSize minimumSize = QWindowsScaling::mapToNativeConstrained(w->minimumSize());
+ const QSize minimumSize = w->minimumSize();
if (minimumSize.isEmpty())
return false;
- const QSize maximumSize = QWindowsScaling::mapToNativeConstrained(w->maximumSize());
+ const QSize maximumSize = w->maximumSize();
const bool fixedWidth = minimumSize.width() == maximumSize.width();
const bool fixedHeight = minimumSize.height() == maximumSize.height();
if (!fixedWidth && !fixedHeight)
return false;
- const QPoint localPos = mapFromGlobalDp(globalPos);
- const QSize size = w->size() * QWindowsScaling::factor();
+ const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
+ const QSize size = w->size();
if (fixedHeight) {
if (localPos.y() >= size.height()) {
*result = HTBORDER; // Unspecified border, no resize cursor.
return true;
}
if (localPos.y() < 0) {
- const QMargins margins = frameMarginsDp();
+ const QMargins margins = frameMargins();
const int topResizeBarPos = margins.left() - margins.top();
if (localPos.y() < topResizeBarPos) {
*result = HTCAPTION; // Extend caption over top resize bar, let's user move the window.
@@ -2245,10 +2235,6 @@ void QWindowsWindow::setWindowIcon(const QIcon &icon)
The property can be set using QPlatformNativeInterface::setWindowProperty() or,
before platform window creation, by setting a dynamic property
on the QWindow (see QWindowsIntegration::createPlatformWindow()).
-
- Note: The function uses (unscaled) device pixels since the QWizard also
- uses AdjustWindowRect() and using device independent pixels would introduce
- rounding errors.
*/
void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index fff90b4b11..d96022e3a5 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -38,7 +38,6 @@
#ifdef Q_OS_WINCE
# include "qplatformfunctions_wince.h"
#endif
-#include "qwindowsscaling.h"
#include "qwindowscursor.h"
#include <qpa/qplatformwindow.h>
@@ -145,28 +144,18 @@ public:
~QWindowsWindow();
QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- void setGeometryDp(const QRect &rectIn);
- void setGeometry(const QRect &rect) Q_DECL_OVERRIDE
- { setGeometryDp(QWindowsScaling::mapToNative(rect)); }
- QRect geometryDp() const { return m_data.geometry; }
- QRect geometry() const Q_DECL_OVERRIDE
- { return QWindowsScaling::mapFromNative(geometryDp()); }
- QRect normalGeometryDp() const;
- QRect normalGeometry() const Q_DECL_OVERRIDE
- { return QWindowsScaling::mapFromNative(normalGeometryDp()); }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE
- { return qreal(QWindowsScaling::factor()); }
+ void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
+ QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
+ QRect normalGeometry() const Q_DECL_OVERRIDE;
+
void setVisible(bool visible) Q_DECL_OVERRIDE;
bool isVisible() const;
bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); }
bool isActive() const Q_DECL_OVERRIDE;
bool isEmbedded(const QPlatformWindow *parentWindow) const Q_DECL_OVERRIDE;
- QPoint mapToGlobalDp(const QPoint &pos) const;
- QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
- { return mapToGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
- QPoint mapFromGlobalDp(const QPoint &pos) const;
- QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE
- { return mapFromGlobalDp(pos * QWindowsScaling::factor()) / QWindowsScaling::factor(); }
+ QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+ QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+
void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE;
void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE;
@@ -184,8 +173,7 @@ public:
void propagateSizeHints() Q_DECL_OVERRIDE;
static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp);
bool handleGeometryChanging(MSG *message) const;
- QMargins frameMarginsDp() const;
- QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); }
+ QMargins frameMargins() const Q_DECL_OVERRIDE;
void setOpacity(qreal level) Q_DECL_OVERRIDE;
void setMask(const QRegion &region) Q_DECL_OVERRIDE;
@@ -196,7 +184,7 @@ public:
bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; }
- bool startSystemResize(const QPoint &, Qt::Corner corner) Q_DECL_OVERRIDE;
+ bool startSystemResize(const QPoint &pos, Qt::Corner corner) Q_DECL_OVERRIDE;
void setFrameStrutEventsEnabled(bool enabled);
bool frameStrutEventsEnabled() const { return testFlag(FrameStrutEventsEnabled); }
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index a0460630a7..665a1f954d 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -40,7 +40,6 @@ SOURCES += \
$$PWD/qwindowsservices.cpp \
$$PWD/qwindowsnativeimage.cpp \
$$PWD/qwindowsnativeinterface.cpp \
- $$PWD/qwindowsscaling.cpp \
$$PWD/qwindowsopengltester.cpp
HEADERS += \
@@ -67,7 +66,6 @@ HEADERS += \
$$PWD/qplatformfunctions_wince.h \
$$PWD/qwindowsnativeimage.h \
$$PWD/qwindowsnativeinterface.h \
- $$PWD/qwindowsscaling.h \
$$PWD/qwindowsopengltester.h
INCLUDEPATH += $$PWD
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index c0f5477f82..e62d515b62 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -49,6 +49,7 @@
#include <qdebug.h>
#include <qpainter.h>
#include <qscreen.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <qpa/qplatformgraphicsbuffer.h>
#include <algorithm>
@@ -313,14 +314,7 @@ void QXcbBackingStore::beginPaint(const QRegion &region)
if (!m_image)
return;
- int dpr = int(m_image->image()->devicePixelRatio());
- const int windowDpr = int(window()->devicePixelRatio());
- if (windowDpr != dpr) {
- resize(window()->size(), QRegion());
- dpr = int(m_image->image()->devicePixelRatio());
- }
-
- m_paintRegion = dpr == 1 ? region : QTransform::fromScale(dpr,dpr).map(region);
+ m_paintRegion = region;
m_image->preparePaint(m_paintRegion);
if (m_image->image()->hasAlphaChannel()) {
@@ -369,18 +363,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
if (!m_image || m_image->size().isEmpty())
return;
- const int dpr = int(window->devicePixelRatio());
-
-#ifndef QT_NO_DEBUG
- const int imageDpr = int(m_image->image()->devicePixelRatio());
- if (dpr != imageDpr)
- qWarning() << "QXcbBackingStore::flush() wrong devicePixelRatio for backingstore image" << dpr << imageDpr;
-#endif
-
- QSize imageSize = m_image->size() / dpr; //because we multiply with the DPR later
+ QSize imageSize = m_image->size();
QRegion clipped = region;
- clipped &= QRect(0, 0, window->width(), window->height());
+ clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window));
clipped &= QRect(0, 0, imageSize.width(), imageSize.height()).translated(-offset);
QRect bounds = clipped.boundingRect();
@@ -398,8 +384,8 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
QVector<QRect> rects = clipped.rects();
for (int i = 0; i < rects.size(); ++i) {
- QRect rect = QRect(rects.at(i).topLeft() * dpr, rects.at(i).size() * dpr);
- m_image->put(platformWindow->xcb_window(), rect.topLeft(), rect.translated(offset * dpr));
+ QRect rect = QRect(rects.at(i).topLeft(), rects.at(i).size());
+ m_image->put(platformWindow->xcb_window(), rect.topLeft(), rect.translated(offset));
}
Q_XCB_NOOP(connection());
@@ -430,9 +416,7 @@ void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion &region, c
void QXcbBackingStore::resize(const QSize &size, const QRegion &)
{
- const int dpr = int(window()->devicePixelRatio());
- const QSize xSize = size * dpr;
- if (m_image && xSize == m_image->size() && dpr == m_image->image()->devicePixelRatio())
+ if (m_image && size == m_image->size())
return;
Q_XCB_NOOP(connection());
@@ -445,13 +429,11 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &)
QXcbWindow* win = static_cast<QXcbWindow *>(pw);
delete m_image;
- m_image = new QXcbShmImage(screen, xSize, win->depth(), win->imageFormat());
- m_image->image()->setDevicePixelRatio(dpr);
+ m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat());
// Slow path for bgr888 VNC: Create an additional image, paint into that and
// swap R and B while copying to m_image after each paint.
if (win->imageNeedsRgbSwap()) {
- m_rgbImage = QImage(xSize, win->imageFormat());
- m_rgbImage.setDevicePixelRatio(dpr);
+ m_rgbImage = QImage(size, win->imageFormat());
}
Q_XCB_NOOP(connection());
}
@@ -463,14 +445,12 @@ bool QXcbBackingStore::scroll(const QRegion &area, int dx, int dy)
if (!m_image || m_image->image()->isNull())
return false;
- const int dpr = int(m_image->image()->devicePixelRatio());
- QRegion xArea = dpr == 1 ? area : QTransform::fromScale(dpr,dpr).map(area);
m_image->preparePaint(area);
- QPoint delta(dx * dpr, dy * dpr);
- const QVector<QRect> xRects = xArea.rects();
- for (int i = 0; i < xRects.size(); ++i)
- qt_scrollRectInImage(*m_image->image(), xRects.at(i), delta);
+ QPoint delta(dx, dy);
+ const QVector<QRect> rects = area.rects();
+ for (int i = 0; i < rects.size(); ++i)
+ qt_scrollRectInImage(*m_image->image(), rects.at(i), delta);
return true;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index c7784ddb48..e165c753ab 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -870,9 +870,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
}
}
if (!angleDelta.isNull()) {
- const int dpr = int(platformWindow->devicePixelRatio());
- QPoint local(fixed1616ToReal(xiDeviceEvent->event_x)/dpr, fixed1616ToReal(xiDeviceEvent->event_y)/dpr);
- QPoint global(fixed1616ToReal(xiDeviceEvent->root_x)/dpr, fixed1616ToReal(xiDeviceEvent->root_y)/dpr);
+ QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
+ QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
if (modifiers & Qt::AltModifier) {
std::swap(angleDelta.rx(), angleDelta.ry());
@@ -898,9 +897,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin
angleDelta.setX(-120);
}
if (!angleDelta.isNull()) {
- const int dpr = int(platformWindow->devicePixelRatio());
- QPoint local(fixed1616ToReal(xiDeviceEvent->event_x)/dpr, fixed1616ToReal(xiDeviceEvent->event_y)/dpr);
- QPoint global(fixed1616ToReal(xiDeviceEvent->root_x)/dpr, fixed1616ToReal(xiDeviceEvent->root_y)/dpr);
+ QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
+ QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
if (modifiers & Qt::AltModifier)
std::swap(angleDelta.rx(), angleDelta.ry());
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index e51ab85e30..d8389bff7a 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -635,15 +635,14 @@ QPoint QXcbCursor::pos() const
{
QPoint p;
queryPointer(connection(), 0, &p);
- return m_screen->mapFromNative(p);
+ return p;
}
void QXcbCursor::setPos(const QPoint &pos)
{
- const QPoint xPos = m_screen->mapToNative(pos);
xcb_window_t root = 0;
queryPointer(connection(), &root, 0);
- xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, xPos.x(), xPos.y());
+ xcb_warp_pointer(xcb_connection(), XCB_NONE, root, 0, 0, 0, 0, pos.x(), pos.y());
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 1d13adf851..8d4878e12e 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -71,12 +71,16 @@ QT_BEGIN_NAMESPACE
const int xdnd_version = 5;
+static inline xcb_window_t xcb_window(QPlatformWindow *w)
+{
+ return static_cast<QXcbWindow *>(w)->xcb_window();
+}
+
static inline xcb_window_t xcb_window(QWindow *w)
{
return static_cast<QXcbWindow *>(w->handle())->xcb_window();
}
-
static xcb_window_t xdndProxy(QXcbConnection *c, xcb_window_t w)
{
xcb_window_t proxy = XCB_NONE;
@@ -297,15 +301,9 @@ xcb_window_t QXcbDrag::findRealWindow(const QPoint & pos, xcb_window_t w, int md
return 0;
}
-void QXcbDrag::move(const QMouseEvent *me)
+void QXcbDrag::move(const QPoint &globalPos)
{
- // The mouse event is in the coordinate system of the window that started the drag.
- // We do not know which window that was at this point, so we just use the device pixel ratio
- // of the QGuiApplication. This will break once we support screens with different DPR. Fixing
- // this properly requires some redesign of the drag and drop architecture.
- static const int dpr = int(qApp->devicePixelRatio());
- QBasicDrag::move(me);
- QPoint globalPos = me->globalPos();
+ QBasicDrag::move(globalPos);
if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid())
return;
@@ -340,7 +338,7 @@ void QXcbDrag::move(const QMouseEvent *me)
// qt_xdnd_current_screen = screen;
xcb_window_t rootwin = current_screen->root();
xcb_translate_coordinates_reply_t *translate =
- ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x() * dpr, globalPos.y() * dpr);
+ ::translateCoordinates(connection(), rootwin, rootwin, globalPos.x(), globalPos.y());
if (!translate)
return;
@@ -443,7 +441,7 @@ void QXcbDrag::move(const QMouseEvent *me)
DEBUG() << "sending Xdnd enter source=" << enter.data.data32[0];
if (w)
- handleEnter(w->window(), &enter);
+ handleEnter(w, &enter);
else if (target)
xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&enter);
waiting_for_status = false;
@@ -463,7 +461,7 @@ void QXcbDrag::move(const QMouseEvent *me)
move.type = atom(QXcbAtom::XdndPosition);
move.data.data32[0] = connection()->clipboard()->owner();
move.data.data32[1] = 0; // flags
- move.data.data32[2] = (globalPos.x() * dpr << 16) + globalPos.y() * dpr;
+ move.data.data32[2] = (globalPos.x() << 16) + globalPos.y();
move.data.data32[3] = connection()->time();
move.data.data32[4] = toXdndAction(defaultAction(currentDrag()->supportedActions(), QGuiApplication::keyboardModifiers()));
DEBUG() << "sending Xdnd position source=" << move.data.data32[0] << "target=" << move.window;
@@ -471,15 +469,15 @@ void QXcbDrag::move(const QMouseEvent *me)
source_time = connection()->time();
if (w)
- handle_xdnd_position(w->window(), &move);
+ handle_xdnd_position(w, &move);
else
xcb_send_event(xcb_connection(), false, proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&move);
}
}
-void QXcbDrag::drop(const QMouseEvent *event)
+void QXcbDrag::drop(const QPoint &globalPos)
{
- QBasicDrag::drop(event);
+ QBasicDrag::drop(globalPos);
if (!current_target)
return;
@@ -505,7 +503,7 @@ void QXcbDrag::drop(const QMouseEvent *event)
connection()->time(),
current_target,
current_proxy_target,
- (w ? w->window() : 0),
+ w,
// current_embeddig_widget,
currentDrag(),
QTime::currentTime()
@@ -518,7 +516,7 @@ void QXcbDrag::drop(const QMouseEvent *event)
}
if (w) {
- handleDrop(w->window(), &drop);
+ handleDrop(w, &drop);
} else {
xcb_send_event(xcb_connection(), false, current_proxy_target, XCB_EVENT_MASK_NO_EVENT, (const char *)&drop);
}
@@ -664,7 +662,7 @@ static bool checkEmbedded(QWidget* w, const XEvent* xe)
#endif
-void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *event)
+void QXcbDrag::handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event)
{
Q_UNUSED(window);
DEBUG() << "handleEnter" << window;
@@ -704,17 +702,14 @@ void QXcbDrag::handleEnter(QWindow *window, const xcb_client_message_event_t *ev
DEBUG() << " " << connection()->atomName(xdnd_types.at(i));
}
-void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *e)
+void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *e)
{
QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff);
Q_ASSERT(w);
QRect geometry = w->geometry();
- const int dpr = int(w->handle()->devicePixelRatio());
-
- p /= dpr;
p -= geometry.topLeft();
- if (!w || (w->type() == Qt::Desktop))
+ if (!w || !w->window() || (w->window()->type() == Qt::Desktop))
return;
if (e->data.data32[0] != xdnd_dragsource) {
@@ -723,7 +718,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
}
currentPosition = p;
- currentWindow = w;
+ currentWindow = w->window();
// timestamp from the source
if (e->data.data32[3] != XCB_NONE) {
@@ -740,7 +735,7 @@ void QXcbDrag::handle_xdnd_position(QWindow *w, const xcb_client_message_event_t
supported_actions = Qt::DropActions(toDropAction(e->data.data32[4]));
}
- QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w,dropData,p,supported_actions);
+ QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(w->window(),dropData,p,supported_actions);
QRect answerRect(p + geometry.topLeft(), QSize(1,1));
answerRect = qt_response.answerRect().translated(geometry.topLeft()).intersected(geometry);
@@ -796,7 +791,7 @@ namespace
};
}
-void QXcbDrag::handlePosition(QWindow * w, const xcb_client_message_event_t *event)
+void QXcbDrag::handlePosition(QPlatformWindow * w, const xcb_client_message_event_t *event)
{
xcb_client_message_event_t *lastEvent = const_cast<xcb_client_message_event_t *>(event);
xcb_generic_event_t *nextEvent;
@@ -830,12 +825,10 @@ void QXcbDrag::handle_xdnd_status(const xcb_client_message_event_t *event)
updateCursor(Qt::IgnoreAction);
}
- static const int dpr = int(qApp->devicePixelRatio());
-
if ((event->data.data32[1] & 2) == 0) {
QPoint p((event->data.data32[2] & 0xffff0000) >> 16, event->data.data32[2] & 0x0000ffff);
QSize s((event->data.data32[3] & 0xffff0000) >> 16, event->data.data32[3] & 0x0000ffff);
- source_sameanswer = QRect(p / dpr, s / dpr);
+ source_sameanswer = QRect(p, s);
} else {
source_sameanswer = QRect();
}
@@ -861,10 +854,10 @@ void QXcbDrag::handleStatus(const xcb_client_message_event_t *event)
DEBUG("xdndHandleStatus end");
}
-void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event)
+void QXcbDrag::handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event)
{
DEBUG("xdnd leave");
- if (!currentWindow || w != currentWindow.data())
+ if (!currentWindow || w != currentWindow.data()->handle())
return; // sanity
// ###
@@ -879,7 +872,7 @@ void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event)
DEBUG("xdnd drag leave from unexpected source (%x not %x", event->data.data32[0], xdnd_dragsource);
}
- QWindowSystemInterface::handleDrag(w,0,QPoint(),Qt::IgnoreAction);
+ QWindowSystemInterface::handleDrag(w->window(),0,QPoint(),Qt::IgnoreAction);
xdnd_dragsource = 0;
xdnd_types.clear();
@@ -909,7 +902,7 @@ void QXcbDrag::send_leave()
w = 0;
if (w)
- handleLeave(w->window(), (const xcb_client_message_event_t *)&leave);
+ handleLeave(w, (const xcb_client_message_event_t *)&leave);
else
xcb_send_event(xcb_connection(), false,current_proxy_target,
XCB_EVENT_MASK_NO_EVENT, (const char *)&leave);
@@ -920,7 +913,7 @@ void QXcbDrag::send_leave()
waiting_for_status = false;
}
-void QXcbDrag::handleDrop(QWindow *, const xcb_client_message_event_t *event)
+void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event)
{
DEBUG("xdndHandleDrop");
if (!currentWindow) {
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 95da76b732..699d402ea6 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -53,8 +53,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DRAGANDDROP
-class QMouseEvent;
class QWindow;
+class QPlatformWindow;
class QXcbConnection;
class QXcbWindow;
class QXcbDropData;
@@ -72,14 +72,14 @@ public:
void startDrag() Q_DECL_OVERRIDE;
void cancel() Q_DECL_OVERRIDE;
- void move(const QMouseEvent *me) Q_DECL_OVERRIDE;
- void drop(const QMouseEvent *me) Q_DECL_OVERRIDE;
+ void move(const QPoint &globalPos) Q_DECL_OVERRIDE;
+ void drop(const QPoint &globalPos) Q_DECL_OVERRIDE;
void endDrag() Q_DECL_OVERRIDE;
- void handleEnter(QWindow *window, const xcb_client_message_event_t *event);
- void handlePosition(QWindow *w, const xcb_client_message_event_t *event);
- void handleLeave(QWindow *w, const xcb_client_message_event_t *event);
- void handleDrop(QWindow *, const xcb_client_message_event_t *event);
+ void handleEnter(QPlatformWindow *window, const xcb_client_message_event_t *event);
+ void handlePosition(QPlatformWindow *w, const xcb_client_message_event_t *event);
+ void handleLeave(QPlatformWindow *w, const xcb_client_message_event_t *event);
+ void handleDrop(QPlatformWindow *, const xcb_client_message_event_t *event);
void handleStatus(const xcb_client_message_event_t *event);
void handleSelectionRequest(const xcb_selection_request_event_t *event);
@@ -99,7 +99,7 @@ private:
void init();
- void handle_xdnd_position(QWindow *w, const xcb_client_message_event_t *event);
+ void handle_xdnd_position(QPlatformWindow *w, const xcb_client_message_event_t *event);
void handle_xdnd_status(const xcb_client_message_event_t *event);
void send_leave();
@@ -146,7 +146,7 @@ private:
xcb_timestamp_t timestamp;
xcb_window_t target;
xcb_window_t proxy_target;
- QWindow *targetWindow;
+ QPlatformWindow *targetWindow;
// QWidget *embedding_widget;
QPointer<QDrag> drag;
QTime time;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index c14ec0bb3f..de1aeb2797 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -44,6 +44,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <private/qmath_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -86,7 +87,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_orientation(Qt::PrimaryOrientation)
, m_refreshRate(60)
, m_forcedDpi(-1)
- , m_devicePixelRatio(1)
+ , m_pixelDensity(1)
, m_hintStyle(QFontEngine::HintStyle(-1))
, m_noFontHinting(false)
, m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1))
@@ -107,9 +108,8 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
updateGeometry(output ? output->timestamp : 0);
}
- const int dpr = int(devicePixelRatio());
if (m_geometry.isEmpty()) {
- m_geometry = QRect(QPoint(), m_virtualSize/dpr);
+ m_geometry = QRect(QPoint(), m_virtualSize);
m_nativeGeometry = QRect(QPoint(), m_virtualSize);
}
if (m_availableGeometry.isEmpty())
@@ -117,12 +117,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
readXResources();
- // disable font hinting when we do UI scaling
- static bool dpr_scaling_enabled = (qgetenv("QT_DEVICE_PIXEL_RATIO").toInt() > 1
- || qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto");
- if (dpr_scaling_enabled)
- m_noFontHinting = true;
-
QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs(
xcb_get_window_attributes_reply(xcb_connection(),
xcb_get_window_attributes_unchecked(xcb_connection(), screen()->root), NULL));
@@ -233,9 +227,8 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
{
xcb_window_t root = screen()->root;
- int dpr = int(devicePixelRatio());
- int x = p.x() / dpr;
- int y = p.y() / dpr;
+ int x = p.x();
+ int y = p.y();
xcb_window_t parent = root;
xcb_window_t child = root;
@@ -269,31 +262,6 @@ QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
return 0;
}
-
-QPoint QXcbScreen::mapToNative(const QPoint &pos) const
-{
- const int dpr = int(devicePixelRatio());
- return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft();
-}
-
-QPoint QXcbScreen::mapFromNative(const QPoint &pos) const
-{
- const int dpr = int(devicePixelRatio());
- return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft();
-}
-
-QRect QXcbScreen::mapToNative(const QRect &rect) const
-{
- const int dpr = int(devicePixelRatio());
- return QRect(mapToNative(rect.topLeft()), rect.size() * dpr);
-}
-
-QRect QXcbScreen::mapFromNative(const QRect &rect) const
-{
- const int dpr = int(devicePixelRatio());
- return QRect(mapFromNative(rect.topLeft()), rect.size() / dpr);
-}
-
void QXcbScreen::windowShown(QXcbWindow *window)
{
// Freedesktop.org Startup Notification
@@ -355,6 +323,7 @@ QDpi QXcbScreen::virtualDpi() const
Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
}
+
QDpi QXcbScreen::logicalDpi() const
{
static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
@@ -362,22 +331,14 @@ QDpi QXcbScreen::logicalDpi() const
return QDpi(overrideDpi, overrideDpi);
if (m_forcedDpi > 0) {
- int primaryDpr = int(connection()->screens().at(0)->devicePixelRatio());
- return QDpi(m_forcedDpi/primaryDpr, m_forcedDpi/primaryDpr);
+ return QDpi(m_forcedDpi, m_forcedDpi);
}
return virtualDpi();
}
-
-qreal QXcbScreen::devicePixelRatio() const
+qreal QXcbScreen::pixelDensity() const
{
- static int override_dpr = qEnvironmentVariableIntValue("QT_DEVICE_PIXEL_RATIO");
- static bool auto_dpr = qgetenv("QT_DEVICE_PIXEL_RATIO").toLower() == "auto";
- if (override_dpr > 0)
- return override_dpr;
- if (auto_dpr)
- return m_devicePixelRatio;
- return 1.0;
+ return m_pixelDensity;
}
QPlatformCursor *QXcbScreen::cursor() const
@@ -536,11 +497,10 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation)
free(workArea);
qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4);
- m_devicePixelRatio = qRound(dpi/96);
- const int dpr = int(devicePixelRatio()); // we may override m_devicePixelRatio
- m_geometry = QRect(xGeometry.topLeft(), xGeometry.size()/dpr);
+ m_pixelDensity = qRound(dpi/96);
+ m_geometry = QRect(xGeometry.topLeft(), xGeometry.size());
m_nativeGeometry = QRect(xGeometry.topLeft(), xGeometry.size());
- m_availableGeometry = QRect(mapFromNative(xAvailableGeometry.topLeft()), xAvailableGeometry.size()/dpr);
+ m_availableGeometry = QRect(xAvailableGeometry.topLeft(), xAvailableGeometry.size());
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index ec05e3bb25..e31436d9d0 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -96,7 +96,7 @@ public:
QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; }
QDpi virtualDpi() const;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
- qreal devicePixelRatio() const Q_DECL_OVERRIDE;
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
qreal refreshRate() const Q_DECL_OVERRIDE { return m_refreshRate; }
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_orientation; }
@@ -141,11 +141,6 @@ public:
QXcbXSettings *xSettings() const;
- QPoint mapToNative(const QPoint &pos) const;
- QPoint mapFromNative(const QPoint &pos) const;
- QRect mapToNative(const QRect &rect) const;
- QRect mapFromNative(const QRect &rect) const;
-
private:
static bool xResource(const QByteArray &identifier,
const QByteArray &expectedIdentifier,
@@ -177,7 +172,7 @@ private:
QXcbCursor *m_cursor;
int m_refreshRate;
int m_forcedDpi;
- int m_devicePixelRatio;
+ int m_pixelDensity;
QFontEngine::HintStyle m_hintStyle;
bool m_noFontHinting;
QFontEngine::SubpixelAntialiasingType m_subpixelType;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index d2da137591..3bc0df6f57 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -37,6 +37,7 @@
#include <QScreen>
#include <QtGui/QIcon>
#include <QtGui/QRegion>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include "qxcbintegration.h"
#include "qxcbconnection.h"
@@ -140,73 +141,11 @@ enum QX11EmbedMessageType {
const quint32 XEMBED_VERSION = 0;
-static inline QRect mapLocalGeometryToNative(const QRect &qtRect, int dpr)
-{
- return QRect(qtRect.x() * dpr, qtRect.y() * dpr, qtRect.width() * dpr, qtRect.height() * dpr);
-}
-
-// When mapping expose events to Qt rects: round top/left towards the origin and
-// bottom/right away from the origin, making sure that we cover the whole widget
-
-static inline QPoint dpr_floor(const QPoint &p, int dpr)
-{
- return QPoint(p.x()/dpr, p.y()/dpr);
-}
-
-static inline QPoint dpr_ceil(const QPoint &p, int dpr)
-{
- return QPoint((p.x() + dpr - 1) / dpr, (p.y() + dpr - 1) / dpr);
-}
-
-static inline QSize dpr_ceil(const QSize &s, int dpr)
-{
- return QSize((s.width() + dpr - 1) / dpr, (s.height() + dpr - 1) / dpr);
-}
-
-static inline QRect mapExposeFromNative(const QRect &xRect, int dpr)
-{
- return QRect(dpr_floor(xRect.topLeft(), dpr), dpr_ceil(xRect.bottomRight(), dpr));
-}
-
-static inline QRect mapLocalGeometryFromNative(const QRect &xRect, int dpr)
-{
- return QRect(xRect.topLeft() / dpr, dpr_ceil(xRect.size(), dpr));
-}
-
QXcbScreen *QXcbWindow::parentScreen()
{
return parent() ? static_cast<QXcbWindow*>(parent())->parentScreen() : m_xcbScreen;
}
-QPoint QXcbWindow::mapToNative(const QPoint &pos, const QXcbScreen *screen) const
-{
- if (parent())
- return pos * int(screen->devicePixelRatio());
- else
- return screen->mapToNative(pos);
-}
-QPoint QXcbWindow::mapFromNative(const QPoint &pos, const QXcbScreen *screen) const
-{
- if (parent())
- return pos / int(screen->devicePixelRatio());
- else
- return screen->mapFromNative(pos);
-}
-QRect QXcbWindow::mapToNative(const QRect &rect, const QXcbScreen *screen) const
-{
- if (parent())
- return mapLocalGeometryToNative(rect, int(screen->devicePixelRatio()));
- else
- return screen->mapToNative(rect);
-}
-QRect QXcbWindow::mapFromNative(const QRect &rect, const QXcbScreen *screen) const
-{
- if (parent())
- return mapLocalGeometryFromNative(rect, int(screen->devicePixelRatio()));
- else
- return screen->mapFromNative(rect);
-}
-
// Returns \c true if we should set WM_TRANSIENT_FOR on \a w
static inline bool isTransient(const QWindow *w)
{
@@ -382,7 +321,7 @@ void QXcbWindow::create()
Qt::WindowType type = window()->type();
QXcbScreen *currentScreen = xcbScreen();
- QRect rect = window()->geometry();
+ QRect rect = windowGeometry();
QXcbScreen *platformScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
m_xcbScreen = platformScreen;
@@ -420,22 +359,19 @@ void QXcbWindow::create()
// Parameters to XCreateWindow() are frame corner + inner size.
// This fits in case position policy is frame inclusive. There is
// currently no way to implement it for frame-exclusive geometries.
- QPlatformWindow::setGeometry(rect);
if (platformScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
- const int dpr = int(devicePixelRatio());
-
- QSize minimumSize = window()->minimumSize();
+ const QSize minimumSize = windowMinimumSize();
if (rect.width() > 0 || rect.height() > 0) {
- rect.setWidth(qBound(1, rect.width(), XCOORD_MAX/dpr));
- rect.setHeight(qBound(1, rect.height(), XCOORD_MAX/dpr));
+ rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
+ rect.setHeight(qBound(1, rect.height(), XCOORD_MAX));
} else if (minimumSize.width() > 0 || minimumSize.height() > 0) {
rect.setSize(minimumSize);
} else {
- rect.setWidth(defaultWindowWidth);
- rect.setHeight(defaultWindowHeight);
+ rect.setWidth(QHighDpi::toNativePixels(int(defaultWindowWidth), platformScreen->QPlatformScreen::screen()));
+ rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen()));
}
xcb_window_t xcb_parent_id = platformScreen->root();
@@ -479,9 +415,7 @@ void QXcbWindow::create()
m_visualId = visualInfo->visualid;
- const QRect xRect = mapToNative(rect, platformScreen);
-
- m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, xRect.x(), xRect.y(), xRect.width(), xRect.height(),
+ m_window = XCreateWindow(DISPLAY_FROM_XCB(this), xcb_parent_id, rect.x(), rect.y(), rect.width(), rect.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWBackPixel|CWBorderPixel|CWColormap, &a);
@@ -537,16 +471,14 @@ void QXcbWindow::create()
}
m_imageFormat = imageFormatForVisual(m_depth, visual->red_mask, visual->blue_mask, &m_imageRgbSwap);
- const QRect xRect = mapToNative(rect, platformScreen);
-
Q_XCB_CALL(xcb_create_window(xcb_connection(),
m_depth,
m_window, // window id
xcb_parent_id, // parent window id
- xRect.x(),
- xRect.y(),
- xRect.width(),
- xRect.height(),
+ rect.x(),
+ rect.y(),
+ rect.width(),
+ rect.height(),
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
m_visualId, // visual
@@ -709,15 +641,14 @@ void QXcbWindow::setGeometry(const QRect &rect)
propagateSizeHints();
- QXcbScreen *currentScreen = xcbScreen();
+ QXcbScreen *currentScreen = m_xcbScreen;
QXcbScreen *newScreen = parent() ? parentScreen() : static_cast<QXcbScreen*>(screenForGeometry(rect));
if (!newScreen)
- newScreen = currentScreen;
+ newScreen = xcbScreen();
m_xcbScreen = newScreen;
- const QRect xRect = mapToNative(rect, newScreen);
- const QRect wmGeometry = windowToWmGeometry(xRect);
+ const QRect wmGeometry = windowToWmGeometry(rect);
if (newScreen != currentScreen)
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
@@ -1348,7 +1279,7 @@ void QXcbWindow::updateMotifWmHintsBeforeMap()
mwmhints.flags &= ~MWM_HINTS_INPUT_MODE;
}
- if (window()->minimumSize() == window()->maximumSize()) {
+ if (windowMinimumSize() == windowMaximumSize()) {
// fixed size, remove the resize handle (since mwm/dtwm
// isn't smart enough to do it itself)
mwmhints.flags |= MWM_HINTS_FUNCTIONS;
@@ -1634,8 +1565,7 @@ void QXcbWindow::propagateSizeHints()
xcb_size_hints_t hints;
memset(&hints, 0, sizeof(hints));
- const int dpr = int(devicePixelRatio());
- const QRect xRect = windowToWmGeometry(mapToNative(geometry(), xcbScreen()));
+ const QRect xRect = windowToWmGeometry(geometry());
QWindow *win = window();
@@ -1645,10 +1575,10 @@ void QXcbWindow::propagateSizeHints()
xcb_size_hints_set_size(&hints, true, xRect.width(), xRect.height());
xcb_size_hints_set_win_gravity(&hints, m_gravity);
- QSize minimumSize = win->minimumSize() * dpr;
- QSize maximumSize = win->maximumSize() * dpr;
- QSize baseSize = win->baseSize() * dpr;
- QSize sizeIncrement = win->sizeIncrement() * dpr;
+ QSize minimumSize = windowMinimumSize();
+ QSize maximumSize = windowMaximumSize();
+ QSize baseSize = windowBaseSize();
+ QSize sizeIncrement = windowSizeIncrement();
if (minimumSize.width() > 0 || minimumSize.height() > 0)
xcb_size_hints_set_min_size(&hints,
@@ -1896,10 +1826,9 @@ QRect QXcbWindow::systemTrayWindowGlobalGeometry() const
class ExposeCompressor
{
public:
- ExposeCompressor(xcb_window_t window, QRegion *region, int devicePixelRatio)
+ ExposeCompressor(xcb_window_t window, QRegion *region)
: m_window(window)
, m_region(region)
- , m_dpr(devicePixelRatio)
, m_pending(true)
{
}
@@ -1915,7 +1844,7 @@ public:
return false;
if (expose->count == 0)
m_pending = false;
- *m_region |= mapExposeFromNative(QRect(expose->x, expose->y, expose->width, expose->height), m_dpr);
+ *m_region |= QRect(expose->x, expose->y, expose->width, expose->height);
return true;
}
@@ -1927,7 +1856,6 @@ public:
private:
xcb_window_t m_window;
QRegion *m_region;
- int m_dpr;
bool m_pending;
};
@@ -1941,16 +1869,14 @@ bool QXcbWindow::handleGenericEvent(xcb_generic_event_t *event, long *result)
void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event)
{
- const int dpr = int(devicePixelRatio());
- QRect x_rect(event->x, event->y, event->width, event->height);
- QRect rect = mapExposeFromNative(x_rect, dpr);
+ QRect rect(event->x, event->y, event->width, event->height);
if (m_exposeRegion.isEmpty())
m_exposeRegion = rect;
else
m_exposeRegion |= rect;
- ExposeCompressor compressor(m_window, &m_exposeRegion, dpr);
+ ExposeCompressor compressor(m_window, &m_exposeRegion);
xcb_generic_event_t *filter = 0;
do {
filter = connection()->checkEvent(compressor);
@@ -2002,13 +1928,13 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
}
#ifndef QT_NO_DRAGANDDROP
} else if (event->type == atom(QXcbAtom::XdndEnter)) {
- connection()->drag()->handleEnter(window(), event);
+ connection()->drag()->handleEnter(this, event);
} else if (event->type == atom(QXcbAtom::XdndPosition)) {
- connection()->drag()->handlePosition(window(), event);
+ connection()->drag()->handlePosition(this, event);
} else if (event->type == atom(QXcbAtom::XdndLeave)) {
- connection()->drag()->handleLeave(window(), event);
+ connection()->drag()->handleLeave(this, event);
} else if (event->type == atom(QXcbAtom::XdndDrop)) {
- connection()->drag()->handleDrop(window(), event);
+ connection()->drag()->handleDrop(this, event);
#endif
} else if (event->type == atom(QXcbAtom::_XEMBED)) {
handleXEmbedMessage(event);
@@ -2028,26 +1954,6 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
}
}
-// Temporary workaround for bug in QPlatformScreen::screenForGeometry
-// we need the native geometries to detect our screen, but that's not
-// available in cross-platform code. Will be fixed properly when highDPI
-// support is refactored to expose the native coordinate system.
-
-QXcbScreen *QXcbWindow::screenForNativeGeometry(const QRect &newGeometry) const
-{
- QXcbScreen *currentScreen = xcbScreen();
- if (!currentScreen && QGuiApplication::primaryScreen())
- currentScreen = static_cast<QXcbScreen*>(QGuiApplication::primaryScreen()->handle());
- if (currentScreen && !parent() && !currentScreen->nativeGeometry().intersects(newGeometry)) {
- Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
- QXcbScreen *xcbScreen = static_cast<QXcbScreen*>(screen);
- if (xcbScreen->nativeGeometry().intersects(newGeometry))
- return xcbScreen;
- }
- }
- return currentScreen;
-}
-
void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *event)
{
bool fromSendEvent = (event->response_type & 0x80);
@@ -2064,19 +1970,18 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
}
}
- const QRect nativeRect = QRect(pos, QSize(event->width, event->height));
- QXcbScreen *newScreen = parent() ? parentScreen() : screenForNativeGeometry(nativeRect);
+ const QRect rect = QRect(pos, QSize(event->width, event->height));
+ QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(rect);
QXcbScreen *currentScreen = m_xcbScreen;
- m_xcbScreen = newScreen;
+ m_xcbScreen = static_cast<QXcbScreen*>(newScreen);
if (!newScreen)
return;
- const QRect rect = mapFromNative(nativeRect, newScreen);
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
if (newScreen != currentScreen)
- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
m_configureNotifyPending = false;
@@ -2109,11 +2014,10 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
if (!m_embedded)
return pos;
- const int dpr = int(devicePixelRatio());
QPoint ret;
xcb_translate_coordinates_cookie_t cookie =
xcb_translate_coordinates(xcb_connection(), xcb_window(), xcbScreen()->root(),
- pos.x() * dpr, pos.y() * dpr);
+ pos.x(), pos.y());
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) {
@@ -2122,7 +2026,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
free(reply);
}
- return mapFromNative(ret, xcbScreen());
+ return ret;
}
QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
@@ -2130,17 +2034,15 @@ QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
if (!m_embedded)
return pos;
- const int dpr = int(devicePixelRatio());
QPoint ret;
- QPoint xPos = mapToNative(pos, xcbScreen());
xcb_translate_coordinates_cookie_t cookie =
xcb_translate_coordinates(xcb_connection(), xcbScreen()->root(), xcb_window(),
- xPos.x(), xPos.y());
+ pos.x(), pos.y());
xcb_translate_coordinates_reply_t *reply =
xcb_translate_coordinates_reply(xcb_connection(), cookie, NULL);
if (reply) {
- ret.setX(reply->dst_x / dpr);
- ret.setY(reply->dst_y / dpr);
+ ret.setX(reply->dst_x);
+ ret.setY(reply->dst_y);
free(reply);
}
@@ -2156,7 +2058,7 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
if (m_configureNotifyPending)
m_deferredExpose = true;
else
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size() * int(devicePixelRatio())));
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
@@ -2188,9 +2090,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
sendXEmbedMessage(container->xcb_window(), XEMBED_REQUEST_FOCUS);
}
}
- const int dpr = int(devicePixelRatio());
- QPoint local(event_x / dpr, event_y / dpr);
- QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y));
+ QPoint local(event_x, event_y);
+ QPoint global(root_x, root_y);
if (isWheel) {
if (!connection()->isAtLeastXI21()) {
@@ -2212,9 +2113,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in
void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y,
int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
{
- const int dpr = int(devicePixelRatio());
- QPoint local(event_x / dpr, event_y / dpr);
- QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y));
+ QPoint local(event_x, event_y);
+ QPoint global(root_x, root_y);
if (detail >= 4 && detail <= 7) {
// mouse wheel, handled in handleButtonPressEvent()
@@ -2227,11 +2127,8 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x,
void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y,
Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
{
- if (!xcbScreen())
- return;
- const int dpr = int(devicePixelRatio());
- QPoint local(event_x / dpr, event_y / dpr);
- QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y));
+ QPoint local(event_x, event_y);
+ QPoint global(root_x, root_y);
handleMouseEvent(timestamp, local, global, modifiers);
}
@@ -2359,11 +2256,10 @@ void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event)
if (ignoreEnterEvent(event))
return;
- const int dpr = int(devicePixelRatio());
- const QPoint local(event->event_x/dpr, event->event_y/dpr);
+ const QPoint local(event->event_x, event->event_y);
if (!xcbScreen())
return;
- QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
+ QPoint global = QPoint(event->root_x, event->root_y);
QWindowSystemInterface::handleEnterEvent(window(), local, global);
}
@@ -2379,11 +2275,10 @@ void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event)
QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0;
if (enterWindow) {
- const int dpr = int(devicePixelRatio());
- QPoint local(enter->event_x/dpr, enter->event_y/dpr);
+ QPoint local(enter->event_x, enter->event_y);
if (!xcbScreen())
return;
- QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y));
+ QPoint global = QPoint(event->root_x, event->root_y);
QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global);
} else {
@@ -2560,7 +2455,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
xev.type = moveResize;
xev.window = xcb_window();
xev.format = 32;
- const QPoint globalPos = mapToNative(window()->mapToGlobal(pos), xcbScreen());
+ const QPoint globalPos = window()->mapToGlobal(pos);
xev.data.data32[0] = globalPos.x();
xev.data.data32[1] = globalPos.y();
const bool bottom = corner == Qt::BottomRightCorner || corner == Qt::BottomLeftCorner;
@@ -2686,10 +2581,9 @@ void QXcbWindow::setMask(const QRegion &region)
xcb_shape_mask(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_BOUNDING, xcb_window(), 0, 0, XCB_NONE);
} else {
- const int dpr = devicePixelRatio();
QVector<xcb_rectangle_t> rects;
foreach (const QRect &r, region.rects())
- rects.push_back(qRectToXCBRectangle(mapLocalGeometryToNative(r, dpr)));
+ rects.push_back(qRectToXCBRectangle(r));
xcb_shape_rectangles(connection()->xcb_connection(), XCB_SHAPE_SO_SET,
XCB_SHAPE_SK_BOUNDING, XCB_CLIP_ORDERING_UNSORTED,
xcb_window(), 0, 0, rects.size(), &rects[0]);
@@ -2727,11 +2621,6 @@ void QXcbWindow::postSyncWindowRequest()
}
}
-qreal QXcbWindow::devicePixelRatio() const
-{
- return xcbScreen() ? xcbScreen()->devicePixelRatio() : 1.0;
-}
-
QXcbScreen *QXcbWindow::xcbScreen() const
{
return static_cast<QXcbScreen *>(screen());
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 07019223c8..1010600e44 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -163,8 +163,6 @@ public:
void postSyncWindowRequest();
void clearSyncWindowRequest() { m_pendingSyncRequest = 0; }
- qreal devicePixelRatio() const Q_DECL_OVERRIDE;
-
QXcbScreen *xcbScreen() const;
virtual void create();
@@ -180,10 +178,6 @@ protected:
virtual void *createVisual() { return Q_NULLPTR; }
virtual bool supportsSyncProtocol() { return !window()->supportsOpenGL(); }
- QPoint mapToNative(const QPoint &pos, const QXcbScreen *screen) const;
- QPoint mapFromNative(const QPoint &pos, const QXcbScreen *screen) const;
- QRect mapToNative(const QRect &rect, const QXcbScreen *screen) const;
- QRect mapFromNative(const QRect &rect, const QXcbScreen *screen) const;
QXcbScreen *parentScreen();
void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 9bfdc62e60..14e0abf7c7 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -695,7 +695,7 @@ void QOpenGLWidgetPrivate::recreateFbo()
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(samples);
- const QSize deviceSize = q->size() * q->devicePixelRatio();
+ const QSize deviceSize = q->size() * q->devicePixelRatioF();
fbo = new QOpenGLFramebufferObject(deviceSize, format);
if (samples > 0)
resolvedFbo = new QOpenGLFramebufferObject(deviceSize);
@@ -704,7 +704,7 @@ void QOpenGLWidgetPrivate::recreateFbo()
context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
paintDevice->setSize(deviceSize);
- paintDevice->setDevicePixelRatio(q->devicePixelRatio());
+ paintDevice->setDevicePixelRatio(q->devicePixelRatioF());
emit q->resized();
}
@@ -778,8 +778,8 @@ void QOpenGLWidgetPrivate::initialize()
}
paintDevice = new QOpenGLWidgetPaintDevice(q);
- paintDevice->setSize(q->size() * q->devicePixelRatio());
- paintDevice->setDevicePixelRatio(q->devicePixelRatio());
+ paintDevice->setSize(q->size() * q->devicePixelRatioF());
+ paintDevice->setDevicePixelRatio(q->devicePixelRatioF());
context = ctx.take();
initialized = true;
@@ -808,7 +808,7 @@ void QOpenGLWidgetPrivate::invokeUserPaint()
QOpenGLFunctions *f = ctx->functions();
QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbo->handle();
- f->glViewport(0, 0, q->width() * q->devicePixelRatio(), q->height() * q->devicePixelRatio());
+ f->glViewport(0, 0, q->width() * q->devicePixelRatioF(), q->height() * q->devicePixelRatioF());
q->paintGL();
flushPending = true;
@@ -859,8 +859,8 @@ QImage QOpenGLWidgetPrivate::grabFramebuffer()
render();
resolveSamples();
q->makeCurrent();
- QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatio(), false, false);
- res.setDevicePixelRatio(q->devicePixelRatio());
+ QImage res = qt_gl_read_framebuffer(q->size() * q->devicePixelRatioF(), false, false);
+ res.setDevicePixelRatio(q->devicePixelRatioF());
return res;
}
@@ -879,7 +879,7 @@ void QOpenGLWidgetPrivate::resizeViewportFramebuffer()
if (!initialized)
return;
- if (!fbo || q->size() * q->devicePixelRatio() != fbo->size())
+ if (!fbo || q->size() * q->devicePixelRatioF() != fbo->size())
recreateFbo();
}
@@ -1196,6 +1196,7 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const
return QWidget::metric(metric);
QWidget *tlw = window();
+ QWindow *window = tlw ? tlw->windowHandle() : 0;
QScreen *screen = tlw && tlw->windowHandle() ? tlw->windowHandle()->screen() : 0;
if (!screen && QGuiApplication::primaryScreen())
screen = QGuiApplication::primaryScreen();
@@ -1243,8 +1244,13 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const
else
return qRound(dpmy * 0.0254);
case PdmDevicePixelRatio:
- if (screen)
- return screen->devicePixelRatio();
+ if (window)
+ return int(window->devicePixelRatio());
+ else
+ return 1.0;
+ case PdmDevicePixelRatioScaled:
+ if (window)
+ return int(window->devicePixelRatio() * devicePixelRatioFScale);
else
return 1.0;
default:
@@ -1304,7 +1310,7 @@ bool QOpenGLWidget::event(QEvent *e)
}
break;
case QEvent::ScreenChangeInternal:
- if (d->initialized && d->paintDevice->devicePixelRatio() != devicePixelRatio())
+ if (d->initialized && d->paintDevice->devicePixelRatioF() != devicePixelRatioF())
d->recreateFbo();
break;
default:
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index b4943bbe05..6e7479d29a 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -68,6 +68,7 @@
#include "private/qstylesheetstyle_p.h"
#include "private/qstyle_p.h"
#include "qfileinfo.h"
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qinputmethod.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/private/qopenglcontext_p.h>
@@ -2028,7 +2029,7 @@ void QWidgetPrivate::setSystemClip(QPaintDevice *paintDevice, const QRegion &reg
// Transform the system clip region from device-independent pixels to device pixels
QPaintEngine *paintEngine = paintDevice->paintEngine();
QTransform scaleTransform;
- const qreal devicePixelRatio = paintDevice->devicePixelRatio();
+ const qreal devicePixelRatio = paintDevice->devicePixelRatioF();
scaleTransform.scale(devicePixelRatio, devicePixelRatio);
paintEngine->d_func()->systemClip = scaleTransform.map(region);
}
@@ -5354,7 +5355,7 @@ void QWidgetPrivate::render_helper(QPainter *painter, const QPoint &targetOffset
if (size.isNull())
return;
- const qreal pixmapDevicePixelRatio = qreal(painter->device()->devicePixelRatio());
+ const qreal pixmapDevicePixelRatio = painter->device()->devicePixelRatioF();
QPixmap pixmap(size * pixmapDevicePixelRatio);
pixmap.setDevicePixelRatio(pixmapDevicePixelRatio);
@@ -11824,13 +11825,11 @@ void QWidgetPrivate::updateFrameStrut()
Q_Q(QWidget);
if (q->data->fstrut_dirty) {
if (QTLWExtra *te = maybeTopData()) {
- if (te->window) {
- if (const QPlatformWindow *pw = te->window->handle()) {
- const QMargins margins = pw->frameMargins();
- if (!margins.isNull()) {
- te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
- q->data->fstrut_dirty = false;
- }
+ if (te->window && te->window->handle()) {
+ const QMargins margins = te->window->frameMargins();
+ if (!margins.isNull()) {
+ te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom());
+ q->data->fstrut_dirty = false;
}
}
}
@@ -12647,6 +12646,9 @@ int QWidget::metric(PaintDeviceMetric m) const
return qRound(screen->physicalDotsPerInchY());
} else if (m == PdmDevicePixelRatio) {
return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio();
+ } else if (m == PdmDevicePixelRatioScaled) {
+ return (QPaintDevice::devicePixelRatioFScale *
+ (topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio()));
} else {
val = QPaintDevice::metric(m);// XXX
}
@@ -12762,7 +12764,7 @@ void QWidgetPrivate::setMask_sys(const QRegion &region)
Q_Q(QWidget);
if (const QWindow *window = q->windowHandle())
if (QPlatformWindow *platformWindow = window->handle())
- platformWindow->setMask(region);
+ platformWindow->setMask(QHighDpi::toNativeLocalRegion(region, window));
}
/*!
@@ -12862,7 +12864,7 @@ QDebug operator<<(QDebug debug, const QWidget *widget)
frameGeometry.bottom() - geometry.bottom());
debug << ", margins=" << margins;
}
- debug << ", devicePixelRatio=" << widget->devicePixelRatio();
+ debug << ", devicePixelRatio=" << widget->devicePixelRatioF();
if (const WId wid = widget->internalWinId())
debug << ", winId=0x" << hex << wid << dec;
}
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 01d6d89857..633e710853 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -45,6 +45,7 @@
#include <qpa/qplatformtheme.h>
#include <qpa/qplatformwindow.h>
#include <private/qgesturemanager_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -671,7 +672,7 @@ void QWidgetWindow::updateNormalGeometry()
// Ask platform window, default to widget geometry.
QRect normalGeometry;
if (const QPlatformWindow *pw = handle())
- normalGeometry = pw->normalGeometry();
+ normalGeometry = QHighDpi::fromNativePixels(pw->normalGeometry(), this);
if (!normalGeometry.isValid() && effectiveState(m_widget->windowState()) == Qt::WindowNoState)
normalGeometry = m_widget->geometry();
if (normalGeometry.isValid())
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 50c8fd7ed8..518f985b13 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -1977,7 +1977,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
}
}
- int devicePixelRatio = p->device()->devicePixelRatio();
+ int devicePixelRatio = p->device()->devicePixelRatioF();
int width = devicePixelRatio * (int(macRect.size.width) + extraWidth);
int height = devicePixelRatio * (int(macRect.size.height) + extraHeight);
@@ -7204,7 +7204,7 @@ CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
}
CGContextTranslateCTM(ret, 0, pm->height());
- int devicePixelRatio = pdev->devicePixelRatio();
+ qreal devicePixelRatio = pdev->devicePixelRatioF();
CGContextScaleCTM(ret, devicePixelRatio, devicePixelRatio);
CGContextScaleCTM(ret, 1, -1);
return ret;
diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h
index 3d1206b369..c8778cc914 100644
--- a/src/widgets/styles/qwindowsstyle_p_p.h
+++ b/src/widgets/styles/qwindowsstyle_p_p.h
@@ -65,7 +65,7 @@ public:
static int pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0);
static int fixedPixelMetric(QStyle::PixelMetric pm);
static int devicePixelRatio(const QWidget *widget = 0)
- { return widget ? widget->devicePixelRatio() : QWindowsStylePrivate::appDevicePixelRatio(); }
+ { return widget ? int(widget->devicePixelRatioF()) : QWindowsStylePrivate::appDevicePixelRatio(); }
bool hasSeenAlt(const QWidget *widget) const;
bool altDown() const { return alt_down; }
diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp
index 409e4a34f9..c70bc4baef 100644
--- a/src/widgets/widgets/qlabel.cpp
+++ b/src/widgets/widgets/qlabel.cpp
@@ -1085,7 +1085,7 @@ void QLabel::paintEvent(QPaintEvent *)
d->cachedimage = new QImage(d->pixmap->toImage());
delete d->scaledpixmap;
QImage scaledImage =
- d->cachedimage->scaled(cr.size() * devicePixelRatio(),
+ d->cachedimage->scaled(cr.size() * devicePixelRatioF(),
Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
d->scaledpixmap = new QPixmap(QPixmap::fromImage(scaledImage));
}
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index d361aa12a6..9304d91b9a 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -35,6 +35,7 @@
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <QtGui/QPainter>
#include <QtTest/QtTest>
@@ -265,6 +266,11 @@ void tst_QWindow::positioning_data()
#endif
}
+static inline bool qFuzzyCompare(const QPoint &p1, const QPoint p2)
+{
+ return (p1 - p2).manhattanLength() <= 2;
+}
+
void tst_QWindow::positioning()
{
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
@@ -327,21 +333,23 @@ void tst_QWindow::positioning()
// if our positioning is actually fully respected by the window manager
// test whether it correctly handles frame positioning as well
if (originalPos == geometry.topLeft() && (originalMargins.top() != 0 || originalMargins.left() != 0)) {
- QPoint framePos = QPlatformScreen::platformScreenForWindow(&window)->availableGeometry().center();
+ const QPlatformScreen *pScreen = QPlatformScreen::platformScreenForWindow(&window);
+ const QRect availableGeometry = QHighDpi::fromNativeScreenGeometry(pScreen->availableGeometry(), pScreen->screen());
+ const QPoint framePos = availableGeometry.center();
window.reset();
const QPoint oldFramePos = window.framePosition();
window.setFramePosition(framePos);
QTRY_VERIFY(window.received(QEvent::Move));
- if (window.framePosition() != framePos) {
+ if (!qFuzzyCompare(window.framePosition(), framePos)) {
qDebug() << "About to fail auto-test. Here is some additional information:";
qDebug() << "window.framePosition() == " << window.framePosition();
qDebug() << "old frame position == " << oldFramePos;
qDebug() << "We received " << window.received(QEvent::Move) << " move events";
qDebug() << "frame positions after each move event:" << window.m_framePositionsOnMove;
}
- QTRY_COMPARE(framePos, window.framePosition());
+ QTRY_VERIFY(qFuzzyCompare(window.framePosition(), framePos));
QTRY_COMPARE(originalMargins, window.frameMargins());
QCOMPARE(window.position(), window.framePosition() + QPoint(originalMargins.left(), originalMargins.top()));
@@ -661,8 +669,9 @@ void tst_QWindow::testInputEvents()
QCOMPARE(window.keyReleaseCode, int(Qt::Key_A));
QPointF local(12, 34);
- QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(&window, local, local, Qt::NoButton);
+ const QPointF deviceLocal = QHighDpi::toNativeLocalPosition(local, &window);
+ QWindowSystemInterface::handleMouseEvent(&window, deviceLocal, deviceLocal, Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(&window, deviceLocal, deviceLocal, Qt::NoButton);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
@@ -688,15 +697,17 @@ void tst_QWindow::testInputEvents()
// Now with null pointer as window. local param should not be utilized:
// handleMouseEvent() with tlw == 0 means the event is in global coords only.
window.mousePressButton = window.mouseReleaseButton = 0;
- QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window
- QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(0, nonWindowGlobal, nonWindowGlobal, Qt::NoButton);
+ const QPointF nonWindowGlobal(window.geometry().topRight() + QPoint(200, 50)); // not inside the window
+ const QPointF deviceNonWindowGlobal = QHighDpi::toNativePixels(nonWindowGlobal, window.screen());
+ QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(0, deviceNonWindowGlobal, deviceNonWindowGlobal, Qt::NoButton);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, 0);
QCOMPARE(window.mouseReleaseButton, 0);
- QPointF windowGlobal = window.mapToGlobal(local.toPoint());
- QWindowSystemInterface::handleMouseEvent(0, windowGlobal, windowGlobal, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(0, windowGlobal, windowGlobal, Qt::NoButton);
+ const QPointF windowGlobal = window.mapToGlobal(local.toPoint());
+ const QPointF deviceWindowGlobal = QHighDpi::toNativePixels(windowGlobal, window.screen());
+ QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(0, deviceWindowGlobal, deviceWindowGlobal, Qt::NoButton);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressButton, int(Qt::LeftButton));
QCOMPARE(window.mouseReleaseButton, int(Qt::LeftButton));
@@ -718,7 +729,7 @@ void tst_QWindow::touchToMouseTranslation()
const QRectF moveArea(105, 108, 4, 4);
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
- tp1.area = pressArea;
+ tp1.area = QHighDpi::toNativePixels(pressArea, &window);
tp2.id = 2;
tp2.state = Qt::TouchPointPressed;
points << tp1 << tp2;
@@ -729,7 +740,7 @@ void tst_QWindow::touchToMouseTranslation()
tp1.state = Qt::TouchPointStationary;
tp2.id = 1;
tp2.state = Qt::TouchPointMoved;
- tp2.area = moveArea;
+ tp2.area = QHighDpi::toNativePixels(moveArea, &window);
points.clear();
points << tp1 << tp2;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
@@ -946,12 +957,13 @@ void tst_QWindow::touchCancelWithTouchToMouse()
tp1.id = 1;
tp1.state = Qt::TouchPointPressed;
- tp1.area = QRect(100, 100, 4, 4);
+ const QRect area(100, 100, 4, 4);
+ tp1.area = QHighDpi::toNativePixels(area, &window);
points << tp1;
QWindowSystemInterface::handleTouchEvent(&window, touchDevice, points);
QCoreApplication::processEvents();
QTRY_COMPARE(window.mousePressButton, int(Qt::LeftButton));
- QTRY_COMPARE(window.mousePressScreenPos, points[0].area.center());
+ QTRY_VERIFY(qFuzzyCompare(window.mousePressScreenPos.toPoint(), area.center()));
// Cancel the touch. Should result in a mouse release for windows that have
// have an active touch-to-mouse sequence.
@@ -1149,8 +1161,9 @@ void tst_QWindow::mouseEventSequence()
ulong timestamp = 0;
QPointF local(12, 34);
- QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::LeftButton);
- QWindowSystemInterface::handleMouseEvent(&window, timestamp++, local, local, Qt::NoButton);
+ const QPointF deviceLocal = QHighDpi::toNativePixels(local, &window);
+ QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::LeftButton);
+ QWindowSystemInterface::handleMouseEvent(&window, timestamp++, deviceLocal, deviceLocal, Qt::NoButton);
QCoreApplication::processEvents();
QCOMPARE(window.mousePressedCount, 1);
QCOMPARE(window.mouseReleasedCount, 1);
@@ -1337,14 +1350,16 @@ void tst_QWindow::tabletEvents()
window.setGeometry(QRect(m_availableTopLeft + QPoint(10, 10), m_testWindowSize));
qGuiApp->installEventFilter(&window);
- QPoint local(10, 10);
- QPoint global = window.mapToGlobal(local);
- QWindowSystemInterface::handleTabletEvent(&window, true, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
+ const QPoint local(10, 10);
+ const QPoint global = window.mapToGlobal(local);
+ const QPoint deviceLocal = QHighDpi::toNativeLocalPosition(local, &window).toPoint();
+ const QPoint deviceGlobal = QHighDpi::toNativePixels(global, window.screen());
+ QWindowSystemInterface::handleTabletEvent(&window, true, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
QCoreApplication::processEvents();
QTRY_VERIFY(window.eventType == QEvent::TabletPress);
QTRY_COMPARE(window.eventGlobal.toPoint(), global);
QTRY_COMPARE(window.eventLocal.toPoint(), local);
- QWindowSystemInterface::handleTabletEvent(&window, false, local, global, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
+ QWindowSystemInterface::handleTabletEvent(&window, false, deviceLocal, deviceGlobal, 1, 2, 0.5, 1, 2, 0.1, 0, 0, 0);
QCoreApplication::processEvents();
QTRY_VERIFY(window.eventType == QEvent::TabletRelease);
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
index 105afa9a91..f7c871fc0f 100644
--- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
@@ -1653,6 +1653,7 @@ void tst_QTextLayout::testTabDPIScale()
case QPaintDevice::PdmPhysicalDpiY:
return 72;
case QPaintDevice::PdmDevicePixelRatio:
+ case QPaintDevice::PdmDevicePixelRatioScaled:
; // fall through
}
return 0;
diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
index c8d3122e6d..0e679dc661 100644
--- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
+++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp
@@ -1086,6 +1086,8 @@ public:
{
if (PdmDevicePixelRatio == metric)
return 1;
+ if (PdmDevicePixelRatioScaled == metric)
+ return 1 * QPaintDevice::devicePixelRatioFScale;
if (PdmDpiY == metric)
return 96;
if (PdmDpiX == metric)
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index c33fd5a951..5d833eea28 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -62,6 +62,7 @@
#endif
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
#include "../../../qtest-config.h"
@@ -2038,8 +2039,10 @@ void tst_QApplication::touchEventPropagation()
QVERIFY(QTest::qWaitForWindowExposed(&window));
// QPA always takes screen positions and since we map the TouchPoint back to QPA's structure first,
// we must ensure there is a screen position in the TouchPoint that maps to a local 0, 0.
- pressedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
- releasedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
+ const QPoint deviceGlobalPos =
+ QHighDpi::toNativePixels(window.mapToGlobal(QPoint(0, 0)), window.windowHandle()->screen());
+ pressedTouchPoints[0].setScreenPos(deviceGlobalPos);
+ releasedTouchPoints[0].setScreenPos(deviceGlobalPos);
QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
0,
@@ -2091,8 +2094,10 @@ void tst_QApplication::touchEventPropagation()
widget.setObjectName("2. widget");
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
- pressedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
- releasedTouchPoints[0].setScreenPos(window.mapToGlobal(QPoint(0, 0)));
+ const QPoint deviceGlobalPos =
+ QHighDpi::toNativePixels(window.mapToGlobal(QPoint(0, 0)), window.windowHandle()->screen());
+ pressedTouchPoints[0].setScreenPos(deviceGlobalPos);
+ releasedTouchPoints[0].setScreenPos(deviceGlobalPos);
QWindowSystemInterface::handleTouchEvent(window.windowHandle(),
0,
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 68ccaef43f..38a45117a1 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -51,6 +51,7 @@
#include <qdesktopwidget.h>
#include <private/qwidget_p.h>
#include <private/qapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <qcalendarwidget.h>
#include <qmainwindow.h>
#include <qdockwidget.h>
@@ -84,6 +85,7 @@
# include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformintegration.h>
+#include <private/qhighdpiscaling_p.h>
static HWND winHandleOf(const QWidget *w)
{
@@ -193,6 +195,11 @@ static QByteArray msgComparisonFailed(T v1, const char *op, T v2)
return s.toLocal8Bit();
}
+static inline bool qFuzzyCompare(const QPoint &p1, const QPoint p2)
+{
+ return (p1 - p2).manhattanLength() <= 2;
+}
+
class tst_QWidget : public QObject
{
Q_OBJECT
@@ -1906,7 +1913,7 @@ void tst_QWidget::windowState()
widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
QTest::qWait(100);
QVERIFY(!(widget1.windowState() & Qt::WindowMaximized));
- QTRY_COMPARE(widget1.pos(), pos);
+ QTRY_VERIFY(qFuzzyCompare(widget1.pos(), pos));
QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
widget1.setWindowState(Qt::WindowMinimized);
@@ -1927,7 +1934,7 @@ void tst_QWidget::windowState()
widget1.setWindowState(widget1.windowState() ^ Qt::WindowMaximized);
QTest::qWait(100);
QVERIFY(!(widget1.windowState() & (Qt::WindowMinimized|Qt::WindowMaximized)));
- QTRY_COMPARE(widget1.pos(), pos);
+ QTRY_VERIFY(qFuzzyCompare(widget1.pos(), pos));
QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
widget1.setWindowState(Qt::WindowFullScreen);
@@ -1948,7 +1955,7 @@ void tst_QWidget::windowState()
widget1.setWindowState(Qt::WindowNoState);
QTest::qWait(100);
VERIFY_STATE(Qt::WindowNoState);
- QTRY_COMPARE(widget1.pos(), pos);
+ QTRY_VERIFY(qFuzzyCompare(widget1.pos(), pos));
QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
widget1.setWindowState(Qt::WindowFullScreen);
@@ -1981,7 +1988,7 @@ void tst_QWidget::windowState()
QVERIFY(!(widget1.windowState() & stateMask));
QCOMPARE(widget1.windowHandle()->windowState(), Qt::WindowNoState);
- QTRY_COMPARE(widget1.pos(), pos);
+ QTRY_VERIFY(qFuzzyCompare(widget1.pos(), pos));
QTRY_COMPARE(widget1.size(), size);
}
@@ -3676,6 +3683,8 @@ void tst_QWidget::optimizedResizeMove()
void tst_QWidget::optimizedResize_topLevel()
{
+ if (QHighDpiScaling::isActive())
+ QSKIP("Skip due to rounding errors in the regions.");
StaticWidget topLevel;
topLevel.gotPaintEvent = false;
topLevel.show();
diff --git a/tests/manual/highdpi/dragwidget.cpp b/tests/manual/highdpi/dragwidget.cpp
new file mode 100644
index 0000000000..b203566696
--- /dev/null
+++ b/tests/manual/highdpi/dragwidget.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2015 The Qt Company Ltd.
+ ** Contact: http://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL21$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see http://www.qt.io/terms-conditions. For further
+ ** information use the contact form at http://www.qt.io/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU Lesser
+ ** General Public License version 2.1 or version 3 as published by the Free
+ ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+ ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+ ** following information to ensure the GNU Lesser General Public License
+ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** As a special exception, The Qt Company gives you certain additional
+ ** rights. These rights are described in The Qt Company LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include <QtWidgets>
+#include "dragwidget.h"
+
+class FramedLabel : public QLabel
+{
+public:
+ FramedLabel(const QString &text, QWidget *parent)
+ : QLabel(text, parent)
+ {
+ setAutoFillBackground(true);
+ setFrameShape(QFrame::Panel);
+ setFrameShadow(QFrame::Raised);
+ }
+};
+
+DragWidget::DragWidget(QString text, QWidget *parent)
+ : QWidget(parent), otherWindow(0)
+{
+ int x = 5;
+ int y = 5;
+
+ bool createChildWindow = text.isEmpty(); // OK, yes this is a hack...
+ if (text.isEmpty())
+ text = "You can drag from this window and drop text here";
+
+ QStringList words = text.split(' ');
+ foreach (QString word, words) {
+ if (!word.isEmpty()) {
+ FramedLabel *wordLabel = new FramedLabel(word, this);
+ wordLabel->move(x, y);
+ wordLabel->show();
+ x += wordLabel->width() + 2;
+ if (x >= 245) {
+ x = 5;
+ y += wordLabel->height() + 2;
+ }
+ }
+ }
+
+ /*
+ QPalette newPalette = palette();
+ newPalette.setColor(QPalette::Window, Qt::white);
+ setPalette(newPalette);
+ */
+
+ setAcceptDrops(true);
+ setMinimumSize(400, qMax(200, y));
+ setWindowTitle(tr("Draggable Text Window %1").arg(createChildWindow ? 1 : 2));
+ if (createChildWindow)
+ otherWindow = new DragWidget("Here is a second window that accepts drops");
+}
+
+void DragWidget::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (event->mimeData()->hasText()) {
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ }
+ } else {
+ event->ignore();
+ }
+}
+
+void DragWidget::dragMoveEvent(QDragMoveEvent * event)
+{
+ dragPos = event->pos();
+ dragTimer.start(500, this);
+ update();
+}
+
+void DragWidget::dragLeaveEvent(QDragLeaveEvent *)
+{
+ dragTimer.stop();
+ update();
+}
+
+
+void DragWidget::dropEvent(QDropEvent *event)
+{
+ if (event->mimeData()->hasText()) {
+ const QMimeData *mime = event->mimeData();
+ QStringList pieces = mime->text().split(QRegExp("\\s+"),
+ QString::SkipEmptyParts);
+ QPoint position = event->pos();
+ QPoint hotSpot;
+
+ QList<QByteArray> hotSpotPos = mime->data("application/x-hotspot").split(' ');
+ if (hotSpotPos.size() == 2) {
+ hotSpot.setX(hotSpotPos.first().toInt());
+ hotSpot.setY(hotSpotPos.last().toInt());
+ }
+ dropPos = position - hotSpot;
+ dropTimer.start(500, this);
+ update();
+
+ foreach (QString piece, pieces) {
+ FramedLabel *newLabel = new FramedLabel(piece, this);
+ newLabel->move(position - hotSpot);
+ newLabel->show();
+
+ position += QPoint(newLabel->width(), 0);
+ }
+
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ }
+ } else {
+ event->ignore();
+ }
+ foreach (QObject *child, children()) {
+ if (child->inherits("QWidget")) {
+ QWidget *widget = static_cast<QWidget *>(child);
+ if (!widget->isVisible())
+ widget->deleteLater();
+ }
+ }
+}
+
+void DragWidget::mousePressEvent(QMouseEvent *event)
+{
+ QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
+ if (!child)
+ return;
+
+ QPoint hotSpot = event->pos() - child->pos();
+
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setText(child->text());
+ mimeData->setData("application/x-hotspot",
+ QByteArray::number(hotSpot.x()) + " " + QByteArray::number(hotSpot.y()));
+
+ QPixmap pixmap(child->size());
+ child->render(&pixmap);
+
+ QDrag *drag = new QDrag(this);
+ drag->setMimeData(mimeData);
+ drag->setPixmap(pixmap);
+ drag->setHotSpot(hotSpot);
+
+ Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction);
+
+ if (dropAction == Qt::MoveAction)
+ child->close();
+}
+
+void DragWidget::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == dragTimer.timerId())
+ dragTimer.stop();
+ if (e->timerId() == dropTimer.timerId())
+ dropTimer.stop();
+ update();
+}
+
+void DragWidget::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ p.fillRect(rect(), Qt::white);
+
+ if (dropTimer.isActive()) {
+ p.setBrush(Qt::red);
+ p.drawEllipse(dropPos, 50, 50);
+ }
+
+ if (dragTimer.isActive()) {
+ p.setPen(QPen(Qt::blue, 5));
+ QPoint p1 = (rect().topLeft()*3 + rect().bottomRight())/4;
+ QPoint p2 = (rect().topLeft() + rect().bottomRight()*3)/4;
+ p.drawLine(p1, dragPos);
+ p.drawLine(p2, dragPos);
+ }
+}
+
+void DragWidget::showEvent(QShowEvent *)
+{
+ if (otherWindow)
+ otherWindow->show();
+}
+
+void DragWidget::hideEvent(QHideEvent *)
+{
+ if (otherWindow)
+ otherWindow->hide();
+}
diff --git a/tests/manual/highdpi/dragwidget.h b/tests/manual/highdpi/dragwidget.h
new file mode 100644
index 0000000000..0d9631e2f8
--- /dev/null
+++ b/tests/manual/highdpi/dragwidget.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2015 The Qt Company Ltd.
+ ** Contact: http://www.qt.io/licensing/
+ **
+ ** This file is part of the test suite of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL21$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and The Qt Company. For licensing terms
+ ** and conditions see http://www.qt.io/terms-conditions. For further
+ ** information use the contact form at http://www.qt.io/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, this file may be used under the terms of the GNU Lesser
+ ** General Public License version 2.1 or version 3 as published by the Free
+ ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+ ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+ ** following information to ensure the GNU Lesser General Public License
+ ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+ ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ **
+ ** As a special exception, The Qt Company gives you certain additional
+ ** rights. These rights are described in The Qt Company LGPL Exception
+ ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef DRAGWIDGET_H
+#define DRAGWIDGET_H
+
+#include <QWidget>
+#include <QBasicTimer>
+
+QT_BEGIN_NAMESPACE
+class QDragEnterEvent;
+class QDropEvent;
+QT_END_NAMESPACE
+
+class DragWidget : public QWidget
+{
+public:
+ DragWidget(QString text = QString(), QWidget *parent = 0);
+
+protected:
+ void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
+ void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE;
+ void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void dragMoveEvent(QDragMoveEvent * event) Q_DECL_OVERRIDE;
+ void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
+ void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;
+ void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE;
+private:
+ QPoint dragPos;
+ QPoint dropPos;
+ QBasicTimer dragTimer;
+ QBasicTimer dropTimer;
+ QWidget *otherWindow;
+};
+
+#endif // DRAGWIDGET_H
diff --git a/tests/manual/highdpi/highdpi.pro b/tests/manual/highdpi/highdpi.pro
index 7a2979c74c..7d6b42535e 100644
--- a/tests/manual/highdpi/highdpi.pro
+++ b/tests/manual/highdpi/highdpi.pro
@@ -1,10 +1,17 @@
TEMPLATE = app
TARGET = highdpi
INCLUDEPATH += .
-QT += widgets
-CONFIG+=console
+QT += widgets gui-private
+CONFIG +=console
+CONFIG -= app_bundle
+CONFIG += c++11
# Input
-SOURCES += main.cpp
+SOURCES += \
+ dragwidget.cpp \
+ main.cpp
+
+HEADERS += \
+ dragwidget.h
RESOURCES += \
highdpi.qrc
diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp
index fd14523a97..9b7f278765 100644
--- a/tests/manual/highdpi/main.cpp
+++ b/tests/manual/highdpi/main.cpp
@@ -32,6 +32,7 @@
****************************************************************************/
#include <QMainWindow>
+#include <QMenuBar>
#include <QLabel>
#include <QHBoxLayout>
#include <QApplication>
@@ -39,6 +40,7 @@
#include <QStyle>
#include <QToolBar>
#include <QPushButton>
+#include <QButtonGroup>
#include <QLineEdit>
#include <QScrollBar>
#include <QSlider>
@@ -49,10 +51,150 @@
#include <QWindow>
#include <QScreen>
#include <QFile>
+#include <QMouseEvent>
#include <QTemporaryDir>
#include <QCommandLineParser>
#include <QCommandLineOption>
+#include <QDebug>
+#include <private/qhighdpiscaling_p.h>
+#include "dragwidget.h"
+
+class DemoContainerBase
+{
+public:
+ virtual ~DemoContainerBase() {}
+ QString name() { return option().names().first(); }
+ virtual QCommandLineOption &option() = 0;
+ virtual void makeVisible(bool visible) = 0;
+};
+
+typedef QList<DemoContainerBase*> DemoContainerList ;
+
+
+template <class T>
+class DemoContainer : public DemoContainerBase
+{
+public:
+ DemoContainer(const QString &optionName, const QString &description)
+ : m_widget(0), m_option(optionName, description)
+ {
+ }
+ ~DemoContainer() { delete m_widget; }
+
+ QCommandLineOption &option() { return m_option; }
+
+ void makeVisible(bool visible) {
+ if (visible && !m_widget)
+ m_widget = new T;
+ if (m_widget)
+ m_widget->setVisible(visible);
+ }
+private:
+ QWidget *m_widget;
+ QCommandLineOption m_option;
+};
+
+class DemoController : public QWidget
+{
+Q_OBJECT
+public:
+ DemoController(DemoContainerList *demos, QCommandLineParser *parser);
+ ~DemoController();
+private slots:
+ void handleButton(int id, bool toggled);
+private:
+ DemoContainerList *m_demos;
+ QButtonGroup *m_group;
+};
+
+DemoController::DemoController(DemoContainerList *demos, QCommandLineParser *parser)
+ : m_demos(demos)
+{
+ setWindowTitle("screen scale factors");
+ setObjectName("controller"); // make WindowScaleFactorSetter skip this window
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ setLayout(layout);
+
+ // set up one scale control line per screen
+ QList<QScreen *> screens = QGuiApplication::screens();
+ foreach (QScreen *screen, screens) {
+ // create scale control line
+ QHBoxLayout *row = new QHBoxLayout;
+ QSize screenSize = screen->geometry().size();
+ QString screenId = screen->name() + " " + QString::number(screenSize.width())
+ + " " + QString::number(screenSize.height());
+ QLabel *label = new QLabel(screenId);
+ QSlider *slider = new QSlider();
+ slider->setOrientation(Qt::Horizontal);
+ slider->setMinimum(1);
+ slider->setMaximum(40);
+ slider->setValue(10);
+ slider->setTracking(false);
+ slider->setTickInterval(5);
+ slider->setTickPosition(QSlider::TicksBelow);
+ QLabel *scaleFactorLabel = new QLabel("1.0");
+
+ // set up layouts
+ row->addWidget(label);
+ row->addWidget(slider);
+ row->addWidget(scaleFactorLabel);
+ layout->addLayout(row);
+
+ // handle slider position change
+ connect(slider, &QSlider::sliderMoved, [scaleFactorLabel, screen](int scaleFactor){
+ // slider value is scale factor times ten;
+ qreal scalefactorF = qreal(scaleFactor) / 10.0;
+
+ // update label, add ".0" if needed.
+ QString number = QString::number(scalefactorF);
+ if (!number.contains("."))
+ number.append(".0");
+ scaleFactorLabel->setText(number);
+ });
+ // handle slider value change
+ connect(slider, &QSlider::valueChanged, [scaleFactorLabel, screen](int scaleFactor){
+ // slider value is scale factor times ten;
+ qreal scalefactorF = qreal(scaleFactor) / 10.0;
+
+ // set scale factor for screen
+ qreal oldFactor = QHighDpiScaling::factor(screen);
+ QHighDpiScaling::setScreenFactor(screen, scalefactorF);
+ qreal newFactor = QHighDpiScaling::factor(screen);
+
+ qDebug() << "factor was / is" << oldFactor << newFactor;
+ });
+ }
+
+ m_group = new QButtonGroup(this);
+ m_group->setExclusive(false);
+
+ for (int i = 0; i < m_demos->size(); ++i) {
+ DemoContainerBase *demo = m_demos->at(i);
+ QPushButton *button = new QPushButton(demo->name());
+ button->setToolTip(demo->option().description());
+ button->setCheckable(true);
+ layout->addWidget(button);
+ m_group->addButton(button, i);
+
+ if (parser->isSet(demo->option())) {
+ demo->makeVisible(true);
+ button->setChecked(true);
+ }
+ }
+ connect(m_group, SIGNAL(buttonToggled(int, bool)), this, SLOT(handleButton(int, bool)));
+}
+
+DemoController::~DemoController()
+{
+ qDeleteAll(*m_demos);
+}
+
+void DemoController::handleButton(int id, bool toggled)
+{
+ m_demos->at(id)->makeVisible(toggled);
+}
class PixmapPainter : public QWidget
{
@@ -69,7 +211,6 @@ public:
QIcon qtIcon;
};
-
PixmapPainter::PixmapPainter()
{
pixmap1X = QPixmap(":/qticon32.png");
@@ -172,15 +313,18 @@ class MainWindow : public QMainWindow
{
public:
MainWindow();
+ QMenu *addNewMenu(const QString &title, int itemCount = 5);
QIcon qtIcon;
QIcon qtIcon1x;
QIcon qtIcon2x;
QToolBar *fileToolBar;
+ int menuCount;
};
MainWindow::MainWindow()
+ :menuCount(0)
{
// beware that QIcon auto-loads the @2x versions.
qtIcon1x.addFile(":/qticon16.png");
@@ -192,8 +336,33 @@ MainWindow::MainWindow()
// fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
fileToolBar->addAction(new QAction(qtIcon1x, QString("1x"), this));
fileToolBar->addAction(new QAction(qtIcon2x, QString("2x"), this));
+ addNewMenu("&Edit");
+ addNewMenu("&Build");
+ addNewMenu("&Debug", 4);
+ addNewMenu("&Transmogrify", 7);
+ addNewMenu("T&ools");
+ addNewMenu("&Help", 2);
}
+
+QMenu *MainWindow::addNewMenu(const QString &title, int itemCount)
+{
+ QMenu *menu = menuBar()->addMenu(title);
+ for (int i = 0; i < itemCount; i++) {
+ menuCount++;
+ QString s = "Menu item " + QString::number(menuCount);
+ if (i == 3) {
+ QMenu *subMenu = menu->addMenu(s);
+ for (int j = 1; j < 4; j++)
+ subMenu->addAction(QString::fromLatin1("SubMenu item %1.%2").arg(menuCount).arg(j));
+ } else {
+ menu->addAction(s);
+ }
+ }
+ return menu;
+}
+
+
class StandardIcons : public QWidget
{
public:
@@ -205,7 +374,7 @@ public:
int dy = 50;
int maxX = 500;
- for (int iconIndex = QStyle::SP_TitleBarMenuButton; iconIndex < QStyle::SP_MediaVolumeMuted; ++iconIndex) {
+ for (uint iconIndex = QStyle::SP_TitleBarMenuButton; iconIndex < QStyle::SP_MediaVolumeMuted; ++iconIndex) {
QIcon icon = qApp->style()->standardIcon(QStyle::StandardPixmap(iconIndex));
QPainter p(this);
p.drawPixmap(x, y, icon.pixmap(dx - 5, dy - 5));
@@ -295,8 +464,10 @@ public:
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
- int y = 40;
- for (int fontSize = 2; fontSize < 18; fontSize += 2) {
+
+ // Points
+ int y = 10;
+ for (int fontSize = 6; fontSize < 18; fontSize += 2) {
QFont font;
font.setPointSize(fontSize);
QString string = QString(QStringLiteral("%1 The quick brown fox jumped over the lazy Doug.")).arg(fontSize);
@@ -304,6 +475,17 @@ public:
painter.drawText(10, y, string);
y += (fontSize * 2.5);
}
+
+ // Pixels
+ y = 160;
+ for (int fontSize = 6; fontSize < 18; fontSize += 2) {
+ QFont font;
+ font.setPixelSize(fontSize);
+ QString string = QString(QStringLiteral("%1 The quick brown fox jumped over the lazy Doug.")).arg(fontSize);
+ painter.setFont(font);
+ painter.drawText(10, y, string);
+ y += (fontSize * 2.5);
+ }
}
};
@@ -461,97 +643,295 @@ public:
}
};
+class LinePainter : public QWidget
+{
+public:
+ void paintEvent(QPaintEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
-int main(int argc, char **argv)
+ QPoint lastMousePoint;
+ QVector<QPoint> linePoints;
+};
+
+void LinePainter::paintEvent(QPaintEvent *)
{
- QApplication app(argc, argv);
- QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
- QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QPainter p(this);
+ p.fillRect(QRect(QPoint(0, 0), size()), QBrush(Qt::gray));
- QCommandLineParser parser;
- parser.setApplicationDescription("High DPI tester");
- parser.addHelpOption();
- parser.addVersionOption();
- QCommandLineOption pixmapPainterOption("pixmap", "Test pixmap painter");
- parser.addOption(pixmapPainterOption);
- QCommandLineOption labelOption("label", "Test Labels");
- parser.addOption(labelOption);
- QCommandLineOption mainWindowOption("mainwindow", "Test QMainWindow");
- parser.addOption(mainWindowOption);
- QCommandLineOption standardIconsOption("standard-icons", "Test standard icons");
- parser.addOption(standardIconsOption);
- QCommandLineOption cachingOption("caching", "Test caching");
- parser.addOption(cachingOption);
- QCommandLineOption styleOption("styles", "Test style");
- parser.addOption(styleOption);
- QCommandLineOption fontsOption("fonts", "Test fonts");
- parser.addOption(fontsOption);
- QCommandLineOption iconDrawingOption("icondrawing", "Test icon drawing");
- parser.addOption(iconDrawingOption);
- QCommandLineOption buttonsOption("buttons", "Test buttons");
- parser.addOption(buttonsOption);
+ // Default antialiased line
+ p.setRenderHint(QPainter::Antialiasing);
+ p.drawLines(linePoints);
+
+ // Cosmetic 1 antialiased line
+ QPen pen;
+ pen.setCosmetic(true);
+ pen.setWidth(1);
+ p.setPen(pen);
+ p.translate(3, 3);
+ p.drawLines(linePoints);
+
+ // Aliased cosmetic 1 line
+ p.setRenderHint(QPainter::Antialiasing, false);
+ p.translate(3, 3);
+ p.drawLines(linePoints);
+}
- parser.process(app);
+void LinePainter::mousePressEvent(QMouseEvent *event)
+{
+ lastMousePoint = event->pos();
+}
+
+void LinePainter::mouseReleaseEvent(QMouseEvent *)
+{
+ lastMousePoint = QPoint();
+}
+
+void LinePainter::mouseMoveEvent(QMouseEvent *event)
+{
+ if (lastMousePoint.isNull())
+ return;
+
+ QPoint newMousePoint = event->pos();
+ if (lastMousePoint == newMousePoint)
+ return;
+ linePoints.append(lastMousePoint);
+ linePoints.append(newMousePoint);
+ lastMousePoint = newMousePoint;
+ update();
+}
- QScopedPointer<PixmapPainter> pixmapPainter;
- if (parser.isSet(pixmapPainterOption)) {
- pixmapPainter.reset(new PixmapPainter);
- pixmapPainter->show();
+class CursorTester : public QWidget
+{
+public:
+ CursorTester()
+ :moveLabel(0), moving(false)
+ {
}
- QScopedPointer<Labels> label;
- if (parser.isSet(labelOption)) {
- label.reset(new Labels);
- label->resize(200, 200);
- label->show();
+ inline QRect getRect(int idx) const
+ {
+ int h = height() / 2;
+ return QRect(10, 10 + h * (idx - 1), width() - 20, h - 20);
+ }
+ void paintEvent(QPaintEvent *)
+ {
+ QPainter p(this);
+ QRect r1 = getRect(1);
+ QRect r2 = getRect(2);
+ p.fillRect(r1, QColor(200, 200, 250));
+ p.drawText(r1, "Drag from here to move a window based on QCursor::pos()");
+ p.fillRect(r2, QColor(250, 200, 200));
+ p.drawText(r2, "Drag from here to move a window based on mouse event position");
+
+ if (moving) {
+ p.setPen(Qt::darkGray);
+ QFont f = font();
+ f.setPointSize(8);
+ p.setFont(f);
+ p.drawEllipse(mousePos, 30,60);
+ QPoint pt = mousePos - QPoint(0, 60);
+ QPoint pt2 = pt - QPoint(30,10);
+ QPoint offs(30, 0);
+ p.drawLine(pt, pt2);
+ p.drawLine(pt2 - offs, pt2 + offs);
+ p.drawText(pt2 - offs, "mouse pos");
+
+ p.setPen(QColor(50,130,70));
+ QPoint cursorPos = mapFromGlobal(QCursor::pos());
+ pt = cursorPos - QPoint(0, 30);
+ pt2 = pt + QPoint(60, -20);
+ p.drawEllipse(cursorPos, 60, 30);
+ p.drawLine(pt, pt2);
+ p.drawLine(pt2 - offs, pt2 + offs);
+ p.drawText(pt2 - offs, "cursor pos");
+ }
}
- QScopedPointer<MainWindow> mainWindow;
- if (parser.isSet(mainWindowOption)) {
- mainWindow.reset(new MainWindow);
- mainWindow->show();
+ void mousePressEvent(QMouseEvent *e)
+ {
+ if (moving)
+ return;
+ QRect r1 = getRect(1);
+ QRect r2 = getRect(2);
+
+ moving = r1.contains(e->pos()) || r2.contains(e->pos());
+ if (!moving)
+ return;
+ useCursorPos = r1.contains(e->pos());
+
+ if (!moveLabel)
+ moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window );
+
+ if (useCursorPos)
+ moveLabel->setText("I'm following QCursor::pos()");
+ else
+ moveLabel->setText("I'm following QMouseEvent::globalPos()");
+ moveLabel->adjustSize();
+ mouseMoveEvent(e);
+ moveLabel->show();
}
- QScopedPointer<StandardIcons> icons;
- if (parser.isSet(standardIconsOption)) {
- icons.reset(new StandardIcons);
- icons->resize(510, 510);
- icons->show();
+ void mouseReleaseEvent(QMouseEvent *)
+ {
+ if (moveLabel)
+ moveLabel->hide();
+ update();
+ moving = false;
}
- QScopedPointer<Caching> caching;
- if (parser.isSet(cachingOption)) {
- caching.reset(new Caching);
- caching->resize(300, 300);
- caching->show();
+ void mouseMoveEvent(QMouseEvent *e)
+ {
+ if (!moving)
+ return;
+ QPoint pos = useCursorPos ? QCursor::pos() : e->globalPos();
+ pos -= moveLabel->rect().center();
+ moveLabel->move(pos);
+ mousePos = e->pos();
+ update();
}
- QScopedPointer<Style> style;
- if (parser.isSet(styleOption)) {
- style.reset(new Style);
- style->show();
+private:
+ QLabel *moveLabel;
+ bool useCursorPos;
+ bool moving;
+ QPoint mousePos;
+};
+
+
+class ScreenDisplayer : public QWidget
+{
+public:
+ ScreenDisplayer()
+ : QWidget(), moveLabel(0), scaleFactor(1.0)
+ {
}
- QScopedPointer<Fonts> fonts;
- if (parser.isSet(fontsOption)) {
- fonts.reset(new Fonts);
- fonts->show();
+ void timerEvent(QTimerEvent *) {
+ update();
}
- QScopedPointer<IconDrawing> iconDrawing;
- if (parser.isSet(iconDrawingOption)) {
- iconDrawing.reset(new IconDrawing);
- iconDrawing->show();
+ void mousePressEvent(QMouseEvent *) {
+ if (!moveLabel)
+ moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window );
+ moveLabel->setText("Hello, Qt this is a label\nwith some text");
+ moveLabel->show();
+ }
+ void mouseMoveEvent(QMouseEvent *e) {
+ if (!moveLabel)
+ return;
+ moveLabel->move(e->pos() / scaleFactor);
+ QString str;
+ QDebug dbg(&str);
+ dbg.setAutoInsertSpaces(false);
+ dbg << moveLabel->geometry();
+ moveLabel->setText(str);
+ }
+ void mouseReleaseEvent(QMouseEvent *) {
+ if (moveLabel)
+ moveLabel->hide();
}
+ void showEvent(QShowEvent *) {
+ refreshTimer.start(300, this);
+ }
+ void hideEvent(QHideEvent *) {
+ refreshTimer.stop();
+ }
+ void paintEvent(QPaintEvent *) {
+ QPainter p(this);
+ QRectF total;
+ QList<QScreen*> screens = qApp->screens();
+ foreach (QScreen *screen, screens) {
+ total |= screen->geometry();
+ }
+ if (total.isEmpty())
+ return;
+
+ scaleFactor = qMin(width()/total.width(), height()/total.height());
+
+ p.fillRect(rect(), Qt::black);
+ p.scale(scaleFactor, scaleFactor);
+ p.setPen(QPen(Qt::white, 10));
+ p.setBrush(Qt::gray);
+ QFont f = font();
+ f.setPixelSize(height());
+ p.setFont(f);
+
+ foreach (QScreen *screen, screens) {
+ p.drawRect(screen->geometry());
+ p.drawText(screen->geometry(), Qt::AlignCenter, screen->name());
+ }
+ p.setBrush(QColor(200,220,255,127));
+ foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+ if (!widget->isHidden())
+ p.drawRect(widget->geometry());
+ }
- QScopedPointer<Buttons> buttons;
- if (parser.isSet(buttonsOption)) {
- buttons.reset(new Buttons);
- buttons->show();
+ QPolygon cursorShape;
+ cursorShape << QPoint(0,0) << QPoint(20, 60)
+ << QPoint(30, 50) << QPoint(60, 80)
+ << QPoint(80, 60) << QPoint(50, 30)
+ << QPoint(60, 20);
+ cursorShape.translate(QCursor::pos());
+ p.drawPolygon(cursorShape);
}
+private:
+ QLabel *moveLabel;
+ QBasicTimer refreshTimer;
+ qreal scaleFactor;
+};
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+
+ int argumentCount = QCoreApplication::arguments().count();
+
+ QCommandLineParser parser;
+ parser.setApplicationDescription("High DPI tester. Pass one or more of the options to\n"
+ "test various high-dpi aspects. \n"
+ "--interactive is a special option and opens a configuration"
+ " window.");
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption controllerOption("interactive", "Show configuration window.");
+ parser.addOption(controllerOption);
+
+
+ DemoContainerList demoList;
+ demoList << new DemoContainer<PixmapPainter>("pixmap", "Test pixmap painter");
+ demoList << new DemoContainer<Labels>("label", "Test Labels");
+ demoList << new DemoContainer<MainWindow>("mainwindow", "Test QMainWindow");
+ demoList << new DemoContainer<StandardIcons>("standard-icons", "Test standard icons");
+ demoList << new DemoContainer<Caching>("caching", "Test caching");
+ demoList << new DemoContainer<Style>("styles", "Test style");
+ demoList << new DemoContainer<Fonts>("fonts", "Test fonts");
+ demoList << new DemoContainer<IconDrawing>("icondrawing", "Test icon drawing");
+ demoList << new DemoContainer<Buttons>("buttons", "Test buttons");
+ demoList << new DemoContainer<LinePainter>("linepainter", "Test line painting");
+ demoList << new DemoContainer<DragWidget>("draganddrop", "Test drag and drop");
+ demoList << new DemoContainer<CursorTester>("cursorpos", "Test cursor and window positioning");
+ demoList << new DemoContainer<ScreenDisplayer>("screens", "Test screen and window positioning");
+
+
+ foreach (DemoContainerBase *demo, demoList)
+ parser.addOption(demo->option());
+
+ parser.process(app);
+
+ //controller takes ownership of all demos
+ DemoController controller(&demoList, &parser);
+
+ if (parser.isSet(controllerOption) || argumentCount <= 1)
+ controller.show();
if (QApplication::topLevelWidgets().isEmpty())
parser.showHelp(0);
return app.exec();
}
+
+#include "main.moc"