xcb: ignore bigger size window icon when size exceeds limit
In the absence of the BIG-REQUESTS extension, the maximum request length is only 65535, with DPR=2, a 128*128 icon size will be (128*2)^2 = 65536, which exceeds the maximum request length. See also the official doc for xcb_get_maximum_request_length. https://xcb.freedesktop.org/manual/group__XCB__Core__API.html uint32_t xcb_get_maximum_request_length(xcb_connection_t *c) In the absence of the BIG-REQUESTS extension, returns the maximum request length field from the connection setup data, which may be as much as 65535. If the server supports BIG-REQUESTS, then the maximum request length field from the reply to the BigRequestsEnable request will be returned instead. Note that this length is measured in four-byte units, making the theoretical maximum lengths roughly 256kB without BIG-REQUESTS and 16GB with. Fixes: QTBUG-127392 Pick-to: 6.7 6.5 6.2 5.15 Change-Id: Iee53f579802e8bc54ed1519bc5b5591b5e5700e1 Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io> Reviewed-by: Liang Qi <liang.qi@qt.io> (cherry picked from commit 0ed5d4d674c241f7affa3b87feb948c26e11d5cc) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
c237b57983
commit
9f0c48c6b1
@ -1348,6 +1348,7 @@ void QXcbWindow::setWindowIconText(const QString &title)
|
|||||||
void QXcbWindow::setWindowIcon(const QIcon &icon)
|
void QXcbWindow::setWindowIcon(const QIcon &icon)
|
||||||
{
|
{
|
||||||
QList<quint32> icon_data;
|
QList<quint32> icon_data;
|
||||||
|
const uint32_t sizeLimit = xcb_get_maximum_request_length(xcb_connection());
|
||||||
if (!icon.isNull()) {
|
if (!icon.isNull()) {
|
||||||
QList<QSize> availableSizes = icon.availableSizes();
|
QList<QSize> availableSizes = icon.availableSizes();
|
||||||
if (availableSizes.isEmpty()) {
|
if (availableSizes.isEmpty()) {
|
||||||
@ -1363,7 +1364,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
|
|||||||
if (!pixmap.isNull()) {
|
if (!pixmap.isNull()) {
|
||||||
QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
|
QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
|
||||||
int pos = icon_data.size();
|
int pos = icon_data.size();
|
||||||
icon_data.resize(pos + 2 + image.width()*image.height());
|
int newSize = pos + 2 + image.width()*image.height();
|
||||||
|
// In the absence of the BIG-REQUESTS extension, or with too big DPR,
|
||||||
|
// the size of icon data is too big for the xcb request very easily.
|
||||||
|
if (quint64(newSize) > quint64(sizeLimit))
|
||||||
|
break;
|
||||||
|
icon_data.resize(newSize);
|
||||||
icon_data[pos++] = image.width();
|
icon_data[pos++] = image.width();
|
||||||
icon_data[pos++] = image.height();
|
icon_data[pos++] = image.height();
|
||||||
memcpy(icon_data.data() + pos, image.bits(), image.width()*image.height()*4);
|
memcpy(icon_data.data() + pos, image.bits(), image.width()*image.height()*4);
|
||||||
@ -1373,10 +1379,10 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
|
|||||||
|
|
||||||
if (!icon_data.isEmpty()) {
|
if (!icon_data.isEmpty()) {
|
||||||
// Ignore icon exceeding maximum xcb request length
|
// Ignore icon exceeding maximum xcb request length
|
||||||
if (quint64(icon_data.size()) > quint64(xcb_get_maximum_request_length(xcb_connection()))) {
|
if (quint64(icon_data.size()) > quint64(sizeLimit)) {
|
||||||
qWarning() << "Ignoring window icon" << icon_data.size()
|
qWarning() << "Ignoring window icon" << icon_data.size()
|
||||||
<< "exceeds maximum xcb request length"
|
<< "exceeds maximum xcb request length"
|
||||||
<< xcb_get_maximum_request_length(xcb_connection());
|
<< sizeLimit;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xcb_change_property(xcb_connection(),
|
xcb_change_property(xcb_connection(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user