compilerplugins/clang/reservedid.cxx | 2 vcl/unx/gtk3/gtkinst.cxx | 136 +++++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 7 deletions(-)
New commits: commit de74235388015673f32f9fb0bfdcf95071c7ba0e Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Wed Jun 16 20:59:39 2021 +0100 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Thu Jun 17 13:25:19 2021 +0200 gtk4: restore double-decker notebooks add a 'NotifyingLayout' to find out when the size of a widget changes now that size-allocate has been removed Change-Id: Iae55b7fafd2fd26c62afaedd777ae40e84fbb964 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117348 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/compilerplugins/clang/reservedid.cxx b/compilerplugins/clang/reservedid.cxx index 0792c96b2da6..7ac340da282a 100644 --- a/compilerplugins/clang/reservedid.cxx +++ b/compilerplugins/clang/reservedid.cxx @@ -209,6 +209,8 @@ bool ReservedId::VisitNamedDecl(NamedDecl const * decl) { && s != "_GstVideoOverlay" // avmedia/source/gstreamer/gstplayer.hxx && s != "_Module" // extensions/source/activex/StdAfx2.h, CComModule + && s != "_NotifyingLayout" // vcl/unx/gtk3/gtkinst.cxx + && s != "_NotifyingLayoutClass" // vcl/unx/gtk3/gtkinst.cxx && s != "_SurfacePaintable" // vcl/unx/gtk3/gtkinst.cxx && s != "_SurfacePaintableClass" // vcl/unx/gtk3/gtkinst.cxx && s != "_XRegion" // vcl/unx/generic/gdi/x11cairotextrender.cxx diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index de09ae503a21..b1c8a2fbe0b5 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -7785,6 +7785,98 @@ public: } +#if GTK_CHECK_VERSION(4, 0, 0) + +G_BEGIN_DECLS + +G_DECLARE_FINAL_TYPE(NotifyingLayout, notifying_layout, NOTIFYING, LAYOUT, GtkLayoutManager) + +struct _NotifyingLayout +{ + GtkLayoutManager parent_instance; + + GtkWidget* m_pWidget; + GtkLayoutManager* m_pOrigManager; + Link<void*, void> m_aLink; + + void StartWatch(GtkWidget* pWidget, const Link<void*, void>& rLink) + { + m_pWidget = pWidget; + m_aLink = rLink; + + m_pOrigManager = gtk_widget_get_layout_manager(m_pWidget); + g_object_ref(m_pOrigManager); + + gtk_widget_set_layout_manager(pWidget, GTK_LAYOUT_MANAGER(this)); + } + + void StopWatch() + { + gtk_widget_set_layout_manager(m_pWidget, m_pOrigManager); + } +}; + +struct _NotifyingLayoutClass +{ + GtkLayoutManagerClass parent_class; +}; + +G_DEFINE_TYPE(NotifyingLayout, notifying_layout, GTK_TYPE_LAYOUT_MANAGER) + +static void notifying_layout_measure(GtkLayoutManager* pLayoutManager, + GtkWidget* widget, + GtkOrientation orientation, + int for_size, + int *minimum, + int *natural, + int *minimum_baseline, + int *natural_baseline) +{ + NotifyingLayout* self = NOTIFYING_LAYOUT(pLayoutManager); + GtkLayoutManagerClass* pKlass = GTK_LAYOUT_MANAGER_CLASS(G_OBJECT_GET_CLASS(self->m_pOrigManager)); + pKlass->measure(self->m_pOrigManager, widget, orientation, for_size, + minimum, natural, minimum_baseline, natural_baseline); +} + +static void notifying_layout_allocate(GtkLayoutManager* pLayoutManager, + GtkWidget* widget, + int width, + int height, + int baseline) +{ + NotifyingLayout* self = NOTIFYING_LAYOUT(pLayoutManager); + GtkLayoutManagerClass* pKlass = GTK_LAYOUT_MANAGER_CLASS(G_OBJECT_GET_CLASS(self->m_pOrigManager)); + pKlass->allocate(self->m_pOrigManager, widget, width, height, baseline); + self->m_aLink.Call(nullptr); +} + +static GtkSizeRequestMode notifying_layout_get_request_mode(GtkLayoutManager* pLayoutManager, + GtkWidget* widget) +{ + NotifyingLayout* self = NOTIFYING_LAYOUT(pLayoutManager); + GtkLayoutManagerClass* pKlass = GTK_LAYOUT_MANAGER_CLASS(G_OBJECT_GET_CLASS(self->m_pOrigManager)); + return pKlass->get_request_mode(self->m_pOrigManager, widget); +} + +static void notifying_layout_class_init(NotifyingLayoutClass* klass) +{ + GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS(klass); + + layout_class->get_request_mode = notifying_layout_get_request_mode; + layout_class->measure = notifying_layout_measure; + layout_class->allocate = notifying_layout_allocate; +} + +static void notifying_layout_init(NotifyingLayout* self) +{ + self->m_pWidget = nullptr; + self->m_pOrigManager = nullptr; +} + +G_END_DECLS + +#endif + namespace { class GtkInstanceNotebook : public GtkInstanceWidget, public virtual weld::Notebook @@ -7795,8 +7887,10 @@ private: GtkNotebook* m_pOverFlowNotebook; gulong m_nSwitchPageSignalId; gulong m_nOverFlowSwitchPageSignalId; +#if GTK_CHECK_VERSION(4, 0, 0) + NotifyingLayout* m_pLayout; +#else gulong m_nNotebookSizeAllocateSignalId; -#if !GTK_CHECK_VERSION(4, 0, 0) gulong m_nFocusSignalId; #endif gulong m_nChangeCurrentPageId; @@ -8177,11 +8271,15 @@ private: enable_notify_events(); } +#if GTK_CHECK_VERSION(4, 0, 0) + DECL_LINK(SizeAllocateHdl, void*, void); +#else static void signalSizeAllocate(GtkWidget*, GdkRectangle*, gpointer widget) { GtkInstanceNotebook* pThis = static_cast<GtkInstanceNotebook*>(widget); pThis->signal_notebook_size_allocate(); } +#endif bool signal_focus(GtkDirectionType direction) { @@ -8242,7 +8340,10 @@ public: , m_pOverFlowNotebook(GTK_NOTEBOOK(gtk_notebook_new())) , m_nSwitchPageSignalId(g_signal_connect(pNotebook, "switch-page", G_CALLBACK(signalSwitchPage), this)) , m_nOverFlowSwitchPageSignalId(g_signal_connect(m_pOverFlowNotebook, "switch-page", G_CALLBACK(signalOverFlowSwitchPage), this)) -#if !GTK_CHECK_VERSION(4, 0, 0) +#if GTK_CHECK_VERSION(4, 0, 0) + , m_pLayout(nullptr) +#else + , m_nNotebookSizeAllocateSignalId(0) , m_nFocusSignalId(g_signal_connect(pNotebook, "focus", G_CALLBACK(signalFocus), this)) #endif , m_nChangeCurrentPageId(g_signal_connect(pNotebook, "change-current-page", G_CALLBACK(signalChangeCurrentPage), this)) @@ -8256,10 +8357,16 @@ public: #if !GTK_CHECK_VERSION(4, 0, 0) gtk_widget_add_events(GTK_WIDGET(pNotebook), GDK_SCROLL_MASK); #endif - if (get_n_pages() > 6) + gint nPages = gtk_notebook_get_n_pages(m_pNotebook); + if (nPages > 6) + { +#if !GTK_CHECK_VERSION(4, 0, 0) m_nNotebookSizeAllocateSignalId = g_signal_connect_after(pNotebook, "size-allocate", G_CALLBACK(signalSizeAllocate), this); - else - m_nNotebookSizeAllocateSignalId = 0; +#else + m_pLayout = NOTIFYING_LAYOUT(g_object_new(notifying_layout_get_type(), nullptr)); + m_pLayout->StartWatch(GTK_WIDGET(pNotebook), LINK(this, GtkInstanceNotebook, SizeAllocateHdl)); +#endif + } gtk_notebook_set_show_border(m_pOverFlowNotebook, false); // tdf#122623 it's nigh impossible to have a GtkNotebook without an active (checked) tab, so try and theme @@ -8527,8 +8634,16 @@ public: { if (m_nLaunchSplitTimeoutId) g_source_remove(m_nLaunchSplitTimeoutId); +#if !GTK_CHECK_VERSION(4, 0, 0) if (m_nNotebookSizeAllocateSignalId) g_signal_handler_disconnect(m_pNotebook, m_nNotebookSizeAllocateSignalId); +#else + if (m_pLayout) + { + // put it back how we found it initially + m_pLayout->StopWatch(); + } +#endif g_signal_handler_disconnect(m_pNotebook, m_nSwitchPageSignalId); #if !GTK_CHECK_VERSION(4, 0, 0) g_signal_handler_disconnect(m_pNotebook, m_nFocusSignalId); @@ -8547,8 +8662,8 @@ public: // put it back to how we found it initially GtkWidget* pParent = gtk_widget_get_parent(GTK_WIDGET(m_pOverFlowBox)); g_object_ref(m_pNotebook); - gtk_container_remove(GTK_CONTAINER(m_pOverFlowBox), GTK_WIDGET(m_pNotebook)); - gtk_container_add(GTK_CONTAINER(pParent), GTK_WIDGET(m_pNotebook)); + container_remove(GTK_WIDGET(m_pOverFlowBox), GTK_WIDGET(m_pNotebook)); + container_add(GTK_WIDGET(pParent), GTK_WIDGET(m_pNotebook)); g_object_unref(m_pNotebook); #endif @@ -8562,6 +8677,13 @@ public: } }; +#if GTK_CHECK_VERSION(4, 0, 0) +IMPL_LINK_NOARG(GtkInstanceNotebook, SizeAllocateHdl, void*, void) +{ + signal_notebook_size_allocate(); +} +#endif + void update_attr_list(PangoAttrList* pAttrList, const vcl::Font& rFont) { pango_attr_list_change(pAttrList, pango_attr_family_new(OUStringToOString(rFont.GetFamilyName(), RTL_TEXTENCODING_UTF8).getStr())); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits