qwindowkit icon indicating copy to clipboard operation
qwindowkit copied to clipboard

Windows11 display scalin

Open sorudals opened this issue 1 year ago • 14 comments

First of all, thank you for providing such a great library.

While using it, I encountered an issue and I am leaving this message to see if there is a solution.

When changing the Windows display scale, the height of the example qtquick code changes.

For example: If you switch the scale like this: 100% > 225% > 100% > 225% > 100%, you can visibly see the height of the window decrease each time.

Question: Is there any way to fix this problem?

sorudals avatar Sep 10 '24 13:09 sorudals

Qt bug introduced in Qt 6.2, fixed in 6.4 or 6.5. Please upgrade your Qt version to a newer version.

wangwenx190 avatar Sep 10 '24 13:09 wangwenx190

Thank you for your fast response!!

My qt version is 6.7.2

I tested with 6.6.3 and 6.7.2, and both results were the same

Should I downgrade to 6.5??

sorudals avatar Sep 10 '24 14:09 sorudals

Thank you for your fast response!!

My qt version is 6.7.2

I tested with 6.6.3 and 6.7.2, and both results were the same

Should I downgrade to 6.5??

Does the problem still exist in Qt 6.6 or 6.7?

SineStriker avatar Sep 10 '24 15:09 SineStriker

Yes, it was. Versions were 6.6.3 and 6.7.2

I didn't test with qwidget yet.

I'll test it tomorrow

sorudals avatar Sep 10 '24 15:09 sorudals

Sorry for late test. I tested qwidget example with Qt 6.6.3 and checked decreasing of window height!

sorudals avatar Sep 13 '24 06:09 sorudals

Anyway, it's a Qt bug and it's I who pushed a fix for upstream Qt, so it should be fixed already. But now it seems it got broken again later for some reason.

wangwenx190 avatar Sep 14 '24 09:09 wangwenx190

Is it related with this link?? https://github.com/qt/qtbase/commit/17ab11ce493477f891916351b6ac0f0a8ad28ca6#diff-df8d4c1559d15c2e05198d3adb5a1ed9fe096a4584d0b35f7dc614cd20b680a5

sorudals avatar Sep 27 '24 10:09 sorudals

Is it related with this link?? qt/qtbase@17ab11c#diff-df8d4c1559d15c2e05198d3adb5a1ed9fe096a4584d0b35f7dc614cd20b680a5

It's commited by me indeed but not related to the current issue at all. Please check this commit which is the fix I mentioned above.

wangwenx190 avatar Nov 04 '24 03:11 wangwenx190

Is it related with this link?? qt/qtbase@17ab11c#diff-df8d4c1559d15c2e05198d3adb5a1ed9fe096a4584d0b35f7dc614cd20b680a5

It's commited by me indeed but not related to the current issue at all. Please check this commit which is the fix I mentioned above.

我最近也碰到一样的问题,Win11+QT6.8.3,检查了对应版本的代码,确认你的代码是已经被合入,但是看到一些可能的逻辑问题:

void QWindowsWindow::handleDpiScaledSize(WPARAM wParam, LPARAM lParam, LRESULT *result) { // We want to keep QWindow's device independent size constant across the // DPI change. To accomplish this, scale QPlatformWindow's native size // by the change of DPI (e.g. 120 -> 144 = 1.2), also taking any scale // factor rounding into account. The win32 window size includes the margins; // add the margins for the new DPI to the window size. const UINT dpi = UINT(wParam); const qreal scale = dpiRelativeScale(dpi); const QMargins margins = fullFrameMargins(); if (!(m_data.flags & Qt::FramelessWindowHint)) { // We need to update the custom margins to match the current DPI, because // we don't want our users manually hook into this message just to set a // new margin, but here we can't call setCustomMargins() directly, that // function will change the window geometry which conflicts with what we // are currently doing. m_data.customMargins *= scale; }

const QSize windowSize = (geometry().size() * scale).grownBy((margins * scale) + customMargins());
SIZE *size = reinterpret_cast<SIZE *>(lParam);
size->cx = windowSize.width();
size->cy = windowSize.height();
*result = true; // Inform Windows that we've set a size

}

主要是这行的处理是否合理?

m_data.customMargins *= scale;

这行直接*= scale,是否意味着变成了物理像素?其他按照逻辑像素去获取并处理m_data.customMargins的地方是否会相应收到影响,进而出现这个问题?

sonysuqin avatar May 30 '25 04:05 sonysuqin

这里的scale是个相对值,是最新DPI相对于上一次DPI的比例,例如假设用户的缩放系数从125%切换到了150%,那么这个scale应该是1.2,意味着用户设置的自定义margin应该变成原来的1.2倍,这个1.2跟DPI的具体数值没有绑定关系,所以这行代码是没问题的。而且我测试过,在我的代码刚合入的时候,这个issue里提到的问题确实消失了。至于为什么后来又出现了,应该是别的地方有bug。反正我测试在qt6.9这个问题又不见了。

wangwenx190 avatar May 30 '25 09:05 wangwenx190

我测了一下qt6.9.0,也有几率出这个问题,而且在双屏切换时问题更多,感觉不是很稳定,如果关闭QWINDOWKIT_ENABLE_WINDOWS_SYSTEM_BORDERS,这个问题是没有了,但是我看注释: QWINDOWKIT_ENABLE_WINDOWS_SYSTEM_BORDERS

  • If you don't want the system borders on Windows 10/11, you can DISABLE this option.
  • If so, the Windows 10 top border issue will disappear. However, part of the client edge area will be occupied as the resizing margins. 这个是说如果关闭的话在win10上客户区会缺标题栏那么高的一块儿吗?具体有多大副作用?

sonysuqin avatar Jun 01 '25 12:06 sonysuqin

我测了一下qt6.9.0,也有几率出这个问题,而且在双屏切换时问题更多,感觉不是很稳定

我用6.9测试没法复现,我也是双屏,两个屏幕DPI一样和不一样都测试过,都没遇到问题。如果你那边还能复现,说明触发问题的根本原因目前还没有找到。

这个是说如果关闭的话在win10上客户区会缺标题栏那么高的一块儿吗?

不是。win10开始窗口的resize区域视觉上是在窗口外部(除了顶部标题栏那块),这个区域在win10之前是不透明的,当系统缩放是100%时,宽度是8像素,视觉上就是那个窗口的边框。win10开始这个区域彻底透明了,原本8像素的窗口边框变成了一根1像素的线。如果你把那个开关关掉,相当于把resize区域转移到窗口内部了,范围还是8像素,围着窗口边缘一圈,这不过这一圈是沿着窗口边界向内扩展的。这一圈范围内的控件都没法接收鼠标事件(只有这8像素内的部分哈,其余部分还是正常的),因为要优先提供resize功能。所以关掉这个开关后你窗口的内容要注意,不要放的太靠边了。要说“副作用”那有点太夸张了,没什么副作用,就是内部排版也注意。

wangwenx190 avatar Jun 01 '25 12:06 wangwenx190

我在QWindowKit的win32windowcontext.cpp文件setInternalWindowFrameMargins方法里不调用platformWindow->setCustomMargins(margins),和关闭QWINDOWKIT_ENABLE_WINDOWS_SYSTEM_BORDERS有什么区别吗?我发现这两个方式都能够避免这个问题。

sonysuqin avatar Jun 01 '25 16:06 sonysuqin

这俩东西完全不一样,前者是不再设置那个custom margin了,后者就是我们之前说的把resize区域转移到窗口内部。后者这个做法天然上会忽略我们设置的custom margin,所以在你看来二者是等价的。custom margin这个东西,你不设置也可以的,只要你测试下来没遇到问题。有些qt版本是依赖于这个custom margin的,如果你不正确设置,会导致修改窗口位置或者尺寸时总是有警告,或者总是有一定的误差或者offset之类的,但有些版本不会。你可以试试不设置这个custom margin,不过要仔细测试一下,没遇到问题就行。

wangwenx190 avatar Jun 02 '25 03:06 wangwenx190