diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}") set(QT_MIN_VERSION "5.5.0") -set(KF5_MIN_VERSION "5.21.0") +set(KF5_MIN_VERSION "5.30.0") set(ECM_MIN_VERSION "1.6.0") # ECM setup diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1021,7 +1021,7 @@ const QPoint pos = m_container->mapToGlobal(itemRect.topLeft().toPoint()); itemRect.moveTo(pos); - m_toolTipManager->showToolTip(item, itemRect); + m_toolTipManager->showToolTip(item, itemRect, nativeParentWidget()->windowHandle()); } emit requestItemInfo(item); diff --git a/src/views/tooltips/filemetadatatooltip.h b/src/views/tooltips/filemetadatatooltip.h --- a/src/views/tooltips/filemetadatatooltip.h +++ b/src/views/tooltips/filemetadatatooltip.h @@ -37,8 +37,8 @@ #endif /** - * @brief Tooltip, that shows the meta information and a preview of one - * or more files. + * @brief Widget that shows the meta information and a preview of one + * or more files inside a KToolTipWidget. */ class FileMetaDataToolTip : public QWidget { @@ -69,10 +69,6 @@ */ void metaDataRequestFinished(const KFileItemList& items); -protected: - virtual void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE; - virtual void showEvent(QShowEvent *) Q_DECL_OVERRIDE; - private: QLabel* m_preview; QLabel* m_name; diff --git a/src/views/tooltips/filemetadatatooltip.cpp b/src/views/tooltips/filemetadatatooltip.cpp --- a/src/views/tooltips/filemetadatatooltip.cpp +++ b/src/views/tooltips/filemetadatatooltip.cpp @@ -47,9 +47,6 @@ m_name(0), m_fileMetaDataWidget(0) { - setAttribute(Qt::WA_TranslucentBackground); - setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint); - // Create widget for file preview m_preview = new QLabel(this); m_preview->setAlignment(Qt::AlignTop); @@ -161,19 +158,3 @@ return m_fileMetaDataWidget->items(); } -void FileMetaDataToolTip::paintEvent(QPaintEvent* event) -{ - QStylePainter painter(this); - QStyleOptionFrame option; - option.init(this); - painter.drawPrimitive(QStyle::PE_PanelTipLabel, option); - painter.end(); - - QWidget::paintEvent(event); -} - -void FileMetaDataToolTip::showEvent(QShowEvent *) -{ - KWindowEffects::enableBlurBehind(winId(), true, mask()); -} - diff --git a/src/views/tooltips/tooltipmanager.h b/src/views/tooltips/tooltipmanager.h --- a/src/views/tooltips/tooltipmanager.h +++ b/src/views/tooltips/tooltipmanager.h @@ -26,7 +26,9 @@ #include class FileMetaDataToolTip; +class KToolTipWidget; class QTimer; +class QWindow; /** * @brief Manages the tooltips for an item view. @@ -47,9 +49,9 @@ * Triggers the showing of the tooltip for the item \p item * where the item has the maximum boundaries of \p itemRect. * The tooltip manager takes care that the tooltip is shown - * slightly delayed. + * slightly delayed and with a proper \p transientParent. */ - void showToolTip(const KFileItem& item, const QRectF& itemRect); + void showToolTip(const KFileItem& item, const QRectF& itemRect, QWindow *transientParent); /** * Hides the currently shown tooltip. @@ -72,7 +74,11 @@ /// the tooltip content like preview and meta data gets started. QTimer* m_contentRetrievalTimer; + /// Transient parent of the tooltip, mandatory on Wayland. + QWindow* m_transientParent; + FileMetaDataToolTip* m_fileMetaDataToolTip; + QScopedPointer m_tooltipWidget; bool m_toolTipRequested; bool m_metaDataRequested; diff --git a/src/views/tooltips/tooltipmanager.cpp b/src/views/tooltips/tooltipmanager.cpp --- a/src/views/tooltips/tooltipmanager.cpp +++ b/src/views/tooltips/tooltipmanager.cpp @@ -24,18 +24,22 @@ #include #include #include +#include #include #include #include #include #include +#include ToolTipManager::ToolTipManager(QWidget* parent) : QObject(parent), m_showToolTipTimer(0), m_contentRetrievalTimer(0), + m_transientParent(0), m_fileMetaDataToolTip(0), + m_tooltipWidget(new KToolTipWidget()), m_toolTipRequested(false), m_metaDataRequested(false), m_appliedWaitCursor(false), @@ -62,23 +66,23 @@ ToolTipManager::~ToolTipManager() { - delete m_fileMetaDataToolTip; - m_fileMetaDataToolTip = 0; } -void ToolTipManager::showToolTip(const KFileItem& item, const QRectF& itemRect) +void ToolTipManager::showToolTip(const KFileItem& item, const QRectF& itemRect, QWindow *transientParent) { hideToolTip(); m_itemRect = itemRect.toRect(); m_itemRect.adjust(-m_margin, -m_margin, m_margin, m_margin); m_item = item; + m_transientParent = transientParent; + // Only start the retrieving of the content, when the mouse has been over this // item for 200 milliseconds. This prevents a lot of useless preview jobs and // meta data retrieval, when passing rapidly over a lot of items. - Q_ASSERT(!m_fileMetaDataToolTip); + delete m_fileMetaDataToolTip; m_fileMetaDataToolTip = new FileMetaDataToolTip(); connect(m_fileMetaDataToolTip, &FileMetaDataToolTip::metaDataRequestFinished, this, &ToolTipManager::slotMetaDataRequestFinished); @@ -100,14 +104,7 @@ m_metaDataRequested = false; m_showToolTipTimer->stop(); m_contentRetrievalTimer->stop(); - - if (m_fileMetaDataToolTip) { - m_fileMetaDataToolTip->hide(); - // Do not delete the tool tip immediately to prevent crashes when - // QCoreApplication tries to deliver an 'Enter' event to it, see bug 310579. - m_fileMetaDataToolTip->deleteLater(); - m_fileMetaDataToolTip = 0; - } + m_tooltipWidget->hideLater(); } void ToolTipManager::startContentRetrieval() @@ -200,68 +197,9 @@ return; } - const QRect screen = QApplication::desktop()->screenGeometry(QCursor::pos()); - - // Restrict tooltip size to current screen size when needed. - // Because layout controlling widget doesn't respect widget's maximumSize property - // (correct me if I'm wrong), we need to let layout do its work, then manually change - // geometry if resulting widget doesn't fit the screen. - - // Step #1 - make sizeHint return calculated tooltip size - m_fileMetaDataToolTip->layout()->setSizeConstraint(QLayout::SetFixedSize); + // Adjust the size to get a proper sizeHint() m_fileMetaDataToolTip->adjustSize(); - QSize size = m_fileMetaDataToolTip->sizeHint(); - - // Step #2 - correct tooltip size when needed - if (size.width() > screen.width()) { - size.setWidth(screen.width()); - } - if (size.height() > screen.height()) { - size.setHeight(screen.height()); - } - - // m_itemRect defines the area of the item, where the tooltip should be - // shown. Per default the tooltip is shown centered at the bottom. - // It must be assured that: - // - the content is fully visible - // - the content is not drawn inside m_itemRect - const bool hasRoomToLeft = (m_itemRect.left() - size.width() - m_margin >= screen.left()); - const bool hasRoomToRight = (m_itemRect.right() + size.width() + m_margin <= screen.right()); - const bool hasRoomAbove = (m_itemRect.top() - size.height() - m_margin >= screen.top()); - const bool hasRoomBelow = (m_itemRect.bottom() + size.height() + m_margin <= screen.bottom()); - if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) { - return; - } - - int x, y; - if (hasRoomBelow || hasRoomAbove) { - x = qMax(screen.left(), m_itemRect.center().x() - size.width() / 2); - if (x + size.width() >= screen.right()) { - x = screen.right() - size.width() + 1; - } - if (hasRoomBelow) { - y = m_itemRect.bottom() + m_margin; - } else { - y = m_itemRect.top() - size.height() - m_margin; - } - } else { - Q_ASSERT(hasRoomToLeft || hasRoomToRight); - if (hasRoomToRight) { - x = m_itemRect.right() + m_margin; - } else { - x = m_itemRect.left() - size.width() - m_margin; - } - // Put the tooltip at the bottom of the screen. The x-coordinate has already - // been adjusted, so that no overlapping with m_itemRect occurs. - y = screen.bottom() - size.height() + 1; - } - - // Step #3 - Alter tooltip geometry - m_fileMetaDataToolTip->setFixedSize(size); - m_fileMetaDataToolTip->layout()->setSizeConstraint(QLayout::SetNoConstraint); - m_fileMetaDataToolTip->move(QPoint(x, y)); - m_fileMetaDataToolTip->show(); - + m_tooltipWidget->showBelow(m_itemRect, m_fileMetaDataToolTip, m_transientParent); m_toolTipRequested = false; }