File indexing completed on 2024-03-24 04:02:17
0001 /* 0002 SPDX-FileCopyrightText: 2001-2003 Lubos Lunak <l.lunak@kde.org> 0003 0004 SPDX-License-Identifier: MIT 0005 */ 0006 0007 #ifndef KSTARTUPINFO_H 0008 #define KSTARTUPINFO_H 0009 0010 #include <kwindowsystem_export.h> 0011 0012 #include <QChildEvent> 0013 #include <QObject> 0014 #include <QString> 0015 #include <QWidgetList> // for WId 0016 #include <QWindow> 0017 0018 #include <sys/types.h> 0019 0020 typedef struct _XDisplay Display; 0021 0022 struct xcb_connection_t; 0023 0024 class KStartupInfoId; 0025 class KStartupInfoData; 0026 0027 /** 0028 * Class for manipulating the application startup notification. 0029 * 0030 * This class can be used to send information about started application, 0031 * change the information and receive this information. For detailed 0032 * description, see kdelibs/kdecore/README.kstartupinfo. 0033 * 0034 * You usually don't need to use this class for sending the notification 0035 * information, as KDE libraries should do this when an application is 0036 * started (e.g. KRun class). 0037 * 0038 * For receiving the startup notification info, create an instance and connect 0039 * to its slots. It will automatically detect started applications and when 0040 * they are ready. 0041 * 0042 * @see KStartupInfoId 0043 * @see KStartupInfoData 0044 * 0045 * @author Lubos Lunak <l.lunak@kde.org> 0046 */ 0047 class KWINDOWSYSTEM_EXPORT KStartupInfo : public QObject 0048 { 0049 Q_OBJECT 0050 public: 0051 /** 0052 * Manual notification that the application has started. 0053 * If you do not map a (toplevel) window, then startup 0054 * notification will not disappear for the application 0055 * until a timeout. You can use this as an alternative 0056 * method in this case. 0057 */ 0058 static void appStarted(); 0059 0060 /** 0061 * Sends explicit notification that the startup notification 0062 * with id startup_id should end. 0063 */ 0064 static void appStarted(const QByteArray &startup_id); 0065 0066 /** 0067 * Sets a new value for the application startup notification window property for newly 0068 * created toplevel windows. 0069 * @param startup_id the startup notification identifier 0070 * @see KStartupInfo::setNewStartupId 0071 */ 0072 static void setStartupId(const QByteArray &startup_id); 0073 0074 /** 0075 * Use this function if the application got a request with startup 0076 * notification from outside (for example, when KUniqueApplication::newInstance() 0077 * is called, or e.g.\ when khelpcenter opens new URL in its window). 0078 * The window can be either an already existing and visible window, 0079 * or a new one, before being shown. Note that this function is usually 0080 * needed only when a window is reused. 0081 */ 0082 static void setNewStartupId(QWindow *window, const QByteArray &startup_id); 0083 0084 /** 0085 * Creates and returns new startup id. The id includes properly setup 0086 * user timestamp. 0087 * 0088 * On the X11 platform the current timestamp will be fetched from the 0089 * X-Server. If the caller has an adaquat timestamp (e.g. from a QMouseEvent) 0090 * it should prefer using createNewStartupIdForTimestamp to not trigger a 0091 * roundtrip to the X-Server 0092 * 0093 * @see createNewStartupIdForTimestamp 0094 */ 0095 static QByteArray createNewStartupId(); 0096 /** 0097 * Creates and returns new startup id with @p timestamp as user timestamp part. 0098 * 0099 * @param timestamp The timestamp for the startup id. 0100 * @see createNewStartupId 0101 * @since 5.5 0102 **/ 0103 static QByteArray createNewStartupIdForTimestamp(quint32 timestamp); 0104 /** 0105 * 0106 */ 0107 enum { 0108 CleanOnCantDetect = 1 << 0, 0109 DisableKWinModule = 1 << 1, 0110 AnnounceSilenceChanges = 1 << 2, 0111 }; 0112 0113 /** 0114 * Creates an instance that will receive the startup notifications. 0115 * The various flags passed may be 0116 * @li CleanOnCantDetect - when a new unknown window appears, all startup 0117 * notifications for applications that are not compliant with 0118 * the startup protocol are removed 0119 * @li DisableKWinModule - KWinModule, which is normally used to detect 0120 * new windows, is disabled. With this flag, checkStartup() must be 0121 * called in order to check newly mapped windows. 0122 * @li AnnounceSilenceChanges - normally, startup notifications are 0123 * "removed" when they're silenced, and "recreated" when they're resumed. 0124 * With this flag, the change is normally announced with gotStartupChange(). 0125 * 0126 * @param flags OR-ed combination of flags 0127 * @param parent the parent of this QObject (can be @c nullptr for no parent) 0128 * 0129 */ 0130 explicit KStartupInfo(int flags, QObject *parent = nullptr); 0131 0132 ~KStartupInfo() override; 0133 /** 0134 * Sends given notification data about started application 0135 * with the given startup identification. If no notification for this identification 0136 * exists yet, it is created, otherwise it's updated. Note that the name field 0137 * in data is required. 0138 * 0139 * @param id the id of the application 0140 * @param data the application's data 0141 * @return true if successful, false otherwise 0142 * @see KStartupInfoId 0143 * @see KStartupInfoData 0144 */ 0145 static bool sendStartup(const KStartupInfoId &id, const KStartupInfoData &data); 0146 0147 /** 0148 * Like sendStartup , uses @p conn instead of QX11Info::connection() for sending the info. 0149 * @param conn the xcb connection of the application. Note that the name field 0150 * in data is required. 0151 * @param screen The x11 screen the connection belongs to 0152 * @param id the id of the application 0153 * @param data the application's data 0154 * @return true if successful, false otherwise 0155 * @since 5.18 0156 */ 0157 static bool sendStartupXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id, const KStartupInfoData &data); 0158 0159 /** 0160 * Sends given notification data about started application 0161 * with the given startup identification. This is used for updating the notification 0162 * info, if no notification for this identification exists, it's ignored. 0163 * @param id the id of the application 0164 * @param data the application's data 0165 * @return true if successful, false otherwise 0166 * @see KStartupInfoId 0167 * @see KStartupInfoData 0168 */ 0169 static bool sendChange(const KStartupInfoId &id, const KStartupInfoData &data); 0170 0171 /** 0172 * Like sendChange , uses @p conn instead of QX11Info::connection() for sending the info. 0173 * @param conn the xcb connection of the application. 0174 * @param screen The x11 screen the connection belongs to 0175 * @param id the id of the application 0176 * @param data the application's data 0177 * @return true if successful, false otherwise 0178 * @since 5.18 0179 */ 0180 static bool sendChangeXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id, const KStartupInfoData &data); 0181 0182 /** 0183 * Ends startup notification with the given identification. 0184 * @param id the id of the application 0185 * @return true if successful, false otherwise 0186 */ 0187 static bool sendFinish(const KStartupInfoId &id); 0188 0189 /** 0190 * Like sendFinish , uses @p conn instead of QX11Info::connection() for sending the info. 0191 * @param conn the xcb connection of the application. 0192 * @param screen The x11 screen the connection belongs to 0193 * @param id the id of the application 0194 * @return true if successful, false otherwise 0195 * @since 5.18 0196 */ 0197 static bool sendFinishXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id); 0198 0199 /** 0200 * Ends startup notification with the given identification and the given data 0201 * (e.g.\ PIDs of processes for this startup notification that exited). 0202 * @param id the id of the application 0203 * @param data the application's data 0204 * @return true if successful, false otherwise 0205 */ 0206 static bool sendFinish(const KStartupInfoId &id, const KStartupInfoData &data); 0207 0208 /** 0209 * Like sendFinish , uses @p conn instead of QX11Info::connection() for sending the info. 0210 * @param conn the xcb connection of the application. 0211 * @param screen The x11 screen the connection belongs to 0212 * @param id the id of the application 0213 * @param data the application's data 0214 * @return true if successful, false otherwise 0215 * @since 5.18 0216 */ 0217 static bool sendFinishXcb(xcb_connection_t *conn, int screen, const KStartupInfoId &id, const KStartupInfoData &data); 0218 0219 /** 0220 * Unsets the startup notification environment variable. 0221 */ 0222 static void resetStartupEnv(); 0223 /** 0224 * @li NoMatch - the window doesn't match any existing startup notification 0225 * @li Match - the window matches an existing startup notification 0226 * @li CantDetect - unable to detect if the window matches any existing 0227 * startup notification 0228 */ 0229 enum startup_t { NoMatch, Match, CantDetect }; 0230 /** 0231 * Checks if the given windows matches any existing startup notification. 0232 * @param w the window id to check 0233 * @return the result of the operation 0234 */ 0235 startup_t checkStartup(WId w); 0236 /** 0237 * Checks if the given windows matches any existing startup notification, and 0238 * if yes, returns the identification in id. 0239 * @param w the window id to check 0240 * @param id if found, the id of the startup notification will be written here 0241 * @return the result of the operation 0242 */ 0243 startup_t checkStartup(WId w, KStartupInfoId &id); 0244 /** 0245 * Checks if the given windows matches any existing startup notification, and 0246 * if yes, returns the notification data in data. 0247 * @param w the window id to check 0248 * @param data if found, the data of the startup notification will be written here 0249 * @return the result of the operation 0250 */ 0251 startup_t checkStartup(WId w, KStartupInfoData &data); 0252 /** 0253 * Checks if the given windows matches any existing startup notification, and 0254 * if yes, returns the identification in id and notification data in data. 0255 * @param w the window id to check 0256 * @param id if found, the id of the startup notification will be written here 0257 * @param data if found, the data of the startup notification will be written here 0258 * @return the result of the operation 0259 */ 0260 startup_t checkStartup(WId w, KStartupInfoId &id, KStartupInfoData &data); 0261 /** 0262 * Sets the timeout for notifications, after this timeout a notification is removed. 0263 * @param secs the new timeout in seconds 0264 */ 0265 void setTimeout(unsigned int secs); 0266 /** 0267 * Returns startup notification identification of the given window. 0268 * @param w the id of the window 0269 * @return the startup notification id. Can be null if not found. 0270 */ 0271 static QByteArray windowStartupId(WId w); 0272 /** 0273 * @internal 0274 */ 0275 class Data; 0276 0277 /** 0278 * @internal 0279 */ 0280 class Private; 0281 Q_SIGNALS: 0282 /** 0283 * Emitted when a new startup notification is created (i.e.\ a new application is 0284 * being started). 0285 * @param id the notification identification 0286 * @param data the notification data 0287 */ 0288 void gotNewStartup(const KStartupInfoId &id, const KStartupInfoData &data); 0289 /** 0290 * Emitted when a startup notification changes. 0291 * @param id the notification identification 0292 * @param data the notification data 0293 */ 0294 void gotStartupChange(const KStartupInfoId &id, const KStartupInfoData &data); 0295 /** 0296 * Emitted when a startup notification is removed (either because it was detected 0297 * that the application is ready or because of a timeout). 0298 * @param id the notification identification 0299 * @param data the notification data 0300 */ 0301 void gotRemoveStartup(const KStartupInfoId &id, const KStartupInfoData &data); 0302 0303 protected: 0304 /** 0305 * 0306 */ 0307 void customEvent(QEvent *e_P) override; 0308 0309 private: 0310 Q_PRIVATE_SLOT(d, void startups_cleanup()) 0311 Q_PRIVATE_SLOT(d, void startups_cleanup_no_age()) 0312 Q_PRIVATE_SLOT(d, void got_message(const QString &msg)) 0313 Q_PRIVATE_SLOT(d, void window_added(WId w)) 0314 Q_PRIVATE_SLOT(d, void slot_window_added(WId w)) 0315 0316 Private *const d; 0317 0318 Q_DISABLE_COPY(KStartupInfo) 0319 }; 0320 0321 /** 0322 * Class representing an identification of application startup notification. 0323 * 0324 * Every existing notification about a starting application has its own unique 0325 * identification, that's used to identify and manipulate the notification. 0326 * 0327 * @see KStartupInfo 0328 * @see KStartupInfoData 0329 * 0330 * @author Lubos Lunak <l.lunak@kde.org> 0331 */ 0332 class KWINDOWSYSTEM_EXPORT KStartupInfoId 0333 { 0334 public: 0335 /** 0336 * Overloaded operator. 0337 * @return true if the notification identifications are the same 0338 */ 0339 bool operator==(const KStartupInfoId &id) const; 0340 /** 0341 * Overloaded operator. 0342 * @return true if the notification identifications are different 0343 */ 0344 bool operator!=(const KStartupInfoId &id) const; 0345 /** 0346 * Checks whether the identifier is valid. 0347 * @return true if this object doesn't represent a valid notification identification 0348 */ 0349 bool isNull() const; 0350 0351 /** 0352 * Initializes this object with the given identification ( which may be also "0" 0353 * for no notification ), or if "" is given, tries to read it from the startup 0354 * notification environment variable, and if it's not set, creates a new one. 0355 * @param id the new identification, "0" for no notification or "" to read 0356 * the environment variable 0357 */ 0358 void initId(const QByteArray &id = ""); 0359 /** 0360 * Returns the notification identifier as string. 0361 * @return the identification string for the notification 0362 */ 0363 const QByteArray &id() const; 0364 /** 0365 * Return the user timestamp for the startup notification, or 0 if no timestamp 0366 * is set. 0367 */ 0368 unsigned long timestamp() const; 0369 /** 0370 * Sets the startup notification environment variable to this identification. 0371 * @return true if successful, false otherwise 0372 */ 0373 bool setupStartupEnv() const; 0374 /** 0375 * Creates an empty identification 0376 */ 0377 KStartupInfoId(); 0378 /** 0379 * Copy constructor. 0380 */ 0381 KStartupInfoId(const KStartupInfoId &data); 0382 ~KStartupInfoId(); 0383 KStartupInfoId &operator=(const KStartupInfoId &data); 0384 bool operator<(const KStartupInfoId &id) const; 0385 0386 private: 0387 explicit KStartupInfoId(const QString &txt); 0388 friend class KStartupInfo; 0389 friend class KStartupInfo::Private; 0390 struct Private; 0391 Private *const d; 0392 }; 0393 0394 /** 0395 * Class representing data about an application startup notification. 0396 * 0397 * Such data include the icon of the starting application, the desktop on which 0398 * the application should start, the binary name of the application, etc. 0399 * 0400 * @see KStartupInfo 0401 * @see KStartupInfoId 0402 * 0403 * @author Lubos Lunak <l.lunak@kde.org> 0404 */ 0405 class KWINDOWSYSTEM_EXPORT KStartupInfoData 0406 { 0407 public: 0408 /** 0409 * Sets the binary name of the application (e.g.\ 'kcontrol'). 0410 * @param bin the new binary name of the application 0411 */ 0412 void setBin(const QString &bin); 0413 /** 0414 * Returns the binary name of the starting application 0415 * @return the new binary name of the application 0416 */ 0417 const QString &bin() const; 0418 /** 0419 * Sets the name for the notification (e.g.\ 'Control Center'). 0420 */ 0421 void setName(const QString &name); 0422 /** 0423 * Returns the name of the startup notification. If it's not available, 0424 * it tries to use other information (binary name). 0425 * @return the name of the startup notification 0426 */ 0427 const QString &findName() const; 0428 /** 0429 * Returns the name of the startup notification, or empty if not available. 0430 * @return the name of the startup notification, or an empty string 0431 * if not set. 0432 */ 0433 const QString &name() const; 0434 /** 0435 * Sets the description for the notification (e.g.\ 'Launching Control Center'). 0436 * I.e. name() describes what is being started, while description() is 0437 * the actual action performed by the starting. 0438 */ 0439 void setDescription(const QString &descr); 0440 /** 0441 * Returns the description of the startup notification. If it's not available, 0442 * it returns name(). 0443 * @return the description of the startup notification 0444 */ 0445 const QString &findDescription() const; 0446 /** 0447 * Returns the name of the startup notification, or empty if not available. 0448 * @return the name of the startup notification, or an empty string 0449 * if not set. 0450 */ 0451 const QString &description() const; 0452 /** 0453 * Sets the icon for the startup notification (e.g.\ 'kcontrol'). 0454 * @param icon the name of the icon 0455 */ 0456 void setIcon(const QString &icon); 0457 /** 0458 * Returns the icon of the startup notification, and if it's not available, 0459 * tries to get it from the binary name. 0460 * @return the name of the startup notification's icon, or the name of 0461 * the binary if not set 0462 */ 0463 const QString &findIcon() const; 0464 /** 0465 * Returns the icon of the startup notification, or empty if not available. 0466 * @return the name of the icon, or an empty string if not set. 0467 */ 0468 const QString &icon() const; 0469 /** 0470 * Sets the desktop for the startup notification (i.e.\ the desktop on which 0471 * the starting application should appear ). 0472 * @param desktop the desktop for the startup notification 0473 */ 0474 void setDesktop(int desktop); 0475 /** 0476 * Returns the desktop for the startup notification. 0477 * @return the desktop for the startup notification 0478 */ 0479 int desktop() const; 0480 /** 0481 * Sets a WM_CLASS value for the startup notification, it may be used for increasing 0482 * the chance that the windows created by the starting application will be 0483 * detected correctly. 0484 * @param wmclass the WM_CLASS value for the startup notification 0485 */ 0486 void setWMClass(const QByteArray &wmclass); 0487 /** 0488 * Returns the WM_CLASS value for the startup notification, or binary name if not 0489 * available. 0490 * @return the WM_CLASS value for the startup notification, or the binary name 0491 * if not set 0492 */ 0493 const QByteArray findWMClass() const; 0494 /** 0495 * Returns the WM_CLASS value for the startup notification, or empty if not available. 0496 * @return the WM_CLASS value for the startup notification, or empty 0497 * if not set 0498 */ 0499 QByteArray WMClass() const; 0500 /** 0501 * Adds a PID to the list of processes that belong to the startup notification. It 0502 * may be used to increase the chance that the windows created by the starting 0503 * application will be detected correctly, and also for detecting if the application 0504 * has quit without creating any window. 0505 * @param pid the PID to add 0506 */ 0507 void addPid(pid_t pid); 0508 /** 0509 * Returns all PIDs for the startup notification. 0510 * @return the list of all PIDs 0511 */ 0512 QList<pid_t> pids() const; 0513 /** 0514 * Checks whether the given @p pid is in the list of PIDs for startup 0515 * notification. 0516 * @return true if the given @p pid is in the list of PIDs for the startup notification 0517 */ 0518 bool is_pid(pid_t pid) const; 0519 /** 0520 * Sets the hostname on which the application is starting. It's necessary to set 0521 * it if PIDs are set. 0522 * @param hostname the application's hostname. If it's a null string, the current hostname is used 0523 */ 0524 void setHostname(const QByteArray &hostname = QByteArray()); 0525 /** 0526 * Returns the hostname for the startup notification. 0527 * @return the hostname 0528 */ 0529 QByteArray hostname() const; 0530 0531 /** 0532 * 0533 */ 0534 enum TriState { Yes, No, Unknown }; 0535 0536 /** 0537 * Sets whether the visual feedback for this startup notification 0538 * should be silenced (temporarily suspended). 0539 */ 0540 void setSilent(TriState state); 0541 0542 /** 0543 * Return the silence status for the startup notification. 0544 * @return KStartupInfoData::Yes if visual feedback is silenced 0545 */ 0546 TriState silent() const; 0547 0548 /** 0549 * The X11 screen on which the startup notification is happening, -1 if unknown. 0550 */ 0551 int screen() const; 0552 0553 /** 0554 * Sets the X11 screen on which the startup notification should happen. 0555 * This is usually not necessary to set, as it's set by default to QX11Info::screen(). 0556 */ 0557 void setScreen(int screen); 0558 0559 /** 0560 * The Xinerama screen for the startup notification, -1 if unknown. 0561 */ 0562 int xinerama() const; 0563 0564 /** 0565 * Sets the Xinerama screen for the startup notification ( i.e. the screeen on which 0566 * the starting application should appear ). 0567 * @param xinerama the Xinerama screen for the startup notification 0568 */ 0569 void setXinerama(int xinerama); 0570 0571 /** 0572 * The .desktop file used to initiate this startup notification, or empty. This information 0573 * should be used only to identify the application, not to read any additional information. 0574 * @since 4.5 0575 **/ 0576 QString applicationId() const; 0577 0578 /** 0579 * Sets the .desktop file that was used to initiate the startup notification. 0580 * @since 4.5 0581 */ 0582 void setApplicationId(const QString &desktop); 0583 0584 /** 0585 * Updates the notification data from the given data. Some data, such as the desktop 0586 * or the name, won't be rewritten if already set. 0587 * @param data the data to update 0588 */ 0589 void update(const KStartupInfoData &data); 0590 0591 /** 0592 * Constructor. Initializes all the data to their default empty values. 0593 */ 0594 KStartupInfoData(); 0595 0596 /** 0597 * Copy constructor. 0598 */ 0599 KStartupInfoData(const KStartupInfoData &data); 0600 ~KStartupInfoData(); 0601 KStartupInfoData &operator=(const KStartupInfoData &data); 0602 0603 private: 0604 explicit KStartupInfoData(const QString &txt); 0605 friend class KStartupInfo; 0606 friend class KStartupInfo::Data; 0607 friend class KStartupInfo::Private; 0608 struct Private; 0609 Private *const d; 0610 }; 0611 0612 #endif