File indexing completed on 2024-05-05 17:45:24

0001 /*
0002     Holds one embedded window, registers as DBus entry
0003     SPDX-FileCopyrightText: 2015 David Edmundson <davidedmundson@kde.org>
0004     SPDX-FileCopyrightText: 2019 Konrad Materka <materka@gmail.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-or-later
0007 */
0008 
0009 #pragma once
0010 
0011 #include <QDBusArgument>
0012 #include <QDBusConnection>
0013 #include <QDBusObjectPath>
0014 #include <QObject>
0015 #include <QPixmap>
0016 #include <QPoint>
0017 
0018 #include <xcb/xcb.h>
0019 #include <xcb/xcb_image.h>
0020 
0021 #include "snidbus.h"
0022 
0023 class SNIProxy : public QObject
0024 {
0025     Q_OBJECT
0026     Q_PROPERTY(QString Category READ Category)
0027     Q_PROPERTY(QString Id READ Id)
0028     Q_PROPERTY(QString Title READ Title)
0029     Q_PROPERTY(QString Status READ Status)
0030     Q_PROPERTY(int WindowId READ WindowId)
0031     Q_PROPERTY(bool ItemIsMenu READ ItemIsMenu)
0032     Q_PROPERTY(KDbusImageVector IconPixmap READ IconPixmap)
0033 
0034 public:
0035     explicit SNIProxy(xcb_window_t wid, QObject *parent = nullptr);
0036     ~SNIProxy() override;
0037 
0038     void update();
0039     void resizeWindow(const uint16_t width, const uint16_t height) const;
0040     void hideContainerWindow(xcb_window_t windowId) const;
0041 
0042     /**
0043      * @return the category of the application associated to this item
0044      * @see Category
0045      */
0046     QString Category() const;
0047 
0048     /**
0049      * @return the id of this item
0050      */
0051     QString Id() const;
0052 
0053     /**
0054      * @return the title of this item
0055      */
0056     QString Title() const;
0057 
0058     /**
0059      * @return The status of this item
0060      * @see Status
0061      */
0062     QString Status() const;
0063 
0064     /**
0065      * @return The id of the main window of the application that controls the item
0066      */
0067     int WindowId() const;
0068 
0069     /**
0070      * @return The item only support the context menu, the visualization should prefer sending ContextMenu() instead of Activate()
0071      */
0072     bool ItemIsMenu() const;
0073 
0074     /**
0075      * @return a serialization of the icon data
0076      */
0077     KDbusImageVector IconPixmap() const;
0078 
0079 public Q_SLOTS:
0080     // interaction
0081     /**
0082      * Shows the context menu associated to this item
0083      * at the desired screen position
0084      */
0085     void ContextMenu(int x, int y);
0086 
0087     /**
0088      * Shows the main widget and try to position it on top
0089      * of the other windows, if the widget is already visible, hide it.
0090      */
0091     void Activate(int x, int y);
0092 
0093     /**
0094      * The user activated the item in an alternate way (for instance with middle mouse button, this depends from the systray implementation)
0095      */
0096     void SecondaryActivate(int x, int y);
0097 
0098     /**
0099      * Inform this item that the mouse wheel was used on its representation
0100      */
0101     void Scroll(int delta, const QString &orientation);
0102 
0103 Q_SIGNALS:
0104     /**
0105      * Inform the systemtray that the own main icon has been changed,
0106      * so should be reloaded
0107      */
0108     void NewIcon();
0109 
0110     /**
0111      * Inform the systemtray that there is a new icon to be used as overlay
0112      */
0113     void NewOverlayIcon();
0114 
0115     /**
0116      * Inform the systemtray that the requesting attention icon
0117      * has been changed, so should be reloaded
0118      */
0119     void NewAttentionIcon();
0120 
0121     /**
0122      * Inform the systemtray that something in the tooltip has been changed
0123      */
0124     void NewToolTip();
0125 
0126     /**
0127      * Signal the new status when it has been changed
0128      * @see Status
0129      */
0130     void NewStatus(const QString &status);
0131 
0132 private:
0133     enum InjectMode {
0134         Direct,
0135         XTest,
0136     };
0137 
0138     QSize calculateClientWindowSize() const;
0139     void sendClick(uint8_t mouseButton, int x, int y);
0140     QImage getImageNonComposite() const;
0141     bool isTransparentImage(const QImage &image) const;
0142     QImage convertFromNative(xcb_image_t *xcbImage) const;
0143     QPoint calculateClickPoint() const;
0144     void stackContainerWindow(const uint32_t stackMode) const;
0145 
0146     QDBusConnection m_dbus;
0147     xcb_window_t m_windowId;
0148     xcb_window_t m_containerWid;
0149     static int s_serviceCount;
0150     QPixmap m_pixmap;
0151     bool sendingClickEvent;
0152     InjectMode m_injectMode;
0153 };