Warning, file /frameworks/kwindowsystem/src/kx11extras.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 1999 Matthias Ettrich <ettrich@kde.org> 0004 SPDX-FileCopyrightText: 2007 Lubos Lunak <l.lunak@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #include "kx11extras.h" 0010 0011 #include "kwindowsystem.h" 0012 #include "kwindowsystem_p.h" 0013 0014 #include "kxutils_p.h" 0015 #include "netwm.h" 0016 0017 #include <QGuiApplication> 0018 #include <QRect> 0019 0020 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0021 #include <private/qtx11extras_p.h> 0022 #else 0023 #include <QX11Info> 0024 #endif 0025 0026 // QPoint and QSize all have handy / operators which are useful for scaling, positions and sizes for high DPI support 0027 // QRect does not, so we create one for internal purposes within this class 0028 inline QRect operator/(const QRect &rectangle, qreal factor) 0029 { 0030 return QRect(rectangle.topLeft() / factor, rectangle.size() / factor); 0031 } 0032 0033 KX11Extras *KX11Extras::self() 0034 { 0035 static KX11Extras instance; 0036 return &instance; 0037 } 0038 0039 QList<WId> KX11Extras::windows() 0040 { 0041 return KWindowSystem::d_func()->windows(); 0042 } 0043 0044 bool KX11Extras::hasWId(WId w) 0045 { 0046 return windows().contains(w); 0047 } 0048 0049 QList<WId> KX11Extras::stackingOrder() 0050 { 0051 return KWindowSystem::d_func()->stackingOrder(); 0052 } 0053 0054 WId KX11Extras::activeWindow() 0055 { 0056 return KWindowSystem::d_func()->activeWindow(); 0057 } 0058 0059 void KX11Extras::activateWindow(WId win, long time) 0060 { 0061 KWindowSystem::d_func()->activateWindow(win, time); 0062 } 0063 0064 void KX11Extras::forceActiveWindow(WId win, long time) 0065 { 0066 KWindowSystem::d_func()->forceActiveWindow(win, time); 0067 } 0068 0069 bool KX11Extras::compositingActive() 0070 { 0071 return KWindowSystem::d_func()->compositingActive(); 0072 } 0073 0074 int KX11Extras::currentDesktop() 0075 { 0076 return KWindowSystem::d_func()->currentDesktop(); 0077 } 0078 0079 int KX11Extras::numberOfDesktops() 0080 { 0081 return KWindowSystem::d_func()->numberOfDesktops(); 0082 } 0083 0084 void KX11Extras::setCurrentDesktop(int desktop) 0085 { 0086 KWindowSystem::d_func()->setCurrentDesktop(desktop); 0087 } 0088 0089 void KX11Extras::setOnAllDesktops(WId win, bool b) 0090 { 0091 KWindowSystem::d_func()->setOnAllDesktops(win, b); 0092 } 0093 0094 void KX11Extras::setOnDesktop(WId win, int desktop) 0095 { 0096 KWindowSystem::d_func()->setOnDesktop(win, desktop); 0097 } 0098 0099 void KX11Extras::setOnActivities(WId win, const QStringList &activities) 0100 { 0101 KWindowSystem::d_func()->setOnActivities(win, activities); 0102 } 0103 0104 QPixmap KX11Extras::icon(WId win, int width, int height, bool scale) 0105 { 0106 return icon(win, width, height, scale, NETWM | WMHints | ClassHint | XApp); 0107 } 0108 0109 QPixmap KX11Extras::icon(WId win, int width, int height, bool scale, int flags) 0110 { 0111 return KWindowSystem::d_func()->icon(win, width, height, scale, flags); 0112 } 0113 0114 QPixmap iconFromNetWinInfo(int width, int height, bool scale, int flags, NETWinInfo *info) 0115 { 0116 QPixmap result; 0117 if (!info) { 0118 return result; 0119 } 0120 if (flags & KX11Extras::NETWM) { 0121 NETIcon ni = info->icon(width, height); 0122 if (ni.data && ni.size.width > 0 && ni.size.height > 0) { 0123 QImage img((uchar *)ni.data, (int)ni.size.width, (int)ni.size.height, QImage::Format_ARGB32); 0124 if (scale && width > 0 && height > 0 && img.size() != QSize(width, height) && !img.isNull()) { 0125 img = img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 0126 } 0127 if (!img.isNull()) { 0128 result = QPixmap::fromImage(img); 0129 } 0130 return result; 0131 } 0132 } 0133 0134 if (flags & KX11Extras::WMHints) { 0135 xcb_pixmap_t p = info->icccmIconPixmap(); 0136 xcb_pixmap_t p_mask = info->icccmIconPixmapMask(); 0137 0138 if (p != XCB_PIXMAP_NONE) { 0139 QPixmap pm = KXUtils::createPixmapFromHandle(info->xcbConnection(), p, p_mask); 0140 if (scale && width > 0 && height > 0 && !pm.isNull() // 0141 && (pm.width() != width || pm.height() != height)) { 0142 result = QPixmap::fromImage(pm.toImage().scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); 0143 } else { 0144 result = pm; 0145 } 0146 } 0147 } 0148 0149 // Since width can be any arbitrary size, but the icons cannot, 0150 // take the nearest value for best results (ignoring 22 pixel 0151 // icons as they don't exist for apps): 0152 int iconWidth; 0153 if (width < 24) { 0154 iconWidth = 16; 0155 } else if (width < 40) { 0156 iconWidth = 32; 0157 } else if (width < 56) { 0158 iconWidth = 48; 0159 } else if (width < 96) { 0160 iconWidth = 64; 0161 } else if (width < 192) { 0162 iconWidth = 128; 0163 } else { 0164 iconWidth = 256; 0165 } 0166 0167 if (flags & KX11Extras::ClassHint) { 0168 // Try to load the icon from the classhint if the app didn't specify 0169 // its own: 0170 if (result.isNull()) { 0171 const QIcon icon = QIcon::fromTheme(QString::fromUtf8(info->windowClassClass()).toLower()); 0172 const QPixmap pm = icon.isNull() ? QPixmap() : icon.pixmap(iconWidth, iconWidth); 0173 if (scale && !pm.isNull()) { 0174 result = QPixmap::fromImage(pm.toImage().scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); 0175 } else { 0176 result = pm; 0177 } 0178 } 0179 } 0180 0181 if (flags & KX11Extras::XApp) { 0182 // If the icon is still a null pixmap, load the icon for X applications 0183 // as a last resort: 0184 if (result.isNull()) { 0185 const QIcon icon = QIcon::fromTheme(QStringLiteral("xorg")); 0186 const QPixmap pm = icon.isNull() ? QPixmap() : icon.pixmap(iconWidth, iconWidth); 0187 if (scale && !pm.isNull()) { 0188 result = QPixmap::fromImage(pm.toImage().scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); 0189 } else { 0190 result = pm; 0191 } 0192 } 0193 } 0194 return result; 0195 } 0196 0197 QPixmap KX11Extras::icon(WId win, int width, int height, bool scale, int flags, NETWinInfo *info) 0198 { 0199 width *= qGuiApp->devicePixelRatio(); 0200 height *= qGuiApp->devicePixelRatio(); 0201 0202 if (info) { 0203 return iconFromNetWinInfo(width, height, scale, flags, info); 0204 } 0205 0206 NETWinInfo newInfo(QX11Info::connection(), win, QX11Info::appRootWindow(), NET::WMIcon, NET::WM2WindowClass | NET::WM2IconPixmap); 0207 0208 return iconFromNetWinInfo(width, height, scale, flags, &newInfo); 0209 } 0210 0211 void KX11Extras::minimizeWindow(WId win) 0212 { 0213 KWindowSystem::d_func()->minimizeWindow(win); 0214 } 0215 0216 void KX11Extras::unminimizeWindow(WId win) 0217 { 0218 KWindowSystem::d_func()->unminimizeWindow(win); 0219 } 0220 0221 QRect KX11Extras::workArea(int desktop) 0222 { 0223 return KWindowSystem::d_func()->workArea(desktop) / qApp->devicePixelRatio(); 0224 } 0225 0226 QRect KX11Extras::workArea(const QList<WId> &exclude, int desktop) 0227 { 0228 return KWindowSystem::d_func()->workArea(exclude, desktop) / qApp->devicePixelRatio(); 0229 } 0230 0231 QString KX11Extras::desktopName(int desktop) 0232 { 0233 return KWindowSystem::d_func()->desktopName(desktop); 0234 } 0235 0236 void KX11Extras::setDesktopName(int desktop, const QString &name) 0237 { 0238 KWindowSystem::d_func()->setDesktopName(desktop, name); 0239 } 0240 0241 QString KX11Extras::readNameProperty(WId win, unsigned long atom) 0242 { 0243 return KWindowSystem::d_func()->readNameProperty(win, atom); 0244 } 0245 0246 bool KX11Extras::mapViewport() 0247 { 0248 return KWindowSystem::d_func()->mapViewport(); 0249 } 0250 0251 void KX11Extras::setExtendedStrut(WId win, 0252 int left_width, 0253 int left_start, 0254 int left_end, 0255 int right_width, 0256 int right_start, 0257 int right_end, 0258 int top_width, 0259 int top_start, 0260 int top_end, 0261 int bottom_width, 0262 int bottom_start, 0263 int bottom_end) 0264 { 0265 const qreal dpr = qApp->devicePixelRatio(); 0266 KWindowSystem::d_func()->setExtendedStrut(win, 0267 left_width * dpr, 0268 left_start * dpr, 0269 left_end * dpr, 0270 right_width * dpr, 0271 right_start * dpr, 0272 right_end * dpr, 0273 top_width * dpr, 0274 top_start * dpr, 0275 top_end * dpr, 0276 bottom_width * dpr, 0277 bottom_start * dpr, 0278 bottom_end * dpr); 0279 } 0280 0281 void KX11Extras::setStrut(WId win, int left, int right, int top, int bottom) 0282 { 0283 const qreal dpr = qApp->devicePixelRatio(); 0284 KWindowSystem::d_func()->setStrut(win, left * dpr, right * dpr, top * dpr, bottom * dpr); 0285 } 0286 0287 void KX11Extras::connectNotify(const QMetaMethod &signal) 0288 { 0289 KWindowSystem::self()->d_func()->connectNotify(signal); 0290 QObject::connectNotify(signal); 0291 }