include/vcl/weld.hxx | 7 solenv/sanitizers/ui/vcl.suppr | 4 static/CustomTarget_emscripten_fs_image.mk | 2 vcl/UIConfig_vcl.mk | 2 vcl/inc/qt5/QtInstanceBuilder.hxx | 2 vcl/inc/salvtables.hxx | 3 vcl/qt5/QtInstanceBuilder.cxx | 8 vcl/source/app/salvtables.cxx | 37 --- vcl/uiconfig/ui/menutogglebutton3.ui | 40 --- vcl/uiconfig/ui/menutogglebutton4.ui | 37 --- vcl/unx/gtk3/gtkinst.cxx | 348 ----------------------------- 11 files changed, 4 insertions(+), 486 deletions(-)
New commits: commit e9c1861fba12249c74b95021fc708e2e17867e0d Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sat Jul 26 22:05:33 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Jul 29 10:01:17 2025 +0200 tdf#130857 qt weld: Support sd dialogs to manage custom slideshows This means that native Qt widgets are used for that dialog now when using the qt5 or qt6 VCL plugin and starting LO with environment variable SAL_VCL_QT_USE_WELDED_WIDGETS=1 set. These 2 dialogs can be triggered as follows: * start Impress, add a few (dummy) slides * "Slide Show" -> "Custom Slide Show" (starts the first dialog) * press the "New" button (starts the other newly supported dialog) Change-Id: I12844b2556690b28f861a7cdfc2e4ee6fb66abe2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188423 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 9ba083f0e0e5..20204fddd74f 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -117,6 +117,8 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile, const weld::W u"modules/scalc/ui/selectsource.ui"_ustr, u"modules/scalc/ui/showsheetdialog.ui"_ustr, u"modules/schart/ui/insertaxisdlg.ui"_ustr, + u"modules/simpress/ui/customslideshows.ui"_ustr, + u"modules/simpress/ui/definecustomslideshow.ui"_ustr, u"modules/simpress/ui/presentationdialog.ui"_ustr, u"modules/smath/ui/alignmentdialog.ui"_ustr, u"modules/smath/ui/fontdialog.ui"_ustr, commit 0f54fd790a470991ae954728ae070349165ef8f2 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sat Jul 26 10:39:04 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Jul 29 10:01:11 2025 +0200 gtk: Drop now unused GTK 4 path for replaceWidget This helper function is no longer used for gtk4 since Change-Id: I356c50f95da300a82965710010b41dea7dba6325 Author: Michael Weghorn <m.wegh...@posteo.de> Date: Sat Jul 26 10:11:50 2025 +0200 tdf#130857 weld: Drop unused weld::MenuToggleButton , so drop the nested GTK version checks and GTK 4 paths and only leave the toplevel version check around the whole function in place. Change-Id: If75ddd7d357e163136787587928331efdfcb9fc7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188394 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 fb8236127a76..ec6b6cb1b731 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -2210,21 +2210,14 @@ namespace gint nTopAttach(0), nLeftAttach(0), nHeight(1), nWidth(1); if (GTK_IS_GRID(pParent)) { -#if !GTK_CHECK_VERSION(4, 0, 0) gtk_container_child_get(GTK_CONTAINER(pParent), pWidget, "left-attach", &nLeftAttach, "top-attach", &nTopAttach, "width", &nWidth, "height", &nHeight, nullptr); -#else - gtk_grid_query_child(GTK_GRID(pParent), pWidget, - &nLeftAttach, &nTopAttach, - &nWidth, &nHeight); -#endif } -#if !GTK_CHECK_VERSION(4, 0, 0) gboolean bExpand(false), bFill(false); GtkPackType ePackType(GTK_PACK_START); guint nPadding(0); @@ -2239,18 +2232,12 @@ namespace "position", &nPosition, nullptr); } -#endif - -#if !GTK_CHECK_VERSION(4, 0, 0) // for gtk3 remove before replacement inserted, or there are warnings // from GTK_BIN about having two children container_remove(pParent, pWidget); -#endif gtk_widget_set_visible(pReplacement, gtk_widget_get_visible(pWidget)); -#if !GTK_CHECK_VERSION(4, 0, 0) gtk_widget_set_no_show_all(pReplacement, gtk_widget_get_no_show_all(pWidget)); -#endif int nReqWidth, nReqHeight; gtk_widget_get_size_request(pWidget, &nReqWidth, &nReqHeight); @@ -2284,20 +2271,14 @@ namespace } else if (GTK_IS_BOX(pParent)) { -#if !GTK_CHECK_VERSION(4, 0, 0) gtk_box_pack_start(GTK_BOX(pParent), pReplacement, bExpand, bFill, nPadding); gtk_container_child_set(GTK_CONTAINER(pParent), pReplacement, "pack-type", ePackType, "position", nPosition, nullptr); -#else - gtk_box_insert_child_after(GTK_BOX(pParent), pReplacement, pWidget); -#endif } -#if !GTK_CHECK_VERSION(4, 0, 0) else gtk_container_add(GTK_CONTAINER(pParent), pReplacement); -#endif if (gtk_widget_get_hexpand_set(pWidget)) gtk_widget_set_hexpand(pReplacement, gtk_widget_get_hexpand(pWidget)); @@ -2308,17 +2289,10 @@ namespace gtk_widget_set_halign(pReplacement, gtk_widget_get_halign(pWidget)); gtk_widget_set_valign(pReplacement, gtk_widget_get_valign(pWidget)); -#if GTK_CHECK_VERSION(4, 0, 0) - // for gtk4 remove after replacement inserted so we could use gtk_box_insert_child_after - container_remove(pParent, pWidget); -#endif - // coverity[freed_arg : FALSE] - this does not free pWidget, it is reffed by pReplacement g_object_unref(pWidget); } -#endif -#if !GTK_CHECK_VERSION(4, 0, 0) void insertAsParent(GtkWidget* pWidget, GtkWidget* pReplacement) { g_object_ref(pWidget); commit d925df3929ac305c1bb104ebc4a7573a88809c34 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sat Jul 26 10:11:50 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Jul 29 10:01:05 2025 +0200 tdf#130857 weld: Drop unused weld::MenuToggleButton It was introduced specifically for the Start Center in commit fb3c3b2861b6e658c260a22cc58c3f69be327b18 Author: Caolán McNamara <caol...@redhat.com> Date: Mon Oct 19 09:35:00 2020 +0100 add MenuToggleButton for split toggle/menu button which is uniquely used in the start center but is no longer used there since commit 164a1f4c3315fc44161128d3d9ca886f767f7d30 Author: Heiko Tietze <tietze.he...@gmail.com> Date: Fri Sep 9 16:07:28 2022 +0200 Resolves tdf#80934 - GUI means to filter thumbnails in start center For use within toolbars, there's GtkMenuToolButton [1] which seems to provide a similar logic (one button to toggle, and another small one with an arrow to open the menu) without having to implement so much custom logic for the GTK implementation. [1] https://docs.gtk.org/gtk3/class.MenuToolButton.html Change-Id: I356c50f95da300a82965710010b41dea7dba6325 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188393 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index ae8decbde0a8..3fe5cb25e23d 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -1673,12 +1673,6 @@ public: virtual void set_popover(weld::Widget* pPopover) = 0; }; -// Similar to a MenuButton except it is split into two parts, a toggle -// button at the start and a menubutton at the end -class VCL_DLLPUBLIC MenuToggleButton : virtual public MenuButton -{ -}; - class VCL_DLLPUBLIC CheckButton : virtual public Toggleable { public: @@ -2819,7 +2813,6 @@ public: virtual std::unique_ptr<Paned> weld_paned(const OUString& id) = 0; virtual std::unique_ptr<Button> weld_button(const OUString& id) = 0; virtual std::unique_ptr<MenuButton> weld_menu_button(const OUString& id) = 0; - virtual std::unique_ptr<MenuToggleButton> weld_menu_toggle_button(const OUString& id) = 0; virtual std::unique_ptr<Frame> weld_frame(const OUString& id) = 0; /* bUserManagedScrolling of true means that the automatic scrolling of the window is disabled and the owner must specifically listen to adjustment changes and react appropriately to them. diff --git a/solenv/sanitizers/ui/vcl.suppr b/solenv/sanitizers/ui/vcl.suppr index 2f7af214e0c9..cc133ea96574 100644 --- a/solenv/sanitizers/ui/vcl.suppr +++ b/solenv/sanitizers/ui/vcl.suppr @@ -7,10 +7,6 @@ vcl/uiconfig/ui/combobox.ui://GtkEntry[@id='entry'] no-labelled-by vcl/uiconfig/ui/combobox.ui://GtkMenuButton[@id='overlaybutton'] button-no-label vcl/uiconfig/ui/cupspassworddialog.ui://GtkLabel[@id='text'] orphan-label vcl/uiconfig/ui/editmenu.ui://GtkMenuItem[@id='specialchar'] button-no-label -vcl/uiconfig/ui/menutogglebutton3.ui://GtkToggleButton[@id='togglebutton'] button-no-label -vcl/uiconfig/ui/menutogglebutton3.ui://GtkButton[@id='menubutton'] button-no-label -vcl/uiconfig/ui/menutogglebutton4.ui://GtkToggleButton[@id='togglebutton'] button-no-label -vcl/uiconfig/ui/menutogglebutton4.ui://GtkButton[@id='menubutton'] button-no-label vcl/uiconfig/ui/printdialog.ui://GtkLabel[@id='totalnumpages'] orphan-label vcl/uiconfig/ui/printdialog.ui://GtkImage[@id='collateimage'] no-labelled-by vcl/uiconfig/ui/printdialog.ui://GtkLabel[@id='pagemargintxt2'] orphan-label diff --git a/static/CustomTarget_emscripten_fs_image.mk b/static/CustomTarget_emscripten_fs_image.mk index 532eaa5a892f..196065d7eaf2 100644 --- a/static/CustomTarget_emscripten_fs_image.mk +++ b/static/CustomTarget_emscripten_fs_image.mk @@ -1645,8 +1645,6 @@ gb_emscripten_fs_image_files += \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/errornoprinterdialog.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/interimdockparent.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/interimtearableparent.ui \ - $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/menutogglebutton3.ui \ - $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/menutogglebutton4.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/printdialog.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/openlockedquerybox.ui \ $(INSTROOT)/$(LIBO_SHARE_FOLDER)/config/soffice.cfg/vcl/ui/printerdevicepage.ui \ diff --git a/vcl/UIConfig_vcl.mk b/vcl/UIConfig_vcl.mk index 10a823cc87b2..a0bf093c25c2 100644 --- a/vcl/UIConfig_vcl.mk +++ b/vcl/UIConfig_vcl.mk @@ -19,8 +19,6 @@ $(eval $(call gb_UIConfig_add_uifiles,vcl,\ vcl/uiconfig/ui/errornoprinterdialog \ vcl/uiconfig/ui/interimdockparent \ vcl/uiconfig/ui/interimtearableparent \ - vcl/uiconfig/ui/menutogglebutton3 \ - vcl/uiconfig/ui/menutogglebutton4 \ vcl/uiconfig/ui/printdialog \ vcl/uiconfig/ui/printerdevicepage \ vcl/uiconfig/ui/printerpaperpage \ diff --git a/vcl/inc/qt5/QtInstanceBuilder.hxx b/vcl/inc/qt5/QtInstanceBuilder.hxx index c515394cd5fd..9735ab7aa74c 100644 --- a/vcl/inc/qt5/QtInstanceBuilder.hxx +++ b/vcl/inc/qt5/QtInstanceBuilder.hxx @@ -44,8 +44,6 @@ public: virtual std::unique_ptr<weld::Notebook> weld_notebook(const OUString& rId) override; virtual std::unique_ptr<weld::Button> weld_button(const OUString& rId) override; virtual std::unique_ptr<weld::MenuButton> weld_menu_button(const OUString& rId) override; - virtual std::unique_ptr<weld::MenuToggleButton> - weld_menu_toggle_button(const OUString&) override; virtual std::unique_ptr<weld::LinkButton> weld_link_button(const OUString& rId) override; virtual std::unique_ptr<weld::ToggleButton> weld_toggle_button(const OUString& rId) override; virtual std::unique_ptr<weld::RadioButton> weld_radio_button(const OUString& rId) override; diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 85e494965291..253f7a7f2a4c 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -79,9 +79,6 @@ public: virtual std::unique_ptr<weld::MenuButton> weld_menu_button(const OUString& id) override; - virtual std::unique_ptr<weld::MenuToggleButton> - weld_menu_toggle_button(const OUString& id) override; - virtual std::unique_ptr<weld::LinkButton> weld_link_button(const OUString& id) override; virtual std::unique_ptr<weld::ToggleButton> weld_toggle_button(const OUString& id) override; diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 580312c3e882..9ba083f0e0e5 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -363,12 +363,6 @@ std::unique_ptr<weld::MenuButton> QtInstanceBuilder::weld_menu_button(const OUSt return xRet; } -std::unique_ptr<weld::MenuToggleButton> QtInstanceBuilder::weld_menu_toggle_button(const OUString&) -{ - assert(false && "Not implemented yet"); - return nullptr; -} - std::unique_ptr<weld::LinkButton> QtInstanceBuilder::weld_link_button(const OUString& rId) { SolarMutexGuard g; diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 49c9536dffaa..265fdd7c4a04 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -77,7 +77,6 @@ #include <vcl/virdev.hxx> #include <bitmaps.hlst> #include <listbox.hxx> -#include <menutogglebutton.hxx> #include <window.h> #include <wizdlg.hxx> #include <salvtables.hxx> @@ -3099,35 +3098,6 @@ IMPL_LINK_NOARG(SalInstanceMenuButton, ActivateHdl, ::MenuButton*, void) signal_toggled(); } -namespace -{ -class SalInstanceMenuToggleButton : public SalInstanceMenuButton, - public virtual weld::MenuToggleButton -{ -private: - VclPtr<::MenuToggleButton> m_xMenuToggleButton; - -public: - SalInstanceMenuToggleButton(::MenuToggleButton* pButton, SalInstanceBuilder* pBuilder, - bool bTakeOwnership) - : SalInstanceMenuButton(pButton, pBuilder, bTakeOwnership) - , m_xMenuToggleButton(pButton) - { - m_xMenuToggleButton->SetDelayMenu(true); - m_xMenuToggleButton->SetDropDown(PushButtonDropdownStyle::SplitMenuButton); - } - - virtual void set_active(bool active) override - { - disable_notify_events(); - m_xMenuToggleButton->SetActive(active); - enable_notify_events(); - } - - virtual bool get_active() const override { return m_xMenuToggleButton->GetActive(); } -}; -} - IMPL_LINK(SalInstanceLinkButton, ClickHdl, FixedHyperlink&, rButton, void) { bool bConsumed = signal_activate_link(); @@ -7229,13 +7199,6 @@ std::unique_ptr<weld::MenuButton> SalInstanceBuilder::weld_menu_button(const OUS return pButton ? std::make_unique<SalInstanceMenuButton>(pButton, this, false) : nullptr; } -std::unique_ptr<weld::MenuToggleButton> -SalInstanceBuilder::weld_menu_toggle_button(const OUString& id) -{ - MenuToggleButton* pButton = m_xBuilder->get<MenuToggleButton>(id); - return pButton ? std::make_unique<SalInstanceMenuToggleButton>(pButton, this, false) : nullptr; -} - std::unique_ptr<weld::LinkButton> SalInstanceBuilder::weld_link_button(const OUString& id) { FixedHyperlink* pButton = m_xBuilder->get<FixedHyperlink>(id); diff --git a/vcl/uiconfig/ui/menutogglebutton3.ui b/vcl/uiconfig/ui/menutogglebutton3.ui deleted file mode 100644 index 88abac929d9d..000000000000 --- a/vcl/uiconfig/ui/menutogglebutton3.ui +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.40.0 --> -<interface domain="vcl"> - <requires lib="gtk+" version="3.20"/> - <object class="GtkBox" id="box"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="no-show-all">True</property> - <child> - <object class="GtkToggleButton" id="togglebutton"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">True</property> - <property name="use-underline">True</property> - <property name="always-show-image">True</property> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="menubutton"> - <property name="visible">True</property> - <property name="can-focus">True</property> - <property name="receives-default">True</property> - <property name="always-show-image">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - <style> - <class name="linked"/> - </style> - </object> -</interface> diff --git a/vcl/uiconfig/ui/menutogglebutton4.ui b/vcl/uiconfig/ui/menutogglebutton4.ui deleted file mode 100644 index cfecfda02c28..000000000000 --- a/vcl/uiconfig/ui/menutogglebutton4.ui +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.38.2 --> -<interface domain="vcl"> - <requires lib="gtk+" version="3.20"/> - <object class="GtkBox" id="box"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="hexpand">False</property> - <child> - <object class="GtkToggleButton" id="togglebutton"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="receives-default">True</property> - <property name="hexpand">True</property> - <property name="use-underline">True</property> - </object> - </child> - <child> - <object class="GtkSeparator" id="separator"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="orientation">vertical</property> - </object> - </child> - <child> - <object class="GtkButton" id="menubutton"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="icon-name">pan-down-symbolic</property> - <property name="receives-default">True</property> - </object> - </child> - <style> - <class name="linked"/> - </style> - </object> -</interface> diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index 65b2bfdd1798..fb8236127a76 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -2195,6 +2195,7 @@ namespace return pWidget; } +#if !GTK_CHECK_VERSION(4, 0, 0) void replaceWidget(GtkWidget* pWidget, GtkWidget* pReplacement) { // remove the widget and replace it with pReplacement @@ -2315,7 +2316,9 @@ namespace // coverity[freed_arg : FALSE] - this does not free pWidget, it is reffed by pReplacement g_object_unref(pWidget); } +#endif +#if !GTK_CHECK_VERSION(4, 0, 0) void insertAsParent(GtkWidget* pWidget, GtkWidget* pReplacement) { g_object_ref(pWidget); @@ -2328,6 +2331,7 @@ namespace // coverity[freed_arg : FALSE] - this does not free pWidget, it is reffed by pReplacement g_object_unref(pWidget); } +#endif GtkWidget* ensureEventWidget(GtkWidget* pWidget) { @@ -11211,305 +11215,6 @@ public: } }; -class GtkInstanceMenuToggleButton : public GtkInstanceToggleButton, public MenuHelper - , public virtual weld::MenuToggleButton -{ -private: - GtkBox* m_pContainer; - GtkButton* m_pToggleMenuButton; - GtkMenuButton* m_pMenuButton; - gulong m_nMenuBtnClickedId; - gulong m_nToggleStateFlagsChangedId; - gulong m_nMenuBtnStateFlagsChangedId; - - static void signalToggleStateFlagsChanged(GtkWidget* pWidget, GtkStateFlags /*eFlags*/, gpointer widget) - { - GtkInstanceMenuToggleButton* pThis = static_cast<GtkInstanceMenuToggleButton*>(widget); - // mirror togglebutton state to menubutton - gtk_widget_set_state_flags(GTK_WIDGET(pThis->m_pToggleMenuButton), gtk_widget_get_state_flags(pWidget), true); - } - - static void signalMenuBtnStateFlagsChanged(GtkWidget* pWidget, GtkStateFlags /*eFlags*/, gpointer widget) - { - GtkInstanceMenuToggleButton* pThis = static_cast<GtkInstanceMenuToggleButton*>(widget); - // mirror menubutton to togglebutton, keeping depressed state of menubutton - GtkStateFlags eToggleFlags = gtk_widget_get_state_flags(GTK_WIDGET(pThis->m_pToggleButton)); - GtkStateFlags eFlags = gtk_widget_get_state_flags(pWidget); - GtkStateFlags eFinalFlags = static_cast<GtkStateFlags>((eFlags & ~GTK_STATE_FLAG_ACTIVE) | - (eToggleFlags & GTK_STATE_FLAG_ACTIVE)); - gtk_widget_set_state_flags(GTK_WIDGET(pThis->m_pToggleButton), eFinalFlags, true); - } - - static void signalMenuBtnClicked(GtkButton*, gpointer widget) - { - GtkInstanceMenuToggleButton* pThis = static_cast<GtkInstanceMenuToggleButton*>(widget); - pThis->launch_menu(); - } - - void launch_menu() - { - gtk_widget_set_state_flags(GTK_WIDGET(m_pToggleMenuButton), gtk_widget_get_state_flags(GTK_WIDGET(m_pToggleButton)), true); - GtkWidget* pWidget = GTK_WIDGET(m_pToggleButton); - - //run in a sub main loop because we need to keep vcl PopupMenu alive to use - //it during DispatchCommand, returning now to the outer loop causes the - //launching PopupMenu to be destroyed, instead run the subloop here - //until the gtk menu is destroyed - GMainLoop* pLoop = g_main_loop_new(nullptr, true); - -#if GTK_CHECK_VERSION(4, 0, 0) - gulong nSignalId = g_signal_connect_swapped(G_OBJECT(m_pMenu), "closed", G_CALLBACK(g_main_loop_quit), pLoop); - - g_object_ref(m_pMenu); - gtk_menu_button_set_popover(m_pMenuButton, nullptr); - gtk_widget_set_parent(GTK_WIDGET(m_pMenu), pWidget); - gtk_popover_set_position(GTK_POPOVER(m_pMenu), GTK_POS_BOTTOM); - gtk_popover_popup(GTK_POPOVER(m_pMenu)); -#else - gulong nSignalId = g_signal_connect_swapped(G_OBJECT(m_pMenu), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop); - -#if GTK_CHECK_VERSION(3,22,0) - if (gtk_check_version(3, 22, 0) == nullptr) - { - // Send a keyboard event through gtk_main_do_event to toggle any active tooltip offs - // before trying to launch the menu - // https://gitlab.gnome.org/GNOME/gtk/issues/1785 - // Fixed in GTK 3.24 - GdkEvent *pKeyEvent = GtkSalFrame::makeFakeKeyPress(pWidget); - gtk_main_do_event(pKeyEvent); - - GdkEvent *pTriggerEvent = gtk_get_current_event(); - bool bEventOwnership = true; - if (!pTriggerEvent) - { - pTriggerEvent = pKeyEvent; - bEventOwnership = false; - } - - gtk_menu_popup_at_widget(m_pMenu, pWidget, GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, pTriggerEvent); - if (bEventOwnership) - gdk_event_free(pTriggerEvent); - - gdk_event_free(pKeyEvent); - } - else -#endif - { - guint nButton; - guint32 nTime; - - //typically there is an event, and we can then distinguish if this was - //launched from the keyboard (gets auto-mnemoniced) or the mouse (which - //doesn't) - GdkEvent *pEvent = gtk_get_current_event(); - if (pEvent) - { - gdk_event_get_button(pEvent, &nButton); - nTime = gdk_event_get_time(pEvent); - gdk_event_free(pEvent); - } - else - { - nButton = 0; - nTime = GtkSalFrame::GetLastInputEventTime(); - } - - gtk_menu_popup(m_pMenu, nullptr, nullptr, nullptr, nullptr, nButton, nTime); - } -#endif - - if (g_main_loop_is_running(pLoop)) - main_loop_run(pLoop); - - g_main_loop_unref(pLoop); - g_signal_handler_disconnect(m_pMenu, nSignalId); - -#if GTK_CHECK_VERSION(4, 0, 0) - gtk_widget_unparent(GTK_WIDGET(m_pMenu)); - gtk_menu_button_set_popover(m_pMenuButton, GTK_WIDGET(m_pMenu)); - g_object_unref(m_pMenu); -#endif - - } - - static gboolean signalMenuToggleButton(GtkWidget*, gboolean bGroupCycling, gpointer widget) - { - GtkInstanceMenuToggleButton* pThis = static_cast<GtkInstanceMenuToggleButton*>(widget); - return gtk_widget_mnemonic_activate(GTK_WIDGET(pThis->m_pToggleButton), bGroupCycling); - } - -public: - GtkInstanceMenuToggleButton(GtkBuilder* pMenuToggleButtonBuilder, GtkMenuButton* pMenuButton, - GtkInstanceBuilder* pBuilder, bool bTakeOwnership) - : GtkInstanceToggleButton(GTK_TOGGLE_BUTTON(gtk_builder_get_object(pMenuToggleButtonBuilder, "togglebutton")), - pBuilder, bTakeOwnership) -#if !GTK_CHECK_VERSION(4, 0, 0) - , MenuHelper(gtk_menu_button_get_popup(pMenuButton), false) -#else - , MenuHelper(GTK_POPOVER_MENU(gtk_menu_button_get_popover(pMenuButton)), false) -#endif - , m_pContainer(GTK_BOX(gtk_builder_get_object(pMenuToggleButtonBuilder, "box"))) - , m_pToggleMenuButton(GTK_BUTTON(gtk_builder_get_object(pMenuToggleButtonBuilder, "menubutton"))) - , m_pMenuButton(pMenuButton) - , m_nMenuBtnClickedId(g_signal_connect(m_pToggleMenuButton, "clicked", G_CALLBACK(signalMenuBtnClicked), this)) - , m_nToggleStateFlagsChangedId(g_signal_connect(m_pToggleButton, "state-flags-changed", G_CALLBACK(signalToggleStateFlagsChanged), this)) - , m_nMenuBtnStateFlagsChangedId(g_signal_connect(m_pToggleMenuButton, "state-flags-changed", G_CALLBACK(signalMenuBtnStateFlagsChanged), this)) - { -#if !GTK_CHECK_VERSION(4, 0, 0) - GtkInstanceMenuButton::formatMenuButton(gtk_bin_get_child(GTK_BIN(m_pMenuButton))); -#endif - - insertAsParent(GTK_WIDGET(m_pMenuButton), GTK_WIDGET(m_pContainer)); - gtk_widget_set_visible(GTK_WIDGET(m_pMenuButton), false); - - // move the first GtkMenuButton child, as created by GtkInstanceMenuButton ctor, into the GtkToggleButton - // instead, leaving just the indicator behind in the GtkMenuButton -#if !GTK_CHECK_VERSION(4, 0, 0) - GtkWidget* pButtonBox = gtk_bin_get_child(GTK_BIN(m_pMenuButton)); - GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pButtonBox)); - int nGroup = 0; - for (GList* pChild = g_list_first(pChildren); pChild && nGroup < 2; pChild = g_list_next(pChild), ++nGroup) - { - GtkWidget* pWidget = static_cast<GtkWidget*>(pChild->data); - g_object_ref(pWidget); - gtk_container_remove(GTK_CONTAINER(pButtonBox), pWidget); - if (nGroup == 0) - gtk_container_add(GTK_CONTAINER(m_pToggleButton), pWidget); - else - gtk_container_add(GTK_CONTAINER(m_pToggleMenuButton), pWidget); - gtk_widget_show_all(pWidget); - g_object_unref(pWidget); - } - g_list_free(pChildren); -#else - GtkWidget* pChild = gtk_widget_get_first_child(GTK_WIDGET(m_pMenuButton)); - pChild = gtk_widget_get_first_child(pChild); - pChild = gtk_widget_get_first_child(pChild); - - g_object_ref(pChild); - gtk_widget_unparent(pChild); - gtk_button_set_child(GTK_BUTTON(m_pToggleButton), pChild); - g_object_unref(pChild); -#endif - - // match the GtkToggleButton relief to the GtkMenuButton -#if !GTK_CHECK_VERSION(4, 0, 0) - const GtkReliefStyle eStyle = gtk_button_get_relief(GTK_BUTTON(m_pMenuButton)); - gtk_button_set_relief(GTK_BUTTON(m_pToggleButton), eStyle); - gtk_button_set_relief(GTK_BUTTON(m_pToggleMenuButton), eStyle); -#else - const bool bStyle = gtk_menu_button_get_has_frame(GTK_MENU_BUTTON(m_pMenuButton)); - gtk_button_set_has_frame(GTK_BUTTON(m_pToggleButton), bStyle); - gtk_button_set_has_frame(GTK_BUTTON(m_pToggleMenuButton), bStyle); -#endif - - // move the GtkMenuButton margins up to the new parent - gtk_widget_set_margin_top(GTK_WIDGET(m_pContainer), - gtk_widget_get_margin_top(GTK_WIDGET(m_pMenuButton))); - gtk_widget_set_margin_bottom(GTK_WIDGET(m_pContainer), - gtk_widget_get_margin_bottom(GTK_WIDGET(m_pMenuButton))); - gtk_widget_set_margin_start(GTK_WIDGET(m_pContainer), - gtk_widget_get_margin_start(GTK_WIDGET(m_pMenuButton))); - gtk_widget_set_margin_end(GTK_WIDGET(m_pContainer), - gtk_widget_get_margin_end(GTK_WIDGET(m_pMenuButton))); - -#if !GTK_CHECK_VERSION(4, 0, 0) - gtk_menu_detach(m_pMenu); - gtk_menu_attach_to_widget(m_pMenu, GTK_WIDGET(m_pToggleButton), nullptr); -#else - gtk_widget_insert_action_group(GTK_WIDGET(m_pContainer), "menu", m_pActionGroup); - - update_action_group_from_popover_model(); -#endif - - g_signal_connect(m_pContainer, "mnemonic-activate", G_CALLBACK(signalMenuToggleButton), this); - } - - virtual void disable_notify_events() override - { - g_signal_handler_block(m_pToggleMenuButton, m_nMenuBtnClickedId); - GtkInstanceToggleButton::disable_notify_events(); - } - - virtual void enable_notify_events() override - { - GtkInstanceToggleButton::enable_notify_events(); - g_signal_handler_unblock(m_pToggleMenuButton, m_nMenuBtnClickedId); - } - - virtual ~GtkInstanceMenuToggleButton() - { - g_signal_handler_disconnect(m_pToggleButton, m_nToggleStateFlagsChangedId); - g_signal_handler_disconnect(m_pToggleMenuButton, m_nMenuBtnStateFlagsChangedId); - g_signal_handler_disconnect(m_pToggleMenuButton, m_nMenuBtnClickedId); - -#if GTK_CHECK_VERSION(4, 0, 0) - GtkWidget* pChild = gtk_button_get_child(GTK_BUTTON(m_pToggleButton)); - g_object_ref(pChild); - gtk_button_set_child(GTK_BUTTON(m_pToggleButton), nullptr); - gtk_widget_unparent(pChild); - gtk_widget_set_parent(pChild, GTK_WIDGET(m_pMenuButton)); - g_object_unref(pChild); -#endif - } - - virtual void insert_item(int pos, const OUString& rId, const OUString& rStr, - const OUString* pIconName, VirtualDevice* pImageSurface, TriState eCheckRadioFalse) override - { - MenuHelper::insert_item(pos, rId, rStr, pIconName, pImageSurface, eCheckRadioFalse); - } - - virtual void insert_separator(int pos, const OUString& rId) override - { - MenuHelper::insert_separator(pos, rId); - } - - virtual void remove_item(const OUString& rId) override - { - MenuHelper::remove_item(rId); - } - - virtual void clear() override - { - MenuHelper::clear_items(); - } - - virtual void set_item_active(const OUString& rIdent, bool bActive) override - { - MenuHelper::set_item_active(rIdent, bActive); - } - - virtual void set_item_sensitive(const OUString& rIdent, bool bSensitive) override - { - MenuHelper::set_item_sensitive(rIdent, bSensitive); - } - - virtual void set_item_label(const OUString& rIdent, const OUString& rLabel) override - { - MenuHelper::set_item_label(rIdent, rLabel); - } - - virtual OUString get_item_label(const OUString& rIdent) const override - { - return MenuHelper::get_item_label(rIdent); - } - - virtual void set_item_visible(const OUString& rIdent, bool bVisible) override - { - MenuHelper::set_item_visible(rIdent, bVisible); - } - - virtual void signal_item_activate(const OUString& rIdent) override - { - signal_selected(rIdent); - } - - virtual void set_popover(weld::Widget* /*pPopover*/) override - { - assert(false && "not implemented"); - } -}; - class GtkInstanceMenu : public MenuHelper, public virtual weld::Menu { protected: @@ -19505,18 +19210,6 @@ static void signalEntryPopulatePopup(GtkEntry* pEntry, GtkWidget* pMenu, gpointe namespace { -GtkBuilder* makeMenuToggleButtonBuilder() -{ -#if !GTK_CHECK_VERSION(4, 0, 0) - OUString aUri(AllSettings::GetUIRootDir() + "vcl/ui/menutogglebutton3.ui"); -#else - OUString aUri(AllSettings::GetUIRootDir() + "vcl/ui/menutogglebutton4.ui"); -#endif - OUString aPath; - osl::FileBase::getSystemPathFromFileURL(aUri, aPath); - return gtk_builder_new_from_file(OUStringToOString(aPath, RTL_TEXTENCODING_UTF8).getStr()); -} - #if !GTK_CHECK_VERSION(4, 0, 0) GtkBuilder* makeComboBoxBuilder() @@ -24689,17 +24382,6 @@ public: return std::make_unique<GtkInstanceMenuButton>(pButton, nullptr, this, false); } - virtual std::unique_ptr<weld::MenuToggleButton> weld_menu_toggle_button(const OUString &id) override - { - GtkMenuButton* pButton = GTK_MENU_BUTTON(gtk_builder_get_object(m_pBuilder, OUStringToOString(id, RTL_TEXTENCODING_UTF8).getStr())); - if (!pButton) - return nullptr; - auto_add_parentless_widgets_to_container(GTK_WIDGET(pButton)); - // gtk doesn't come with exactly the same concept - GtkBuilder* pMenuToggleButton = makeMenuToggleButtonBuilder(); - return std::make_unique<GtkInstanceMenuToggleButton>(pMenuToggleButton, pButton, this, false); - } - virtual std::unique_ptr<weld::LinkButton> weld_link_button(const OUString &id) override { GtkLinkButton* pButton = GTK_LINK_BUTTON(gtk_builder_get_object(m_pBuilder, OUStringToOString(id, RTL_TEXTENCODING_UTF8).getStr()));