From d89a8ae8f963b3b49db920715cfdee11486764e5 Mon Sep 17 00:00:00 2001 From: Caolán McNamara Date: Thu, 16 Apr 2020 09:26:20 +0100 Subject: don't allow tooltips from parent to appear while popup menu is active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic2ddff3e22a667af992d6b0701f43d3a89153458 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92371 Tested-by: Jenkins Reviewed-by: Caolán McNamara --- vcl/inc/unx/gtk/gtkframe.hxx | 3 +++ vcl/unx/gtk3/gtk3gtkframe.cxx | 16 ++++++++++++++-- vcl/unx/gtk3/gtk3gtkinst.cxx | 28 ++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index f62dd649dbef..e8a76758a959 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -189,6 +189,7 @@ class GtkSalFrame final : public SalFrame bool m_bSpanMonitorsWhenFullscreen; bool m_bDefaultPos; bool m_bDefaultSize; + bool m_bTooltipBlocked; OUString m_sWMClass; std::unique_ptr m_pIMHandler; @@ -489,6 +490,8 @@ public: virtual void SetModal(bool bModal) override; virtual bool GetModal() const override; void HideTooltip(); + void BlockTooltip(); + void UnblockTooltip(); virtual bool ShowTooltip(const OUString& rHelpText, const tools::Rectangle& rHelpArea) override; virtual void* ShowPopover(const OUString& rHelpText, vcl::Window* pParent, const tools::Rectangle& rHelpArea, QuickHelpFlags nFlags) override; virtual bool UpdatePopover(void* nId, const OUString& rHelpText, vcl::Window* pParent, const tools::Rectangle& rHelpArea) override; diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index 18db569607ee..588081965554 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -928,6 +928,7 @@ void GtkSalFrame::InitCommon() m_pDropTarget = nullptr; m_pDragSource = nullptr; m_bGeometryIsProvisional = false; + m_bTooltipBlocked = false; m_ePointerStyle = static_cast(0xffff); m_pSalMenu = nullptr; m_nWatcherId = 0; @@ -2344,7 +2345,7 @@ gboolean GtkSalFrame::signalTooltipQuery(GtkWidget*, gint /*x*/, gint /*y*/, gpointer frame) { GtkSalFrame* pThis = static_cast(frame); - if (pThis->m_aTooltip.isEmpty()) + if (pThis->m_aTooltip.isEmpty() || pThis->m_bTooltipBlocked) return false; gtk_tooltip_set_text(tooltip, OUStringToOString(pThis->m_aTooltip, RTL_TEXTENCODING_UTF8).getStr()); @@ -2367,10 +2368,21 @@ bool GtkSalFrame::ShowTooltip(const OUString& rHelpText, const tools::Rectangle& return true; } +void GtkSalFrame::BlockTooltip() +{ + m_bTooltipBlocked = true; +} + +void GtkSalFrame::UnblockTooltip() +{ + m_bTooltipBlocked = false; +} + void GtkSalFrame::HideTooltip() { m_aTooltip.clear(); - gtk_widget_trigger_tooltip_query(getMouseEventWidget()); + GtkWidget* pEventWidget = getMouseEventWidget(); + gtk_widget_trigger_tooltip_query(pEventWidget); } namespace diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index e24c41a0b4ce..e38911f1c4b1 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -6993,6 +6993,20 @@ bool show_menu_newer_gtk(GtkWidget* pComboBox, GtkWindow* pMenu) void show_menu(GtkWidget* pMenuButton, GtkWindow* pMenu) { + // tdf#120764 It isn't allowed under wayland to have two visible popups that share + // the same top level parent. The problem is that since gtk 3.24 tooltips are also + // implemented as popups, which means that we cannot show any popup if there is a + // visible tooltip. + GtkWidget* pParent = gtk_widget_get_toplevel(pMenuButton); + GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : nullptr; + if (pFrame) + { + // hide any current tooltip + pFrame->HideTooltip(); + // don't allow any more to appear until menu is dismissed + pFrame->BlockTooltip(); + } + // try with gdk_window_move_to_rect, but if that's not available, try without if (!show_menu_newer_gtk(pMenuButton, pMenu)) show_menu_older_gtk(pMenuButton, pMenu); @@ -7038,6 +7052,14 @@ private: // so gdk_window_move_to_rect will work again the next time gtk_widget_unrealize(GTK_WIDGET(m_pMenuHack)); + + gtk_widget_set_size_request(GTK_WIDGET(m_pMenuHack), -1, -1); + + // undo show_menu tooltip blocking + GtkWidget* pParent = gtk_widget_get_toplevel(GTK_WIDGET(m_pMenuButton)); + GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : nullptr; + if (pFrame) + pFrame->UnblockTooltip(); } else { @@ -12787,6 +12809,12 @@ private: if (!m_bActivateCalled) set_cursor(m_nPrePopupCursorPos); + + // undo show_menu tooltip blocking + GtkWidget* pParent = gtk_widget_get_toplevel(m_pToggleButton); + GtkSalFrame* pFrame = pParent ? GtkSalFrame::getFromWindow(pParent) : nullptr; + if (pFrame) + pFrame->UnblockTooltip(); } else { -- cgit