Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgenericunixservices.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <QtGui/private/qtguiglobal_p.h>
6#include "qguiapplication.h"
7#include "qwindow.h"
8#include <QtGui/qpa/qplatformwindow_p.h>
9#include <QtGui/qpa/qplatformwindow.h>
10#include <QtGui/qpa/qplatformnativeinterface.h>
11
12#include <QtCore/QDebug>
13#include <QtCore/QFile>
14#if QT_CONFIG(process)
15# include <QtCore/QProcess>
16#endif
17#if QT_CONFIG(settings)
18#include <QtCore/QSettings>
19#endif
20#include <QtCore/QStandardPaths>
21#include <QtCore/QUrl>
22
23#if QT_CONFIG(dbus)
24// These QtCore includes are needed for xdg-desktop-portal support
25#include <QtCore/private/qcore_unix_p.h>
26
27#include <QtCore/QFileInfo>
28#include <QtCore/QUrlQuery>
29
30#include <QtDBus/QDBusConnection>
31#include <QtDBus/QDBusMessage>
32#include <QtDBus/QDBusPendingCall>
33#include <QtDBus/QDBusPendingCallWatcher>
34#include <QtDBus/QDBusPendingReply>
35#include <QtDBus/QDBusUnixFileDescriptor>
36
37#include <fcntl.h>
38
39#endif // QT_CONFIG(dbus)
40
41#include <stdlib.h>
42
44
45using namespace Qt::StringLiterals;
46
47#if QT_CONFIG(multiprocess)
48
49enum { debug = 0 };
50
51static inline QByteArray detectDesktopEnvironment()
52{
53 const QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
54 if (!xdgCurrentDesktop.isEmpty())
55 return xdgCurrentDesktop.toUpper(); // KDE, GNOME, UNITY, LXDE, MATE, XFCE...
56
57 // Classic fallbacks
58 if (!qEnvironmentVariableIsEmpty("KDE_FULL_SESSION"))
59 return QByteArrayLiteral("KDE");
60 if (!qEnvironmentVariableIsEmpty("GNOME_DESKTOP_SESSION_ID"))
61 return QByteArrayLiteral("GNOME");
62
63 // Fallback to checking $DESKTOP_SESSION (unreliable)
64 QByteArray desktopSession = qgetenv("DESKTOP_SESSION");
65
66 // This can be a path in /usr/share/xsessions
67 int slash = desktopSession.lastIndexOf('/');
68 if (slash != -1) {
69#if QT_CONFIG(settings)
70 QSettings desktopFile(QFile::decodeName(desktopSession + ".desktop"), QSettings::IniFormat);
71 desktopFile.beginGroup(QStringLiteral("Desktop Entry"));
72 QByteArray desktopName = desktopFile.value(QStringLiteral("DesktopNames")).toByteArray();
73 if (!desktopName.isEmpty())
74 return desktopName;
75#endif
76
77 // try decoding just the basename
78 desktopSession = desktopSession.mid(slash + 1);
79 }
80
81 if (desktopSession == "gnome")
82 return QByteArrayLiteral("GNOME");
83 else if (desktopSession == "xfce")
84 return QByteArrayLiteral("XFCE");
85 else if (desktopSession == "kde")
86 return QByteArrayLiteral("KDE");
87
88 return QByteArrayLiteral("UNKNOWN");
89}
90
91static inline bool checkExecutable(const QString &candidate, QString *result)
92{
94 return !result->isEmpty();
95}
96
97static inline bool detectWebBrowser(const QByteArray &desktop,
98 bool checkBrowserVariable,
99 QString *browser)
100{
101 const char *browsers[] = {"google-chrome", "firefox", "mozilla", "opera"};
102
103 browser->clear();
104 if (checkExecutable(QStringLiteral("xdg-open"), browser))
105 return true;
106
107 if (checkBrowserVariable) {
108 QByteArray browserVariable = qgetenv("DEFAULT_BROWSER");
109 if (browserVariable.isEmpty())
110 browserVariable = qgetenv("BROWSER");
111 if (!browserVariable.isEmpty() && checkExecutable(QString::fromLocal8Bit(browserVariable), browser))
112 return true;
113 }
114
115 if (desktop == QByteArray("KDE")) {
116 if (checkExecutable(QStringLiteral("kde-open5"), browser))
117 return true;
118 // Konqueror launcher
119 if (checkExecutable(QStringLiteral("kfmclient"), browser)) {
120 browser->append(" exec"_L1);
121 return true;
122 }
123 } else if (desktop == QByteArray("GNOME")) {
124 if (checkExecutable(QStringLiteral("gnome-open"), browser))
125 return true;
126 }
127
128 for (size_t i = 0; i < sizeof(browsers)/sizeof(char *); ++i)
129 if (checkExecutable(QLatin1StringView(browsers[i]), browser))
130 return true;
131 return false;
132}
133
134static inline bool launch(const QString &launcher, const QUrl &url,
135 const QString &xdgActivationToken)
136{
137 if (!xdgActivationToken.isEmpty()) {
138 qputenv("XDG_ACTIVATION_TOKEN", xdgActivationToken.toUtf8());
139 }
140
141 const QString command = launcher + u' ' + QLatin1StringView(url.toEncoded());
142 if (debug)
143 qDebug("Launching %s", qPrintable(command));
144#if !QT_CONFIG(process)
145 const bool ok = ::system(qPrintable(command + " &"_L1));
146#else
147 QStringList args = QProcess::splitCommand(command);
148 bool ok = false;
149 if (!args.isEmpty()) {
151 ok = QProcess::startDetached(program, args);
152 }
153#endif
154 if (!ok)
155 qWarning("Launch failed (%s)", qPrintable(command));
156
157 qunsetenv("XDG_ACTIVATION_TOKEN");
158
159 return ok;
160}
161
162#if QT_CONFIG(dbus)
163static inline bool checkNeedPortalSupport()
164{
165 return QFileInfo::exists("/.flatpak-info"_L1) || qEnvironmentVariableIsSet("SNAP");
166}
167
168static inline QDBusMessage xdgDesktopPortalOpenFile(const QUrl &url, const QString &parentWindow,
169 const QString &xdgActivationToken)
170{
171 // DBus signature:
172 // OpenFile (IN s parent_window,
173 // IN h fd,
174 // IN a{sv} options,
175 // OUT o handle)
176 // Options:
177 // handle_token (s) - A string that will be used as the last element of the @handle.
178 // writable (b) - Whether to allow the chosen application to write to the file.
179
180 const int fd = qt_safe_open(QFile::encodeName(url.toLocalFile()), O_RDONLY);
181 if (fd != -1) {
182 QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.portal.Desktop"_L1,
183 "/org/freedesktop/portal/desktop"_L1,
184 "org.freedesktop.portal.OpenURI"_L1,
185 "OpenFile"_L1);
186
187 QDBusUnixFileDescriptor descriptor;
188 descriptor.giveFileDescriptor(fd);
189
190 QVariantMap options = {};
191
192 if (!xdgActivationToken.isEmpty()) {
193 options.insert("activation_token"_L1, xdgActivationToken);
194 }
195
196 message << parentWindow << QVariant::fromValue(descriptor) << options;
197
199 }
200
202}
203
204static inline QDBusMessage xdgDesktopPortalOpenUrl(const QUrl &url, const QString &parentWindow,
205 const QString &xdgActivationToken)
206{
207 // DBus signature:
208 // OpenURI (IN s parent_window,
209 // IN s uri,
210 // IN a{sv} options,
211 // OUT o handle)
212 // Options:
213 // handle_token (s) - A string that will be used as the last element of the @handle.
214 // writable (b) - Whether to allow the chosen application to write to the file.
215 // This key only takes effect the uri points to a local file that is exported in the document portal,
216 // and the chosen application is sandboxed itself.
217
218 QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.portal.Desktop"_L1,
219 "/org/freedesktop/portal/desktop"_L1,
220 "org.freedesktop.portal.OpenURI"_L1,
221 "OpenURI"_L1);
222 // FIXME parent_window_id and handle writable option
223 QVariantMap options;
224
225 if (!xdgActivationToken.isEmpty()) {
226 options.insert("activation_token"_L1, xdgActivationToken);
227 }
228
229 message << parentWindow << url.toString() << options;
230
232}
233
234static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url, const QString &parentWindow,
235 const QString &xdgActivationToken)
236{
237 // DBus signature:
238 // ComposeEmail (IN s parent_window,
239 // IN a{sv} options,
240 // OUT o handle)
241 // Options:
242 // address (s) - The email address to send to.
243 // subject (s) - The subject for the email.
244 // body (s) - The body for the email.
245 // attachment_fds (ah) - File descriptors for files to attach.
246
247 QUrlQuery urlQuery(url);
248 QVariantMap options;
249 options.insert("address"_L1, url.path());
250 options.insert("subject"_L1, urlQuery.queryItemValue("subject"_L1));
251 options.insert("body"_L1, urlQuery.queryItemValue("body"_L1));
252
253 // O_PATH seems to be present since Linux 2.6.39, which is not case of RHEL 6
254#ifdef O_PATH
255 QList<QDBusUnixFileDescriptor> attachments;
256 const QStringList attachmentUris = urlQuery.allQueryItemValues("attachment"_L1);
257
258 for (const QString &attachmentUri : attachmentUris) {
259 const int fd = qt_safe_open(QFile::encodeName(attachmentUri), O_PATH);
260 if (fd != -1) {
261 QDBusUnixFileDescriptor descriptor(fd);
262 attachments << descriptor;
264 }
265 }
266
267 options.insert("attachment_fds"_L1, QVariant::fromValue(attachments));
268#endif
269
270 if (!xdgActivationToken.isEmpty()) {
271 options.insert("activation_token"_L1, xdgActivationToken);
272 }
273
274 QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.portal.Desktop"_L1,
275 "/org/freedesktop/portal/desktop"_L1,
276 "org.freedesktop.portal.Email"_L1,
277 "ComposeEmail"_L1);
278
279 message << parentWindow << options;
280
282}
283
284namespace {
285struct XDGDesktopColor
286{
287 double r = 0;
288 double g = 0;
289 double b = 0;
290
291 QColor toQColor() const
292 {
293 constexpr auto rgbMax = 255;
294 return { static_cast<int>(r * rgbMax), static_cast<int>(g * rgbMax),
295 static_cast<int>(b * rgbMax) };
296 }
297};
298
299const QDBusArgument &operator>>(const QDBusArgument &argument, XDGDesktopColor &myStruct)
300{
302 argument >> myStruct.r >> myStruct.g >> myStruct.b;
304 return argument;
305}
306
307class XdgDesktopPortalColorPicker : public QPlatformServiceColorPicker
308{
310public:
311 XdgDesktopPortalColorPicker(const QString &parentWindowId, QWindow *parent)
312 : QPlatformServiceColorPicker(parent), m_parentWindowId(parentWindowId)
313 {
314 }
315
316 void pickColor() override
317 {
318 // DBus signature:
319 // PickColor (IN s parent_window,
320 // IN a{sv} options
321 // OUT o handle)
322 // Options:
323 // handle_token (s) - A string that will be used as the last element of the @handle.
324
326 "org.freedesktop.portal.Desktop"_L1, "/org/freedesktop/portal/desktop"_L1,
327 "org.freedesktop.portal.Screenshot"_L1, "PickColor"_L1);
328 message << m_parentWindowId << QVariantMap();
329
330 QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
331 auto watcher = new QDBusPendingCallWatcher(pendingCall, this);
334 watcher->deleteLater();
335 QDBusPendingReply<QDBusObjectPath> reply = *watcher;
336 if (reply.isError()) {
337 qWarning("DBus call to pick color failed: %s",
338 qPrintable(reply.error().message()));
339 Q_EMIT colorPicked({});
340 } else {
342 "org.freedesktop.portal.Desktop"_L1, reply.value().path(),
343 "org.freedesktop.portal.Request"_L1, "Response"_L1, this,
344 // clang-format off
345 SLOT(gotColorResponse(uint,QVariantMap))
346 // clang-format on
347 );
348 }
349 });
350 }
351
352private Q_SLOTS:
353 void gotColorResponse(uint result, const QVariantMap &map)
354 {
355 if (result != 0)
356 return;
357 if (map.contains(u"color"_s)) {
358 XDGDesktopColor color{};
359 map.value(u"color"_s).value<QDBusArgument>() >> color;
360 Q_EMIT colorPicked(color.toQColor());
361 } else {
362 Q_EMIT colorPicked({});
363 }
364 deleteLater();
365 }
366
367private:
368 const QString m_parentWindowId;
369};
370} // namespace
371
372#endif // QT_CONFIG(dbus)
373
375{
376#if QT_CONFIG(dbus)
377 if (qEnvironmentVariableIntValue("QT_NO_XDG_DESKTOP_PORTAL") > 0) {
378 return;
379 }
381 "org.freedesktop.portal.Desktop"_L1, "/org/freedesktop/portal/desktop"_L1,
382 "org.freedesktop.DBus.Properties"_L1, "Get"_L1);
383 message << "org.freedesktop.portal.Screenshot"_L1
384 << "version"_L1;
385
386 QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
387 auto watcher = new QDBusPendingCallWatcher(pendingCall);
390 watcher->deleteLater();
391 QDBusPendingReply<QVariant> reply = *watcher;
392 if (!reply.isError() && reply.value().toUInt() >= 2)
393 m_hasScreenshotPortalWithColorPicking = true;
394 });
395
396#endif
397}
398
400{
401#if QT_CONFIG(dbus)
402 // Make double sure that we are in a wayland environment. In particular check
403 // WAYLAND_DISPLAY so also XWayland apps benefit from portal-based color picking.
404 // Outside wayland we'll rather rely on other means than the XDG desktop portal.
405 if (!qEnvironmentVariableIsEmpty("WAYLAND_DISPLAY")
406 || QGuiApplication::platformName().startsWith("wayland"_L1)) {
407 return new XdgDesktopPortalColorPicker(portalWindowIdentifier(parent), parent);
408 }
409 return nullptr;
410#else
411 Q_UNUSED(parent);
412 return nullptr;
413#endif
414}
415
417{
418 static const QByteArray result = detectDesktopEnvironment();
419 return result;
420}
421
422template<typename F>
423void runWithXdgActivationToken(F &&functionToCall)
424{
425#if QT_CONFIG(wayland)
426 QWindow *window = qGuiApp->focusWindow();
427
428 if (!window) {
429 functionToCall({});
430 return;
431 }
432
433 auto waylandApp = dynamic_cast<QNativeInterface::QWaylandApplication *>(
434 qGuiApp->platformNativeInterface());
435 auto waylandWindow =
436 dynamic_cast<QNativeInterface::Private::QWaylandWindow *>(window->handle());
437
438 if (!waylandWindow || !waylandApp) {
439 functionToCall({});
440 return;
441 }
442
443 QObject::connect(waylandWindow,
444 &QNativeInterface::Private::QWaylandWindow::xdgActivationTokenCreated,
445 waylandWindow, functionToCall, Qt::SingleShotConnection);
446 waylandWindow->requestXdgActivationToken(waylandApp->lastInputSerial());
447#else
448 functionToCall({});
449#endif
450}
451
453{
454 auto openUrlInternal = [this](const QUrl &url, const QString &xdgActivationToken) {
455 if (url.scheme() == "mailto"_L1) {
456# if QT_CONFIG(dbus)
458 const QString parentWindow = QGuiApplication::focusWindow()
460 : QString();
461 QDBusError error = xdgDesktopPortalSendEmail(url, parentWindow, xdgActivationToken);
462 if (!error.isValid())
463 return true;
464
465 // service not running, fall back
466 }
467# endif
468 return openDocument(url);
469 }
470
471# if QT_CONFIG(dbus)
473 const QString parentWindow = QGuiApplication::focusWindow()
475 : QString();
476 QDBusError error = xdgDesktopPortalOpenUrl(url, parentWindow, xdgActivationToken);
477 if (!error.isValid())
478 return true;
479 }
480# endif
481
482 if (m_webBrowser.isEmpty()
483 && !detectWebBrowser(desktopEnvironment(), true, &m_webBrowser)) {
484 qWarning("Unable to detect a web browser to launch '%s'", qPrintable(url.toString()));
485 return false;
486 }
487 return launch(m_webBrowser, url, xdgActivationToken);
488 };
489
490 if (QGuiApplication::platformName().startsWith("wayland"_L1)) {
491 runWithXdgActivationToken(
492 [openUrlInternal, url](const QString &token) { openUrlInternal(url, token); });
493
494 return true;
495
496 } else {
497 return openUrlInternal(url, QString());
498 }
499}
500
502{
503 auto openDocumentInternal = [this](const QUrl &url, const QString &xdgActivationToken) {
504
505# if QT_CONFIG(dbus)
507 const QString parentWindow = QGuiApplication::focusWindow()
509 : QString();
510 QDBusError error = xdgDesktopPortalOpenFile(url, parentWindow, xdgActivationToken);
511 if (!error.isValid())
512 return true;
513 }
514# endif
515
516 if (m_documentLauncher.isEmpty()
517 && !detectWebBrowser(desktopEnvironment(), false, &m_documentLauncher)) {
518 qWarning("Unable to detect a launcher for '%s'", qPrintable(url.toString()));
519 return false;
520 }
521 return launch(m_documentLauncher, url, xdgActivationToken);
522 };
523
524 if (QGuiApplication::platformName().startsWith("wayland"_L1)) {
525 runWithXdgActivationToken([openDocumentInternal, url](const QString &token) {
526 openDocumentInternal(url, token);
527 });
528
529 return true;
530 } else {
531 return openDocumentInternal(url, QString());
532 }
533}
534
535#else
537
542
544{
545 Q_UNUSED(url);
546 qWarning("openUrl() not supported on this platform");
547 return false;
548}
549
551{
552 Q_UNUSED(url);
553 qWarning("openDocument() not supported on this platform");
554 return false;
555}
556
558{
559 Q_UNUSED(parent);
560 return nullptr;
561}
562
563#endif // QT_NO_MULTIPROCESS
564
570
572{
573 switch (capability) {
575 return m_hasScreenshotPortalWithColorPicking;
576 }
577 return false;
578}
579
581{
582#if QT_CONFIG(dbus)
583 if (qGuiApp->desktopFileName().isEmpty()) {
584 qWarning("QGuiApplication::desktopFileName() is empty");
585 return;
586 }
587
588
589 const QString launcherUrl = QStringLiteral("application://") + qGuiApp->desktopFileName() + QStringLiteral(".desktop");
590 const qint64 count = qBound(0, number, 9999);
591 QVariantMap dbusUnityProperties;
592
593 if (count > 0) {
594 dbusUnityProperties[QStringLiteral("count")] = count;
595 dbusUnityProperties[QStringLiteral("count-visible")] = true;
596 } else {
597 dbusUnityProperties[QStringLiteral("count-visible")] = false;
598 }
599
600 auto signal = QDBusMessage::createSignal(QStringLiteral("/com/canonical/unity/launcherentry/")
601 + qGuiApp->applicationName(), QStringLiteral("com.canonical.Unity.LauncherEntry"), QStringLiteral("Update"));
602
603 signal.setArguments({launcherUrl, dbusUnityProperties});
604
606#else
608#endif
609}
610
612
613#include "qgenericunixservices.moc"
\inmodule QtCore
Definition qbytearray.h:57
QByteArray mid(qsizetype index, qsizetype len=-1) const &
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
\inmodule QtDBus
void beginStructure()
Opens a new D-Bus structure suitable for appending new arguments.
void endStructure()
Closes a D-Bus structure opened with beginStructure().
static QDBusConnection sessionBus()
Returns a QDBusConnection object opened with the session bus.
\inmodule QtDBus
Definition qdbuserror.h:21
\inmodule QtDBus
static QDBusMessage createSignal(const QString &path, const QString &interface, const QString &name)
Constructs a new DBus message with the given path, interface and name, representing a signal emission...
static QDBusMessage createError(const QString &name, const QString &msg)
Constructs a new DBus message representing an error, with the given name and msg.
static QDBusMessage createMethodCall(const QString &destination, const QString &path, const QString &interface, const QString &method)
Constructs a new DBus message representing a method call.
void finished(QDBusPendingCallWatcher *self=nullptr)
This signal is emitted when the pending call has finished and its reply is available.
\inmodule QtDBus
void giveFileDescriptor(int fileDescriptor)
bool exists() const
Returns true if the file system entry this QFileInfo refers to exists; otherwise returns false.
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
Definition qfile.h:158
static QString decodeName(const QByteArray &localFileName)
This does the reverse of QFile::encodeName() using localFileName.
Definition qfile.h:162
bool openDocument(const QUrl &url) override
bool hasCapability(Capability capability) const override
virtual QString portalWindowIdentifier(QWindow *window)
void setApplicationBadge(qint64 number)
QPlatformServiceColorPicker * colorPicker(QWindow *parent=nullptr) override
bool openUrl(const QUrl &url) override
QByteArray desktopEnvironment() const override
QPlatformServices::desktopEnvironment returns the active desktop environment.
static QWindow * focusWindow()
Returns the QWindow that receives events tied to focus, such as key events.
QString platformName
The name of the underlying platform plugin.
bool isEmpty() const noexcept
Definition qlist.h:401
value_type takeFirst()
Definition qlist.h:566
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
bool contains(const Key &key) const
Definition qmap.h:341
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
Capability
Capabilities are used to determine a specific platform service's availability.
\inmodule QtCore
Definition qsettings.h:30
static QString findExecutable(const QString &executableName, const QStringList &paths=QStringList())
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5949
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\inmodule QtCore
Definition qurlquery.h:20
\inmodule QtCore
Definition qurl.h:94
QByteArray toEncoded(FormattingOptions options=FullyEncoded) const
Returns the encoded representation of the URL if it's valid; otherwise an empty QByteArray is returne...
Definition qurl.cpp:2967
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
QString toString(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2831
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition qurl.cpp:3425
QString path(ComponentFormattingOptions options=FullyDecoded) const
Returns the path of the URL.
Definition qurl.cpp:2468
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
\inmodule QtGui
Definition qwindow.h:63
QMap< QString, QString > map
[6]
auto signal
Token token
Definition keywords.cpp:444
Combined button and popup list for selecting options.
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
@ SingleShotConnection
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
QMap< QString, QVariant > QVariantMap
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
static int qt_safe_close(int fd)
DBusConnection const char DBusError * error
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
static bool checkNeedPortalSupport()
#define qGuiApp
Q_DECL_COLD_FUNCTION Q_CORE_EXPORT QString qt_error_string(int errorCode=-1)
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
#define SLOT(a)
Definition qobjectdefs.h:52
GLboolean GLboolean GLboolean b
GLboolean r
[2]
GLenum GLenum GLsizei count
GLuint color
[2]
GLsizei const GLenum * attachments
GLuint program
GLuint GLsizei const GLchar * message
GLboolean GLboolean g
GLuint64 GLenum GLint fd
GLuint64EXT * result
[6]
#define O_PATH
static QString checkExecutable(const QString &path)
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
bool qputenv(const char *varName, QByteArrayView raw)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
Q_CORE_EXPORT bool qunsetenv(const char *varName)
#define Q_OBJECT
#define Q_EMIT
#define Q_SLOTS
#define Q_UNUSED(x)
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
QFutureWatcher< int > watcher
QUrl url("example.com")
[constructor-url-reference]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
QDataStream & operator>>(QDataStream &in, MyClass &myObj)
aWidget window() -> setWindowTitle("New Window Title")
[2]
QNetworkReply * reply
QDBusArgument argument
QJSValueList args