vcl/inc/qt5/QtInstanceTreeView.hxx |    4 ++++
 vcl/qt5/QtInstanceTreeView.cxx     |   29 +++++++++++++++++++++++++++++
 vcl/unx/gtk3/gtkinst.cxx           |    2 ++
 3 files changed, 35 insertions(+)

New commits:
commit b6cded6e887aa8e15496afb68bd3a4add4af7c12
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Thu Aug 28 10:53:58 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Thu Aug 28 12:18:09 2025 +0200

    tdf#168041 gtk: Hold SolarMutex when querying tree view tooltip
    
    This fixes the below assert seen with gtk4 when
    hovering over paragraph styles in the "Styles" sidebar
    deck in Writer with.
    
        soffice.bin: 
/home/michi/development/git/libreoffice/vcl/source/app/dbggui.cxx:36: void 
ImplDbgTestSolarMutex(bool): Assertion 
`ImplGetSVData()->mpDefInst->GetYieldMutex()->IsCurrentThread() && "SolarMutex 
not owned!"' failed.
    
        Thread 1 received signal SIGABRT, Aborted.
        __pthread_kill_implementation (threadid=<optimized out>, 
signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
        warning: 44     ./nptl/pthread_kill.c: No such file or directory
        (rr) bt
        #0  __pthread_kill_implementation (threadid=<optimized out>, 
signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
        #1  0x00007fe0abe9e9ff in __pthread_kill_internal (threadid=<optimized 
out>, signo=6) at ./nptl/pthread_kill.c:89
        #2  0x00007fe0abe49cc2 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/posix/raise.c:26
        #3  0x00007fe0abe324ac in __GI_abort () at ./stdlib/abort.c:73
        #4  0x00007fe0abe32420 in __assert_fail_base (fmt=<optimized out>, 
assertion=<optimized out>, file=<optimized out>, line=36, function=<optimized 
out>) at ./assert/assert.c:118
        #5  0x00007fe0a31b5ccc in ImplDbgTestSolarMutex (owned=true) at 
/home/michi/development/git/libreoffice/vcl/source/app/dbggui.cxx:36
        #6  0x00007fe0aa32b044 in DbgTestSolarMutex (owned=true) at 
/home/michi/development/git/libreoffice/tools/source/debug/debug.cxx:54
        #7  0x00007fe0549fc572 in SwModify::CallSwClientNotify 
(this=0x559770009880, rHint=...) at 
/home/michi/development/git/libreoffice/sw/source/core/attr/calbck.cxx:273
        #8  0x00007fe0549fc9b1 in sw::BroadcastingModify::CallSwClientNotify 
(this=0x559770009880, rHint=...) at 
/home/michi/development/git/libreoffice/sw/source/core/attr/calbck.cxx:297
        #9  0x00007fe054f0cd67 in SwDoc::IsUsed (this=0x55976fdd1cf0, 
rModify=...) at 
/home/michi/development/git/libreoffice/sw/source/core/doc/poolfmt.cxx:109
        #10 0x00007fe055e8fe47 in SwDocStyleSheet::IsUsed (this=0x55976fe02e80) 
at 
/home/michi/development/git/libreoffice/sw/source/uibase/app/docstyle.cxx:2481
        #11 0x00007fe0a83f603d in StyleList::QueryTooltipHdl 
(this=0x559771b48dd0, rEntry=...) at 
/home/michi/development/git/libreoffice/sfx2/source/dialog/StyleList.cxx:1753
        #12 0x00007fe0a83edd68 in StyleList::LinkStubQueryTooltipHdl 
(instance=0x559771b48dd0, data=...) at 
/home/michi/development/git/libreoffice/sfx2/source/dialog/StyleList.cxx:1743
        #13 0x00007fe09a7907bd in Link<weld::TreeIter const&, 
rtl::OUString>::Call (this=0x559771b27bb8, data=...) at 
include/tools/link.hxx:105
        #14 0x00007fe09a79075f in weld::TreeView::signal_query_tooltip 
(this=0x559771b27a08, rIter=...) at include/vcl/weld.hxx:1025
        #15 0x00007fe09a6e8d09 in (anonymous 
namespace)::GtkInstanceTreeView::signalQueryTooltip (x=382, y=153, 
keyboard_tip=0, tooltip=0x559769fbaa90, widget=0x559771b27400) at 
vcl/unx/gtk4/../gtk3/gtkinst.cxx:14531
        #16 0x00007fe0994dedfc in _gtk_marshal_BOOLEAN__INT_INT_BOOLEAN_OBJECT 
(closure=0x559771b24580, return_value=0x7ffef76e15b0, n_param_values=5, 
param_values=0x7ffef76e1640, invocation_hint=0x7ffef76e1590, marshal_data=0x0)
            at gtk/gtkmarshalers.c:1109
        #17 0x00007fe0a967d950 in g_closure_invoke () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #18 0x00007fe0a9691d43 in ??? () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #19 0x00007fe0a9693032 in ??? () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #20 0x00007fe0a96995a6 in g_signal_emit_valist () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #21 0x00007fe0a9699663 in g_signal_emit () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #22 0x00007fe0997c6ada in gtk_widget_query_tooltip 
(widget=0x55976892b2b0, x=382, y=153, keyboard_mode=0, tooltip=0x559769fbaa90) 
at ../gtk/gtkwidget.c:5114
        #23 0x00007fe0997af430 in gtk_tooltip_run_requery 
(widget=0x7ffef76e1a58, tooltip=0x559769fbaa90, x=0x7ffef76e1a90, 
y=0x7ffef76e1a8c) at ../gtk/gtktooltip.c:559
        #24 0x00007fe0997b01bb in gtk_tooltip_handle_event_internal 
(event_type=GDK_MOTION_NOTIFY, surface=0x559764aa88a0, 
target_widget=0x55976892b2b0, dx=382.953125, dy=153.796875) at 
../gtk/gtktooltip.c:1009
        #25 0x00007fe0997b0065 in _gtk_tooltip_handle_event 
(target=0x55976892b2b0, event=0x559772515280) at ../gtk/gtktooltip.c:957
        #26 0x00007fe099686120 in gtk_main_do_event (event=0x559772515280) at 
../gtk/gtkmain.c:1751
        #27 0x00007fe0997e6720 in surface_event (surface=0x559764aa88a0, 
event=0x559772515280, widget=0x55976a125f10) at ../gtk/gtkwindow.c:4951
        #28 0x00007fe099a684cb in _gdk_marshal_BOOLEAN__POINTERv 
(closure=0x55976bc7ddf0, return_value=0x7ffef76e1eb0, instance=0x559764aa88a0, 
args=0x7ffef76e1fb0, marshal_data=0x0, n_params=1, param_types=0x559764ac5730)
            at gdk/gdkmarshalers.c:302
        #29 0x00007fe099b50e3c in gdk_surface_event_marshallerv 
(closure=0x55976bc7ddf0, return_value=0x7ffef76e1eb0, instance=0x559764aa88a0, 
args=0x7ffef76e1fb0, marshal_data=0x0, n_params=1, param_types=0x559764ac5730)
            at ../gdk/gdksurface.c:465
        #30 0x00007fe0a967db81 in ??? () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #31 0x00007fe0a9692b33 in ??? () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #32 0x00007fe0a96995a6 in g_signal_emit_valist () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #33 0x00007fe0a9699663 in g_signal_emit () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #34 0x00007fe099b55ee7 in gdk_surface_handle_event 
(event=0x559772515280) at ../gdk/gdksurface.c:3001
        #35 0x00007fe099b0ae91 in _gdk_event_emit (event=0x559772515280) at 
../gdk/gdkevents.c:491
        #36 0x00007fe099b0b946 in _gdk_event_queue_flush 
(display=0x5597649c1140) at ../gdk/gdkevents.c:856
        #37 0x00007fe099b54d84 in gdk_surface_flush_events 
(clock=0x559764a437b0, data=0x559764aa88a0) at ../gdk/gdksurface.c:2419
        #38 0x00007fe0a967db81 in ??? () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #39 0x00007fe0a96938b8 in ??? () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #40 0x00007fe0a96995a6 in g_signal_emit_valist () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #41 0x00007fe0a9699663 in g_signal_emit () at 
/lib/x86_64-linux-gnu/libgobject-2.0.so.0
        #42 0x00007fe099b13cae in _gdk_frame_clock_emit_flush_events 
(frame_clock=0x559764a437b0) at ../gdk/gdkframeclock.c:701
        #43 0x00007fe099b1492d in gdk_frame_clock_flush_idle 
(data=0x559764a437b0) at ../gdk/gdkframeclockidle.c:391
        #44 0x00007fe09e50744e in ??? () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
        #45 0x00007fe09e5043c5 in ??? () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
        #46 0x00007fe09e5065f7 in ??? () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
        #47 0x00007fe09e506d60 in g_main_context_iteration () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
        #48 0x00007fe09a683dac in GtkSalData::Yield (this=0x5597637370a0, 
bWait=true, bHandleAllCurrentEvents=false) at 
vcl/unx/gtk4/../gtk3/gtkdata.cxx:403
        #49 0x00007fe09a689403 in GtkInstance::DoYield (this=0x559763736f50, 
bWait=true, bHandleAllCurrentEvents=false) at 
vcl/unx/gtk4/../gtk3/gtkinst.cxx:440
        #50 0x00007fe0a328c606 in ImplYield (i_bWait=true, i_bAllEvents=false) 
at /home/michi/development/git/libreoffice/vcl/source/app/svapp.cxx:385
        #51 0x00007fe0a328bf1f in Application::Yield () at 
/home/michi/development/git/libreoffice/vcl/source/app/svapp.cxx:488
        #52 0x00007fe0a328bd00 in Application::Execute () at 
/home/michi/development/git/libreoffice/vcl/source/app/svapp.cxx:360
        #53 0x00007fe0ac129915 in desktop::Desktop::Main (this=0x7ffef76e4160) 
at /home/michi/development/git/libreoffice/desktop/source/app/app.cxx:1678
        #54 0x00007fe0a32b8526 in ImplSVMain () at 
/home/michi/development/git/libreoffice/vcl/source/app/svmain.cxx:230
        #55 0x00007fe0a32ba019 in SVMain () at 
/home/michi/development/git/libreoffice/vcl/source/app/svmain.cxx:248
        #56 0x00007fe0ac1a35ca in soffice_main () at 
/home/michi/development/git/libreoffice/desktop/source/app/sofficemain.cxx:122
        #57 0x0000559759c3b9fd in sal_main () at 
/home/michi/development/git/libreoffice/desktop/source/app/main.c:51
        #58 0x0000559759c3b9d7 in main (argc=2, argv=0x7ffef76e4368) at 
/home/michi/development/git/libreoffice/desktop/source/app/main.c:49
    
    Change-Id: If520816e8f748a7f082226d216b10aa5a2c27717
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190318
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index b51c24893707..81fac405b837 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -14528,6 +14528,8 @@ private:
         if (!gtk_tree_view_get_tooltip_context(pTreeView, &x, &y, 
keyboard_tip, &pModel, &pPath, &iter))
             return false;
 #endif
+
+        SolarMutexGuard g;
         OUString aTooltip = 
pThis->signal_query_tooltip(GtkInstanceTreeIter(iter));
         if (!aTooltip.isEmpty())
         {
commit 39075c7db1d10542dec318f410ae9b03ac615355
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Thu Aug 28 10:41:11 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Thu Aug 28 12:18:02 2025 +0200

    tdf#130857 qt weld: Implement TreeView tooltip handling
    
    Handle the QEvent::ToolTip event for the
    QTreeView's viewport. Retrieve the tooltip
    for the item using weld::TreeView::signal_query_tooltip
    and display it if it's non-empty.
    
    This makes the file path of the corresponding template
    show up when hovering over an item in the
    "File" -> "Templates" -> "Manage Templates" dialog
    with the list view mode enabled with
    SAL_VCL_QT_USE_WELDED_WIDGETS=1, in a WIP branch
    where support for that dialog using native Qt widgets
    is declared.
    
    Change-Id: Ia849a9fa6506ffbd2d74be00600e0a694f1b9efd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190317
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/inc/qt5/QtInstanceTreeView.hxx 
b/vcl/inc/qt5/QtInstanceTreeView.hxx
index aa78075d38aa..cc36e5bbbea6 100644
--- a/vcl/inc/qt5/QtInstanceTreeView.hxx
+++ b/vcl/inc/qt5/QtInstanceTreeView.hxx
@@ -209,6 +209,8 @@ public:
     static void setColumnRoles(QTreeView& rTreeView,
                                const QList<QList<Qt::ItemDataRole>>& 
rDataRoles);
 
+    virtual bool eventFilter(QObject* pObject, QEvent* pEvent) override;
+
 private:
     QModelIndex modelIndex(int nRow, int nCol = 0,
                            const QModelIndex& rParentIndex = QModelIndex()) 
const;
@@ -221,6 +223,8 @@ private:
 
     void setImage(const weld::TreeIter& rIter, const QPixmap& rPixmap, int 
nCol);
 
+    bool handleToolTipEvent(const QHelpEvent* pEvent);
+
 private Q_SLOTS:
     void handleActivated();
     void handleDataChanged(const QModelIndex& rTopLeft, const QModelIndex& 
rBottomRight,
diff --git a/vcl/qt5/QtInstanceTreeView.cxx b/vcl/qt5/QtInstanceTreeView.cxx
index 3a767595546e..fa5126f42f78 100644
--- a/vcl/qt5/QtInstanceTreeView.cxx
+++ b/vcl/qt5/QtInstanceTreeView.cxx
@@ -13,6 +13,7 @@
 #include <vcl/qt/QtUtils.hxx>
 
 #include <QtWidgets/QHeaderView>
+#include <QtWidgets/QToolTip>
 
 // role used for the ID in the QStandardItem
 constexpr int ROLE_ID = Qt::UserRole + 1000;
@@ -43,6 +44,9 @@ QtInstanceTreeView::QtInstanceTreeView(QTreeView* pTreeView)
             &QtInstanceTreeView::handleSelectionChanged);
     connect(m_pModel, &QSortFilterProxyModel::dataChanged, this,
             &QtInstanceTreeView::handleDataChanged);
+
+    assert(m_pTreeView->viewport());
+    m_pTreeView->viewport()->installEventFilter(this);
 }
 
 void QtInstanceTreeView::insert(const weld::TreeIter* pParent, int nPos, const 
OUString* pStr,
@@ -1097,6 +1101,14 @@ void QtInstanceTreeView::setColumnRoles(QTreeView& 
rTreeView,
     rTreeView.setProperty(PROPERTY_COLUMN_ROLES, 
QVariant::fromValue(rDataRoles));
 }
 
+bool QtInstanceTreeView::eventFilter(QObject* pObject, QEvent* pEvent)
+{
+    if (pEvent->type() == QEvent::ToolTip && pObject == 
m_pTreeView->viewport())
+        return handleToolTipEvent(static_cast<QHelpEvent*>(pEvent));
+
+    return QtInstanceWidget::eventFilter(pObject, pEvent);
+}
+
 QModelIndex QtInstanceTreeView::modelIndex(int nRow, int nCol,
                                            const QModelIndex& rParentIndex) 
const
 {
@@ -1158,6 +1170,23 @@ void QtInstanceTreeView::setImage(const weld::TreeIter& 
rIter, const QPixmap& rP
     });
 }
 
+bool QtInstanceTreeView::handleToolTipEvent(const QHelpEvent* pHelpEvent)
+{
+    QModelIndex aIndex = m_pTreeView->indexAt(pHelpEvent->pos());
+    if (!aIndex.isValid())
+        return false;
+
+    SolarMutexGuard g;
+    const QtInstanceTreeIter aIter(aIndex);
+    const QString sToolTip = toQString(signal_query_tooltip(aIter));
+    if (sToolTip.isEmpty())
+        return false;
+
+    QToolTip::showText(pHelpEvent->globalPos(), sToolTip, m_pTreeView,
+                       m_pTreeView->visualRect(aIndex));
+    return true;
+}
+
 void QtInstanceTreeView::handleActivated()
 {
     SolarMutexGuard g;

Reply via email to