diff --git a/src/kstartupinfo.h b/src/kstartupinfo.h index 31498f5..2d41b75 100644 --- a/src/kstartupinfo.h +++ b/src/kstartupinfo.h @@ -1,760 +1,762 @@ /**************************************************************************** Copyright (C) 2001-2003 Lubos Lunak Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ #ifndef KSTARTUPINFO_H #define KSTARTUPINFO_H #include #include #include #include #include // for WId #include #include typedef struct _XDisplay Display; struct xcb_connection_t; #ifdef Q_CC_MSVC typedef int pid_t; #endif class KStartupInfoId; class KStartupInfoData; /** * Class for manipulating the application startup notification. * * This class can be used to send information about started application, * change the information and receive this information. For detailed * description, see kdelibs/kdecore/README.kstartupinfo. * * You usually don't need to use this class for sending the notification * information, as KDE libraries should do this when an application is * started (e.g. KRun class). * * For receiving the startup notification info, create an instance and connect * to its slots. It will automatically detect started applications and when * they are ready. * * @see KStartupInfoId * @see KStartupInfoData * * @author Lubos Lunak */ class KWINDOWSYSTEM_EXPORT KStartupInfo : public QObject { Q_OBJECT public: /** * Manual notification that the application has started. * If you do not map a (toplevel) window, then startup * notification will not disappear for the application * until a timeout. You can use this as an alternative * method in this case. */ static void appStarted(); /** * Sends explicit notification that the startup notification * with id startup_id should end. */ static void appStarted(const QByteArray &startup_id); /** * Returns the app startup notification identifier for this running * application. * @return the startup notification identifier */ static QByteArray startupId(); /** * Sets a new value for the application startup notification window property for newly * created toplevel windows. * @param startup_id the startup notification identifier * @see KStartupInfo::setNewStartupId */ static void setStartupId(const QByteArray &startup_id); /** * Use this function if the application got a request with startup * notification from outside (for example, when KUniqueApplication::newInstance() * is called, or e.g. when khelpcenter opens new URL in its window). * The window can be either an already existing and visible window, * or a new one, before being shown. Note that this function is usually * needed only when a window is reused. */ static void setNewStartupId(QWindow *window, const QByteArray &startup_id); /** * Use this function if the application got a request with startup * notification from outside (for example, when KUniqueApplication::newInstance() * is called, or e.g. when khelpcenter opens new URL in its window). * The window can be either an already existing and visible window, * or a new one, before being shown. Note that this function is usually * needed only when a window is reused. * @deprecated since 5.62, use setNewStartupId(QWindow *) instead + * Note: if all you have is a QWidget*, you might need to call + * setAttribute(Qt::WA_NativeWindow, true); before calling window()->windowHandle(). */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWINDOWSYSTEM_DEPRECATED static void setNewStartupId(QWidget *window, const QByteArray &startup_id); #endif /** * If your application shows temporarily some window during its startup, * for example a dialog, and only after closing it shows the main window, * startup notification would normally be shown while the dialog is visible. * To temporarily suspend and resume the notification, use this function. * Note that this is cumulative, i.e. after suspending twice, you have to * resume twice. */ static void silenceStartup(bool silence); /** * Creates and returns new startup id. The id includes properly setup * user timestamp. * * On the X11 platform the current timestamp will be fetched from the * X-Server. If the caller has an adaquat timestamp (e.g. from a QMouseEvent) * it should prefer using createNewStartupIdForTimestamp to not trigger a * roundtrip to the X-Server * * @see createNewStartupIdForTimestamp */ static QByteArray createNewStartupId(); /** * Creates and returns new startup id with @p timestamp as user timestamp part. * * @param timestamp The timestamp for the startup id. * @see createNewStartupId * @since 5.5 **/ static QByteArray createNewStartupIdForTimestamp(quint32 timestamp); /** * */ enum { CleanOnCantDetect = 1 << 0, DisableKWinModule = 1 << 1, AnnounceSilenceChanges = 1 << 2 }; /** * Creates an instance that will receive the startup notifications. * The various flags passed may be * @li CleanOnCantDetect - when a new unknown window appears, all startup * notifications for applications that are not compliant with * the startup protocol are removed * @li DisableKWinModule - KWinModule, which is normally used to detect * new windows, is disabled. With this flag, checkStartup() must be * called in order to check newly mapped windows. * @li AnnounceSilenceChanges - normally, startup notifications are * "removed" when they're silenced, and "recreated" when they're resumed. * With this flag, the change is normally announced with gotStartupChange(). * * @param flags OR-ed combination of flags * @param parent the parent of this QObject (can be @c nullptr for no parent) * */ explicit KStartupInfo(int flags, QObject *parent = nullptr); /** * Creates an instance that will receive the startup notifications. * * @param clean_on_cantdetect if true, and a new unknown window appears, * removes all notification for applications that are not compliant * with the app startup protocol * @param parent the parent of this QObject (can be @c nullptr for no parent) * * @obsolete * @deprecated since 5.0 */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWINDOWSYSTEM_DEPRECATED explicit KStartupInfo(bool clean_on_cantdetect, QObject *parent = nullptr); #endif ~KStartupInfo() override; /** * Sends given notification data about started application * with the given startup identification. If no notification for this identification * exists yet, it is created, otherwise it's updated. Note that the name field * in data is required. * * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @see KStartupInfoId * @see KStartupInfoData */ static bool sendStartup(const KStartupInfoId &id, const KStartupInfoData &data); /** * Like sendStartup , uses dpy instead of qt_x11display() for sending the info. * @param dpy the display of the application. Note that the name field * in data is required. * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @deprecated since 5.18 use sendStartupXcb */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWINDOWSYSTEM_DEPRECATED static bool sendStartupX(Display *dpy, const KStartupInfoId &id, const KStartupInfoData &data); #endif /** * Like sendStartup , uses @p conn instead of QX11Info::connection() for sending the info. * @param conn the xcb connection of the application. Note that the name field * in data is required. * @param screen The x11 screen the connection belongs to * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @since 5.18 */ static bool sendStartupXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id, const KStartupInfoData &data); /** * Sends given notification data about started application * with the given startup identification. This is used for updating the notification * info, if no notification for this identification exists, it's ignored. * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @see KStartupInfoId * @see KStartupInfoData */ static bool sendChange(const KStartupInfoId &id, const KStartupInfoData &data); /** * Like sendChange , uses dpy instead of qt_x11display() for sending the info. * @param dpy the display of the application. * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @deprecated since 5.18 use sendChangeXcb */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWINDOWSYSTEM_DEPRECATED static bool sendChangeX(Display *dpy, const KStartupInfoId &id, const KStartupInfoData &data); #endif /** * Like sendChange , uses @p conn instead of QX11Info::connection() for sending the info. * @param conn the xcb connection of the application. * @param screen The x11 screen the connection belongs to * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @since 5.18 */ static bool sendChangeXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id, const KStartupInfoData &data); /** * Ends startup notification with the given identification. * @param id the id of the application * @return true if successful, false otherwise */ static bool sendFinish(const KStartupInfoId &id); /** * Like sendFinish , uses dpy instead of qt_x11display() for sending the info. * @param dpy the display of the application. * @param id the id of the application * @return true if successful, false otherwise * @deprecated since 5.18 use sendFinishXcb */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWINDOWSYSTEM_DEPRECATED static bool sendFinishX(Display *dpy, const KStartupInfoId &id); #endif /** * Like sendFinish , uses @p conn instead of QX11Info::connection() for sending the info. * @param conn the xcb connection of the application. * @param screen The x11 screen the connection belongs to * @param id the id of the application * @return true if successful, false otherwise * @since 5.18 */ static bool sendFinishXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id); /** * Ends startup notification with the given identification and the given data ( e.g. * PIDs of processes for this startup notification that exited ). * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise */ static bool sendFinish(const KStartupInfoId &id, const KStartupInfoData &data); /** * Like sendFinish , uses dpy instead of qt_x11display() for sending the info. * @param dpy the display of the application. * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @deprecated since 5.18 use sendFinishXcb */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWINDOWSYSTEM_DEPRECATED static bool sendFinishX(Display *dpy, const KStartupInfoId &id, const KStartupInfoData &data); #endif /** * Like sendFinish , uses @p conn instead of QX11Info::connection() for sending the info. * @param conn the xcb connection of the application. * @param screen The x11 screen the connection belongs to * @param id the id of the application * @param data the application's data * @return true if successful, false otherwise * @since 5.18 */ static bool sendFinishXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id, const KStartupInfoData &data); /** * Returns the current startup notification identification for the current * startup notification environment variable. Note that KApplication constructor * unsets the variable and you have to use KApplication::startupId . * @return the current startup notification identification */ static KStartupInfoId currentStartupIdEnv(); /** * Unsets the startup notification environment variable. */ static void resetStartupEnv(); /** * @li NoMatch - the window doesn't match any existing startup notification * @li Match - the window matches an existing startup notification * @li CantDetect - unable to detect if the window matches any existing * startup notification */ enum startup_t { NoMatch, Match, CantDetect }; /** * Checks if the given windows matches any existing startup notification. * @param w the window id to check * @return the result of the operation */ startup_t checkStartup(WId w); /** * Checks if the given windows matches any existing startup notification, and * if yes, returns the identification in id. * @param w the window id to check * @param id if found, the id of the startup notification will be written here * @return the result of the operation */ startup_t checkStartup(WId w, KStartupInfoId &id); /** * Checks if the given windows matches any existing startup notification, and * if yes, returns the notification data in data. * @param w the window id to check * @param data if found, the data of the startup notification will be written here * @return the result of the operation */ startup_t checkStartup(WId w, KStartupInfoData &data); /** * Checks if the given windows matches any existing startup notification, and * if yes, returns the identification in id and notification data in data. * @param w the window id to check * @param id if found, the id of the startup notification will be written here * @param data if found, the data of the startup notification will be written here * @return the result of the operation */ startup_t checkStartup(WId w, KStartupInfoId &id, KStartupInfoData &data); /** * Sets the timeout for notifications, after this timeout a notification is removed. * @param secs the new timeout in seconds */ void setTimeout(unsigned int secs); /** * Sets the startup notification window property on the given window. * @param window the id of the window * @param id the startup notification id */ static void setWindowStartupId(WId window, const QByteArray &id); /** * Returns startup notification identification of the given window. * @param w the id of the window * @return the startup notification id. Can be null if not found. */ static QByteArray windowStartupId(WId w); /** * @internal */ class Data; /** * @internal */ class Private; Q_SIGNALS: /** * Emitted when a new startup notification is created (i.e. a new application is * being started). * @param id the notification identification * @param data the notification data */ void gotNewStartup(const KStartupInfoId &id, const KStartupInfoData &data); /** * Emitted when a startup notification changes. * @param id the notification identification * @param data the notification data */ void gotStartupChange(const KStartupInfoId &id, const KStartupInfoData &data); /** * Emitted when a startup notification is removed (either because it was detected * that the application is ready or because of a timeout). * @param id the notification identification * @param data the notification data */ void gotRemoveStartup(const KStartupInfoId &id, const KStartupInfoData &data); protected: /** * */ void customEvent(QEvent *e_P) override; private: Q_PRIVATE_SLOT(d, void startups_cleanup()) Q_PRIVATE_SLOT(d, void startups_cleanup_no_age()) Q_PRIVATE_SLOT(d, void got_message(const QString &msg)) Q_PRIVATE_SLOT(d, void window_added(WId w)) Q_PRIVATE_SLOT(d, void slot_window_added(WId w)) Private *const d; Q_DISABLE_COPY(KStartupInfo) }; /** * Class representing an identification of application startup notification. * * Every existing notification about a starting application has its own unique * identification, that's used to identify and manipulate the notification. * * @see KStartupInfo * @see KStartupInfoData * * @author Lubos Lunak */ class KWINDOWSYSTEM_EXPORT KStartupInfoId { public: /** * Overloaded operator. * @return true if the notification identifications are the same */ bool operator==(const KStartupInfoId &id) const; /** * Overloaded operator. * @return true if the notification identifications are different */ bool operator!=(const KStartupInfoId &id) const; /** * Checks whether the identifier is valid. * @return true if this object doesn't represent a valid notification identification */ bool isNull() const; #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWINDOWSYSTEM_DEPRECATED bool none() const { return isNull(); } #endif /** * Initializes this object with the given identification ( which may be also "0" * for no notification ), or if "" is given, tries to read it from the startup * notification environment variable, and if it's not set, creates a new one. * @param id the new identification, "0" for no notification or "" to read * the environment variable */ void initId(const QByteArray &id = ""); /** * Returns the notification identifier as string. * @return the identification string for the notification */ const QByteArray &id() const; /** * Return the user timestamp for the startup notification, or 0 if no timestamp * is set. */ unsigned long timestamp() const; /** * Sets the startup notification environment variable to this identification. * @return true if successful, false otherwise */ bool setupStartupEnv() const; /** * Creates an empty identification */ KStartupInfoId(); /** * Copy constructor. */ KStartupInfoId(const KStartupInfoId &data); ~KStartupInfoId(); KStartupInfoId &operator=(const KStartupInfoId &data); bool operator<(const KStartupInfoId &id) const; private: explicit KStartupInfoId(const QString &txt); friend class KStartupInfo; friend class KStartupInfo::Private; struct Private; Private *const d; }; /** * Class representing data about an application startup notification. * * Such data include the icon of the starting application, the desktop on which * the application should start, the binary name of the application, etc. * * @see KStartupInfo * @see KStartupInfoId * * @author Lubos Lunak */ class KWINDOWSYSTEM_EXPORT KStartupInfoData { public: /** * Sets the binary name of the application ( e.g. 'kcontrol' ). * @param bin the new binary name of the application */ void setBin(const QString &bin); /** * Returns the binary name of the starting application * @return the new binary name of the application */ const QString &bin() const; /** * Sets the name for the notification (e.g. 'Control Center') */ void setName(const QString &name); /** * Returns the name of the startup notification. If it's not available, * it tries to use other information (binary name). * @return the name of the startup notification */ const QString &findName() const; /** * Returns the name of the startup notification, or empty if not available. * @return the name of the startup notification, or an empty string * if not set. */ const QString &name() const; /** * Sets the description for the notification (e.g. 'Launching Control Center'). * I.e. name() describes what is being started, while description() is * the actual action performed by the starting. */ void setDescription(const QString &descr); /** * Returns the description of the startup notification. If it's not available, * it returns name(). * @return the description of the startup notification */ const QString &findDescription() const; /** * Returns the name of the startup notification, or empty if not available. * @return the name of the startup notificaiton, or an empty string * if not set. */ const QString &description() const; /** * Sets the icon for the startup notification ( e.g. 'kcontrol' ) * @param icon the name of the icon */ void setIcon(const QString &icon); /** * Returns the icon of the startup notification, and if it's not available, * tries to get it from the binary name. * @return the name of the startup notification's icon, or the name of * the binary if not set */ const QString &findIcon() const; /** * Returns the icon of the startup notification, or empty if not available. * @return the name of the icon, or an empty string if not set. */ const QString &icon() const; /** * Sets the desktop for the startup notification ( i.e. the desktop on which * the starting application should appear ). * @param desktop the desktop for the startup notification */ void setDesktop(int desktop); /** * Returns the desktop for the startup notification. * @return the desktop for the startup notification */ int desktop() const; /** * Sets a WM_CLASS value for the startup notification, it may be used for increasing * the chance that the windows created by the starting application will be * detected correctly. * @param wmclass the WM_CLASS value for the startup notification */ void setWMClass(const QByteArray &wmclass); /** * Returns the WM_CLASS value for the startup notification, or binary name if not * available. * @return the WM_CLASS value for the startup notification, or the binary name * if not set */ const QByteArray findWMClass() const; /** * Returns the WM_CLASS value for the startup notification, or empty if not available. * @return the WM_CLASS value for the startup notification, or empty * if not set */ QByteArray WMClass() const; /** * Adds a PID to the list of processes that belong to the startup notification. It * may be used to increase the chance that the windows created by the starting * application will be detected correctly, and also for detecting if the application * has quit without creating any window. * @param pid the PID to add */ void addPid(pid_t pid); /** * Returns all PIDs for the startup notification. * @return the list of all PIDs */ QList< pid_t > pids() const; /** * Checks whether the given @p pid is in the list of PIDs for starup * notification. * @return true if the given @p pid is in the list of PIDs for the startup notification */ bool is_pid(pid_t pid) const; /** * Sets the hostname on which the application is starting. It's necessary to set * it if PIDs are set. * @param hostname the application's hostname. If it's a null string, the current hostname is used */ void setHostname(const QByteArray &hostname = QByteArray()); /** * Returns the hostname for the startup notification. * @return the hostname */ QByteArray hostname() const; /** * */ enum TriState { Yes, No, Unknown }; /** * Sets whether the visual feedback for this startup notification * should be silenced (temporarily suspended). */ void setSilent(TriState state); /** * Return the silence status for the startup notification. * @return KStartupInfoData::Yes if visual feedback is silenced */ TriState silent() const; /** * The X11 screen on which the startup notification is happening, -1 if unknown. */ int screen() const; /** * Sets the X11 screen on which the startup notification should happen. * This is usually not necessary to set, as it's set by default to QX11Info::screen(). */ void setScreen(int screen); /** * The Xinerama screen for the startup notification, -1 if unknown. */ int xinerama() const; /** * Sets the Xinerama screen for the startup notification ( i.e. the screeen on which * the starting application should appear ). * @param xinerama the Xinerama screen for the startup notification */ void setXinerama(int xinerama); /** * The toplevel window of the application that caused this startup notification, * 0 if unknown. */ WId launchedBy() const; /** * Sets the toplevel window of the application that caused this startup notification. * @param window window ID of the toplevel window that is responsible for this startup */ void setLaunchedBy(WId window); /** * The .desktop file used to initiate this startup notification, or empty. This information * should be used only to identify the application, not to read any additional information. * @since 4.5 **/ QString applicationId() const; /** * Sets the .desktop file that was used to initiate the startup notification. * @since 4.5 */ void setApplicationId(const QString &desktop); /** * Updates the notification data from the given data. Some data, such as the desktop * or the name, won't be rewritten if already set. * @param data the data to update */ void update(const KStartupInfoData &data); /** * Constructor. Initializes all the data to their default empty values. */ KStartupInfoData(); /** * Copy constructor. */ KStartupInfoData(const KStartupInfoData &data); ~KStartupInfoData(); KStartupInfoData &operator=(const KStartupInfoData &data); private: explicit KStartupInfoData(const QString &txt); friend class KStartupInfo; friend class KStartupInfo::Data; friend class KStartupInfo::Private; struct Private; Private *const d; }; #endif diff --git a/src/kwindowsystem.cpp b/src/kwindowsystem.cpp index 8558a0a..b35a881 100644 --- a/src/kwindowsystem.cpp +++ b/src/kwindowsystem.cpp @@ -1,751 +1,754 @@ /* * Copyright 2014 Martin Gräßlin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "kwindowsystem.h" #include "kwindowsystem_dummy_p.h" #include "kwindowsystemplugininterface_p.h" #include "pluginwrapper_p.h" #include #include #include #include #include #include #include #if KWINDOWSYSTEM_HAVE_X11 #include #endif //QPoint and QSize all have handy / operators which are useful for scaling, positions and sizes for high DPI support //QRect does not, so we create one for internal purposes within this class inline QRect operator/(const QRect &rectangle, qreal factor) { return QRect(rectangle.topLeft() / factor, rectangle.size() / factor); } class KWindowSystemStaticContainer { public: KWindowSystemStaticContainer() { d.reset(KWindowSystemPluginWrapper::self().createWindowSystem()); if (QCoreApplication::instance()) { kwm.moveToThread(QCoreApplication::instance()->thread()); } } KWindowSystemPrivate *xcbPlugin() { if (xcbPrivate.isNull()) { QPluginLoader loader(QStringLiteral(XCB_PLUGIN_PATH)); QScopedPointer xcbPlugin(qobject_cast< KWindowSystemPluginInterface* >(loader.instance())); if (!xcbPlugin.isNull()) { xcbPrivate.reset(xcbPlugin->createWindowSystem()); } } return xcbPrivate.data(); } KWindowSystem kwm; QScopedPointer d; QScopedPointer xcbPrivate; }; Q_GLOBAL_STATIC(KWindowSystemStaticContainer, g_kwmInstanceContainer) KWindowSystemPrivate::~KWindowSystemPrivate() { } QPixmap KWindowSystemPrivate::iconFromNetWinInfo(int width, int height, bool scale, int flags, NETWinInfo *info) { Q_UNUSED(width) Q_UNUSED(height) Q_UNUSED(scale) Q_UNUSED(flags) Q_UNUSED(info) return QPixmap(); } QList KWindowSystemPrivateDummy::windows() { return QList(); } QList KWindowSystemPrivateDummy::stackingOrder() { return QList(); } WId KWindowSystemPrivateDummy::activeWindow() { return 0; } void KWindowSystemPrivateDummy::activateWindow(WId win, long time) { Q_UNUSED(win) Q_UNUSED(time) } void KWindowSystemPrivateDummy::forceActiveWindow(WId win, long time) { Q_UNUSED(win) Q_UNUSED(time) } void KWindowSystemPrivateDummy::demandAttention(WId win, bool set) { Q_UNUSED(win) Q_UNUSED(set) } bool KWindowSystemPrivateDummy::compositingActive() { return false; } int KWindowSystemPrivateDummy::currentDesktop() { return 0; } int KWindowSystemPrivateDummy::numberOfDesktops() { return 0; } void KWindowSystemPrivateDummy::setCurrentDesktop(int desktop) { Q_UNUSED(desktop) } void KWindowSystemPrivateDummy::setOnAllDesktops(WId win, bool b) { Q_UNUSED(win) Q_UNUSED(b) } void KWindowSystemPrivateDummy::setOnDesktop(WId win, int desktop) { Q_UNUSED(win) Q_UNUSED(desktop) } void KWindowSystemPrivateDummy::setOnActivities(WId win, const QStringList &activities) { Q_UNUSED(win) Q_UNUSED(activities) } #ifndef KWINDOWSYSTEM_NO_DEPRECATED WId KWindowSystemPrivateDummy::transientFor(WId window) { Q_UNUSED(window) return 0; } WId KWindowSystemPrivateDummy::groupLeader(WId window) { Q_UNUSED(window) return 0; } #endif QPixmap KWindowSystemPrivateDummy::icon(WId win, int width, int height, bool scale, int flags) { Q_UNUSED(win) Q_UNUSED(width) Q_UNUSED(height) Q_UNUSED(scale) Q_UNUSED(flags) return QPixmap(); } void KWindowSystemPrivateDummy::setIcons(WId win, const QPixmap &icon, const QPixmap &miniIcon) { Q_UNUSED(win) Q_UNUSED(icon) Q_UNUSED(miniIcon) } void KWindowSystemPrivateDummy::setType(WId win, NET::WindowType windowType) { Q_UNUSED(win) Q_UNUSED(windowType) } void KWindowSystemPrivateDummy::setState(WId win, NET::States state) { Q_UNUSED(win) Q_UNUSED(state) } void KWindowSystemPrivateDummy::clearState(WId win, NET::States state) { Q_UNUSED(win) Q_UNUSED(state) } void KWindowSystemPrivateDummy::minimizeWindow(WId win) { Q_UNUSED(win) } void KWindowSystemPrivateDummy::unminimizeWindow(WId win) { Q_UNUSED(win) } void KWindowSystemPrivateDummy::raiseWindow(WId win) { Q_UNUSED(win) } void KWindowSystemPrivateDummy::lowerWindow(WId win) { Q_UNUSED(win) } bool KWindowSystemPrivateDummy::icccmCompliantMappingState() { return false; } QRect KWindowSystemPrivateDummy::workArea(int desktop) { Q_UNUSED(desktop) return QRect(); } QRect KWindowSystemPrivateDummy::workArea(const QList &excludes, int desktop) { Q_UNUSED(excludes) Q_UNUSED(desktop) return QRect(); } QString KWindowSystemPrivateDummy::desktopName(int desktop) { Q_UNUSED(desktop) return QString(); } void KWindowSystemPrivateDummy::setDesktopName(int desktop, const QString &name) { Q_UNUSED(desktop) Q_UNUSED(name) } bool KWindowSystemPrivateDummy::showingDesktop() { return false; } void KWindowSystemPrivateDummy::setShowingDesktop(bool showing) { Q_UNUSED(showing); } void KWindowSystemPrivateDummy::setUserTime(WId win, long time) { Q_UNUSED(win) Q_UNUSED(time) } void KWindowSystemPrivateDummy::setExtendedStrut(WId win, int left_width, int left_start, int left_end, int right_width, int right_start, int right_end, int top_width, int top_start, int top_end, int bottom_width, int bottom_start, int bottom_end) { Q_UNUSED(win) Q_UNUSED(left_width) Q_UNUSED(left_start) Q_UNUSED(left_end) Q_UNUSED(right_width) Q_UNUSED(right_start) Q_UNUSED(right_end) Q_UNUSED(top_width) Q_UNUSED(top_start) Q_UNUSED(top_end) Q_UNUSED(bottom_width) Q_UNUSED(bottom_start) Q_UNUSED(bottom_end) } void KWindowSystemPrivateDummy::setStrut(WId win, int left, int right, int top, int bottom) { Q_UNUSED(win) Q_UNUSED(left) Q_UNUSED(right) Q_UNUSED(top) Q_UNUSED(bottom) } bool KWindowSystemPrivateDummy::allowedActionsSupported() { return false; } QString KWindowSystemPrivateDummy::readNameProperty(WId window, unsigned long atom) { Q_UNUSED(window) Q_UNUSED(atom) return QString(); } void KWindowSystemPrivateDummy::allowExternalProcessWindowActivation(int pid) { Q_UNUSED(pid) } void KWindowSystemPrivateDummy::setBlockingCompositing(WId window, bool active) { Q_UNUSED(window) Q_UNUSED(active) } bool KWindowSystemPrivateDummy::mapViewport() { return false; } int KWindowSystemPrivateDummy::viewportToDesktop(const QPoint &pos) { Q_UNUSED(pos) return 0; } int KWindowSystemPrivateDummy::viewportWindowToDesktop(const QRect &r) { Q_UNUSED(r) return 0; } QPoint KWindowSystemPrivateDummy::desktopToViewport(int desktop, bool absolute) { Q_UNUSED(desktop) Q_UNUSED(absolute) return QPoint(); } QPoint KWindowSystemPrivateDummy::constrainViewportRelativePosition(const QPoint &pos) { Q_UNUSED(pos) return QPoint(); } void KWindowSystemPrivateDummy::connectNotify(const QMetaMethod &signal) { Q_UNUSED(signal) } KWindowSystem *KWindowSystem::self() { return &(g_kwmInstanceContainer()->kwm); } KWindowSystemPrivate *KWindowSystem::d_func() { return g_kwmInstanceContainer()->d.data(); } void KWindowSystem::connectNotify(const QMetaMethod &signal) { Q_D(KWindowSystem); d->connectNotify(signal); QObject::connectNotify(signal); } QList KWindowSystem::windows() { Q_D(KWindowSystem); return d->windows(); } #ifndef KWINDOWSYSTEM_NO_DEPRECATED KWindowInfo KWindowSystem::windowInfo(WId win, NET::Properties properties, NET::Properties2 properties2) { return KWindowInfo(win, properties, properties2); } #endif bool KWindowSystem::hasWId(WId w) { return windows().contains(w); } QList KWindowSystem::stackingOrder() { Q_D(KWindowSystem); return d->stackingOrder(); } int KWindowSystem::currentDesktop() { Q_D(KWindowSystem); return d->currentDesktop(); } int KWindowSystem::numberOfDesktops() { Q_D(KWindowSystem); return d->numberOfDesktops(); } void KWindowSystem::setCurrentDesktop(int desktop) { Q_D(KWindowSystem); d->setCurrentDesktop(desktop); } void KWindowSystem::setOnAllDesktops(WId win, bool b) { Q_D(KWindowSystem); d->setOnAllDesktops(win, b); } void KWindowSystem::setOnDesktop(WId win, int desktop) { Q_D(KWindowSystem); d->setOnDesktop(win, desktop); } void KWindowSystem::setOnActivities(WId win, const QStringList &activities) { Q_D(KWindowSystem); d->setOnActivities(win, activities); } WId KWindowSystem::activeWindow() { Q_D(KWindowSystem); return d->activeWindow(); } void KWindowSystem::activateWindow(WId win, long time) { Q_D(KWindowSystem); d->activateWindow(win, time); } void KWindowSystem::forceActiveWindow(WId win, long time) { Q_D(KWindowSystem); d->forceActiveWindow(win, time); } void KWindowSystem::demandAttention(WId win, bool set) { Q_D(KWindowSystem); d->demandAttention(win, set); } #ifndef KWINDOWSYSTEM_NO_DEPRECATED WId KWindowSystem::transientFor(WId win) { Q_D(KWindowSystem); return d->transientFor(win); } -#endif void KWindowSystem::setMainWindow(QWidget *subWidget, WId mainWindowId) { // Set the WA_NativeWindow attribute to force the creation of the QWindow. // Without this QWidget::windowHandle() returns 0. subWidget->setAttribute(Qt::WA_NativeWindow, true); QWindow *subWindow = subWidget->windowHandle(); Q_ASSERT(subWindow); + setMainWindow(subWindow, mainWindowId); +} +#endif +void KWindowSystem::setMainWindow(QWindow *subWindow, WId mainWindowId) +{ QWindow *mainWindow = QWindow::fromWinId(mainWindowId); - if (!mainWindow) { - // foreign windows not supported on all platforms - return; + if (mainWindow) { // foreign windows not supported on all platforms + subWindow->setTransientParent(mainWindow); + + // mainWindow is not the child of any object, so make sure it gets deleted at some point + connect(subWindow, &QObject::destroyed, mainWindow, &QObject::deleteLater); } - // mainWindow is not the child of any object, so make sure it gets deleted at some point - connect(subWidget, &QObject::destroyed, mainWindow, &QObject::deleteLater); - subWindow->setTransientParent(mainWindow); } #ifndef KWINDOWSYSTEM_NO_DEPRECATED WId KWindowSystem::groupLeader(WId win) { Q_D(KWindowSystem); return d->groupLeader(win); } #endif QPixmap KWindowSystem::icon(WId win, int width, int height, bool scale) { return icon(win, width, height, scale, NETWM | WMHints | ClassHint | XApp); } QPixmap KWindowSystem::icon(WId win, int width, int height, bool scale, int flags) { Q_D(KWindowSystem); return d->icon(win, width, height, scale, flags); } QPixmap KWindowSystem::icon(WId win, int width, int height, bool scale, int flags, NETWinInfo *info) { Q_D(KWindowSystem); width *= qApp->devicePixelRatio(); height *= qApp->devicePixelRatio(); #if KWINDOWSYSTEM_HAVE_X11 if (info) { if (isPlatformX11()) { // this is the xcb plugin, we can just delegate return d->iconFromNetWinInfo(width, height, scale, flags, info); } else { // other platform plugin, load xcb plugin to delegate to it if (KWindowSystemPrivate *p = g_kwmInstanceContainer()->xcbPlugin()) { return p->iconFromNetWinInfo(width, height, scale, flags, info); } } } #else Q_UNUSED(info) #endif return d->icon(win, width, height, scale, flags); } void KWindowSystem::setIcons(WId win, const QPixmap &icon, const QPixmap &miniIcon) { Q_D(KWindowSystem); d->setIcons(win, icon, miniIcon); } void KWindowSystem::setType(WId win, NET::WindowType windowType) { Q_D(KWindowSystem); d->setType(win, windowType); } void KWindowSystem::setState(WId win, NET::States state) { Q_D(KWindowSystem); d->setState(win, state); } void KWindowSystem::clearState(WId win, NET::States state) { Q_D(KWindowSystem); d->clearState(win, state); } void KWindowSystem::minimizeWindow(WId win) { Q_D(KWindowSystem); d->minimizeWindow(win); } void KWindowSystem::unminimizeWindow(WId win) { Q_D(KWindowSystem); d->unminimizeWindow(win); } #ifndef KWINDOWSYSTEM_NO_DEPRECATED void KWindowSystem::minimizeWindow(WId win, bool animation) { Q_UNUSED(animation) minimizeWindow(win); } #endif #ifndef KWINDOWSYSTEM_NO_DEPRECATED void KWindowSystem::unminimizeWindow(WId win, bool animation) { Q_UNUSED(animation) unminimizeWindow(win); } #endif void KWindowSystem::raiseWindow(WId win) { Q_D(KWindowSystem); d->raiseWindow(win); } void KWindowSystem::lowerWindow(WId win) { Q_D(KWindowSystem); d->lowerWindow(win); } bool KWindowSystem::compositingActive() { Q_D(KWindowSystem); return d->compositingActive(); } QRect KWindowSystem::workArea(int desktop) { Q_D(KWindowSystem); return d->workArea(desktop) / qApp->devicePixelRatio(); } QRect KWindowSystem::workArea(const QList &exclude, int desktop) { Q_D(KWindowSystem); return d->workArea(exclude, desktop) / qApp->devicePixelRatio(); } QString KWindowSystem::desktopName(int desktop) { Q_D(KWindowSystem); return d->desktopName(desktop); } void KWindowSystem::setDesktopName(int desktop, const QString &name) { Q_D(KWindowSystem); d->setDesktopName(desktop, name); } bool KWindowSystem::showingDesktop() { Q_D(KWindowSystem); return d->showingDesktop(); } void KWindowSystem::setShowingDesktop(bool showing) { Q_D(KWindowSystem); return d->setShowingDesktop(showing); } void KWindowSystem::setUserTime(WId win, long time) { Q_D(KWindowSystem); d->setUserTime(win, time); } void KWindowSystem::setExtendedStrut(WId win, int left_width, int left_start, int left_end, int right_width, int right_start, int right_end, int top_width, int top_start, int top_end, int bottom_width, int bottom_start, int bottom_end) { Q_D(KWindowSystem); const qreal dpr = qApp->devicePixelRatio(); d->setExtendedStrut(win, left_width * dpr, left_start * dpr, left_end * dpr, right_width * dpr, right_start * dpr, right_end * dpr, top_width * dpr, top_start * dpr, top_end * dpr, bottom_width * dpr, bottom_start * dpr, bottom_end * dpr); } void KWindowSystem::setStrut(WId win, int left, int right, int top, int bottom) { Q_D(KWindowSystem); const qreal dpr = qApp->devicePixelRatio(); d->setStrut(win, left * dpr, right * dpr, top * dpr, bottom * dpr); } bool KWindowSystem::icccmCompliantMappingState() { Q_D(KWindowSystem); return d->icccmCompliantMappingState(); } bool KWindowSystem::allowedActionsSupported() { Q_D(KWindowSystem); return d->allowedActionsSupported(); } QString KWindowSystem::readNameProperty(WId win, unsigned long atom) { Q_D(KWindowSystem); return d->readNameProperty(win, atom); } void KWindowSystem::allowExternalProcessWindowActivation(int pid) { Q_D(KWindowSystem); d->allowExternalProcessWindowActivation(pid); } void KWindowSystem::setBlockingCompositing(WId window, bool active) { Q_D(KWindowSystem); d->setBlockingCompositing(window, active); } bool KWindowSystem::mapViewport() { Q_D(KWindowSystem); return d->mapViewport(); } int KWindowSystem::viewportToDesktop(const QPoint &p) { Q_D(KWindowSystem); return d->viewportToDesktop(p / qApp->devicePixelRatio()); } int KWindowSystem::viewportWindowToDesktop(const QRect &r) { Q_D(KWindowSystem); return d->viewportWindowToDesktop(r / qApp->devicePixelRatio()); } QPoint KWindowSystem::desktopToViewport(int desktop, bool absolute) { Q_D(KWindowSystem); return d->desktopToViewport(desktop, absolute); } QPoint KWindowSystem::constrainViewportRelativePosition(const QPoint &pos) { Q_D(KWindowSystem); return d->constrainViewportRelativePosition(pos / qApp->devicePixelRatio()); } static inline KWindowSystem::Platform initPlatform() { auto platformName = QGuiApplication::platformName(); if (platformName == QLatin1String("flatpak")) { // here we cannot know what is the actual windowing system, let's try it's env variable const auto flatpakPlatform = QString::fromLocal8Bit(qgetenv("QT_QPA_FLATPAK_PLATFORM")); if (!flatpakPlatform.isEmpty()) { platformName = flatpakPlatform; } } #if KWINDOWSYSTEM_HAVE_X11 if (platformName == QLatin1String("xcb")) { return KWindowSystem::Platform::X11; } #endif if (platformName.startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) { return KWindowSystem::Platform::Wayland; } return KWindowSystem::Platform::Unknown; } KWindowSystem::Platform KWindowSystem::platform() { static Platform s_platform = initPlatform(); return s_platform; } bool KWindowSystem::isPlatformX11() { return platform() == Platform::X11; } bool KWindowSystem::isPlatformWayland() { return platform() == Platform::Wayland; } diff --git a/src/kwindowsystem.h b/src/kwindowsystem.h index 8adcb92..dcf0257 100644 --- a/src/kwindowsystem.h +++ b/src/kwindowsystem.h @@ -1,761 +1,778 @@ /* This file is part of the KDE libraries Copyright (C) 1999 Matthias Ettrich (ettrich@kde.org) Copyright (C) 2007 Lubos Lunak (l.lunak@kde.org) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ /* * kwindowsystem.h. Part of the KDE project. */ #ifndef KWINDOWSYSTEM_H #define KWINDOWSYSTEM_H #include #include #include //For WId #include #include class KWindowSystemPrivate; class NETWinInfo; /** * * Convenience access to certain properties and features of the * window manager. * * The class KWindowSystem provides information about the state of the * window manager and allows asking the window manager to change them * using a more high-level interface than the NETWinInfo/NETRootInfo * lowlevel classes. * * Because of limitiations of the way Qt is implemented on Mac OSX, the WId's * returned by methods in this class are not compatible with those expected * by other Qt methods. So while it should be fine to pass WId's retrieved by * for example calling the winId method on a QWidget to methods in this class * the reverse is not true. You should never pass a WId obtained from this class * to a Qt method accepting a WId parameter. * * @short Class for interaction with the window manager. * @author Matthias Ettrich (ettrich@kde.org) */ class KWINDOWSYSTEM_EXPORT KWindowSystem : public QObject, public NET { Q_OBJECT public: /** * Access to the singleton instance. Useful mainly for connecting to signals. */ static KWindowSystem *self(); /** * Returns the list of all toplevel windows currently managed by the * window manager in the order of creation. Please do not rely on * indexes of this list: Whenever you enter Qt's event loop in your * application, it may happen that entries are removed or added. * Your module should perhaps work on a copy of this list and verify a * window with hasWId() before any operations. * * Iteration over this list can be done easily with * \code * QList windows = KWindowSystem::windows(); * for (auto it = windows.cbegin(), end = windows.cend(); it != end; ++it) { * ... do something here, (*it) is the current WId. * } * \endcode * @return the list of all toplevel windows */ static QList windows(); /** * Test to see if @p id still managed at present. * @param id the window id to test * @return true if the window id is still managed **/ static bool hasWId(WId id); #ifndef KWINDOWSYSTEM_NO_DEPRECATED /** * Returns information about window @p win. It is recommended to check * whether the returned info is valid by calling the valid() method. * @param win the id of the window * @param properties all properties that should be retrieved (see NET::Property * enum for details). Unlisted properties cause related information to be invalid * in the returned data, but make this function faster when not all data is needed. * @param properties2 additional properties (see NET::Property2 enum) * @return the window information * @deprecated use KWindowInfo directly */ KWINDOWSYSTEM_DEPRECATED static KWindowInfo windowInfo(WId win, NET::Properties properties, NET::Properties2 properties2 = NET::Properties2()); #endif /** * Returns the list of all toplevel windows currently managed by the * window manager in the current stacking order (from lower to * higher). May be useful for pagers. * @return the list of all toplevel windows in stacking order */ static QList stackingOrder(); /** * Returns the currently active window, or 0 if no window is active. * @return the window id of the active window, or 0 if no window is * active **/ static WId activeWindow(); /** * Requests that window @p win is activated. * * There are two ways how to activate a window, by calling * activateWindow() and forceActiveWindow(). Generally, * applications shouldn't make attempts to explicitly activate * their windows, and instead let the user to activate them. * In the special cases where this may be needed, applications * should use activateWindow(). Window manager may consider whether * this request wouldn't result in focus stealing, which * would be obtrusive, and may refuse the request. * * The usage of forceActiveWindow() is meant only for pagers * and similar tools, which represent direct user actions * related to window manipulation. * Except for rare cases, this request will be always honored, * and normal applications are forbidden to use it. * * In case of problems, consult the KWin README in the kdebase * package (kdebase/kwin/README), or ask on the kwin@kde.org * mailing list. * * @param win the id of the window to make active * @param time X server timestamp of the user activity that * caused this request */ static void activateWindow(WId win, long time = 0); /** * Sets window @p win to be the active window. Note that this * should be called only in special cases, applications * shouldn't force themselves or other windows to be the active * window. Generally, this call should used only by pagers * and similar tools. See the explanation in description * of activateWindow(). * * @param win the id of the window to make active * @param time X server timestamp of the user activity that * caused this request */ static void forceActiveWindow(WId win, long time = 0); /** * When application finishes some operation and wants to notify * the user about it, it can call demandAttention(). Instead * of activating the window, which could be obtrusive, the window * will be marked specially as demanding user's attention. * See also explanation in description of activateWindow(). * * Note that it's usually better to use KNotifyClient. */ static void demandAttention(WId win, bool set = true); /** * Returns true if a compositing manager is running (i.e. ARGB windows * are supported, effects will be provided, etc.). */ static bool compositingActive(); /** * Returns the current virtual desktop. * @return the current virtual desktop **/ static int currentDesktop(); /** * Returns the number of virtual desktops. * @return the number of virtual desktops **/ static int numberOfDesktops(); /** * Convenience function to set the current desktop to @p desktop. * See NETRootInfo. * @param desktop the number of the new desktop */ static void setCurrentDesktop(int desktop); /** * Sets window @p win to be present on all virtual desktops if @p * is true. Otherwise the window lives only on one single desktop. * * @param win the id of the window * @param b true to show the window on all desktops, false * otherwise */ static void setOnAllDesktops(WId win, bool b); /** * Moves window @p win to desktop @p desktop. * * @param win the id of the window * @param desktop the number of the new desktop */ static void setOnDesktop(WId win, int desktop); /** * Moves window @p win to activities @p activities. * * @param win the id of the window * @param activities the list of activity UUIDs * * @since 5.1 * @see KWindowInfo::activities */ static void setOnActivities(WId win, const QStringList &activities); + /** + * Sets the parent window of @p subwindow to be @p mainwindow. + * This overrides the parent set the usual way as the QWidget or QWindow parent, + * but only for the window manager - e.g. stacking order and window grouping + * will be affected, but features like automatic deletion of children + * when the parent is deleted are unaffected and normally use + * the QObject parent. + * + * This function should be used before a dialog is shown for a window + * that belongs to another application. + */ + static void setMainWindow(QWindow *subwindow, WId mainwindow); + +#ifndef KWINDOWSYSTEM_NO_DEPRECATED /** * Sets the parent window of @p subwindow to be @p mainwindow. * This overrides the parent set the usual way as the QWidget parent, * but only for the window manager - e.g. stacking order and window grouping * will be affected, but features like automatic deletion of children * when the parent is deleted are unaffected and normally use * the QWidget parent. * * This function should be used before a dialog is shown for a window * that belongs to another application. + * @deprecated since 5.62, use setMainWindow(QWindow *). If all you have is a QWidget*, + * you might need to call setAttribute(Qt::WA_NativeWindow, true); before calling + * >window()->windowHandle(). */ - static void setMainWindow(QWidget *subwindow, WId mainwindow); -#ifndef KWINDOWSYSTEM_NO_DEPRECATED + KWINDOWSYSTEM_DEPRECATED static void setMainWindow(QWidget *subwindow, WId mainwindow); + /** * Returns the WM_TRANSIENT_FOR property for the given window, i.e. the mainwindow * for this window. * * @param window the id of the window * @deprecated Use KWindowInfo::transientFor */ KWINDOWSYSTEM_DEPRECATED static WId transientFor(WId window); /** * Returns the leader window for the group the given window is in, if any. * @param window the id of the window * @deprecated Use KWindowInfo::groupLeader */ KWINDOWSYSTEM_DEPRECATED static WId groupLeader(WId window); #endif /** * Returns an icon for window @p win. * * If @p width and @p height are specified, the best icon for the requested * size is returned. * * If @p scale is true, the icon is smooth-scaled to have exactly * the requested size. * * @param win the id of the window * @param width the desired width, or -1 * @param height the desired height, or -1 * @param scale if true the icon will be scaled to the desired size. Otherwise the * icon will not be modified. * @return the icon of the window */ static QPixmap icon(WId win, int width = -1, int height = -1, bool scale = false); /** * Masks specifying from which sources to read an icon. They are tried from the best * until an icon is found. * @li NETWM from property from the window manager specification * @li WMHints from WMHints property * @li ClassHint load icon after getting name from the classhint * @li XApp load the standard X icon (last fallback) */ enum IconSource { NETWM = 1, //!< read from property from the window manager specification WMHints = 2, //!< read from WMHints property ClassHint = 4, //!< load icon after getting name from the classhint XApp = 8 //! &excludes, int desktop = -1); /** * Returns the name of the specified desktop. * @param desktop the number of the desktop * @return the name of the desktop **/ static QString desktopName(int desktop); /** * Sets the name of the specified desktop. * @param desktop the number of the desktop * @param name the new name for the desktop **/ static void setDesktopName(int desktop, const QString &name); /** * Returns the state of showing the desktop. */ static bool showingDesktop(); /** * Sets the state of the "showing desktop" mode of the window manager. If on, * windows are hidden and desktop background is shown and focused. * * @param showing if true, the window manager is put in "showing desktop" mode. * If false, the window manager is put out of that mode. * * @since 5.7.0 */ static void setShowingDesktop(bool showing); /** * Sets user timestamp @p time on window @p win. The timestamp * is expressed as XServer time. If a window * is shown with user timestamp older than the time of the last * user action, it won't be activated after being shown. * The most common case is the special value 0 which means * not to activate the window after being shown. */ static void setUserTime(WId win, long time); /** * Sets the strut of window @p win to @p left_width * ranging from @p left_start to @p left_end on the left edge, * and simiarly for the other edges. For not reserving a strut, pass 0 as the width. * E.g. to reserve 10x10 square in the topleft corner, use e.g. * setExtendedStrut( w, 10, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 ). * * @param win the id of the window * @param left_width width of the strut at the left edge * @param left_start starting y coordinate of the strut at the left edge * @param left_end ending y coordinate of the strut at the left edge * @param right_width width of the strut at the right edge * @param right_start starting y coordinate of the strut at the right edge * @param right_end ending y coordinate of the strut at the right edge * @param top_width width of the strut at the top edge * @param top_start starting x coordinate of the strut at the top edge * @param top_end ending x coordinate of the strut at the top edge * @param bottom_width width of the strut at the bottom edge * @param bottom_start starting x coordinate of the strut at the bottom edge * @param bottom_end ending x coordinate of the strut at the bottom edge */ static void setExtendedStrut(WId win, int left_width, int left_start, int left_end, int right_width, int right_start, int right_end, int top_width, int top_start, int top_end, int bottom_width, int bottom_start, int bottom_end); /** * Convenience function for setExtendedStrut() that automatically makes struts * as wide/high as the screen width/height. * Sets the strut of window @p win to @p left, @p right, @p top, @p bottom. * * @param win the id of the window * @param left the left strut * @param right the right strut * @param top the top strut * @param bottom the bottom strut */ static void setStrut(WId win, int left, int right, int top, int bottom); /** * Returns true if the WM announces which actions it allows for windows. */ static bool allowedActionsSupported(); /** * Function that reads and returns the contents of the given text * property (WM_NAME, WM_ICON_NAME,...). */ static QString readNameProperty(WId window, unsigned long atom); /** * Allows a window from another process to raise and activate itself. * Depending on the window manager, the grant may only be temporary, * or for a single activation, and it may require the current process * to be the "foreground" one" (ie. the process with the input focus). * * You should call this function before executing actions that may trigger * the showing of a window or dialog in another process, e.g. a dbus signal * or function call, or any other inter-process notification mechanism. * * This is mostly used on Windows, where windows are not allowed to be raised * and activated if their process is not the foreground one, but it may also * apply to other window managers. * * @param pid if specified, the grant only applies to windows belonging to the * specific process. By default, a value of -1 means all processes. */ static void allowExternalProcessWindowActivation(int pid = -1); /** * Sets whether the client wishes to block compositing (for better performance) * @since 4.7 */ static void setBlockingCompositing(WId window, bool active); /** * @internal * Returns true if viewports are mapped to virtual desktops. */ static bool mapViewport(); /** * @internal * Returns mapped virtual desktop for the given position in the viewport. */ static int viewportToDesktop(const QPoint &pos); /** * @internal * Returns mapped virtual desktop for the given window geometry. */ static int viewportWindowToDesktop(const QRect &r); /** * @internal * Returns topleft corner of the viewport area for the given mapped virtual desktop. */ static QPoint desktopToViewport(int desktop, bool absolute); /** * @internal * @since 4.0.1 * Checks the relative difference used to move a window will still be inside * valid desktop area. */ static QPoint constrainViewportRelativePosition(const QPoint &pos); /** * Enum describing the windowing system platform used by the QGuiApplication. * @see platform * @since 5.25 **/ enum class Platform { /** * A platform unknown to the application is used **/ Unknown, /** * The xcb/X11 windowing system platorm. **/ X11, /** * The Wayland windowing system platform. **/ Wayland }; /** * Returns the Platform used by the QGuiApplication. * This method allows to check for the used windowing system in a cheap and reliable way. * The Platform gets resolved the first time the method is invoked and cached for further * usages. * @returns The Platform used by the QGuiApplication. * @since 5.25 **/ static Platform platform(); /** * Convenience method to check whether the Platform is X11. * @see platform * @see isPlatformWayland * @since 5.25 **/ static bool isPlatformX11(); /** * Convenience method to check whether the Platform is Wayland. * @see platform * @see isPlatformX11 * @since 5.25 **/ static bool isPlatformWayland(); Q_SIGNALS: /** * Switched to another virtual desktop. * @param desktop the number of the new desktop */ void currentDesktopChanged(int desktop); /** * A window has been added. * @param id the id of the window */ void windowAdded(WId id); /** * A window has been removed. * @param id the id of the window that has been removed */ void windowRemoved(WId id); /** * Hint that \ is active (= has focus) now. * @param id the id of the window that is active */ void activeWindowChanged(WId id); /** * Desktops have been renamed. */ void desktopNamesChanged(); /** * The number of desktops changed. * @param num the new number of desktops */ void numberOfDesktopsChanged(int num); /** * The workarea has changed. */ void workAreaChanged(); /** * Something changed with the struts, may or may not have changed * the work area. Usually just using the workAreaChanged() signal * is sufficient. */ void strutChanged(); /** * Emitted when the stacking order of the window changed. The new order * can be obtained with stackingOrder(). */ void stackingOrderChanged(); /** * The window changed. * * Carries the NET::Properties and NET::Properties2 that were changed. * * @param id the id of the window * @param properties the properties that were modified * @param properties2 the properties2 that were modified * * @since 5.0 **/ void windowChanged(WId id, NET::Properties properties, NET::Properties2 properties2); /** * The window changed. * * The properties parameter contains the NET properties that * were modified (see netwm_def.h). First element are NET::Property * values, second element are NET::Property2 values (i.e. the format * is the same like for the NETWinInfo class constructor). * @param id the id of the window * @param properties the properties that were modified * * @deprecated since 5.0 use windowChanged(WId, NET::Properties, NET::Properties2) */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED QT_MOC_COMPAT void windowChanged(WId id, const unsigned long *properties); #endif /** * @deprecated * The window changed. * * The unsigned int parameter contains the NET properties that * were modified (see netwm_def.h). * @param id the id of the window * @param properties the properties that were modified */ #ifndef KWINDOWSYSTEM_NO_DEPRECATED QT_MOC_COMPAT void windowChanged(WId id, unsigned int properties); #endif /** * The window changed somehow. * @param id the id of the window */ void windowChanged(WId id); /** * The state of showing the desktop has changed. */ void showingDesktopChanged(bool showing); /** * Compositing was enabled or disabled. * * Note that this signal may be emitted before any compositing plugins * have been initialized in the window manager. * * If you need to check if a specific compositing plugin such as the * blur effect is enabled, you should track that separately rather * than test for it in a slot connected to this signal. * * @since 4.7.1 */ void compositingChanged(bool enabled); protected: void connectNotify(const QMetaMethod &signal) override; private: friend class KWindowSystemStaticContainer; KWindowSystem() {} static KWindowSystemPrivate *d_func(); }; #endif