[Libreoffice-commits] core.git: 2 commits - vcl/unx
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Wed Jul 7 15:57:52 UTC 2021
vcl/unx/gtk3/gtkinst.cxx | 273 +++++++++++++++++++++++------------------------
1 file changed, 138 insertions(+), 135 deletions(-)
New commits:
commit c118d90e13fff1b9404e179b61cd5919115a449c
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Jul 7 16:03:04 2021 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Jul 7 17:57:32 2021 +0200
gtk4: add get_item_id to MenuHelper
and implement for the GMenuModel case
Change-Id: I57da4d984f6a743043cd82c32edff35115fe94c6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118575
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index cd4f8efc8e40..da39cf03f41a 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -5248,6 +5248,30 @@ public:
#endif
}
+ OString get_item_id(int pos) const
+ {
+#if !GTK_CHECK_VERSION(4, 0, 0)
+ GList* pChildren = gtk_container_get_children(GTK_CONTAINER(m_pMenu));
+ gpointer pMenuItem = g_list_nth_data(pChildren, pos);
+ OString id = ::get_buildable_id(GTK_BUILDABLE(pMenuItem));
+ g_list_free(pChildren);
+ return id;
+#else
+ OString sTarget;
+ if (GMenuModel* pMenuModel = gtk_popover_menu_get_menu_model(m_pMenu))
+ {
+ auto aSectionAndPos = get_section_and_pos_for(pMenuModel, pos);
+ char *id;
+ if (g_menu_model_get_item_attribute(aSectionAndPos.first, aSectionAndPos.second, "target", "s", &id))
+ {
+ sTarget = OString(id);
+ g_free(id);
+ }
+ }
+ return sTarget;
+#endif
+ }
+
void clear_items()
{
#if !GTK_CHECK_VERSION(4, 0, 0)
@@ -10486,15 +10510,7 @@ public:
virtual OString get_id(int pos) const override
{
-#if !GTK_CHECK_VERSION(4, 0, 0)
- GList* pChildren = gtk_container_get_children(GTK_CONTAINER(m_pMenu));
- gpointer pMenuItem = g_list_nth_data(pChildren, pos);
- OString id = ::get_buildable_id(GTK_BUILDABLE(pMenuItem));
- g_list_free(pChildren);
- return id;
-#else
- return OString();
-#endif
+ return get_item_id(pos);
}
virtual int n_children() const override
commit 857943a0e4e75f12ffe7b1dc9d91ef88fbdb75d6
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Wed Jul 7 15:22:58 2021 +0100
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Wed Jul 7 17:57:17 2021 +0200
gtk4: move more GMenuModel/GtkPopoverMenu handling into MenuHelper
Change-Id: I994a0c6aeb2bfabec01999e4722ac0f72a3f359e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118574
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index c5bc9657f309..cd4f8efc8e40 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -4775,6 +4775,8 @@ protected:
bool m_bTakeOwnership;
private:
+ virtual void signal_item_activate(const OString& rIdent) = 0;
+
#if !GTK_CHECK_VERSION(4, 0, 0)
static void collect(GtkWidget* pItem, gpointer widget)
{
@@ -4791,8 +4793,6 @@ private:
SolarMutexGuard aGuard;
pThis->signal_item_activate(::get_buildable_id(GTK_BUILDABLE(pItem)));
}
-
- virtual void signal_item_activate(const OString& rIdent) = 0;
#else
static std::pair<GMenuModel*, int> find_id(GMenuModel* pMenuModel, const OString& rId)
{
@@ -4825,6 +4825,28 @@ private:
return std::make_pair(nullptr, -1);
}
+
+ void clear_actions()
+ {
+ for (const auto& rAction : m_aActionEntries)
+ {
+ g_action_map_remove_action(G_ACTION_MAP(m_pActionGroup), rAction.name);
+ g_action_map_remove_action(G_ACTION_MAP(m_pHiddenActionGroup), rAction.name);
+ }
+ m_aActionEntries.clear();
+ m_aInsertedActions.clear();
+ m_aIdToAction.clear();
+ }
+
+ static void action_activated(GSimpleAction*, GVariant* pParameter, gpointer widget)
+ {
+ gsize nLength(0);
+ const gchar* pStr = g_variant_get_string(pParameter, &nLength);
+ OString aStr(pStr, nLength);
+ MenuHelper* pThis = static_cast<MenuHelper*>(widget);
+ SolarMutexGuard aGuard;
+ pThis->signal_item_activate(aStr);
+ }
#endif
public:
@@ -4907,11 +4929,75 @@ public:
}
#endif
-#if !GTK_CHECK_VERSION(4, 0, 0)
- void insert_item(int pos, std::u16string_view rId, const OUString& rStr,
+#if GTK_CHECK_VERSION(4, 0, 0)
+ void process_menu_model(GMenuModel* pMenuModel)
+ {
+ for (int i = 0, nCount = g_menu_model_get_n_items(pMenuModel); i < nCount; ++i)
+ {
+ OString sAction, sTarget;
+ char *id;
+ if (g_menu_model_get_item_attribute(pMenuModel, i, "action", "s", &id))
+ {
+ assert(OString(id).startsWith("menu."));
+
+ sAction = OString(id + 5);
+
+ auto res = m_aInsertedActions.insert(sAction);
+ if (res.second)
+ {
+ // the const char* arg isn't copied by anything so it must continue to exist for the life time of
+ // the action group
+ if (sAction.startsWith("radio."))
+ m_aActionEntries.push_back({res.first->getStr(), action_activated, "s", "'none'", nullptr, {}});
+ else
+ m_aActionEntries.push_back({res.first->getStr(), action_activated, "s", nullptr, nullptr, {}});
+ }
+
+ g_free(id);
+ }
+
+ if (g_menu_model_get_item_attribute(pMenuModel, i, "target", "s", &id))
+ {
+ sTarget = OString(id);
+ g_free(id);
+ }
+
+ m_aIdToAction[sTarget] = sAction;
+
+ if (GMenuModel* pSectionModel = g_menu_model_get_item_link(pMenuModel, i, G_MENU_LINK_SECTION))
+ process_menu_model(pSectionModel);
+ if (GMenuModel* pSubMenuModel = g_menu_model_get_item_link(pMenuModel, i, G_MENU_LINK_SUBMENU))
+ process_menu_model(pSubMenuModel);
+ }
+ }
+
+ // build an action group for the menu, "action" is the normal menu entry case
+ // the others are radiogroups
+ void update_action_group_from_popover_model()
+ {
+ clear_actions();
+
+ if (GMenuModel* pMenuModel = gtk_popover_menu_get_menu_model(m_pMenu))
+ {
+ process_menu_model(pMenuModel);
+ }
+
+ // move hidden entries to m_pHiddenActionGroup
+ g_action_map_add_action_entries(G_ACTION_MAP(m_pActionGroup), m_aActionEntries.data(), m_aActionEntries.size(), this);
+ for (const auto& id : m_aHiddenIds)
+ {
+ GAction* pAction = g_action_map_lookup_action(G_ACTION_MAP(m_pActionGroup), m_aIdToAction[id].getStr());
+ g_action_map_add_action(G_ACTION_MAP(m_pHiddenActionGroup), pAction);
+ g_action_map_remove_action(G_ACTION_MAP(m_pActionGroup), m_aIdToAction[id].getStr());
+ }
+ }
+#endif
+
+ void insert_item(int pos, const OUString& rId, const OUString& rStr,
const OUString* pIconName, const VirtualDevice* pImageSurface,
TriState eCheckRadioFalse)
{
+#if !GTK_CHECK_VERSION(4, 0, 0)
GtkWidget* pImage = nullptr;
if (pIconName && !pIconName->isEmpty())
{
@@ -4951,8 +5037,29 @@ public:
add_to_map(GTK_MENU_ITEM(pItem));
if (pos != -1)
gtk_menu_reorder_child(m_pMenu, pItem, pos);
- }
+#else
+ (void)pIconName; (void)pImageSurface;
+
+ if (GMenuModel* pMenuModel = gtk_popover_menu_get_menu_model(m_pMenu))
+ {
+ auto aSectionAndPos = get_section_and_pos_for(pMenuModel, pos);
+ GMenu* pMenu = G_MENU(aSectionAndPos.first);
+ // action with a target value ... the action name and target value are separated by a double
+ // colon ... For example: "app.action::target"
+ OUString sActionAndTarget;
+ if (eCheckRadioFalse == TRISTATE_INDET)
+ sActionAndTarget = "menu.normal." + rId + "::" + rId;
+ else
+ sActionAndTarget = "menu.radio." + rId + "::" + rId;
+ g_menu_insert(pMenu, aSectionAndPos.second, MapToGtkAccelerator(rStr).getStr(), sActionAndTarget.toUtf8().getStr());
+
+ assert(eCheckRadioFalse == TRISTATE_INDET); // come back to this later
+
+ // TODO not redo entire group
+ update_action_group_from_popover_model();
+ }
#endif
+ }
void insert_separator(int pos, const OUString& rId)
{
@@ -9499,88 +9606,6 @@ private:
#endif
}
-#if GTK_CHECK_VERSION(4, 0, 0)
- void clear_actions()
- {
- for (const auto& rAction : m_aActionEntries)
- {
- g_action_map_remove_action(G_ACTION_MAP(m_pActionGroup), rAction.name);
- g_action_map_remove_action(G_ACTION_MAP(m_pHiddenActionGroup), rAction.name);
- }
- m_aActionEntries.clear();
- m_aInsertedActions.clear();
- m_aIdToAction.clear();
- }
-#endif
-
-#if GTK_CHECK_VERSION(4, 0, 0)
- void process_menu_model(GMenuModel* pMenuModel)
- {
- for (int i = 0, nCount = g_menu_model_get_n_items(pMenuModel); i < nCount; ++i)
- {
- OString sAction, sTarget;
- char *id;
- if (g_menu_model_get_item_attribute(pMenuModel, i, "action", "s", &id))
- {
- assert(OString(id).startsWith("menu."));
-
- sAction = OString(id + 5);
-
- auto res = m_aInsertedActions.insert(sAction);
- if (res.second)
- {
- // the const char* arg isn't copied by anything so it must continue to exist for the life time of
- // the action group
- if (sAction.startsWith("radio."))
- m_aActionEntries.push_back({res.first->getStr(), action_activated, "s", "'none'", nullptr, {}});
- else
- m_aActionEntries.push_back({res.first->getStr(), action_activated, "s", nullptr, nullptr, {}});
- }
-
- g_free(id);
- }
-
- if (g_menu_model_get_item_attribute(pMenuModel, i, "target", "s", &id))
- {
- sTarget = OString(id);
- g_free(id);
- }
-
- m_aIdToAction[sTarget] = sAction;
-
- if (GMenuModel* pSectionModel = g_menu_model_get_item_link(pMenuModel, i, G_MENU_LINK_SECTION))
- process_menu_model(pSectionModel);
- if (GMenuModel* pSubMenuModel = g_menu_model_get_item_link(pMenuModel, i, G_MENU_LINK_SUBMENU))
- process_menu_model(pSubMenuModel);
- }
- }
-
- // build an action group for the menu, "action" is the normal menu entry case
- // the others are radiogroups
- void update_action_group_from_popover_model()
- {
- clear_actions();
-
- GtkPopover* pPopover = gtk_menu_button_get_popover(m_pMenuButton);
- if (GMenuModel* pMenuModel = GTK_IS_POPOVER_MENU(pPopover) ?
- gtk_popover_menu_get_menu_model(GTK_POPOVER_MENU(pPopover)) :
- nullptr)
- {
- process_menu_model(pMenuModel);
- }
-
- // move hidden entries to m_pHiddenActionGroup
- g_action_map_add_action_entries(G_ACTION_MAP(m_pActionGroup), m_aActionEntries.data(), m_aActionEntries.size(), this);
- for (const auto& id : m_aHiddenIds)
- {
- GAction* pAction = g_action_map_lookup_action(G_ACTION_MAP(m_pActionGroup), m_aIdToAction[id].getStr());
- g_action_map_add_action(G_ACTION_MAP(m_pHiddenActionGroup), pAction);
- g_action_map_remove_action(G_ACTION_MAP(m_pActionGroup), m_aIdToAction[id].getStr());
- }
- }
-
-#endif
-
static void signalFlagsChanged(GtkToggleButton* pToggleButton, GtkStateFlags flags, gpointer widget)
{
GtkInstanceMenuButton* pThis = static_cast<GtkInstanceMenuButton*>(widget);
@@ -9741,33 +9766,7 @@ public:
virtual void insert_item(int pos, const OUString& rId, const OUString& rStr,
const OUString* pIconName, VirtualDevice* pImageSurface, TriState eCheckRadioFalse) override
{
-#if !GTK_CHECK_VERSION(4, 0, 0)
MenuHelper::insert_item(pos, rId, rStr, pIconName, pImageSurface, eCheckRadioFalse);
-#else
- (void)pIconName; (void)pImageSurface;
-
- GtkPopover* pPopover = gtk_menu_button_get_popover(m_pMenuButton);
- if (GMenuModel* pMenuModel = GTK_IS_POPOVER_MENU(pPopover) ?
- gtk_popover_menu_get_menu_model(GTK_POPOVER_MENU(pPopover)) :
- nullptr)
- {
- auto aSectionAndPos = get_section_and_pos_for(pMenuModel, pos);
- GMenu* pMenu = G_MENU(aSectionAndPos.first);
- // action with a target value ... the action name and target value are separated by a double
- // colon ... For example: "app.action::target"
- OUString sActionAndTarget;
- if (eCheckRadioFalse == TRISTATE_INDET)
- sActionAndTarget = "menu.normal." + rId + "::" + rId;
- else
- sActionAndTarget = "menu.radio." + rId + "::" + rId;
- g_menu_insert(pMenu, aSectionAndPos.second, MapToGtkAccelerator(rStr).getStr(), sActionAndTarget.toUtf8().getStr());
-
- assert(eCheckRadioFalse == TRISTATE_INDET); // come back to this later
-
- // TODO not redo entire group
- update_action_group_from_popover_model();
- }
-#endif
}
virtual void insert_separator(int pos, const OUString& rId) override
@@ -9824,22 +9823,10 @@ public:
MenuHelper::set_item_visible(rIdent, bVisible);
}
-#if GTK_CHECK_VERSION(4, 0, 0)
- static void action_activated(GSimpleAction*, GVariant* pParameter, gpointer widget)
- {
- gsize nLength;
- const gchar* pStr = g_variant_get_string(pParameter, &nLength);
- OString aStr(pStr, nLength);
- GtkInstanceMenuButton* pThis = static_cast<GtkInstanceMenuButton*>(widget);
- SolarMutexGuard aGuard;
- pThis->signal_selected(aStr);
- }
-#else
virtual void signal_item_activate(const OString& rIdent) override
{
signal_selected(rIdent);
}
-#endif
virtual void set_popover(weld::Widget* pPopover) override
{
@@ -10224,13 +10211,13 @@ protected:
#endif
private:
-#if !GTK_CHECK_VERSION(4, 0, 0)
virtual void signal_item_activate(const OString& rIdent) override
{
m_sActivated = rIdent;
weld::Menu::signal_activate(m_sActivated);
}
+#if !GTK_CHECK_VERSION(4, 0, 0)
void clear_extras()
{
if (m_aExtraItems.empty())
More information about the Libreoffice-commits
mailing list