File indexing completed on 2024-11-24 04:59:26

0001 /*
0002     SPDX-FileCopyrightText: 2013 Sebastian Kügler <sebas@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "tooltipdialog.h"
0008 
0009 #include <QDebug>
0010 #include <QFile>
0011 #include <QPlatformSurfaceEvent>
0012 #include <QQmlEngine>
0013 #include <QQuickItem>
0014 
0015 #include <KWindowSystem>
0016 #include <plasmaquick/sharedqmlengine.h>
0017 
0018 #include "waylandintegration_p.h"
0019 
0020 ToolTipDialog::ToolTipDialog()
0021     : PopupPlasmaWindow(QStringLiteral("widgets/tooltip"))
0022     , m_qmlObject(nullptr)
0023     , m_hideTimeout(-1)
0024     , m_interactive(false)
0025     , m_owner(nullptr)
0026 {
0027     Qt::WindowFlags flags = Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint;
0028     if (KWindowSystem::isPlatformX11()) {
0029         flags |= Qt::ToolTip | Qt::BypassWindowManagerHint;
0030     } else {
0031         flags |= Qt::FramelessWindowHint;
0032         PlasmaShellWaylandIntegration::get(this)->setRole(QtWayland::org_kde_plasma_surface::role_tooltip);
0033     }
0034     setFlags(flags);
0035 
0036     m_showTimer = new QTimer(this);
0037     m_showTimer->setSingleShot(true);
0038     connect(m_showTimer, &QTimer::timeout, this, [this]() {
0039         setVisible(false);
0040     });
0041 
0042     connect(this, &PlasmaQuick::PlasmaWindow::mainItemChanged, this, [this]() {
0043         if (m_lastMainItem) {
0044             disconnect(m_lastMainItem, &QQuickItem::implicitWidthChanged, this, &ToolTipDialog::updateSize);
0045             disconnect(m_lastMainItem, &QQuickItem::implicitHeightChanged, this, &ToolTipDialog::updateSize);
0046         }
0047         m_lastMainItem = mainItem();
0048 
0049         if (!mainItem()) {
0050             return;
0051         }
0052         connect(mainItem(), &QQuickItem::implicitWidthChanged, this, &ToolTipDialog::updateSize);
0053         connect(mainItem(), &QQuickItem::implicitHeightChanged, this, &ToolTipDialog::updateSize);
0054         updateSize();
0055     });
0056 }
0057 
0058 ToolTipDialog::~ToolTipDialog()
0059 {
0060 }
0061 
0062 void ToolTipDialog::updateSize()
0063 {
0064     QSize popupSize = QSize(mainItem()->implicitWidth(), mainItem()->implicitHeight());
0065     popupSize = popupSize.grownBy(padding());
0066     if (!popupSize.isEmpty()) {
0067         resize(popupSize);
0068     }
0069 }
0070 
0071 QQuickItem *ToolTipDialog::loadDefaultItem()
0072 {
0073     if (!m_qmlObject) {
0074         m_qmlObject = new PlasmaQuick::SharedQmlEngine(this);
0075     }
0076 
0077     if (!m_qmlObject->rootObject()) {
0078         m_qmlObject->setSource(QUrl(QStringLiteral("qrc:/plasma/DefaultToolTip.qml")));
0079     }
0080 
0081     return qobject_cast<QQuickItem *>(m_qmlObject->rootObject());
0082 }
0083 
0084 void ToolTipDialog::showEvent(QShowEvent *event)
0085 {
0086     keepalive();
0087 
0088     PlasmaQuick::PopupPlasmaWindow::showEvent(event);
0089 }
0090 
0091 void ToolTipDialog::hideEvent(QHideEvent *event)
0092 {
0093     m_showTimer->stop();
0094 
0095     PlasmaQuick::PopupPlasmaWindow::hideEvent(event);
0096 }
0097 
0098 bool ToolTipDialog::event(QEvent *e)
0099 {
0100     if (e->type() == QEvent::Enter) {
0101         if (m_interactive) {
0102             m_showTimer->stop();
0103         }
0104     } else if (e->type() == QEvent::Leave) {
0105         dismiss();
0106     }
0107 
0108     return PopupPlasmaWindow::event(e);
0109 }
0110 
0111 QObject *ToolTipDialog::owner() const
0112 {
0113     return m_owner;
0114 }
0115 
0116 void ToolTipDialog::setOwner(QObject *owner)
0117 {
0118     m_owner = owner;
0119 }
0120 
0121 void ToolTipDialog::dismiss()
0122 {
0123     m_showTimer->start(200);
0124 }
0125 
0126 void ToolTipDialog::keepalive()
0127 {
0128     if (m_hideTimeout > 0) {
0129         m_showTimer->start(m_hideTimeout);
0130     } else {
0131         m_showTimer->stop();
0132     }
0133 }
0134 
0135 bool ToolTipDialog::interactive()
0136 {
0137     return m_interactive;
0138 }
0139 
0140 void ToolTipDialog::setInteractive(bool interactive)
0141 {
0142     m_interactive = interactive;
0143 }
0144 
0145 void ToolTipDialog::valueChanged(const QVariant &value)
0146 {
0147     setPosition(value.toPoint());
0148 }
0149 
0150 void ToolTipDialog::setHideTimeout(int timeout)
0151 {
0152     m_hideTimeout = timeout;
0153 }
0154 
0155 int ToolTipDialog::hideTimeout() const
0156 {
0157     return m_hideTimeout;
0158 }
0159 
0160 #include "moc_tooltipdialog.cpp"