[Libreoffice-commits] core.git: compilerplugins/clang vcl/unx
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Thu Jun 17 11:26:00 UTC 2021
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 <caolanm at redhat.com>
AuthorDate: Wed Jun 16 20:59:39 2021 +0100
Commit: Caolán McNamara <caolanm at 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 <caolanm at 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()));
More information about the Libreoffice-commits
mailing list