[gimp/gimp-2-10] app: start porting away from GtkAction and friends



commit 417d0dccd780b49bdea1c0ac6b05e8424d197827
Author: Michael Natterer <mitch gimp org>
Date:   Tue Jul 2 03:54:38 2019 +0200

    app: start porting away from GtkAction and friends
    
    Step one: get rid of all those deprecation warnings that make
    it hard to see any other warnings:
    
    - add a lot of dummy API to GimpAction, GimpActionGroup, GimpUIManager
      etc. which simply forwards to the deprecated GTK functions, they
      will all go away again later
    - rename GimpAction to GimpActionImpl
    - add interface GimpAction that is implemented by all action classes,
      creates a common interface and allows to remove some duplicated
      logic from GimpToggleAction and GimpRadioAction, and at the same
      time adds more features
    
    (cherry picked from commit 86e07c16b5306c3459026386c3d62e6d3456e958)
    
    Merged to gimp-2-10 to keep the diff to master as small as possible

 app/actions/cursor-info-commands.c     |   4 +-
 app/actions/dashboard-commands.c       |  11 +-
 app/actions/data-editor-commands.c     |   3 +-
 app/actions/debug-commands.c           |  21 +-
 app/actions/dock-commands.c            |   7 +-
 app/actions/dockable-commands.c        |  13 +-
 app/actions/drawable-commands.c        |  10 +-
 app/actions/edit-actions.c             |  10 +-
 app/actions/error-console-commands.c   |   7 +-
 app/actions/file-actions.c             |   9 +-
 app/actions/filters-actions.c          |  35 +--
 app/actions/filters-commands.c         |  38 +--
 app/actions/filters-commands.h         |   8 +-
 app/actions/gradient-editor-commands.c |   9 +-
 app/actions/image-commands.c           |  10 +-
 app/actions/items-commands.c           |  10 +-
 app/actions/layers-commands.c          |  16 +-
 app/actions/plug-in-actions.c          |  18 +-
 app/actions/quick-mask-commands.c      |   6 +-
 app/actions/sample-points-commands.c   |   3 +-
 app/actions/text-editor-commands.c     |   3 +-
 app/actions/text-tool-commands.c       |   3 +-
 app/actions/tool-options-actions.c     |   9 +-
 app/actions/tools-actions.c            |  11 +-
 app/actions/tools-commands.c           |   4 +-
 app/actions/view-actions.c             |   6 +-
 app/actions/view-commands.c            |  54 ++--
 app/actions/window-actions.c           |  27 +-
 app/actions/windows-actions.c          |  71 +++---
 app/actions/windows-commands.c         |  10 +-
 app/dialogs/action-search-dialog.c     |  27 +-
 app/display/gimpdisplayshell.c         |   2 +-
 app/display/gimpimagewindow.c          |   7 +-
 app/gui/gui.c                          |  32 ++-
 app/menus/file-menu.c                  |  31 ++-
 app/menus/filters-menu.c               |  10 +-
 app/menus/plug-in-menus.c              |  65 +++--
 app/menus/tool-options-menu.c          |  16 +-
 app/menus/window-menu.c                |  29 ++-
 app/menus/windows-menu.c               |  61 ++---
 app/tools/gimptexttool.c               |   4 +-
 app/widgets/Makefile.am                |   2 +
 app/widgets/gimpaction-history.c       |  10 +-
 app/widgets/gimpaction-history.h       |   4 +-
 app/widgets/gimpaction.c               | 442 +++++++++------------------------
 app/widgets/gimpaction.h               |  82 +++---
 app/widgets/gimpactiongroup.c          | 217 ++++++++--------
 app/widgets/gimpactiongroup.h          |  20 +-
 app/widgets/gimpactionimpl.c           | 394 +++++++++++++++++++++++++++++
 app/widgets/gimpactionimpl.h           |  61 +++++
 app/widgets/gimpactionview.c           |  36 +--
 app/widgets/gimpcontrollereditor.c     |   5 +-
 app/widgets/gimpcontrollers.c          |  15 +-
 app/widgets/gimpdashboard.c            |  57 ++---
 app/widgets/gimpdockbook.c             |  45 ++--
 app/widgets/gimpdockwindow.c           |   3 +-
 app/widgets/gimpeditor.c               |  28 ++-
 app/widgets/gimpenumaction.c           |  29 ++-
 app/widgets/gimpenumaction.h           |   8 +-
 app/widgets/gimpitemtreeview.c         |   5 +-
 app/widgets/gimpmenufactory.c          |  23 +-
 app/widgets/gimpprocedureaction.c      |  26 +-
 app/widgets/gimpprocedureaction.h      |  10 +-
 app/widgets/gimpradioaction.c          |  55 ++--
 app/widgets/gimpradioaction.h          |  19 +-
 app/widgets/gimpsearchpopup.c          |  35 +--
 app/widgets/gimpsearchpopup.h          |   2 +-
 app/widgets/gimpstringaction.c         |   7 +-
 app/widgets/gimpstringaction.h         |   8 +-
 app/widgets/gimptexteditor.c           |   4 +-
 app/widgets/gimptoggleaction.c         |  57 ++---
 app/widgets/gimptoggleaction.h         |  15 +-
 app/widgets/gimptoolbox-color-area.c   |   9 +-
 app/widgets/gimptooloptionseditor.c    |   4 +-
 app/widgets/gimptoolpalette.c          |   2 +-
 app/widgets/gimpuimanager.c            | 129 ++++++++--
 app/widgets/gimpuimanager.h            |  33 ++-
 app/widgets/gimpwidgets-utils.c        |  22 +-
 app/widgets/gimpwidgets-utils.h        |   2 +-
 79 files changed, 1550 insertions(+), 1105 deletions(-)
---
diff --git a/app/actions/cursor-info-commands.c b/app/actions/cursor-info-commands.c
index 57861546ce..774d780e18 100644
--- a/app/actions/cursor-info-commands.c
+++ b/app/actions/cursor-info-commands.c
@@ -22,6 +22,8 @@
 
 #include "actions-types.h"
 
+#include "widgets/gimptoggleaction.h"
+
 #include "display/gimpcursorview.h"
 
 #include "cursor-info-commands.h"
@@ -36,7 +38,7 @@ cursor_info_sample_merged_cmd_callback (GtkAction *action,
   GimpCursorView *view = GIMP_CURSOR_VIEW (data);
   gboolean        active;
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   gimp_cursor_view_set_sample_merged (view, active);
 }
diff --git a/app/actions/dashboard-commands.c b/app/actions/dashboard-commands.c
index c628e9858e..d9ffeb30cf 100644
--- a/app/actions/dashboard-commands.c
+++ b/app/actions/dashboard-commands.c
@@ -28,6 +28,8 @@
 
 #include "widgets/gimpdashboard.h"
 #include "widgets/gimphelp-ids.h"
+#include "widgets/gimpradioaction.h"
+#include "widgets/gimptoggleaction.h"
 #include "widgets/gimpuimanager.h"
 
 #include "dialogs/dialogs.h"
@@ -59,7 +61,8 @@ dashboard_update_interval_cmd_callback (GtkAction *action,
   GimpDashboard              *dashboard = GIMP_DASHBOARD (data);
   GimpDashboardUpdateInteval  update_interval;
 
-  update_interval = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  update_interval =
+    gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   gimp_dashboard_set_update_interval (dashboard, update_interval);
 }
@@ -72,7 +75,8 @@ dashboard_history_duration_cmd_callback (GtkAction *action,
   GimpDashboard                *dashboard = GIMP_DASHBOARD (data);
   GimpDashboardHistoryDuration  history_duration;
 
-  history_duration = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  history_duration =
+    gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   gimp_dashboard_set_history_duration (dashboard, history_duration);
 }
@@ -235,7 +239,8 @@ dashboard_low_swap_space_warning_cmd_callback (GtkAction *action,
   GimpDashboard *dashboard = GIMP_DASHBOARD (data);
   gboolean       low_swap_space_warning;
 
-  low_swap_space_warning = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  low_swap_space_warning =
+    gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   gimp_dashboard_set_low_swap_space_warning (dashboard, low_swap_space_warning);
 }
diff --git a/app/actions/data-editor-commands.c b/app/actions/data-editor-commands.c
index f885d808bf..e4aff4ed40 100644
--- a/app/actions/data-editor-commands.c
+++ b/app/actions/data-editor-commands.c
@@ -23,6 +23,7 @@
 #include "actions-types.h"
 
 #include "widgets/gimpdataeditor.h"
+#include "widgets/gimptoggleaction.h"
 
 #include "data-editor-commands.h"
 
@@ -36,7 +37,7 @@ data_editor_edit_active_cmd_callback (GtkAction *action,
   GimpDataEditor *editor = GIMP_DATA_EDITOR (data);
   gboolean        edit_active;
 
-  edit_active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  edit_active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   gimp_data_editor_set_edit_active (editor, edit_active);
 }
diff --git a/app/actions/debug-commands.c b/app/actions/debug-commands.c
index dc9bcace5d..02660fdcaf 100644
--- a/app/actions/debug-commands.c
+++ b/app/actions/debug-commands.c
@@ -36,6 +36,7 @@
 #include "gegl/gimp-gegl-utils.h"
 
 #include "widgets/gimpaction.h"
+#include "widgets/gimpactiongroup.h"
 #include "widgets/gimpmenufactory.h"
 #include "widgets/gimpuimanager.h"
 
@@ -169,7 +170,7 @@ debug_dump_managers_cmd_callback (GtkAction *action,
                    "========================================\n\n",
                    entry->identifier);
 
-          g_print ("%s\n", gtk_ui_manager_get_ui (managers->data));
+          g_print ("%s\n", gimp_ui_manager_get_ui (managers->data));
         }
     }
 }
@@ -180,19 +181,19 @@ debug_dump_keyboard_shortcuts_cmd_callback (GtkAction *action,
 {
   GimpDisplay      *display;
   GimpImageWindow  *window;
-  GtkUIManager     *manager;
+  GimpUIManager    *manager;
   GtkAccelGroup    *accel_group;
   GList            *group_it;
   GList            *strings = NULL;
   return_if_no_display (display, data);
 
   window  = gimp_display_shell_get_window (gimp_display_get_shell (display));
-  manager = GTK_UI_MANAGER (gimp_image_window_get_ui_manager (window));
+  manager = gimp_image_window_get_ui_manager (window);
 
-  accel_group = gtk_ui_manager_get_accel_group (manager);
+  accel_group = gimp_ui_manager_get_accel_group (manager);
 
   /* Gather formatted strings of keyboard shortcuts */
-  for (group_it = gtk_ui_manager_get_action_groups (manager);
+  for (group_it = gimp_ui_manager_get_action_groups (manager);
        group_it;
        group_it = g_list_next (group_it))
     {
@@ -200,13 +201,13 @@ debug_dump_keyboard_shortcuts_cmd_callback (GtkAction *action,
       GList           *actions   = NULL;
       GList           *action_it = NULL;
 
-      actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
+      actions = gimp_action_group_list_actions (group);
       actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare);
 
       for (action_it = actions; action_it; action_it = g_list_next (action_it))
         {
-          GtkAction   *action        = action_it->data;
-          const gchar *name          = gtk_action_get_name (action);
+          GimpAction  *action        = action_it->data;
+          const gchar *name          = gimp_action_get_name (action);
           GClosure    *accel_closure = NULL;
 
           if (strstr (name, "-menu")  ||
@@ -214,7 +215,7 @@ debug_dump_keyboard_shortcuts_cmd_callback (GtkAction *action,
               name[0] == '<')
               continue;
 
-          accel_closure = gtk_action_get_accel_closure (action);
+          accel_closure = gimp_action_get_accel_closure (action);
 
           if (accel_closure)
             {
@@ -229,7 +230,7 @@ debug_dump_keyboard_shortcuts_cmd_callback (GtkAction *action,
                   gchar       *label;
                   gchar       *key_string;
 
-                  label_tmp  = gtk_action_get_label (action);
+                  label_tmp  = gimp_action_get_label (action);
                   label      = gimp_strip_uline (label_tmp);
                   key_string = gtk_accelerator_get_label (key->accel_key,
                                                           key->accel_mods);
diff --git a/app/actions/dock-commands.c b/app/actions/dock-commands.c
index 5d465597a4..d6c5cbc9a3 100644
--- a/app/actions/dock-commands.c
+++ b/app/actions/dock-commands.c
@@ -26,6 +26,7 @@
 
 #include "widgets/gimpdockwindow.h"
 #include "widgets/gimpdockwindow.h"
+#include "widgets/gimptoggleaction.h"
 
 #include "actions.h"
 #include "dock-commands.h"
@@ -58,7 +59,8 @@ dock_toggle_image_menu_cmd_callback (GtkAction *action,
 
   if (dock_window)
     {
-      gboolean active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      gboolean active =
+        gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_dock_window_set_show_image_menu (dock_window, active);
     }
@@ -76,7 +78,8 @@ dock_toggle_auto_cmd_callback (GtkAction *action,
 
   if (dock_window)
     {
-      gboolean active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      gboolean active =
+        gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_dock_window_set_auto_follow_active (dock_window, active);
     }
diff --git a/app/actions/dockable-commands.c b/app/actions/dockable-commands.c
index bd5b2d24cf..7faeabacc7 100644
--- a/app/actions/dockable-commands.c
+++ b/app/actions/dockable-commands.c
@@ -33,7 +33,9 @@
 #include "widgets/gimpdockable.h"
 #include "widgets/gimpdockbook.h"
 #include "widgets/gimpdocked.h"
+#include "widgets/gimpradioaction.h"
 #include "widgets/gimpsessioninfo.h"
+#include "widgets/gimptoggleaction.h"
 
 #include "dockable-commands.h"
 
@@ -91,7 +93,8 @@ dockable_lock_tab_cmd_callback (GtkAction *action,
 
   if (dockable)
     {
-      gboolean lock = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      gboolean lock =
+        gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_dockable_set_locked (dockable, lock);
     }
@@ -108,7 +111,7 @@ dockable_toggle_view_cmd_callback (GtkAction *action,
   gint          page_num;
 
   view_type = (GimpViewType)
-    gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+    gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (dockbook));
 
@@ -219,7 +222,7 @@ dockable_view_size_cmd_callback (GtkAction *action,
   GimpDockable *dockable = dockable_get_current (dockbook);
   gint          view_size;
 
-  view_size = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  view_size = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (dockable)
     {
@@ -248,7 +251,7 @@ dockable_tab_style_cmd_callback (GtkAction *action,
   GimpTabStyle  tab_style;
 
   tab_style = (GimpTabStyle)
-    gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+    gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (dockable && gimp_dockable_get_tab_style (dockable) != tab_style)
     {
@@ -277,7 +280,7 @@ dockable_show_button_bar_cmd_callback (GtkAction *action,
       gboolean    show;
 
       docked = GIMP_DOCKED (gtk_bin_get_child (GTK_BIN (dockable)));
-      show   = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      show   = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_docked_set_show_button_bar (docked, show);
     }
diff --git a/app/actions/drawable-commands.c b/app/actions/drawable-commands.c
index 03afd7141d..287454dee7 100644
--- a/app/actions/drawable-commands.c
+++ b/app/actions/drawable-commands.c
@@ -35,6 +35,8 @@
 #include "core/gimplayermask.h"
 #include "core/gimpprogress.h"
 
+#include "widgets/gimptoggleaction.h"
+
 #include "dialogs/dialogs.h"
 
 #include "actions.h"
@@ -91,7 +93,7 @@ drawable_linked_cmd_callback (GtkAction *action,
   gboolean      linked;
   return_if_no_drawable (image, drawable, data);
 
-  linked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  linked = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (GIMP_IS_LAYER_MASK (drawable))
     drawable =
@@ -122,7 +124,7 @@ drawable_visible_cmd_callback (GtkAction *action,
   gboolean      visible;
   return_if_no_drawable (image, drawable, data);
 
-  visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  visible = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (GIMP_IS_LAYER_MASK (drawable))
     drawable =
@@ -153,7 +155,7 @@ drawable_lock_content_cmd_callback (GtkAction *action,
   gboolean      locked;
   return_if_no_drawable (image, drawable, data);
 
-  locked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  locked = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (GIMP_IS_LAYER_MASK (drawable))
     drawable =
@@ -188,7 +190,7 @@ drawable_lock_position_cmd_callback (GtkAction *action,
   gboolean      locked;
   return_if_no_drawable (image, drawable, data);
 
-  locked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  locked = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (GIMP_IS_LAYER_MASK (drawable))
     drawable =
diff --git a/app/actions/edit-actions.c b/app/actions/edit-actions.c
index 9a1d732481..a1b6c4c811 100644
--- a/app/actions/edit-actions.c
+++ b/app/actions/edit-actions.c
@@ -34,6 +34,7 @@
 #include "core/gimptoolinfo.h"
 #include "core/gimpundostack.h"
 
+#include "widgets/gimpaction.h"
 #include "widgets/gimpactiongroup.h"
 #include "widgets/gimphelp-ids.h"
 
@@ -235,7 +236,7 @@ edit_actions_setup (GimpActionGroup *group)
   GimpContext *context = gimp_get_user_context (group->gimp);
   GimpRGB      color;
   GimpPattern *pattern;
-  GtkAction   *action;
+  GimpAction  *action;
 
   gimp_action_group_add_actions (group, "edit-action",
                                  edit_actions,
@@ -251,9 +252,10 @@ edit_actions_setup (GimpActionGroup *group)
                                       G_N_ELEMENTS (edit_fill_actions),
                                       G_CALLBACK (edit_fill_cmd_callback));
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                        "edit-paste-as-new-image-short");
-  gtk_action_set_accel_path (action, "<Actions>/edit/edit-paste-as-new-image");
+  action = gimp_action_group_get_action (group,
+                                         "edit-paste-as-new-image-short");
+  gimp_action_set_accel_path (action,
+                              "<Actions>/edit/edit-paste-as-new-image");
 
   gimp_action_group_set_action_context (group, "edit-fill-fg", context);
   gimp_action_group_set_action_context (group, "edit-fill-bg", context);
diff --git a/app/actions/error-console-commands.c b/app/actions/error-console-commands.c
index 5a626e67a3..7969bf8bec 100644
--- a/app/actions/error-console-commands.c
+++ b/app/actions/error-console-commands.c
@@ -30,6 +30,7 @@
 #include "widgets/gimperrorconsole.h"
 #include "widgets/gimphelp-ids.h"
 #include "widgets/gimptextbuffer.h"
+#include "widgets/gimptoggleaction.h"
 
 #include "error-console-commands.h"
 
@@ -138,7 +139,7 @@ error_console_highlight_error_cmd_callback (GtkAction *action,
   GimpErrorConsole *console = GIMP_ERROR_CONSOLE (data);
   gboolean          active;
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   console->highlight[GIMP_MESSAGE_ERROR] = active;
 }
@@ -150,7 +151,7 @@ error_console_highlight_warning_cmd_callback (GtkAction *action,
   GimpErrorConsole *console = GIMP_ERROR_CONSOLE (data);
   gboolean          active;
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   console->highlight[GIMP_MESSAGE_WARNING] = active;
 }
@@ -162,7 +163,7 @@ error_console_highlight_info_cmd_callback (GtkAction *action,
   GimpErrorConsole *console = GIMP_ERROR_CONSOLE (data);
   gboolean          active;
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   console->highlight[GIMP_MESSAGE_INFO] = active;
 }
diff --git a/app/actions/file-actions.c b/app/actions/file-actions.c
index 982720d627..ee0faa09d7 100644
--- a/app/actions/file-actions.c
+++ b/app/actions/file-actions.c
@@ -39,6 +39,7 @@
 
 #include "widgets/gimpaction.h"
 #include "widgets/gimpactiongroup.h"
+#include "widgets/gimpactionimpl.h"
 #include "widgets/gimphelp-ids.h"
 
 #include "display/gimpdisplay.h"
@@ -355,17 +356,17 @@ file_actions_last_opened_update (GimpContainer   *container,
 
   for (i = 0; i < n; i++)
     {
-      GtkAction *action;
-      gchar     *name = g_strdup_printf ("file-open-recent-%02d", i + 1);
+      GimpAction *action;
+      gchar      *name = g_strdup_printf ("file-open-recent-%02d", i + 1);
 
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), name);
+      action = gimp_action_group_get_action (group, name);
 
       if (i < num_documents)
         {
           GimpImagefile *imagefile = (GimpImagefile *)
             gimp_container_get_child_by_index (container, i);
 
-          if (GIMP_ACTION (action)->viewable != (GimpViewable *) imagefile)
+          if (GIMP_ACTION_IMPL (action)->viewable != (GimpViewable *) imagefile)
             {
               GFile       *file;
               const gchar *name;
diff --git a/app/actions/filters-actions.c b/app/actions/filters-actions.c
index 16b3fcbf02..4f3901f97d 100644
--- a/app/actions/filters-actions.c
+++ b/app/actions/filters-actions.c
@@ -30,6 +30,7 @@
 
 #include "pdb/gimpprocedure.h"
 
+#include "widgets/gimpaction.h"
 #include "widgets/gimpactiongroup.h"
 #include "widgets/gimphelp-ids.h"
 #include "widgets/gimpuimanager.h"
@@ -1068,7 +1069,7 @@ filters_actions_history_changed (Gimp            *gimp,
 
   if (proc)
     {
-      GtkAction   *actual_action = NULL;
+      GimpAction  *actual_action = NULL;
       const gchar *label;
       gchar       *repeat;
       gchar       *reshow;
@@ -1088,8 +1089,8 @@ filters_actions_history_changed (Gimp            *gimp,
       if (g_str_has_prefix (gimp_object_get_name (proc), "filters-"))
         {
           actual_action =
-            gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                         gimp_object_get_name (proc));
+            gimp_action_group_get_action (group,
+                                          gimp_object_get_name (proc));
         }
       else if (plug_in_group)
         {
@@ -1100,12 +1101,12 @@ filters_actions_history_changed (Gimp            *gimp,
            *  #517683.
            */
           actual_action =
-            gtk_action_group_get_action (GTK_ACTION_GROUP (plug_in_group),
-                                         gimp_object_get_name (proc));
+            gimp_action_group_get_action (plug_in_group,
+                                          gimp_object_get_name (proc));
         }
 
       if (actual_action)
-        sensitive = gtk_action_get_sensitive (actual_action);
+        sensitive = gimp_action_get_sensitive (actual_action);
 
       gimp_action_group_set_action_sensitive (group, "filters-repeat",
                                               sensitive);
@@ -1125,14 +1126,14 @@ filters_actions_history_changed (Gimp            *gimp,
 
   for (i = 0; i < gimp_filter_history_length (gimp); i++)
     {
-      GtkAction   *action;
-      GtkAction   *actual_action = NULL;
+      GimpAction  *action;
+      GimpAction  *actual_action = NULL;
       const gchar *label;
       gchar       *name;
       gboolean     sensitive = FALSE;
 
       name = g_strdup_printf ("filters-recent-%02d", i + 1);
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), name);
+      action = gimp_action_group_get_action (group, name);
       g_free (name);
 
       proc = gimp_filter_history_nth (gimp, i);
@@ -1142,19 +1143,19 @@ filters_actions_history_changed (Gimp            *gimp,
       if (g_str_has_prefix (gimp_object_get_name (proc), "filters-"))
         {
           actual_action =
-            gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                         gimp_object_get_name (proc));
+            gimp_action_group_get_action (group,
+                                          gimp_object_get_name (proc));
         }
       else if (plug_in_group)
         {
           /*  see comment above  */
           actual_action =
-            gtk_action_group_get_action (GTK_ACTION_GROUP (plug_in_group),
-                                         gimp_object_get_name (proc));
+            gimp_action_group_get_action (plug_in_group,
+                                          gimp_object_get_name (proc));
         }
 
       if (actual_action)
-        sensitive = gtk_action_get_sensitive (actual_action);
+        sensitive = gimp_action_get_sensitive (actual_action);
 
       g_object_set (action,
                     "visible",   TRUE,
@@ -1168,10 +1169,10 @@ filters_actions_history_changed (Gimp            *gimp,
 
   for (; i < gimp_filter_history_size (gimp); i++)
     {
-      GtkAction *action;
-      gchar     *name = g_strdup_printf ("filters-recent-%02d", i + 1);
+      GimpAction *action;
+      gchar      *name = g_strdup_printf ("filters-recent-%02d", i + 1);
 
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), name);
+      action = gimp_action_group_get_action (group, name);
       g_free (name);
 
       g_object_set (action,
diff --git a/app/actions/filters-commands.c b/app/actions/filters-commands.c
index 720d0a675e..949bf86918 100644
--- a/app/actions/filters-commands.c
+++ b/app/actions/filters-commands.c
@@ -36,6 +36,8 @@
 #include "core/gimpprogress.h"
 #include "core/gimpsettings.h"
 
+#include "widgets/gimpaction.h"
+
 #include "actions.h"
 #include "filters-commands.h"
 #include "gimpgeglprocedure.h"
@@ -58,7 +60,7 @@ static void    filters_run_procedure   (Gimp          *gimp,
 /*  public functions  */
 
 void
-filters_apply_cmd_callback (GtkAction   *action,
+filters_apply_cmd_callback (GimpAction  *action,
                             const gchar *operation_str,
                             gpointer     data)
 {
@@ -71,18 +73,17 @@ filters_apply_cmd_callback (GtkAction   *action,
 
   operation = filters_parse_operation (image->gimp,
                                        operation_str,
-                                       gtk_action_get_icon_name (action),
+                                       gimp_action_get_icon_name (action),
                                        &settings);
 
   procedure = gimp_gegl_procedure_new (image->gimp,
                                        GIMP_RUN_NONINTERACTIVE, settings,
                                        operation,
-                                       gtk_action_get_name (action),
-                                       gtk_action_get_label (action),
-                                       gtk_action_get_tooltip (action),
-                                       gtk_action_get_icon_name (action),
-                                       g_object_get_qdata (G_OBJECT (action),
-                                                           GIMP_HELP_ID));
+                                       gimp_action_get_name (action),
+                                       gimp_action_get_label (action),
+                                       gimp_action_get_tooltip (action),
+                                       gimp_action_get_icon_name (action),
+                                       gimp_action_get_help_id (action));
 
   g_free (operation);
 
@@ -96,7 +97,7 @@ filters_apply_cmd_callback (GtkAction   *action,
 }
 
 void
-filters_apply_interactive_cmd_callback (GtkAction   *action,
+filters_apply_interactive_cmd_callback (GimpAction  *action,
                                         const gchar *operation,
                                         gpointer     data)
 {
@@ -108,12 +109,11 @@ filters_apply_interactive_cmd_callback (GtkAction   *action,
   procedure = gimp_gegl_procedure_new (image->gimp,
                                        GIMP_RUN_INTERACTIVE, NULL,
                                        operation,
-                                       gtk_action_get_name (action),
-                                       gtk_action_get_label (action),
-                                       gtk_action_get_tooltip (action),
-                                       gtk_action_get_icon_name (action),
-                                       g_object_get_qdata (G_OBJECT (action),
-                                                           GIMP_HELP_ID));
+                                       gimp_action_get_name (action),
+                                       gimp_action_get_label (action),
+                                       gimp_action_get_tooltip (action),
+                                       gimp_action_get_icon_name (action),
+                                       gimp_action_get_help_id (action));
 
   gimp_filter_history_add (image->gimp, procedure);
   filters_history_cmd_callback (NULL, procedure, data);
@@ -122,9 +122,9 @@ filters_apply_interactive_cmd_callback (GtkAction   *action,
 }
 
 void
-filters_repeat_cmd_callback (GtkAction *action,
-                             gint       value,
-                             gpointer   data)
+filters_repeat_cmd_callback (GimpAction *action,
+                             gint        value,
+                             gpointer    data)
 {
   GimpImage     *image;
   GimpDrawable  *drawable;
@@ -141,7 +141,7 @@ filters_repeat_cmd_callback (GtkAction *action,
 }
 
 void
-filters_history_cmd_callback (GtkAction     *action,
+filters_history_cmd_callback (GimpAction    *action,
                               GimpProcedure *procedure,
                               gpointer       data)
 {
diff --git a/app/actions/filters-commands.h b/app/actions/filters-commands.h
index 321d487def..f69893991b 100644
--- a/app/actions/filters-commands.h
+++ b/app/actions/filters-commands.h
@@ -19,17 +19,17 @@
 #define __FILTERS_COMMANDS_H__
 
 
-void   filters_apply_cmd_callback             (GtkAction     *action,
+void   filters_apply_cmd_callback             (GimpAction    *action,
                                                const gchar   *operation,
                                                gpointer       data);
-void   filters_apply_interactive_cmd_callback (GtkAction     *action,
+void   filters_apply_interactive_cmd_callback (GimpAction    *action,
                                                const gchar   *operation,
                                                gpointer       data);
 
-void   filters_repeat_cmd_callback            (GtkAction     *action,
+void   filters_repeat_cmd_callback            (GimpAction    *action,
                                                gint           value,
                                                gpointer       data);
-void   filters_history_cmd_callback           (GtkAction     *action,
+void   filters_history_cmd_callback           (GimpAction    *action,
                                                GimpProcedure *procedure,
                                                gpointer       data);
 
diff --git a/app/actions/gradient-editor-commands.c b/app/actions/gradient-editor-commands.c
index 5a2ee49aff..44bdaf0a60 100644
--- a/app/actions/gradient-editor-commands.c
+++ b/app/actions/gradient-editor-commands.c
@@ -31,6 +31,7 @@
 
 #include "widgets/gimpgradienteditor.h"
 #include "widgets/gimphelp-ids.h"
+#include "widgets/gimpradioaction.h"
 #include "widgets/gimpuimanager.h"
 #include "widgets/gimpviewabledialog.h"
 
@@ -72,7 +73,7 @@ gradient_editor_left_color_type_cmd_callback (GtkAction *action,
 
   gimp_gradient_editor_get_selection (editor, &gradient, &left, NULL);
 
-  color_type = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  color_type = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (gradient        &&
       color_type >= 0 &&
@@ -189,7 +190,7 @@ gradient_editor_right_color_type_cmd_callback (GtkAction *action,
 
   gimp_gradient_editor_get_selection (editor, &gradient, NULL, &right);
 
-  color_type = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  color_type = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (gradient        &&
       color_type >= 0 &&
@@ -299,7 +300,7 @@ gradient_editor_blending_func_cmd_callback (GtkAction *action,
 
   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
 
-  type = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  type = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   enum_class = g_type_class_ref (GIMP_TYPE_GRADIENT_SEGMENT_TYPE);
 
@@ -327,7 +328,7 @@ gradient_editor_coloring_type_cmd_callback (GtkAction *action,
 
   gimp_gradient_editor_get_selection (editor, &gradient, &left, &right);
 
-  color = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  color = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   enum_class = g_type_class_ref (GIMP_TYPE_GRADIENT_SEGMENT_COLOR);
 
diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c
index 130495df6f..f8b0da8056 100644
--- a/app/actions/image-commands.c
+++ b/app/actions/image-commands.c
@@ -54,6 +54,8 @@
 #include "widgets/gimpdialogfactory.h"
 #include "widgets/gimpdock.h"
 #include "widgets/gimphelp-ids.h"
+#include "widgets/gimpradioaction.h"
+#include "widgets/gimptoggleaction.h"
 #include "widgets/gimpwidgets-utils.h"
 
 #include "display/gimpdisplay.h"
@@ -243,7 +245,7 @@ image_convert_base_type_cmd_callback (GtkAction *action,
   return_if_no_display (display, data);
   return_if_no_widget (widget, data);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value == gimp_image_get_base_type (image))
     return;
@@ -359,7 +361,7 @@ image_convert_precision_cmd_callback (GtkAction *action,
   return_if_no_display (display, data);
   return_if_no_widget (widget, data);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value == gimp_image_get_component_type (image))
     return;
@@ -407,7 +409,7 @@ image_convert_gamma_cmd_callback (GtkAction *action,
   return_if_no_image (image, data);
   return_if_no_display (display, data);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value == gimp_babl_format_get_linear (gimp_image_get_layer_format (image,
                                                                          FALSE)))
@@ -432,7 +434,7 @@ image_color_management_enabled_cmd_callback (GtkAction *action,
   gboolean   enabled;
   return_if_no_image (image, data);
 
-  enabled = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  enabled = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (enabled != gimp_image_get_is_color_managed (image))
     {
diff --git a/app/actions/items-commands.c b/app/actions/items-commands.c
index 5d81524bc4..678de49700 100644
--- a/app/actions/items-commands.c
+++ b/app/actions/items-commands.c
@@ -33,6 +33,8 @@
 #include "core/gimpitem.h"
 #include "core/gimpitemundo.h"
 
+#include "widgets/gimptoggleaction.h"
+
 #include "dialogs/dialogs.h"
 #include "dialogs/fill-dialog.h"
 #include "dialogs/stroke-dialog.h"
@@ -68,7 +70,7 @@ items_visible_cmd_callback (GtkAction *action,
 {
   gboolean visible;
 
-  visible = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  visible = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (visible != gimp_item_get_visible (item))
     {
@@ -93,7 +95,7 @@ items_linked_cmd_callback (GtkAction *action,
 {
   gboolean linked;
 
-  linked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  linked = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (linked != gimp_item_get_linked (item))
     {
@@ -118,7 +120,7 @@ items_lock_content_cmd_callback (GtkAction *action,
 {
   gboolean locked;
 
-  locked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  locked = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (locked != gimp_item_get_lock_content (item))
     {
@@ -143,7 +145,7 @@ items_lock_position_cmd_callback (GtkAction *action,
 {
   gboolean locked;
 
-  locked = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  locked = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (locked != gimp_item_get_lock_position (item))
     {
diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c
index 289a0f0228..2425cd24f6 100644
--- a/app/actions/layers-commands.c
+++ b/app/actions/layers-commands.c
@@ -65,6 +65,8 @@
 #include "widgets/gimpdock.h"
 #include "widgets/gimphelp-ids.h"
 #include "widgets/gimpprogressdialog.h"
+#include "widgets/gimpradioaction.h"
+#include "widgets/gimptoggleaction.h"
 
 #include "display/gimpdisplay.h"
 #include "display/gimpdisplayshell.h"
@@ -1006,7 +1008,7 @@ layers_mask_edit_cmd_callback (GtkAction *action,
     {
       gboolean active;
 
-      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_layer_set_edit_mask (layer, active);
       gimp_image_flush (image);
@@ -1025,7 +1027,7 @@ layers_mask_show_cmd_callback (GtkAction *action,
     {
       gboolean active;
 
-      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_layer_set_show_mask (layer, active, TRUE);
       gimp_image_flush (image);
@@ -1044,7 +1046,7 @@ layers_mask_disable_cmd_callback (GtkAction *action,
     {
       gboolean active;
 
-      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_layer_set_apply_mask (layer, ! active, TRUE);
       gimp_image_flush (image);
@@ -1190,7 +1192,7 @@ layers_blend_space_cmd_callback (GtkAction *action,
   GimpLayerColorSpace  blend_space;
   return_if_no_layer (image, layer, data);
 
-  blend_space = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  blend_space = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (blend_space != gimp_layer_get_blend_space (layer))
     {
@@ -1218,7 +1220,7 @@ layers_composite_space_cmd_callback (GtkAction *action,
   GimpLayerColorSpace  composite_space;
   return_if_no_layer (image, layer, data);
 
-  composite_space = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  composite_space = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (composite_space != gimp_layer_get_composite_space (layer))
     {
@@ -1246,7 +1248,7 @@ layers_composite_mode_cmd_callback (GtkAction *action,
   GimpLayerCompositeMode  composite_mode;
   return_if_no_layer (image, layer, data);
 
-  composite_mode = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  composite_mode = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (composite_mode != gimp_layer_get_composite_mode (layer))
     {
@@ -1317,7 +1319,7 @@ layers_lock_alpha_cmd_callback (GtkAction *action,
   gboolean   lock_alpha;
   return_if_no_layer (image, layer, data);
 
-  lock_alpha = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  lock_alpha = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (lock_alpha != gimp_layer_get_lock_alpha (layer))
     {
diff --git a/app/actions/plug-in-actions.c b/app/actions/plug-in-actions.c
index ad39a614bf..b5c5148651 100644
--- a/app/actions/plug-in-actions.c
+++ b/app/actions/plug-in-actions.c
@@ -38,7 +38,9 @@
 #include "plug-in/gimppluginmanager-menu-branch.h"
 #include "plug-in/gimppluginprocedure.h"
 
+#include "widgets/gimpaction.h"
 #include "widgets/gimpactiongroup.h"
+#include "widgets/gimpactionimpl.h"
 #include "widgets/gimphelp-ids.h"
 
 #include "actions.h"
@@ -253,18 +255,18 @@ plug_in_actions_unregister_procedure (GimpPDB         *pdb,
       if ((plug_in_proc->menu_label || plug_in_proc->menu_paths) &&
           ! plug_in_proc->file_proc)
         {
-          GtkAction *action;
+          GimpAction *action;
 
 #if 0
           g_print ("%s: %s\n", G_STRFUNC,
                    gimp_object_get_name (procedure));
 #endif
 
-          action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                                gimp_object_get_name (procedure));
+          action = gimp_action_group_get_action (group,
+                                                 gimp_object_get_name (procedure));
 
           if (action)
-            gtk_action_group_remove_action (GTK_ACTION_GROUP (group), action);
+            gimp_action_group_remove_action (group, action);
         }
     }
 }
@@ -487,8 +489,8 @@ plug_in_actions_build_path (GimpActionGroup *group,
 
   if (p1 && p2 && ! g_hash_table_lookup (path_table, copy_original))
     {
-      GtkAction *action;
-      gchar     *label;
+      GimpAction *action;
+      gchar      *label;
 
       label = p2 + 1;
 
@@ -497,8 +499,8 @@ plug_in_actions_build_path (GimpActionGroup *group,
                copy_original, label);
 #endif
 
-      action = gtk_action_new (copy_original, label, NULL, NULL);
-      gtk_action_group_add_action (GTK_ACTION_GROUP (group), action);
+      action = gimp_action_impl_new (copy_original, label, NULL, NULL, NULL);
+      gimp_action_group_add_action (group, action);
       g_object_unref (action);
 
       g_hash_table_insert (path_table, g_strdup (copy_original), action);
diff --git a/app/actions/quick-mask-commands.c b/app/actions/quick-mask-commands.c
index ef3ee25a1e..8f9d282199 100644
--- a/app/actions/quick-mask-commands.c
+++ b/app/actions/quick-mask-commands.c
@@ -31,6 +31,8 @@
 #include "core/gimpimage-quick-mask.h"
 
 #include "widgets/gimphelp-ids.h"
+#include "widgets/gimpradioaction.h"
+#include "widgets/gimptoggleaction.h"
 
 #include "dialogs/dialogs.h"
 #include "dialogs/channel-options-dialog.h"
@@ -72,7 +74,7 @@ quick_mask_toggle_cmd_callback (GtkAction *action,
   gboolean   active;
   return_if_no_image (image, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_image_get_quick_mask_state (image))
     {
@@ -90,7 +92,7 @@ quick_mask_invert_cmd_callback (GtkAction *action,
   gint       value;
   return_if_no_image (image, data);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value != gimp_image_get_quick_mask_inverted (image))
     {
diff --git a/app/actions/sample-points-commands.c b/app/actions/sample-points-commands.c
index 919ab99c99..d8c1822a74 100644
--- a/app/actions/sample-points-commands.c
+++ b/app/actions/sample-points-commands.c
@@ -23,6 +23,7 @@
 #include "actions-types.h"
 
 #include "widgets/gimpsamplepointeditor.h"
+#include "widgets/gimptoggleaction.h"
 
 #include "sample-points-commands.h"
 
@@ -36,7 +37,7 @@ sample_points_sample_merged_cmd_callback (GtkAction *action,
   GimpSamplePointEditor *editor = GIMP_SAMPLE_POINT_EDITOR (data);
   gboolean               active;
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   gimp_sample_point_editor_set_sample_merged (editor, active);
 }
diff --git a/app/actions/text-editor-commands.c b/app/actions/text-editor-commands.c
index 362e6bb0fb..d207fd70ad 100644
--- a/app/actions/text-editor-commands.c
+++ b/app/actions/text-editor-commands.c
@@ -28,6 +28,7 @@
 #include "core/gimp.h"
 
 #include "widgets/gimphelp-ids.h"
+#include "widgets/gimpradioaction.h"
 #include "widgets/gimptextbuffer.h"
 #include "widgets/gimptexteditor.h"
 #include "widgets/gimpuimanager.h"
@@ -110,7 +111,7 @@ text_editor_direction_cmd_callback (GtkAction *action,
   GimpTextEditor *editor = GIMP_TEXT_EDITOR (data);
   gint            value;
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   gimp_text_editor_set_direction (editor, (GimpTextDirection) value);
 }
diff --git a/app/actions/text-tool-commands.c b/app/actions/text-tool-commands.c
index 6a8bf61608..a1b396a482 100644
--- a/app/actions/text-tool-commands.c
+++ b/app/actions/text-tool-commands.c
@@ -29,6 +29,7 @@
 #include "core/gimptoolinfo.h"
 
 #include "widgets/gimphelp-ids.h"
+#include "widgets/gimpradioaction.h"
 #include "widgets/gimptextbuffer.h"
 #include "widgets/gimpuimanager.h"
 #include "widgets/gimpwidgets-utils.h"
@@ -182,7 +183,7 @@ text_tool_direction_cmd_callback (GtkAction *action,
   GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
   gint          value;
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   g_object_set (text_tool->proxy,
                 "base-direction", (GimpTextDirection) value,
diff --git a/app/actions/tool-options-actions.c b/app/actions/tool-options-actions.c
index b0c4610406..0d9bc8f634 100644
--- a/app/actions/tool-options-actions.c
+++ b/app/actions/tool-options-actions.c
@@ -172,18 +172,17 @@ tool_options_actions_update_presets (GimpActionGroup *group,
 
   for (i = 0; ; i++)
     {
-      gchar     *action_name;
-      GtkAction *action;
+      gchar      *action_name;
+      GimpAction *action;
 
       action_name = g_strdup_printf ("%s-%03d", action_prefix, i);
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                            action_name);
+      action = gimp_action_group_get_action (group, action_name);
       g_free (action_name);
 
       if (! action)
         break;
 
-      gtk_action_group_remove_action (GTK_ACTION_GROUP (group), action);
+      gimp_action_group_remove_action (group, action);
     }
 
   if (presets)
diff --git a/app/actions/tools-actions.c b/app/actions/tools-actions.c
index ec007c63c3..d3c249e876 100644
--- a/app/actions/tools-actions.c
+++ b/app/actions/tools-actions.c
@@ -31,6 +31,7 @@
 #include "core/gimpcontext.h"
 #include "core/gimptoolinfo.h"
 
+#include "widgets/gimpaction.h"
 #include "widgets/gimpactiongroup.h"
 #include "widgets/gimphelp-ids.h"
 
@@ -618,8 +619,8 @@ static const GimpEnumActionEntry tools_object_2_actions[] =
 void
 tools_actions_setup (GimpActionGroup *group)
 {
-  GtkAction *action;
-  GList     *list;
+  GimpAction *action;
+  GList      *list;
 
   gimp_action_group_add_actions (group, "tools-action",
                                  tools_actions,
@@ -630,9 +631,9 @@ tools_actions_setup (GimpActionGroup *group)
                                         G_N_ELEMENTS (tools_alternative_actions),
                                         G_CALLBACK (tools_select_cmd_callback));
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                        "tools-by-color-select-short");
-  gtk_action_set_accel_path (action, "<Actions>/tools/tools-by-color-select");
+  action = gimp_action_group_get_action (group,
+                                         "tools-by-color-select-short");
+  gimp_action_set_accel_path (action, "<Actions>/tools/tools-by-color-select");
 
   gimp_action_group_add_enum_actions (group, NULL,
                                       tools_color_average_radius_actions,
diff --git a/app/actions/tools-commands.c b/app/actions/tools-commands.c
index f8a4360560..5780ef2de1 100644
--- a/app/actions/tools-commands.c
+++ b/app/actions/tools-commands.c
@@ -701,8 +701,8 @@ tools_activate_enum_action (const gchar *action_desc,
 
   if (action_name)
     {
-      GList     *managers;
-      GtkAction *action;
+      GList      *managers;
+      GimpAction *action;
 
       *action_name++ = '\0';
 
diff --git a/app/actions/view-actions.c b/app/actions/view-actions.c
index 3b0203f91c..b16d6078f2 100644
--- a/app/actions/view-actions.c
+++ b/app/actions/view-actions.c
@@ -693,7 +693,7 @@ static const GimpEnumActionEntry view_scroll_vertical_actions[] =
 void
 view_actions_setup (GimpActionGroup *group)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   gimp_action_group_add_actions (group, "view-action",
                                  view_actions,
@@ -761,8 +761,8 @@ view_actions_setup (GimpActionGroup *group)
   /*  connect "activate" of view-zoom-other manually so it can be
    *  selected even if it's the active item of the radio group
    */
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                        "view-zoom-other");
+  action = gimp_action_group_get_action (group, "view-zoom-other");
+
   g_signal_connect (action, "activate",
                     G_CALLBACK (view_zoom_other_cmd_callback),
                     group->user_data);
diff --git a/app/actions/view-commands.c b/app/actions/view-commands.c
index 84d2b1ebd4..018cc06626 100644
--- a/app/actions/view-commands.c
+++ b/app/actions/view-commands.c
@@ -38,6 +38,8 @@
 #include "widgets/gimpcolordialog.h"
 #include "widgets/gimpdock.h"
 #include "widgets/gimpdialogfactory.h"
+#include "widgets/gimpradioaction.h"
+#include "widgets/gimptoggleaction.h"
 #include "widgets/gimpuimanager.h"
 #include "widgets/gimpwidgets-utils.h"
 #include "widgets/gimpwindowstrategy.h"
@@ -269,7 +271,7 @@ view_zoom_explicit_cmd_callback (GtkAction *action,
   gint              value;
   return_if_no_shell (shell, data);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value != 0 /* not Other... */)
     {
@@ -289,7 +291,7 @@ view_zoom_other_cmd_callback (GtkAction *action,
   return_if_no_shell (shell, data);
 
   /* check if we are activated by the user or from
-   * view_actions_set_zoom()
+   * view_actions_set_zoom(), also SIC GTK_TOGGLE_ACTION()
    */
   if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) &&
       shell->other_scale != gimp_zoom_model_get_factor (shell->zoom))
@@ -309,7 +311,7 @@ view_dot_for_dot_cmd_callback (GtkAction *action,
 
   shell = gimp_display_get_shell (display);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != shell->dot_for_dot)
     {
@@ -338,7 +340,7 @@ view_flip_horizontally_cmd_callback (GtkAction *action,
 
   shell = gimp_display_get_shell (display);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != shell->flip_horizontally)
     {
@@ -357,7 +359,7 @@ view_flip_vertically_cmd_callback (GtkAction *action,
 
   shell = gimp_display_get_shell (display);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != shell->flip_vertically)
     {
@@ -540,7 +542,7 @@ view_color_management_enable_cmd_callback (GtkAction *action,
 
   color_config = gimp_display_shell_get_color_config (shell);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   mode = gimp_color_config_get_mode (color_config);
 
@@ -575,7 +577,7 @@ view_color_management_softproof_cmd_callback (GtkAction *action,
 
   color_config = gimp_display_shell_get_color_config (shell);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   mode = gimp_color_config_get_mode (color_config);
 
@@ -610,7 +612,7 @@ view_display_intent_cmd_callback (GtkAction *action,
 
   color_config = gimp_display_shell_get_color_config (shell);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value != gimp_color_config_get_display_intent (color_config))
     {
@@ -632,7 +634,7 @@ view_display_bpc_cmd_callback (GtkAction *action,
 
   color_config = gimp_display_shell_get_color_config (shell);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_color_config_get_display_bpc (color_config))
     {
@@ -696,7 +698,7 @@ view_softproof_intent_cmd_callback (GtkAction *action,
 
   color_config = gimp_display_shell_get_color_config (shell);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value != gimp_color_config_get_simulation_intent (color_config))
     {
@@ -718,7 +720,7 @@ view_softproof_bpc_cmd_callback (GtkAction *action,
 
   color_config = gimp_display_shell_get_color_config (shell);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_color_config_get_simulation_bpc (color_config))
     {
@@ -740,7 +742,7 @@ view_softproof_gamut_check_cmd_callback (GtkAction *action,
 
   color_config = gimp_display_shell_get_color_config (shell);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_color_config_get_simulation_gamut_check (color_config))
     {
@@ -759,7 +761,7 @@ view_toggle_selection_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_selection (shell))
     {
@@ -775,7 +777,7 @@ view_toggle_layer_boundary_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_layer (shell))
     {
@@ -791,7 +793,7 @@ view_toggle_menubar_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_menubar (shell))
     {
@@ -807,7 +809,7 @@ view_toggle_rulers_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_rulers (shell))
     {
@@ -823,7 +825,7 @@ view_toggle_scrollbars_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_scrollbars (shell))
     {
@@ -839,7 +841,7 @@ view_toggle_statusbar_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_statusbar (shell))
     {
@@ -855,7 +857,7 @@ view_toggle_guides_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_guides (shell))
     {
@@ -871,7 +873,7 @@ view_toggle_grid_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_grid (shell))
     {
@@ -887,7 +889,7 @@ view_toggle_sample_points_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_show_sample_points (shell))
     {
@@ -903,7 +905,7 @@ view_snap_to_guides_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_snap_to_guides (shell))
     {
@@ -919,7 +921,7 @@ view_snap_to_grid_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_snap_to_grid (shell))
     {
@@ -935,7 +937,7 @@ view_snap_to_canvas_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_snap_to_canvas (shell))
     {
@@ -951,7 +953,7 @@ view_snap_to_vectors_cmd_callback (GtkAction *action,
   gboolean          active;
   return_if_no_shell (shell, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != gimp_display_shell_get_snap_to_vectors (shell))
     {
@@ -1080,7 +1082,7 @@ view_fullscreen_cmd_callback (GtkAction *action,
     {
       gboolean active;
 
-      active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+      active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
       gimp_image_window_set_fullscreen (window, active);
     }
diff --git a/app/actions/window-actions.c b/app/actions/window-actions.c
index 9869b119cd..d1e0df48c7 100644
--- a/app/actions/window-actions.c
+++ b/app/actions/window-actions.c
@@ -89,7 +89,7 @@ window_actions_update (GimpActionGroup *group,
   gint         show_menu = FALSE;
   gchar       *name;
 
-  group_name = gtk_action_group_get_name (GTK_ACTION_GROUP (group));
+  group_name = gimp_action_group_get_name (group);
 
 #define SET_ACTIVE(action,active) \
         gimp_action_group_set_action_active (group, action, (active) != 0)
@@ -174,7 +174,7 @@ window_actions_display_opened (GdkDisplayManager *manager,
 
   help_id = g_object_get_data (G_OBJECT (group), "change-to-screen-help-id");
 
-  group_name = gtk_action_group_get_name (GTK_ACTION_GROUP (group));
+  group_name = gimp_action_group_get_name (group);
 
   n_screens = gdk_display_get_n_screens (display);
 
@@ -211,11 +211,11 @@ window_actions_display_opened (GdkDisplayManager *manager,
 
   for (i = 0; i < n_screens; i++)
     {
-      GdkScreen *screen = gdk_display_get_screen (display, i);
-      GtkAction *action;
+      GdkScreen  *screen = gdk_display_get_screen (display, i);
+      GimpAction *action;
+
+      action = gimp_action_group_get_action (group, entries[i].name);
 
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                            entries[i].name);
       if (action)
         g_object_set_data (G_OBJECT (action), "screen", screen);
 
@@ -260,24 +260,23 @@ window_actions_display_closed (GdkDisplay      *display,
 
   g_hash_table_remove (displays, display_name);
 
-  group_name = gtk_action_group_get_name (GTK_ACTION_GROUP (group));
+  group_name = gimp_action_group_get_name (group);
 
   n_screens = gdk_display_get_n_screens (display);
 
   for (i = 0; i < n_screens; i++)
     {
-      GdkScreen *screen = gdk_display_get_screen (display, i);
-      GtkAction *action;
-      gchar     *screen_name;
-      gchar     *action_name;
+      GdkScreen  *screen = gdk_display_get_screen (display, i);
+      GimpAction *action;
+      gchar      *screen_name;
+      gchar      *action_name;
 
       screen_name = gdk_screen_make_display_name (screen);
       action_name = g_strdup_printf ("%s-move-to-screen-%s",
                                      group_name, screen_name);
       g_free (screen_name);
 
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                            action_name);
+      action = gimp_action_group_get_action (group, action_name);
 
       if (action)
         {
@@ -287,7 +286,7 @@ window_actions_display_closed (GdkDisplay      *display,
           if (radio_group->data == (gpointer) action)
             radio_group = radio_group->next;
 
-          gtk_action_group_remove_action (GTK_ACTION_GROUP (group), action);
+          gimp_action_group_remove_action (group, action);
 
           g_object_set_data (G_OBJECT (group), "change-to-screen-radio-group",
                              radio_group);
diff --git a/app/actions/windows-actions.c b/app/actions/windows-actions.c
index 5b247e4ed0..d128ba09e7 100644
--- a/app/actions/windows-actions.c
+++ b/app/actions/windows-actions.c
@@ -322,7 +322,7 @@ windows_actions_display_remove (GimpContainer   *container,
                                 GimpActionGroup *group)
 {
   GimpDisplayShell *shell = gimp_display_get_shell (display);
-  GtkAction        *action;
+  GimpAction       *action;
   gchar            *action_name;
 
   if (shell)
@@ -331,13 +331,11 @@ windows_actions_display_remove (GimpContainer   *container,
                                           group);
 
   action_name = gimp_display_get_action_name (display);
-
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
+  g_free (action_name);
 
   if (action)
-    gimp_action_group_remove_action (group,
-                                     GIMP_ACTION (action));
-  g_free (action_name);
+    gimp_action_group_remove_action_and_accel (group, action);
 
   windows_actions_update_display_accels (group);
 }
@@ -356,14 +354,13 @@ windows_actions_image_notify (GimpDisplay      *display,
                               const GParamSpec *unused,
                               GimpActionGroup  *group)
 {
-  GimpImage *image = gimp_display_get_image (display);
-  GtkAction *action;
-  gchar     *action_name;
+  GimpImage  *image = gimp_display_get_image (display);
+  GimpAction *action;
+  gchar      *action_name;
 
   action_name = gimp_display_get_action_name (display);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                        action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -381,8 +378,7 @@ windows_actions_image_notify (GimpDisplay      *display,
 
       gimp_action_group_set_action_always_show_image (group, action_name,
                                                       TRUE);
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                            action_name);
+      action = gimp_action_group_get_action (group, action_name);
 
       g_object_set_data (G_OBJECT (action), "display", display);
     }
@@ -443,7 +439,7 @@ windows_actions_update_display_accels (GimpActionGroup *group)
        list = g_list_next (list), i++)
     {
       GimpDisplay *display = list->data;
-      GtkAction   *action;
+      GimpAction  *action;
       gchar       *action_name;
 
       if (! gimp_display_get_image (display))
@@ -451,8 +447,7 @@ windows_actions_update_display_accels (GimpActionGroup *group)
 
       action_name = gimp_display_get_action_name (display);
 
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                            action_name);
+      action = gimp_action_group_get_action (group, action_name);
       g_free (action_name);
 
       if (action)
@@ -460,7 +455,7 @@ windows_actions_update_display_accels (GimpActionGroup *group)
           const gchar *accel_path;
           guint        accel_key;
 
-          accel_path = gtk_action_get_accel_path (action);
+          accel_path = gimp_action_get_accel_path (action);
 
           if (i < 9)
             accel_key = GDK_KEY_1 + i;
@@ -479,7 +474,7 @@ windows_actions_dock_window_added (GimpDialogFactory *factory,
                                    GimpDockWindow    *dock_window,
                                    GimpActionGroup   *group)
 {
-  GtkAction       *action;
+  GimpAction      *action;
   GimpActionEntry  entry;
   gchar           *action_name = windows_actions_dock_window_to_action_name (dock_window);
 
@@ -493,8 +488,7 @@ windows_actions_dock_window_added (GimpDialogFactory *factory,
 
   gimp_action_group_add_actions (group, NULL, &entry, 1);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                        action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   g_object_set (action,
                 "ellipsize", PANGO_ELLIPSIZE_END,
@@ -517,15 +511,15 @@ windows_actions_dock_window_removed (GimpDialogFactory *factory,
                                      GimpDockWindow    *dock_window,
                                      GimpActionGroup   *group)
 {
-  GtkAction *action;
-  gchar     *action_name = windows_actions_dock_window_to_action_name (dock_window);
+  GimpAction *action;
+  gchar      *action_name;
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action_name = windows_actions_dock_window_to_action_name (dock_window);
+  action = gimp_action_group_get_action (group, action_name);
+  g_free (action_name);
 
   if (action)
-    gimp_action_group_remove_action (group, GIMP_ACTION (action));
-
-  g_free (action_name);
+    gimp_action_group_remove_action_and_accel (group, action);
 }
 
 static void
@@ -533,11 +527,11 @@ windows_actions_dock_window_notify (GimpDockWindow   *dock_window,
                                     const GParamSpec *pspec,
                                     GimpActionGroup  *group)
 {
-  GtkAction *action;
-  gchar     *action_name;
+  GimpAction *action;
+  gchar      *action_name;
 
   action_name = windows_actions_dock_window_to_action_name (dock_window);
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
   g_free (action_name);
 
   if (action)
@@ -552,7 +546,7 @@ windows_actions_recent_add (GimpContainer   *container,
                             GimpSessionInfo *info,
                             GimpActionGroup *group)
 {
-  GtkAction       *action;
+  GimpAction      *action;
   GimpActionEntry  entry;
   gint             info_id;
   static gint      info_id_counter = 1;
@@ -581,8 +575,7 @@ windows_actions_recent_add (GimpContainer   *container,
 
   gimp_action_group_add_actions (group, NULL, &entry, 1);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                        action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   g_object_set (action,
                 "ellipsize",       PANGO_ELLIPSIZE_END,
@@ -599,21 +592,19 @@ windows_actions_recent_remove (GimpContainer   *container,
                                GimpSessionInfo *info,
                                GimpActionGroup *group)
 {
-  GtkAction *action;
-  gint       info_id;
-  gchar     *action_name;
+  GimpAction *action;
+  gint        info_id;
+  gchar      *action_name;
 
   info_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info),
                                                 "recent-action-id"));
 
   action_name = g_strdup_printf ("windows-recent-%04d", info_id);
-
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
+  g_free (action_name);
 
   if (action)
-    gimp_action_group_remove_action (group, GIMP_ACTION (action));
-
-  g_free (action_name);
+    gimp_action_group_remove_action_and_accel (group, action);
 }
 
 static void
diff --git a/app/actions/windows-commands.c b/app/actions/windows-commands.c
index 045db56a67..1f38b977ba 100644
--- a/app/actions/windows-commands.c
+++ b/app/actions/windows-commands.c
@@ -34,7 +34,9 @@
 
 #include "widgets/gimpactiongroup.h"
 #include "widgets/gimpdialogfactory.h"
+#include "widgets/gimpradioaction.h"
 #include "widgets/gimpsessioninfo.h"
+#include "widgets/gimptoggleaction.h"
 #include "widgets/gimpwidgets-utils.h"
 
 #include "display/gimpdisplay.h"
@@ -57,7 +59,7 @@ windows_hide_docks_cmd_callback (GtkAction *action,
   gboolean  active;
   return_if_no_gimp (gimp, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != GIMP_GUI_CONFIG (gimp->config)->hide_docks)
     g_object_set (gimp->config,
@@ -73,7 +75,7 @@ windows_show_tabs_cmd_callback (GtkAction *action,
   gboolean  active;
   return_if_no_gimp (gimp, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != GIMP_GUI_CONFIG (gimp->config)->show_tabs)
     g_object_set (gimp->config,
@@ -91,7 +93,7 @@ windows_set_tabs_position_cmd_callback (GtkAction *action,
   GimpPosition  value;
   return_if_no_gimp (gimp, data);
 
-  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+  value = gimp_radio_action_get_current_value (GIMP_RADIO_ACTION (action));
 
   if (value != GIMP_GUI_CONFIG (gimp->config)->tabs_position)
     g_object_set (gimp->config,
@@ -107,7 +109,7 @@ windows_use_single_window_mode_cmd_callback (GtkAction *action,
   gboolean  active;
   return_if_no_gimp (gimp, data);
 
-  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+  active = gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action));
 
   if (active != GIMP_GUI_CONFIG (gimp->config)->single_window_mode)
     g_object_set (gimp->config,
diff --git a/app/dialogs/action-search-dialog.c b/app/dialogs/action-search-dialog.c
index cfb5104d71..7b1d4346e4 100644
--- a/app/dialogs/action-search-dialog.c
+++ b/app/dialogs/action-search-dialog.c
@@ -36,6 +36,7 @@
 #include "core/gimp.h"
 
 #include "widgets/gimpaction.h"
+#include "widgets/gimpactiongroup.h"
 #include "widgets/gimpaction-history.h"
 #include "widgets/gimpdialogfactory.h"
 #include "widgets/gimpsearchpopup.h"
@@ -49,7 +50,7 @@
 static void         action_search_history_and_actions      (GimpSearchPopup   *popup,
                                                             const gchar       *keyword,
                                                             gpointer           data);
-static gboolean     action_search_match_keyword            (GtkAction         *action,
+static gboolean     action_search_match_keyword            (GimpAction        *action,
                                                             const gchar*       keyword,
                                                             gint              *section,
                                                             Gimp              *gimp);
@@ -97,11 +98,11 @@ action_search_history_and_actions (GimpSearchPopup *popup,
   /* First put on top of the list any matching action of user history. */
   for (list = history_actions; list; list = g_list_next (list))
     {
-      gimp_search_popup_add_result (popup, GTK_ACTION (list->data), 0);
+      gimp_search_popup_add_result (popup, list->data, 0);
     }
 
   /* Now check other actions. */
-  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
+  for (list = gimp_ui_manager_get_action_groups (manager);
        list;
        list = g_list_next (list))
     {
@@ -109,17 +110,17 @@ action_search_history_and_actions (GimpSearchPopup *popup,
       GimpActionGroup *group   = list->data;
       GList           *actions = NULL;
 
-      actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
+      actions = gimp_action_group_list_actions (group);
       actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare);
 
       for (list2 = actions; list2; list2 = g_list_next (list2))
         {
           const gchar *name;
-          GtkAction   *action       = list2->data;
+          GimpAction  *action       = list2->data;
           gboolean     is_redundant = FALSE;
           gint         section;
 
-          name = gtk_action_get_name (action);
+          name = gimp_action_get_name (action);
 
           /* The action search dialog doesn't show any non-historized
            * actions, with a few exceptions.  See the difference between
@@ -129,8 +130,8 @@ action_search_history_and_actions (GimpSearchPopup *popup,
           if (gimp_action_history_is_blacklisted_action (name))
             continue;
 
-          if (! gtk_action_is_visible (action)    ||
-              (! gtk_action_is_sensitive (action) &&
+          if (! gimp_action_is_visible (action)    ||
+              (! gimp_action_is_sensitive (action) &&
                ! GIMP_GUI_CONFIG (gimp->config)->search_show_unavailable))
             continue;
 
@@ -143,7 +144,7 @@ action_search_history_and_actions (GimpSearchPopup *popup,
                */
               for (list3 = history_actions; list3; list3 = g_list_next (list3))
                 {
-                  if (strcmp (gtk_action_get_name (GTK_ACTION (list3->data)),
+                  if (strcmp (gimp_action_get_name (list3->data),
                               name) == 0)
                     {
                       is_redundant = TRUE;
@@ -165,7 +166,7 @@ action_search_history_and_actions (GimpSearchPopup *popup,
 }
 
 static gboolean
-action_search_match_keyword (GtkAction   *action,
+action_search_match_keyword (GimpAction  *action,
                              const gchar *keyword,
                              gint        *section,
                              Gimp        *gimp)
@@ -189,7 +190,7 @@ action_search_match_keyword (GtkAction   *action,
     }
 
   key_tokens   = g_str_tokenize_and_fold (keyword, gimp->config->language, NULL);
-  tmp          = gimp_strip_uline (gtk_action_get_label (action));
+  tmp          = gimp_strip_uline (gimp_action_get_label (action));
   label_tokens = g_str_tokenize_and_fold (tmp, gimp->config->language, &label_alternates);
   g_free (tmp);
 
@@ -283,14 +284,14 @@ one_matched:
     }
 
   if (! matched && key_tokens[0] && g_utf8_strlen (key_tokens[0], -1) > 2 &&
-      gtk_action_get_tooltip (action) != NULL)
+      gimp_action_get_tooltip (action) != NULL)
     {
       gchar    **tooltip_tokens;
       gchar    **tooltip_alternates = NULL;
       gboolean   mixed_match;
       gint       i;
 
-      tooltip_tokens = g_str_tokenize_and_fold (gtk_action_get_tooltip (action),
+      tooltip_tokens = g_str_tokenize_and_fold (gimp_action_get_tooltip (action),
                                                 gimp->config->language, &tooltip_alternates);
 
       if (g_strv_length (tooltip_tokens) > 0)
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index 559d01bea5..ddcf8a6f68 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -391,7 +391,7 @@ gimp_display_shell_constructed (GObject *object)
   GtkWidget             *lower_hbox;
   GtkWidget             *inner_table;
   GtkWidget             *gtk_image;
-  GtkAction             *action;
+  GimpAction            *action;
   gint                   image_width;
   gint                   image_height;
   gint                   shell_width;
diff --git a/app/display/gimpimagewindow.c b/app/display/gimpimagewindow.c
index 6d659872d5..a5d3a5ede3 100644
--- a/app/display/gimpimagewindow.c
+++ b/app/display/gimpimagewindow.c
@@ -399,7 +399,7 @@ gimp_image_window_constructed (GObject *object)
                            window, G_CONNECT_SWAPPED);
 
   gtk_window_add_accel_group (GTK_WINDOW (window),
-                              gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (private->menubar_manager)));
+                              gimp_ui_manager_get_accel_group (private->menubar_manager));
 
   g_signal_connect (private->menubar_manager, "show-tooltip",
                     G_CALLBACK (gimp_image_window_show_tooltip),
@@ -417,9 +417,8 @@ gimp_image_window_constructed (GObject *object)
 
   /* Create the menubar */
 #ifndef GDK_WINDOWING_QUARTZ
-  private->menubar =
-    gtk_ui_manager_get_widget (GTK_UI_MANAGER (private->menubar_manager),
-                               "/image-menubar");
+  private->menubar = gimp_ui_manager_get_widget (private->menubar_manager,
+                                                 "/image-menubar");
 #endif /* !GDK_WINDOWING_QUARTZ */
   if (private->menubar)
     {
diff --git a/app/gui/gui.c b/app/gui/gui.c
index 022d3b91e9..2b372c4bd6 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -48,6 +48,8 @@
 #include "tools/gimptool.h"
 #include "tools/tool_manager.h"
 
+#include "widgets/gimpaction.h"
+#include "widgets/gimpactiongroup.h"
 #include "widgets/gimpaction-history.h"
 #include "widgets/gimpclipboard.h"
 #include "widgets/gimpcolorselectorpalette.h"
@@ -562,7 +564,7 @@ gui_add_to_app_menu (GimpUIManager     *ui_manager,
 {
   GtkWidget *item;
 
-  item = gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui_manager), action_path);
+  item = gimp_ui_manager_get_widget (ui_manager, action_path);
 
   if (GTK_IS_MENU_ITEM (item))
     gtkosx_application_insert_app_menu_item (osx_app, GTK_WIDGET (item), index);
@@ -637,8 +639,8 @@ gui_restore_after_callback (Gimp               *gimp,
 
     osx_app = gtkosx_application_get ();
 
-    menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (image_ui_manager),
-                                      "/image-menubar");
+    menu = gimp_ui_manager_get_widget (image_ui_manager,
+                                       "/image-menubar");
     if (GTK_IS_MENU_ITEM (menu))
       menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu));
 
@@ -671,8 +673,8 @@ gui_restore_after_callback (Gimp               *gimp,
     item = gtk_separator_menu_item_new ();
     gtkosx_application_insert_app_menu_item (osx_app, item, 8);
 
-    item = gtk_ui_manager_get_widget (GTK_UI_MANAGER (image_ui_manager),
-                                      "/image-menubar/File/file-quit");
+    item = gimp_ui_manager_get_widget (image_ui_manager,
+                                       "/image-menubar/File/file-quit");
     gtk_widget_hide (item);
 
     g_signal_connect (osx_app, "NSApplicationBlockTermination",
@@ -1025,30 +1027,34 @@ gui_check_action_exists (const gchar *accel_path)
   GList         *list;
 
   manager = gimp_ui_managers_from_name ("<Image>")->data;
-  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
+
+  for (list = gimp_ui_manager_get_action_groups (manager);
        list;
        list = g_list_next (list))
     {
-      GtkActionGroup *group   = list->data;
-      GList          *actions = NULL;
-      GList          *list2;
+      GimpActionGroup *group   = list->data;
+      GList           *actions = NULL;
+      GList           *list2;
+
+      actions = gimp_action_group_list_actions (group);
 
-      actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
       for (list2 = actions; list2; list2 = g_list_next (list2))
         {
-          const gchar *path;
-          GtkAction   *action = list2->data;
+          GimpAction  *action = list2->data;
+          const gchar *path   = gimp_action_get_accel_path (action);
 
-          path = gtk_action_get_accel_path (action);
           if (g_strcmp0 (path, accel_path) == 0)
             {
               action_exists = TRUE;
               break;
             }
         }
+
       g_list_free (actions);
+
       if (action_exists)
         break;
     }
+
   return action_exists;
 }
diff --git a/app/menus/file-menu.c b/app/menus/file-menu.c
index 954dc40163..019b6b0a98 100644
--- a/app/menus/file-menu.c
+++ b/app/menus/file-menu.c
@@ -30,6 +30,7 @@
 #include "core/gimpviewable.h"
 
 #include "widgets/gimpaction.h"
+#include "widgets/gimpactionimpl.h"
 #include "widgets/gimpuimanager.h"
 
 #include "file-menu.h"
@@ -47,19 +48,16 @@ void
 file_menu_setup (GimpUIManager *manager,
                  const gchar   *ui_path)
 {
-  GtkUIManager *ui_manager;
-  gint          n_entries;
-  guint         merge_id;
-  gint          i;
+  gint  n_entries;
+  guint merge_id;
+  gint  i;
 
   g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
   g_return_if_fail (ui_path != NULL);
 
-  ui_manager = GTK_UI_MANAGER (manager);
-
   n_entries = GIMP_GUI_CONFIG (manager->gimp->config)->last_opened_size;
 
-  merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+  merge_id = gimp_ui_manager_new_merge_id (manager);
 
   for (i = 0; i < n_entries; i++)
     {
@@ -71,18 +69,18 @@ file_menu_setup (GimpUIManager *manager,
       action_name = g_strdup_printf ("file-open-recent-%02d", i + 1);
       action_path = g_strdup_printf ("%s/File/Open Recent/Files", ui_path);
 
-      gtk_ui_manager_add_ui (ui_manager, merge_id,
-                             action_path, action_name, action_name,
-                             GTK_UI_MANAGER_MENUITEM,
-                             FALSE);
+      gimp_ui_manager_add_ui (manager, merge_id,
+                              action_path, action_name, action_name,
+                              GTK_UI_MANAGER_MENUITEM,
+                              FALSE);
 
       full_path = g_strconcat (action_path, "/", action_name, NULL);
 
-      widget = gtk_ui_manager_get_widget (ui_manager, full_path);
+      widget = gimp_ui_manager_get_widget (manager, full_path);
 
       if (widget)
         {
-          GtkAction *action;
+          GimpAction *action;
 
           action = gimp_ui_manager_find_action (manager, "file", action_name);
 
@@ -105,15 +103,16 @@ file_menu_open_recent_query_tooltip (GtkWidget  *widget,
                                      GtkTooltip *tooltip,
                                      GimpAction *action)
 {
-  gchar *text;
+  GimpActionImpl *impl = GIMP_ACTION_IMPL (action);
+  gchar          *text;
 
   text = gtk_widget_get_tooltip_text (widget);
   gtk_tooltip_set_text (tooltip, text);
   g_free (text);
 
   gtk_tooltip_set_icon (tooltip,
-                        gimp_viewable_get_pixbuf (action->viewable,
-                                                  action->context,
+                        gimp_viewable_get_pixbuf (impl->viewable,
+                                                  impl->context,
                                                   GIMP_THUMB_SIZE_NORMAL,
                                                   GIMP_THUMB_SIZE_NORMAL));
 
diff --git a/app/menus/filters-menu.c b/app/menus/filters-menu.c
index 5f1e33993d..8ffbcc3ca1 100644
--- a/app/menus/filters-menu.c
+++ b/app/menus/filters-menu.c
@@ -42,7 +42,7 @@ filters_menu_setup (GimpUIManager *manager,
   g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
   g_return_if_fail (ui_path != NULL);
 
-  merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+  merge_id = gimp_ui_manager_new_merge_id (manager);
 
   for (i = 0; i < gimp_filter_history_size (manager->gimp); i++)
     {
@@ -53,10 +53,10 @@ filters_menu_setup (GimpUIManager *manager,
       action_path = g_strdup_printf ("%s/Filters/Recently Used/Filters",
                                      ui_path);
 
-      gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                             action_path, action_name, action_name,
-                             GTK_UI_MANAGER_MENUITEM,
-                             FALSE);
+      gimp_ui_manager_add_ui (manager, merge_id,
+                              action_path, action_name, action_name,
+                              GTK_UI_MANAGER_MENUITEM,
+                              FALSE);
 
       g_free (action_name);
       g_free (action_path);
diff --git a/app/menus/plug-in-menus.c b/app/menus/plug-in-menus.c
index a86957bc00..8efdeb4306 100644
--- a/app/menus/plug-in-menus.c
+++ b/app/menus/plug-in-menus.c
@@ -97,7 +97,7 @@ plug_in_menus_setup (GimpUIManager *manager,
 
   plug_in_manager = manager->gimp->plug_in_manager;
 
-  merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+  merge_id = gimp_ui_manager_new_merge_id (manager);
 
   for (i = 0; i < manager->gimp->config->filter_history_size; i++)
     {
@@ -108,10 +108,10 @@ plug_in_menus_setup (GimpUIManager *manager,
       action_path = g_strdup_printf ("%s/Filters/Recently Used/Plug-ins",
                                      ui_path);
 
-      gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                             action_path, action_name, action_name,
-                             GTK_UI_MANAGER_MENUITEM,
-                             FALSE);
+      gimp_ui_manager_add_ui (manager, merge_id,
+                              action_path, action_name, action_name,
+                              GTK_UI_MANAGER_MENUITEM,
+                              FALSE);
 
       g_free (action_name);
       g_free (action_path);
@@ -266,8 +266,7 @@ plug_in_menus_unregister_procedure (GimpPDB       *pdb,
                   g_free (merge_key);
 
                   if (merge_id)
-                    gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager),
-                                              merge_id);
+                    gimp_ui_manager_remove_ui (manager, merge_id);
 
                   break;
                 }
@@ -404,7 +403,7 @@ plug_in_menus_add_proc (GimpUIManager       *manager,
 
   if (! merge_id)
     {
-      merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+      merge_id = gimp_ui_manager_new_merge_id (manager);
       g_object_set_data (G_OBJECT (manager), merge_key,
                          GUINT_TO_POINTER (merge_id));
     }
@@ -416,7 +415,7 @@ plug_in_menus_add_proc (GimpUIManager       *manager,
 
   if (! menu_merge_id)
     {
-      menu_merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+      menu_merge_id = gimp_ui_manager_new_merge_id (manager);
       g_object_set_data (G_OBJECT (manager), "plug-in-menu-merge-id",
                          GUINT_TO_POINTER (menu_merge_id));
     }
@@ -435,12 +434,12 @@ plug_in_menus_add_proc (GimpUIManager       *manager,
   GIMP_LOG (MENUS, "adding menu item for '%s' (@ %s)",
             gimp_object_get_name (proc), action_path);
 
-  gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                         action_path,
-                         gimp_object_get_name (proc),
-                         gimp_object_get_name (proc),
-                         GTK_UI_MANAGER_MENUITEM,
-                         FALSE);
+  gimp_ui_manager_add_ui (manager, merge_id,
+                          action_path,
+                          gimp_object_get_name (proc),
+                          gimp_object_get_name (proc),
+                          GTK_UI_MANAGER_MENUITEM,
+                          FALSE);
 
   g_free (action_path);
   g_free (path);
@@ -494,7 +493,7 @@ plug_in_menus_build_path (GimpUIManager *manager,
 
   action_path = g_strdup_printf ("%s%s", ui_path, strchr (menu_path, '/'));
 
-  if (! gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), action_path))
+  if (! gimp_ui_manager_get_widget (manager, action_path))
     {
       gchar *parent_menu_path   = g_strdup (menu_path);
       gchar *parent_action_path = NULL;
@@ -517,26 +516,25 @@ plug_in_menus_build_path (GimpUIManager *manager,
           action_path = g_strdup_printf ("%s/%s",
                                          parent_action_path, menu_item_name);
 
-          if (! gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager),
-                                           action_path))
+          if (! gimp_ui_manager_get_widget (manager, action_path))
             {
               GIMP_LOG (MENUS, "adding menu '%s' at path '%s' for action '%s'",
                         menu_item_name, action_path, menu_path);
 
-              gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                                     parent_action_path, menu_item_name,
-                                     menu_path,
-                                     GTK_UI_MANAGER_MENU,
-                                     FALSE);
-
-              gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                                     action_path, "Menus", NULL,
-                                     GTK_UI_MANAGER_PLACEHOLDER,
-                                     FALSE);
-              gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                                     action_path, "Separator", NULL,
-                                     GTK_UI_MANAGER_SEPARATOR,
-                                     FALSE);
+              gimp_ui_manager_add_ui (manager, merge_id,
+                                      parent_action_path, menu_item_name,
+                                      menu_path,
+                                      GTK_UI_MANAGER_MENU,
+                                      FALSE);
+
+              gimp_ui_manager_add_ui (manager, merge_id,
+                                      action_path, "Menus", NULL,
+                                      GTK_UI_MANAGER_PLACEHOLDER,
+                                      FALSE);
+              gimp_ui_manager_add_ui (manager, merge_id,
+                                      action_path, "Separator", NULL,
+                                      GTK_UI_MANAGER_SEPARATOR,
+                                      FALSE);
             }
 
           g_free (parent_action_path);
@@ -556,8 +554,7 @@ plug_in_menus_build_path (GimpUIManager *manager,
     {
       gchar *placeholder_path = g_strdup_printf ("%s/%s", action_path, "Menus");
 
-      if (gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager),
-                                     placeholder_path))
+      if (gimp_ui_manager_get_widget (manager, placeholder_path))
         {
           g_free (action_path);
 
diff --git a/app/menus/tool-options-menu.c b/app/menus/tool-options-menu.c
index 2a4daf1d66..6ba21a1306 100644
--- a/app/menus/tool-options-menu.c
+++ b/app/menus/tool-options-menu.c
@@ -80,12 +80,12 @@ tool_options_menu_update (GimpUIManager *manager,
 
   if (merge_id)
     {
-      gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager), merge_id);
+      gimp_ui_manager_remove_ui (manager, merge_id);
 
       g_object_set_data (G_OBJECT (manager), "tool-options-merge-id",
                          GINT_TO_POINTER (0));
 
-      gtk_ui_manager_ensure_update (GTK_UI_MANAGER (manager));
+      gimp_ui_manager_ensure_update (manager);
     }
 }
 
@@ -104,7 +104,7 @@ tool_options_menu_update_after (GimpUIManager *manager,
   if (! tool_info->presets)
     return;
 
-  merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+  merge_id = gimp_ui_manager_new_merge_id (manager);
 
   g_object_set_data (G_OBJECT (manager), "tool-options-merge-id",
                      GUINT_TO_POINTER (merge_id));
@@ -125,7 +125,7 @@ tool_options_menu_update_after (GimpUIManager *manager,
                                     "Delete", "delete",
                                     tool_info->presets);
 
-  gtk_ui_manager_ensure_update (GTK_UI_MANAGER (manager));
+  gimp_ui_manager_ensure_update (manager);
 }
 
 static void
@@ -150,10 +150,10 @@ tool_options_menu_update_presets (GimpUIManager *manager,
                                      which_action, i);
       path        = g_strdup_printf ("%s/%s", ui_path, menu_path);
 
-      gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                             path, action_name, action_name,
-                             GTK_UI_MANAGER_MENUITEM,
-                             FALSE);
+      gimp_ui_manager_add_ui (manager, merge_id,
+                              path, action_name, action_name,
+                              GTK_UI_MANAGER_MENUITEM,
+                              FALSE);
 
       g_free (action_name);
       g_free (path);
diff --git a/app/menus/window-menu.c b/app/menus/window-menu.c
index 0d43cf0a76..7391e92989 100644
--- a/app/menus/window-menu.c
+++ b/app/menus/window-menu.c
@@ -87,15 +87,14 @@ window_menu_display_opened (GdkDisplayManager *disp_manager,
                             GdkDisplay        *display,
                             GimpUIManager     *manager)
 {
-  GtkUIManager *ui_manager = GTK_UI_MANAGER (manager);
-  const gchar  *group_name;
-  const gchar  *ui_path;
-  const gchar  *display_name;
-  gchar        *action_path;
-  gchar        *merge_key;
-  guint         merge_id;
-  gint          n_screens;
-  gint          i;
+  const gchar *group_name;
+  const gchar *ui_path;
+  const gchar *display_name;
+  gchar       *action_path;
+  gchar       *merge_key;
+  guint        merge_id;
+  gint         n_screens;
+  gint         i;
 
   group_name = g_object_get_data (G_OBJECT (manager),
                                   "move-to-screen-group-name");
@@ -110,7 +109,7 @@ window_menu_display_opened (GdkDisplayManager *disp_manager,
 
   merge_key = g_strdup_printf ("%s-display-merge-id", display_name);
 
-  merge_id = gtk_ui_manager_new_merge_id (ui_manager);
+  merge_id = gimp_ui_manager_new_merge_id (manager);
   g_object_set_data (G_OBJECT (manager), merge_key,
                      GUINT_TO_POINTER (merge_id));
 
@@ -131,10 +130,10 @@ window_menu_display_opened (GdkDisplayManager *disp_manager,
                                      group_name, screen_name);
       g_free (screen_name);
 
-      gtk_ui_manager_add_ui (ui_manager, merge_id,
-                             action_path, action_name, action_name,
-                             GTK_UI_MANAGER_MENUITEM,
-                             FALSE);
+      gimp_ui_manager_add_ui (manager, merge_id,
+                              action_path, action_name, action_name,
+                              GTK_UI_MANAGER_MENUITEM,
+                              FALSE);
 
       g_free (action_name);
     }
@@ -165,5 +164,5 @@ window_menu_display_closed (GdkDisplay    *display,
   g_free (merge_key);
 
   if (merge_id)
-    gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager), merge_id);
+    gimp_ui_manager_remove_ui (manager, merge_id);
 }
diff --git a/app/menus/windows-menu.c b/app/menus/windows-menu.c
index 5fe057ff2a..9e203e0c83 100644
--- a/app/menus/windows-menu.c
+++ b/app/menus/windows-menu.c
@@ -33,6 +33,7 @@
 #include "core/gimpviewable.h"
 
 #include "widgets/gimpaction.h"
+#include "widgets/gimpactionimpl.h"
 #include "widgets/gimpdialogfactory.h"
 #include "widgets/gimpdock.h"
 #include "widgets/gimpdockwindow.h"
@@ -178,7 +179,7 @@ windows_menu_display_remove (GimpContainer *container,
                                                   merge_key));
 
   if (merge_id)
-    gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager), merge_id);
+    gimp_ui_manager_remove_ui (manager, merge_id);
 
   g_object_set_data (G_OBJECT (manager), merge_key, NULL);
 
@@ -205,7 +206,7 @@ windows_menu_display_reorder (GimpContainer *container,
    * the same ones may simply cancel the effect of the removal, hence
    * losing the menu reordering.
    */
-  gtk_ui_manager_ensure_update (GTK_UI_MANAGER (manager));
+  gimp_ui_manager_ensure_update (manager);
 
   for (i = new_index; i < n_display; i++)
     {
@@ -243,24 +244,23 @@ windows_menu_image_notify (GimpDisplay      *display,
           action_name = gimp_display_get_action_name (display);
           action_path = g_strdup_printf ("%s/Windows/Images", ui_path);
 
-          merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+          merge_id = gimp_ui_manager_new_merge_id (manager);
 
           g_object_set_data (G_OBJECT (manager), merge_key,
                              GUINT_TO_POINTER (merge_id));
 
-          gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                                 action_path, action_name, action_name,
-                                 GTK_UI_MANAGER_MENUITEM,
-                                 FALSE);
+          gimp_ui_manager_add_ui (manager, merge_id,
+                                  action_path, action_name, action_name,
+                                  GTK_UI_MANAGER_MENUITEM,
+                                  FALSE);
 
           full_path = g_strconcat (action_path, "/", action_name, NULL);
 
-          widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager),
-                                              full_path);
+          widget = gimp_ui_manager_get_widget (manager, full_path);
 
           if (widget)
             {
-              GtkAction *action;
+              GimpAction *action;
 
               action = gimp_ui_manager_find_action (manager,
                                                     "windows", action_name);
@@ -301,15 +301,15 @@ windows_menu_dock_window_added (GimpDialogFactory *factory,
                                  ui_path);
 
   merge_key = windows_menu_dock_window_to_merge_id (dock_window);
-  merge_id  = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+  merge_id  = gimp_ui_manager_new_merge_id (manager);
 
   g_object_set_data (G_OBJECT (manager), merge_key,
                      GUINT_TO_POINTER (merge_id));
 
-  gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                         action_path, action_name, action_name,
-                         GTK_UI_MANAGER_MENUITEM,
-                         FALSE);
+  gimp_ui_manager_add_ui (manager, merge_id,
+                          action_path, action_name, action_name,
+                          GTK_UI_MANAGER_MENUITEM,
+                          FALSE);
 
   g_free (merge_key);
   g_free (action_path);
@@ -325,7 +325,7 @@ windows_menu_dock_window_removed (GimpDialogFactory *factory,
   guint  merge_id  = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (manager),
                                                           merge_key));
   if (merge_id)
-    gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager), merge_id);
+    gimp_ui_manager_remove_ui (manager, merge_id);
 
   g_object_set_data (G_OBJECT (manager), merge_key, NULL);
 
@@ -360,15 +360,15 @@ windows_menu_recent_add (GimpContainer   *container,
   action_path = g_strdup_printf ("%s/Windows/Recently Closed Docks", ui_path);
 
   merge_key = g_strdup_printf ("windows-recent-%04d-merge-id", info_id);
-  merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+  merge_id = gimp_ui_manager_new_merge_id (manager);
 
   g_object_set_data (G_OBJECT (manager), merge_key,
                      GUINT_TO_POINTER (merge_id));
 
-  gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                         action_path, action_name, action_name,
-                         GTK_UI_MANAGER_MENUITEM,
-                         TRUE);
+  gimp_ui_manager_add_ui (manager, merge_id,
+                          action_path, action_name, action_name,
+                          GTK_UI_MANAGER_MENUITEM,
+                          TRUE);
 
   g_free (merge_key);
   g_free (action_path);
@@ -393,7 +393,7 @@ windows_menu_recent_remove (GimpContainer   *container,
                                                   merge_key));
 
   if (merge_id)
-    gtk_ui_manager_remove_ui (GTK_UI_MANAGER (manager), merge_id);
+    gimp_ui_manager_remove_ui (manager, merge_id);
 
   g_object_set_data (G_OBJECT (manager), merge_key, NULL);
 
@@ -408,12 +408,13 @@ windows_menu_display_query_tooltip (GtkWidget  *widget,
                                     GtkTooltip *tooltip,
                                     GimpAction *action)
 {
-  GimpImage *image = GIMP_IMAGE (action->viewable);
-  gchar     *text;
-  gdouble    xres;
-  gdouble    yres;
-  gint       width;
-  gint       height;
+  GimpActionImpl *impl  = GIMP_ACTION_IMPL (action);
+  GimpImage      *image = GIMP_IMAGE (impl->viewable);
+  gchar          *text;
+  gdouble         xres;
+  gdouble         yres;
+  gint            width;
+  gint            height;
 
   if (! image)
     return FALSE;
@@ -431,8 +432,8 @@ windows_menu_display_query_tooltip (GtkWidget  *widget,
                                    &width, &height, NULL);
 
   gtk_tooltip_set_icon (tooltip,
-                        gimp_viewable_get_pixbuf (action->viewable,
-                                                  action->context,
+                        gimp_viewable_get_pixbuf (impl->viewable,
+                                                  impl->context,
                                                   width, height));
 
   return TRUE;
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 5edad2403a..d2d852d547 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -837,8 +837,8 @@ gimp_text_tool_get_popup (GimpTool         *tool,
                                            "<TextTool>",
                                            text_tool, FALSE);
 
-          im_menu = gtk_ui_manager_get_widget (GTK_UI_MANAGER (text_tool->ui_manager),
-                                               "/text-tool-popup/text-tool-input-methods-menu");
+          im_menu = gimp_ui_manager_get_widget (text_tool->ui_manager,
+                                                "/text-tool-popup/text-tool-input-methods-menu");
 
           if (GTK_IS_MENU_ITEM (im_menu))
             im_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (im_menu));
diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am
index 7567909349..2466635c8b 100644
--- a/app/widgets/Makefile.am
+++ b/app/widgets/Makefile.am
@@ -42,6 +42,8 @@ libappwidgets_a_sources = \
        gimpactionfactory.h             \
        gimpactiongroup.c               \
        gimpactiongroup.h               \
+       gimpactionimpl.c                \
+       gimpactionimpl.h                \
        gimpactionview.c                \
        gimpactionview.h                \
        gimpblobeditor.c                \
diff --git a/app/widgets/gimpaction-history.c b/app/widgets/gimpaction-history.c
index 6a41605e81..4a24f94fe2 100644
--- a/app/widgets/gimpaction-history.c
+++ b/app/widgets/gimpaction-history.c
@@ -288,14 +288,14 @@ gimp_action_history_search (Gimp                *gimp,
        actions = g_list_next (actions), i++)
     {
       GimpActionHistoryItem *item   = actions->data;
-      GtkAction             *action;
+      GimpAction            *action;
 
       action = gimp_ui_manager_find_action (manager, NULL, item->action_name);
       if (action == NULL)
         continue;
 
-      if (! gtk_action_is_visible (action)    ||
-          (! gtk_action_is_sensitive (action) &&
+      if (! gimp_action_is_visible (action)    ||
+          (! gimp_action_is_sensitive (action) &&
            ! config->search_show_unavailable))
         continue;
 
@@ -352,7 +352,7 @@ gimp_action_history_is_excluded_action (const gchar *action_name)
  * It allows us to log all used actions.
  */
 void
-gimp_action_history_action_activated (GtkAction *action)
+gimp_action_history_action_activated (GimpAction *action)
 {
   GimpGuiConfig         *config;
   const gchar           *action_name;
@@ -366,7 +366,7 @@ gimp_action_history_action_activated (GtkAction *action)
   if (config->action_history_size == 0)
     return;
 
-  action_name = gtk_action_get_name (action);
+  action_name = gimp_action_get_name (action);
 
   /* Some specific actions are of no log interest. */
   if (gimp_action_history_is_excluded_action (action_name))
diff --git a/app/widgets/gimpaction-history.h b/app/widgets/gimpaction-history.h
index 5b76eb7954..40252a85fe 100644
--- a/app/widgets/gimpaction-history.h
+++ b/app/widgets/gimpaction-history.h
@@ -22,7 +22,7 @@
 #define __GIMP_ACTION_HISTORY_H__
 
 
-typedef gboolean (* GimpActionMatchFunc) (GtkAction   *action,
+typedef gboolean (* GimpActionMatchFunc) (GimpAction  *action,
                                           const gchar *keyword,
                                           gint        *section,
                                           Gimp        *gimp);
@@ -40,7 +40,7 @@ GList    * gimp_action_history_search                (Gimp                *gimp,
 gboolean   gimp_action_history_is_blacklisted_action (const gchar         *action_name);
 gboolean   gimp_action_history_is_excluded_action    (const gchar         *action_name);
 
-void       gimp_action_history_action_activated      (GtkAction           *action);
+void       gimp_action_history_action_activated      (GimpAction          *action);
 
 
 #endif  /* __GIMP_ACTION_HISTORY_H__ */
diff --git a/app/widgets/gimpaction.c b/app/widgets/gimpaction.c
index 5a64edcd56..1f29edd7c3 100644
--- a/app/widgets/gimpaction.c
+++ b/app/widgets/gimpaction.c
@@ -2,7 +2,7 @@
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
  * gimpaction.c
- * Copyright (C) 2004 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2004-2019 Michael Natterer <mitch gimp org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,283 +20,192 @@
 
 #include "config.h"
 
-#include <string.h>
-
 #include <gegl.h>
 #include <gtk/gtk.h>
 
-#include "libgimpbase/gimpbase.h"
-#include "libgimpcolor/gimpcolor.h"
 #include "libgimpwidgets/gimpwidgets.h"
 
 #include "widgets-types.h"
 
-#include "config/gimpcoreconfig.h"
-
-#include "core/gimp.h"
-#include "core/gimpcontext.h"
-#include "core/gimpmarshal.h"
-#include "core/gimpimagefile.h"  /* eek */
-#include "core/gimpviewable.h"
-
 #include "gimpaction.h"
-#include "gimpaction-history.h"
-#include "gimpview.h"
-#include "gimpviewrenderer.h"
 
 
-enum
-{
-  PROP_0,
-  PROP_CONTEXT,
-  PROP_COLOR,
-  PROP_VIEWABLE,
-  PROP_ELLIPSIZE,
-  PROP_MAX_WIDTH_CHARS
-};
-
-
-static void   gimp_action_finalize          (GObject          *object);
-static void   gimp_action_set_property      (GObject          *object,
-                                             guint             prop_id,
-                                             const GValue     *value,
-                                             GParamSpec       *pspec);
-static void   gimp_action_get_property      (GObject          *object,
-                                             guint             prop_id,
-                                             GValue           *value,
-                                             GParamSpec       *pspec);
-
-static void   gimp_action_activate          (GtkAction        *action);
-static void   gimp_action_connect_proxy     (GtkAction        *action,
-                                             GtkWidget        *proxy);
-static void   gimp_action_set_proxy         (GimpAction       *action,
-                                             GtkWidget        *proxy);
 static void   gimp_action_set_proxy_tooltip (GimpAction       *action,
                                              GtkWidget        *proxy);
 static void   gimp_action_tooltip_notify    (GimpAction       *action,
                                              const GParamSpec *pspec,
                                              gpointer          data);
 
-
-G_DEFINE_TYPE (GimpAction, gimp_action, GTK_TYPE_ACTION)
-
-#define parent_class gimp_action_parent_class
-
+G_DEFINE_INTERFACE (GimpAction, gimp_action, GTK_TYPE_ACTION)
 
 static void
-gimp_action_class_init (GimpActionClass *klass)
+gimp_action_default_init (GimpActionInterface *iface)
 {
-  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
-  GtkActionClass *action_class = GTK_ACTION_CLASS (klass);
-  GimpRGB         black;
-
-  object_class->finalize      = gimp_action_finalize;
-  object_class->set_property  = gimp_action_set_property;
-  object_class->get_property  = gimp_action_get_property;
-
-  action_class->activate      = gimp_action_activate;
-  action_class->connect_proxy = gimp_action_connect_proxy;
-
-  gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
-
-  g_object_class_install_property (object_class, PROP_CONTEXT,
-                                   g_param_spec_object ("context",
-                                                        NULL, NULL,
-                                                        GIMP_TYPE_CONTEXT,
-                                                        GIMP_PARAM_READWRITE));
-
-  g_object_class_install_property (object_class, PROP_COLOR,
-                                   gimp_param_spec_rgb ("color",
-                                                        NULL, NULL,
-                                                        TRUE, &black,
-                                                        GIMP_PARAM_READWRITE));
-
-  g_object_class_install_property (object_class, PROP_VIEWABLE,
-                                   g_param_spec_object ("viewable",
-                                                        NULL, NULL,
-                                                        GIMP_TYPE_VIEWABLE,
-                                                        GIMP_PARAM_READWRITE));
-
-  g_object_class_install_property (object_class, PROP_ELLIPSIZE,
-                                   g_param_spec_enum ("ellipsize",
-                                                      NULL, NULL,
-                                                      PANGO_TYPE_ELLIPSIZE_MODE,
-                                                      PANGO_ELLIPSIZE_NONE,
-                                                      GIMP_PARAM_READWRITE));
-
-  g_object_class_install_property (object_class, PROP_MAX_WIDTH_CHARS,
-                                   g_param_spec_int ("max-width-chars",
-                                                     NULL, NULL,
-                                                     -1, G_MAXINT, -1,
-                                                     GIMP_PARAM_READWRITE));
 }
 
-static void
+void
 gimp_action_init (GimpAction *action)
 {
-  action->color           = NULL;
-  action->viewable        = NULL;
-  action->ellipsize       = PANGO_ELLIPSIZE_NONE;
-  action->max_width_chars = -1;
+  g_return_if_fail (GIMP_IS_ACTION (action));
 
   g_signal_connect (action, "notify::tooltip",
                     G_CALLBACK (gimp_action_tooltip_notify),
                     NULL);
 }
 
-static void
-gimp_action_finalize (GObject *object)
+
+/*  public functions  */
+
+void
+gimp_action_set_proxy (GimpAction *action,
+                       GtkWidget  *proxy)
 {
-  GimpAction *action = GIMP_ACTION (object);
+  g_return_if_fail (GIMP_IS_ACTION (action));
+  g_return_if_fail (GTK_IS_WIDGET (proxy));
+
+  gimp_action_set_proxy_tooltip (action, proxy);
+}
 
-  g_clear_object (&action->context);
-  g_clear_pointer (&action->color, g_free);
-  g_clear_object (&action->viewable);
 
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+const gchar *
+gimp_action_get_name (GimpAction *action)
+{
+  return gtk_action_get_name ((GtkAction *) action);
 }
 
-static void
-gimp_action_get_property (GObject    *object,
-                          guint       prop_id,
-                          GValue     *value,
-                          GParamSpec *pspec)
+void
+gimp_action_set_label (GimpAction  *action,
+                       const gchar *label)
 {
-  GimpAction *action = GIMP_ACTION (object);
+  gtk_action_set_label ((GtkAction *) action, label);
+}
 
-  switch (prop_id)
-    {
-    case PROP_CONTEXT:
-      g_value_set_object (value, action->context);
-      break;
+const gchar *
+gimp_action_get_label (GimpAction *action)
+{
+  return gtk_action_get_label ((GtkAction *) action);
+}
 
-    case PROP_COLOR:
-      g_value_set_boxed (value, action->color);
-      break;
+void
+gimp_action_set_tooltip (GimpAction  *action,
+                         const gchar *tooltip)
+{
+  gtk_action_set_tooltip ((GtkAction *) action, tooltip);
+}
 
-    case PROP_VIEWABLE:
-      g_value_set_object (value, action->viewable);
-      break;
+const gchar *
+gimp_action_get_tooltip (GimpAction *action)
+{
+  return gtk_action_get_tooltip ((GtkAction *) action);
+}
 
-    case PROP_ELLIPSIZE:
-      g_value_set_enum (value, action->ellipsize);
-      break;
+const gchar *
+gimp_action_get_icon_name (GimpAction *action)
+{
+  return gtk_action_get_icon_name ((GtkAction *) action);
+}
 
-    case PROP_MAX_WIDTH_CHARS:
-      g_value_set_int (value, action->max_width_chars);
-      break;
+void
+gimp_action_set_help_id (GimpAction  *action,
+                         const gchar *help_id)
+{
+  g_return_if_fail (GIMP_IS_ACTION (action));
 
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
+  g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
+                           g_strdup (help_id),
+                           (GDestroyNotify) g_free);
 }
 
-static void
-gimp_action_set_property (GObject      *object,
-                          guint         prop_id,
-                          const GValue *value,
-                          GParamSpec   *pspec)
+const gchar *
+gimp_action_get_help_id (GimpAction *action)
 {
-  GimpAction *action    = GIMP_ACTION (object);
-  gboolean    set_proxy = FALSE;
+  g_return_val_if_fail (GIMP_IS_ACTION (action), NULL);
 
-  switch (prop_id)
-    {
-    case PROP_CONTEXT:
-      if (action->context)
-        g_object_unref  (action->context);
-      action->context = g_value_dup_object (value);
-      break;
-
-    case PROP_COLOR:
-      if (action->color)
-        g_free (action->color);
-      action->color = g_value_dup_boxed (value);
-      set_proxy = TRUE;
-      break;
-
-    case PROP_VIEWABLE:
-      if (action->viewable)
-        g_object_unref  (action->viewable);
-      action->viewable = g_value_dup_object (value);
-      set_proxy = TRUE;
-      break;
-
-    case PROP_ELLIPSIZE:
-      action->ellipsize = g_value_get_enum (value);
-      set_proxy = TRUE;
-      break;
-
-    case PROP_MAX_WIDTH_CHARS:
-      action->max_width_chars = g_value_get_int (value);
-      set_proxy = TRUE;
-      break;
-
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-    }
+  return g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID);
+}
 
-  if (set_proxy)
-    {
-      GSList *list;
-
-      for (list = gtk_action_get_proxies (GTK_ACTION (action));
-           list;
-           list = g_slist_next (list))
-        {
-          gimp_action_set_proxy (action, list->data);
-        }
-    }
+void
+gimp_action_set_visible (GimpAction *action,
+                         gboolean    visible)
+{
+  gtk_action_set_visible ((GtkAction *) action, visible);
 }
 
-static void
-gimp_action_activate (GtkAction *action)
+gboolean
+gimp_action_get_visible (GimpAction *action)
 {
-  if (GTK_ACTION_CLASS (parent_class)->activate)
-    GTK_ACTION_CLASS (parent_class)->activate (action);
+  return gtk_action_get_visible ((GtkAction *) action);
+}
 
-  gimp_action_history_action_activated (action);
+gboolean
+gimp_action_is_visible (GimpAction *action)
+{
+  return gtk_action_is_visible ((GtkAction *) action);
 }
 
-static void
-gimp_action_connect_proxy (GtkAction *action,
-                           GtkWidget *proxy)
+void
+gimp_action_set_sensitive (GimpAction *action,
+                           gboolean    sensitive)
 {
-  GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
+  gtk_action_set_sensitive ((GtkAction *) action, sensitive);
+}
 
-  gimp_action_set_proxy (GIMP_ACTION (action), proxy);
-  gimp_action_set_proxy_tooltip (GIMP_ACTION (action), proxy);
+gboolean
+gimp_action_get_sensitive (GimpAction *action)
+{
+  return gtk_action_get_sensitive ((GtkAction *) action);
 }
 
+gboolean
+gimp_action_is_sensitive (GimpAction *action)
+{
+  return gtk_action_is_sensitive ((GtkAction *) action);
+}
 
-/*  public functions  */
+GClosure *
+gimp_action_get_accel_closure (GimpAction *action)
+{
+  return gtk_action_get_accel_closure ((GtkAction *) action);
+}
+
+void
+gimp_action_set_accel_path (GimpAction  *action,
+                            const gchar *accel_path)
+{
+  gtk_action_set_accel_path ((GtkAction *) action, accel_path);
+}
 
-GimpAction *
-gimp_action_new (const gchar *name,
-                 const gchar *label,
-                 const gchar *tooltip,
-                 const gchar *icon_name)
+const gchar *
+gimp_action_get_accel_path (GimpAction *action)
 {
-  GimpAction *action;
+  return gtk_action_get_accel_path ((GtkAction *) action);
+}
 
-  action = g_object_new (GIMP_TYPE_ACTION,
-                         "name",      name,
-                         "label",     label,
-                         "tooltip",   tooltip,
-                         "icon-name", icon_name,
-                         NULL);
+void
+gimp_action_set_accel_group (GimpAction  *action,
+                             GtkAccelGroup *accel_group)
+{
+  gtk_action_set_accel_group ((GtkAction *) action, accel_group);
+}
 
-  return action;
+void
+gimp_action_connect_accelerator (GimpAction  *action)
+{
+  gtk_action_connect_accelerator ((GtkAction *) action);
+}
+
+void
+gimp_action_activate (GimpAction *action)
+{
+  gtk_action_activate ((GtkAction *) action);
 }
 
 gint
 gimp_action_name_compare (GimpAction  *action1,
                           GimpAction  *action2)
 {
-  return strcmp (gtk_action_get_name ((GtkAction *) action1),
-                 gtk_action_get_name ((GtkAction *) action2));
+  return strcmp (gimp_action_get_name (action1),
+                 gimp_action_get_name (action2));
 }
 
 gboolean
@@ -367,120 +276,11 @@ gimp_action_is_gui_blacklisted (const gchar *action_name)
 
 /*  private functions  */
 
-static void
-gimp_action_set_proxy (GimpAction *action,
-                       GtkWidget  *proxy)
-{
-  if (! GTK_IS_IMAGE_MENU_ITEM (proxy))
-    return;
-
-  if (action->color)
-    {
-      GtkWidget *area;
-
-      area = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
-
-      if (GIMP_IS_COLOR_AREA (area))
-        {
-          gimp_color_area_set_color (GIMP_COLOR_AREA (area), action->color);
-        }
-      else
-        {
-          gint width, height;
-
-          area = gimp_color_area_new (action->color,
-                                      GIMP_COLOR_AREA_SMALL_CHECKS, 0);
-          gimp_color_area_set_draw_border (GIMP_COLOR_AREA (area), TRUE);
-
-          if (action->context)
-            gimp_color_area_set_color_config (GIMP_COLOR_AREA (area),
-                                              action->context->gimp->config->color_management);
-
-          gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (proxy),
-                                             GTK_ICON_SIZE_MENU,
-                                             &width, &height);
-
-          gtk_widget_set_size_request (area, width, height);
-          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), area);
-          gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (proxy),
-                                                     TRUE);
-          gtk_widget_show (area);
-        }
-    }
-  else if (action->viewable)
-    {
-      GtkWidget *view;
-
-      view = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
-
-      if (GIMP_IS_VIEW (view) &&
-          g_type_is_a (G_TYPE_FROM_INSTANCE (action->viewable),
-                       GIMP_VIEW (view)->renderer->viewable_type))
-        {
-          gimp_view_set_viewable (GIMP_VIEW (view), action->viewable);
-        }
-      else
-        {
-          GtkIconSize size;
-          gint        width, height;
-          gint        border_width;
-
-          if (GIMP_IS_IMAGEFILE (action->viewable))
-            {
-              size         = GTK_ICON_SIZE_LARGE_TOOLBAR;
-              border_width = 0;
-            }
-          else
-            {
-              size         = GTK_ICON_SIZE_MENU;
-              border_width = 1;
-            }
-
-          gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (proxy),
-                                             size, &width, &height);
-
-          view = gimp_view_new_full (action->context, action->viewable,
-                                     width, height, border_width,
-                                     FALSE, FALSE, FALSE);
-          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), view);
-          gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (proxy),
-                                                     TRUE);
-          gtk_widget_show (view);
-        }
-    }
-  else
-    {
-      GtkWidget *image;
-
-      image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
-
-      if (GIMP_IS_VIEW (image) || GIMP_IS_COLOR_AREA (image))
-        {
-          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), NULL);
-          gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (proxy),
-                                                     FALSE);
-          g_object_notify (G_OBJECT (action), "icon-name");
-        }
-    }
-
-  {
-    GtkWidget *child = gtk_bin_get_child (GTK_BIN (proxy));
-
-    if (GTK_IS_LABEL (child))
-      {
-        GtkLabel *label = GTK_LABEL (child);
-
-        gtk_label_set_ellipsize (label, action->ellipsize);
-        gtk_label_set_max_width_chars (label, action->max_width_chars);
-      }
-  }
-}
-
 static void
 gimp_action_set_proxy_tooltip (GimpAction *action,
                                GtkWidget  *proxy)
 {
-  const gchar *tooltip = gtk_action_get_tooltip (GTK_ACTION (action));
+  const gchar *tooltip = gimp_action_get_tooltip (action);
 
   if (tooltip)
     gimp_help_set_help_data (proxy, tooltip,
diff --git a/app/widgets/gimpaction.h b/app/widgets/gimpaction.h
index 8df06e047e..d2d7a533a5 100644
--- a/app/widgets/gimpaction.h
+++ b/app/widgets/gimpaction.h
@@ -2,7 +2,7 @@
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
  * gimpaction.h
- * Copyright (C) 2004 Michael Natterer <mitch gimp org>
+ * Copyright (C) 2004-2019 Michael Natterer <mitch gimp org>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,45 +22,71 @@
 #define __GIMP_ACTION_H__
 
 
-#define GIMP_TYPE_ACTION            (gimp_action_get_type ())
-#define GIMP_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ACTION, GimpAction))
-#define GIMP_ACTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ACTION, GimpActionClass))
-#define GIMP_IS_ACTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ACTION))
-#define GIMP_IS_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GIMP_TYPE_ACTION))
-#define GIMP_ACTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GIMP_TYPE_ACTION, GimpActionClass))
+#define GIMP_TYPE_ACTION               (gimp_action_get_type ())
+#define GIMP_ACTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ACTION, GimpAction))
+#define GIMP_IS_ACTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ACTION))
+#define GIMP_ACTION_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE((obj), GIMP_TYPE_ACTION, 
GimpActionInterface))
 
 
-typedef struct _GimpActionClass GimpActionClass;
+typedef struct _GimpActionInterface GimpActionInterface;
 
-struct _GimpAction
+struct _GimpActionInterface
 {
-  GtkAction           parent_instance;
+  GTypeInterface base_interface;
+};
 
-  GimpContext        *context;
 
-  GimpRGB            *color;
-  GimpViewable       *viewable;
-  PangoEllipsizeMode  ellipsize;
-  gint                max_width_chars;
-};
+GType         gimp_action_get_type            (void) G_GNUC_CONST;
 
-struct _GimpActionClass
-{
-  GtkActionClass parent_class;
-};
+void          gimp_action_init                (GimpAction    *action);
+
+void          gimp_action_set_proxy           (GimpAction    *action,
+                                               GtkWidget     *proxy);
+
+const gchar * gimp_action_get_name            (GimpAction    *action);
+
+void          gimp_action_set_label           (GimpAction    *action,
+                                               const gchar   *label);
+const gchar * gimp_action_get_label           (GimpAction    *action);
+
+void          gimp_action_set_tooltip         (GimpAction    *action,
+                                               const gchar   *tooltip);
+const gchar * gimp_action_get_tooltip         (GimpAction    *action);
+
+void          gimp_action_set_icon_name       (GimpAction    *action,
+                                               const gchar   *icon_name);
+const gchar * gimp_action_get_icon_name       (GimpAction    *action);
+
+void          gimp_action_set_help_id         (GimpAction    *action,
+                                               const gchar   *help_id);
+const gchar * gimp_action_get_help_id         (GimpAction    *action);
+
+void          gimp_action_set_visible         (GimpAction    *action,
+                                               gboolean       visible);
+gboolean      gimp_action_get_visible         (GimpAction    *action);
+gboolean      gimp_action_is_visible          (GimpAction    *action);
+
+void          gimp_action_set_sensitive       (GimpAction    *action,
+                                               gboolean       sensitive);
+gboolean      gimp_action_get_sensitive       (GimpAction    *action);
+gboolean      gimp_action_is_sensitive        (GimpAction    *action);
+
+GClosure    * gimp_action_get_accel_closure   (GimpAction    *action);
 
+void          gimp_action_set_accel_path      (GimpAction    *action,
+                                               const gchar   *accel_path);
+const gchar * gimp_action_get_accel_path      (GimpAction    *action);
 
-GType        gimp_action_get_type           (void) G_GNUC_CONST;
+void          gimp_action_set_accel_group     (GimpAction    *action,
+                                               GtkAccelGroup *accel_group);
+void          gimp_action_connect_accelerator (GimpAction    *action);
 
-GimpAction * gimp_action_new                (const gchar *name,
-                                             const gchar *label,
-                                             const gchar *tooltip,
-                                             const gchar *icon_name);
+void          gimp_action_activate            (GimpAction    *action);
 
-gint         gimp_action_name_compare       (GimpAction  *action1,
-                                             GimpAction  *action2);
+gint          gimp_action_name_compare        (GimpAction    *action1,
+                                               GimpAction    *action2);
 
-gboolean     gimp_action_is_gui_blacklisted (const gchar *action_name);
+gboolean      gimp_action_is_gui_blacklisted  (const gchar   *action_name);
 
 
 #endif  /* __GIMP_ACTION_H__ */
diff --git a/app/widgets/gimpactiongroup.c b/app/widgets/gimpactiongroup.c
index 0898db5a13..8104ab9bb1 100644
--- a/app/widgets/gimpactiongroup.c
+++ b/app/widgets/gimpactiongroup.c
@@ -33,8 +33,9 @@
 #include "core/gimpmarshal.h"
 #include "core/gimpviewable.h"
 
-#include "gimpactiongroup.h"
 #include "gimpaction.h"
+#include "gimpactiongroup.h"
+#include "gimpactionimpl.h"
 #include "gimpenumaction.h"
 #include "gimpprocedureaction.h"
 #include "gimpradioaction.h"
@@ -120,7 +121,7 @@ gimp_action_group_class_init (GimpActionGroupClass *klass)
                   NULL, NULL,
                   gimp_marshal_VOID__OBJECT,
                   G_TYPE_NONE, 1,
-                  GTK_TYPE_ACTION);
+                  GIMP_TYPE_ACTION);
 }
 
 static void
@@ -138,7 +139,7 @@ gimp_action_group_constructed (GObject *object)
 
   gimp_assert (GIMP_IS_GIMP (group->gimp));
 
-  name = gtk_action_group_get_name (GTK_ACTION_GROUP (object));
+  name = gimp_action_group_get_name (object);
 
   if (name)
     {
@@ -159,7 +160,7 @@ gimp_action_group_constructed (GObject *object)
 static void
 gimp_action_group_dispose (GObject *object)
 {
-  const gchar *name = gtk_action_group_get_name (GTK_ACTION_GROUP (object));
+  const gchar *name = gimp_action_group_get_name (object);
 
   if (name)
     {
@@ -252,12 +253,11 @@ static gboolean
 gimp_action_group_check_unique_action (GimpActionGroup *group,
                                        const gchar     *action_name)
 {
-  if (G_UNLIKELY (gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                               action_name)))
+  if (G_UNLIKELY (gimp_action_group_get_action (group, action_name)))
     {
       g_warning ("Refusing to add non-unique action '%s' to action group '%s'",
                  action_name,
-                 gtk_action_group_get_name (GTK_ACTION_GROUP (group)));
+                 gimp_action_group_get_name (group));
       return FALSE;
     }
 
@@ -307,6 +307,52 @@ gimp_action_group_new (Gimp                      *gimp,
   return group;
 }
 
+const gchar *
+gimp_action_group_get_name (GimpActionGroup *group)
+{
+  return gtk_action_group_get_name ((GtkActionGroup *) group);
+}
+
+void
+gimp_action_group_add_action (GimpActionGroup *action_group,
+                              GimpAction      *action)
+{
+  gtk_action_group_add_action ((GtkActionGroup *) action_group,
+                               (GtkAction *) action);
+}
+
+void
+gimp_action_group_add_action_with_accel (GimpActionGroup *action_group,
+                                         GimpAction      *action,
+                                         const gchar     *accelerator)
+{
+  gtk_action_group_add_action_with_accel ((GtkActionGroup *) action_group,
+                                          (GtkAction *) action,
+                                          accelerator);
+}
+
+void
+gimp_action_group_remove_action (GimpActionGroup *action_group,
+                                 GimpAction      *action)
+{
+  gtk_action_group_remove_action ((GtkActionGroup *) action_group,
+                                  (GtkAction *) action);
+}
+
+GimpAction *
+gimp_action_group_get_action (GimpActionGroup *group,
+                              const gchar     *action_name)
+{
+  return (GimpAction *) gtk_action_group_get_action ((GtkActionGroup *) group,
+                                                     action_name);
+}
+
+GList *
+gimp_action_group_list_actions (GimpActionGroup *group)
+{
+  return gtk_action_group_list_actions ((GtkActionGroup *) group);
+}
+
 GList *
 gimp_action_groups_from_name (const gchar *name)
 {
@@ -366,24 +412,19 @@ gimp_action_group_add_actions (GimpActionGroup       *group,
           tooltip = gettext (entries[i].tooltip);
         }
 
-      action = gimp_action_new (entries[i].name, label, tooltip,
-                                entries[i].icon_name);
+      action = gimp_action_impl_new (entries[i].name, label, tooltip,
+                                     entries[i].icon_name,
+                                     entries[i].help_id);
 
       if (entries[i].callback)
         g_signal_connect (action, "activate",
                           entries[i].callback,
                           group->user_data);
 
-      gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
-                                              GTK_ACTION (action),
-                                              entries[i].accelerator);
+      gimp_action_group_add_action_with_accel (group, action,
+                                               entries[i].accelerator);
       g_signal_emit (group, signals[ACTION_ADDED], 0, action);
 
-      if (entries[i].help_id)
-        g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
-                                 g_strdup (entries[i].help_id),
-                                 (GDestroyNotify) g_free);
-
       g_object_unref (action);
     }
 }
@@ -421,7 +462,8 @@ gimp_action_group_add_toggle_actions (GimpActionGroup             *group,
         }
 
       action = gimp_toggle_action_new (entries[i].name, label, tooltip,
-                                       entries[i].icon_name);
+                                       entries[i].icon_name,
+                                       entries[i].help_id);
 
       gtk_toggle_action_set_active (action, entries[i].is_active);
 
@@ -430,16 +472,10 @@ gimp_action_group_add_toggle_actions (GimpActionGroup             *group,
                           entries[i].callback,
                           group->user_data);
 
-      gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
-                                              GTK_ACTION (action),
-                                              entries[i].accelerator);
+      gimp_action_group_add_action_with_accel (group, action,
+                                               entries[i].accelerator);
       g_signal_emit (group, signals[ACTION_ADDED], 0, action);
 
-      if (entries[i].help_id)
-        g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
-                                 g_strdup (entries[i].help_id),
-                                 (GDestroyNotify) g_free);
-
       g_object_unref (action);
     }
 }
@@ -482,6 +518,7 @@ gimp_action_group_add_radio_actions (GimpActionGroup            *group,
 
       action = gimp_radio_action_new (entries[i].name, label, tooltip,
                                       entries[i].icon_name,
+                                      entries[i].help_id,
                                       entries[i].value);
 
       if (i == 0)
@@ -493,16 +530,10 @@ gimp_action_group_add_radio_actions (GimpActionGroup            *group,
       if (value == entries[i].value)
         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
 
-      gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
-                                              GTK_ACTION (action),
-                                              entries[i].accelerator);
+      gimp_action_group_add_action_with_accel (group, action,
+                                               entries[i].accelerator);
       g_signal_emit (group, signals[ACTION_ADDED], 0, action);
 
-      if (entries[i].help_id)
-        g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
-                                 g_strdup (entries[i].help_id),
-                                 (GDestroyNotify) g_free);
-
       g_object_unref (action);
     }
 
@@ -549,6 +580,7 @@ gimp_action_group_add_enum_actions (GimpActionGroup           *group,
 
       action = gimp_enum_action_new (entries[i].name, label, tooltip,
                                      entries[i].icon_name,
+                                     entries[i].help_id,
                                      entries[i].value,
                                      entries[i].value_variable);
 
@@ -557,16 +589,10 @@ gimp_action_group_add_enum_actions (GimpActionGroup           *group,
                           callback,
                           group->user_data);
 
-      gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
-                                              GTK_ACTION (action),
-                                              entries[i].accelerator);
+      gimp_action_group_add_action_with_accel (group, action,
+                                               entries[i].accelerator);
       g_signal_emit (group, signals[ACTION_ADDED], 0, action);
 
-      if (entries[i].help_id)
-        g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
-                                 g_strdup (entries[i].help_id),
-                                 (GDestroyNotify) g_free);
-
       g_object_unref (action);
     }
 }
@@ -606,6 +632,7 @@ gimp_action_group_add_string_actions (GimpActionGroup             *group,
 
       action = gimp_string_action_new (entries[i].name, label, tooltip,
                                        entries[i].icon_name,
+                                       entries[i].help_id,
                                        entries[i].value);
 
       if (callback)
@@ -613,16 +640,10 @@ gimp_action_group_add_string_actions (GimpActionGroup             *group,
                           callback,
                           group->user_data);
 
-      gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
-                                              GTK_ACTION (action),
-                                              entries[i].accelerator);
+      gimp_action_group_add_action_with_accel (group, action,
+                                               entries[i].accelerator);
       g_signal_emit (group, signals[ACTION_ADDED], 0, action);
 
-      if (entries[i].help_id)
-        g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
-                                 g_strdup (entries[i].help_id),
-                                 (GDestroyNotify) g_free);
-
       g_object_unref (action);
     }
 }
@@ -648,6 +669,7 @@ gimp_action_group_add_procedure_actions (GimpActionGroup                *group,
                                           entries[i].label,
                                           entries[i].tooltip,
                                           entries[i].icon_name,
+                                          entries[i].help_id,
                                           entries[i].procedure);
 
       if (callback)
@@ -655,22 +677,16 @@ gimp_action_group_add_procedure_actions (GimpActionGroup                *group,
                           callback,
                           group->user_data);
 
-      gtk_action_group_add_action_with_accel (GTK_ACTION_GROUP (group),
-                                              GTK_ACTION (action),
-                                              entries[i].accelerator);
+      gimp_action_group_add_action_with_accel (group, action,
+                                               entries[i].accelerator);
       g_signal_emit (group, signals[ACTION_ADDED], 0, action);
 
-      if (entries[i].help_id)
-        g_object_set_qdata_full (G_OBJECT (action), GIMP_HELP_ID,
-                                 g_strdup (entries[i].help_id),
-                                 (GDestroyNotify) g_free);
-
       g_object_unref (action);
     }
 }
 
 /**
- * gimp_action_group_remove_action:
+ * gimp_action_group_remove_action_and_accel:
  * @group:  the #GimpActionGroup to which @action belongs.
  * @action: the #GimpAction.
  *
@@ -680,22 +696,21 @@ gimp_action_group_add_procedure_actions (GimpActionGroup                *group,
  * gtk_action_group_remove_action() instead.
  */
 void
-gimp_action_group_remove_action (GimpActionGroup *group,
-                                 GimpAction      *action)
+gimp_action_group_remove_action_and_accel (GimpActionGroup *group,
+                                           GimpAction      *action)
 {
   const gchar *action_name;
   const gchar *group_name;
   gchar       *accel_path;
 
-  action_name = gtk_action_get_name (GTK_ACTION (action));
-  group_name  = gtk_action_group_get_name (GTK_ACTION_GROUP (group));
+  action_name = gimp_action_get_name (action);
+  group_name  = gimp_action_group_get_name (group);
   accel_path = g_strconcat ("<Actions>/", group_name, "/",
                             action_name, NULL);
 
   gtk_accel_map_change_entry (accel_path, 0, 0, FALSE);
 
-  gtk_action_group_remove_action (GTK_ACTION_GROUP (group),
-                                  GTK_ACTION (action));
+  gimp_action_group_remove_action (group, action);
   g_free (accel_path);
 }
 
@@ -703,12 +718,12 @@ void
 gimp_action_group_activate_action (GimpActionGroup *group,
                                    const gchar     *action_name)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -717,7 +732,7 @@ gimp_action_group_activate_action (GimpActionGroup *group,
       return;
     }
 
-  gtk_action_activate (action);
+  gimp_action_activate (action);
 }
 
 void
@@ -725,12 +740,12 @@ gimp_action_group_set_action_visible (GimpActionGroup *group,
                                       const gchar     *action_name,
                                       gboolean         visible)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -740,7 +755,7 @@ gimp_action_group_set_action_visible (GimpActionGroup *group,
       return;
     }
 
-  gtk_action_set_visible (action, visible);
+  gimp_action_set_visible (action, visible);
 }
 
 void
@@ -748,12 +763,12 @@ gimp_action_group_set_action_sensitive (GimpActionGroup *group,
                                         const gchar     *action_name,
                                         gboolean         sensitive)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -763,7 +778,7 @@ gimp_action_group_set_action_sensitive (GimpActionGroup *group,
       return;
     }
 
-  gtk_action_set_sensitive (action, sensitive);
+  gimp_action_set_sensitive (action, sensitive);
 }
 
 void
@@ -771,12 +786,12 @@ gimp_action_group_set_action_active (GimpActionGroup *group,
                                      const gchar     *action_name,
                                      gboolean         active)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -794,8 +809,8 @@ gimp_action_group_set_action_active (GimpActionGroup *group,
       return;
     }
 
-  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-                                active ? TRUE : FALSE);
+  gimp_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
+                                 active ? TRUE : FALSE);
 }
 
 void
@@ -803,12 +818,12 @@ gimp_action_group_set_action_label (GimpActionGroup *group,
                                     const gchar     *action_name,
                                     const gchar     *label)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -818,7 +833,7 @@ gimp_action_group_set_action_label (GimpActionGroup *group,
       return;
     }
 
-  gtk_action_set_label (action, label);
+  gimp_action_set_label (action, label);
 }
 
 void
@@ -826,12 +841,12 @@ gimp_action_group_set_action_pixbuf (GimpActionGroup *group,
                                      const gchar     *action_name,
                                      GdkPixbuf       *pixbuf)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -841,7 +856,7 @@ gimp_action_group_set_action_pixbuf (GimpActionGroup *group,
       return;
     }
 
-  gtk_action_set_gicon (action, G_ICON (pixbuf));
+  gtk_action_set_gicon (GTK_ACTION (action), G_ICON (pixbuf));
 }
 
 
@@ -850,12 +865,12 @@ gimp_action_group_set_action_tooltip (GimpActionGroup     *group,
                                       const gchar         *action_name,
                                       const gchar         *tooltip)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -865,19 +880,19 @@ gimp_action_group_set_action_tooltip (GimpActionGroup     *group,
       return;
     }
 
-  gtk_action_set_tooltip (action, tooltip);
+  gimp_action_set_tooltip (action, tooltip);
 }
 
 const gchar *
 gimp_action_group_get_action_tooltip (GimpActionGroup     *group,
                                       const gchar         *action_name)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_val_if_fail (GIMP_IS_ACTION_GROUP (group), NULL);
   g_return_val_if_fail (action_name != NULL, NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -887,7 +902,7 @@ gimp_action_group_get_action_tooltip (GimpActionGroup     *group,
       return NULL;
     }
 
-  return gtk_action_get_tooltip (action);
+  return gimp_action_get_tooltip (action);
 }
 
 void
@@ -895,13 +910,13 @@ gimp_action_group_set_action_context (GimpActionGroup *group,
                                       const gchar     *action_name,
                                       GimpContext     *context)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
   g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context));
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -928,12 +943,12 @@ gimp_action_group_set_action_color (GimpActionGroup *group,
                                     const GimpRGB   *color,
                                     gboolean         set_label)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -978,13 +993,13 @@ gimp_action_group_set_action_viewable (GimpActionGroup *group,
                                        const gchar     *action_name,
                                        GimpViewable    *viewable)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
   g_return_if_fail (viewable == NULL || GIMP_IS_VIEWABLE (viewable));
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -1010,12 +1025,12 @@ gimp_action_group_set_action_hide_empty (GimpActionGroup *group,
                                          const gchar     *action_name,
                                          gboolean         hide_empty)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -1033,12 +1048,12 @@ gimp_action_group_set_action_always_show_image (GimpActionGroup *group,
                                                 const gchar     *action_name,
                                                 gboolean         always_show_image)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_if_fail (GIMP_IS_ACTION_GROUP (group));
   g_return_if_fail (action_name != NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group), action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   if (! action)
     {
@@ -1048,5 +1063,5 @@ gimp_action_group_set_action_always_show_image (GimpActionGroup *group,
       return;
     }
 
-  gtk_action_set_always_show_image (action, always_show_image);
+  gtk_action_set_always_show_image (GTK_ACTION (action), always_show_image);
 }
diff --git a/app/widgets/gimpactiongroup.h b/app/widgets/gimpactiongroup.h
index 8b934b1d48..8d59d32df1 100644
--- a/app/widgets/gimpactiongroup.h
+++ b/app/widgets/gimpactiongroup.h
@@ -53,7 +53,7 @@ struct _GimpActionGroupClass
 
   /* signals */
   void (* action_added) (GimpActionGroup *group,
-                         GtkAction       *action);
+                         GimpAction      *action);
 };
 
 struct _GimpActionEntry
@@ -142,6 +142,20 @@ GimpActionGroup *gimp_action_group_new        (Gimp                  *gimp,
 
 GList *gimp_action_groups_from_name           (const gchar           *name);
 
+const gchar * gimp_action_group_get_name       (GimpActionGroup       *group);
+
+void  gimp_action_group_add_action            (GimpActionGroup *action_group,
+                                               GimpAction      *action);
+void  gimp_action_group_add_action_with_accel (GimpActionGroup *action_group,
+                                               GimpAction      *action,
+                                               const gchar     *accelerator);
+void  gimp_action_group_remove_action         (GimpActionGroup *action_group,
+                                               GimpAction      *action);
+
+GimpAction  * gimp_action_group_get_action     (GimpActionGroup       *group,
+                                                const gchar           *action_name);
+GList       * gimp_action_group_list_actions   (GimpActionGroup       *group);
+
 void   gimp_action_group_update               (GimpActionGroup       *group,
                                                gpointer               update_data);
 
@@ -175,8 +189,8 @@ void   gimp_action_group_add_procedure_actions(GimpActionGroup             *grou
                                                guint                        n_entries,
                                                GCallback                    callback);
 
-void   gimp_action_group_remove_action        (GimpActionGroup             *group,
-                                               GimpAction                  *action);
+void   gimp_action_group_remove_action_and_accel (GimpActionGroup          *group,
+                                                  GimpAction               *action);
 
 void          gimp_action_group_activate_action       (GimpActionGroup *group,
                                                        const gchar     *action_name);
diff --git a/app/widgets/gimpactionimpl.c b/app/widgets/gimpactionimpl.c
new file mode 100644
index 0000000000..183a5b0b63
--- /dev/null
+++ b/app/widgets/gimpactionimpl.c
@@ -0,0 +1,394 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpaction.c
+ * Copyright (C) 2004-2019 Michael Natterer <mitch gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "widgets-types.h"
+
+#include "config/gimpcoreconfig.h"
+
+#include "core/gimp.h"
+#include "core/gimpcontext.h"
+#include "core/gimpmarshal.h"
+#include "core/gimpimagefile.h"  /* eek */
+
+#include "gimpaction.h"
+#include "gimpactionimpl.h"
+#include "gimpaction-history.h"
+#include "gimpview.h"
+#include "gimpviewrenderer.h"
+#include "gimpwidgets-utils.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_CONTEXT,
+  PROP_COLOR,
+  PROP_VIEWABLE,
+  PROP_ELLIPSIZE,
+  PROP_MAX_WIDTH_CHARS
+};
+
+
+static void   gimp_action_impl_finalize      (GObject        *object);
+static void   gimp_action_impl_set_property  (GObject        *object,
+                                              guint           prop_id,
+                                              const GValue   *value,
+                                              GParamSpec     *pspec);
+static void   gimp_action_impl_get_property  (GObject        *object,
+                                              guint           prop_id,
+                                              GValue         *value,
+                                              GParamSpec     *pspec);
+
+static void   gimp_action_impl_activate      (GtkAction      *action);
+static void   gimp_action_impl_connect_proxy (GtkAction      *action,
+                                              GtkWidget      *proxy);
+
+static void   gimp_action_impl_set_proxy     (GimpActionImpl *impl,
+                                              GtkWidget      *proxy);
+
+G_DEFINE_TYPE_WITH_CODE (GimpActionImpl, gimp_action_impl, GTK_TYPE_ACTION,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_ACTION, NULL))
+
+#define parent_class gimp_action_impl_parent_class
+
+static void
+gimp_action_impl_class_init (GimpActionImplClass *klass)
+{
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+  GtkActionClass *action_class = GTK_ACTION_CLASS (klass);
+  GimpRGB         black;
+
+  object_class->finalize      = gimp_action_impl_finalize;
+  object_class->set_property  = gimp_action_impl_set_property;
+  object_class->get_property  = gimp_action_impl_get_property;
+
+  action_class->activate      = gimp_action_impl_activate;
+  action_class->connect_proxy = gimp_action_impl_connect_proxy;
+
+  gimp_rgba_set (&black, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
+
+  g_object_class_install_property (object_class, PROP_CONTEXT,
+                                   g_param_spec_object ("context",
+                                                        NULL, NULL,
+                                                        GIMP_TYPE_CONTEXT,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_COLOR,
+                                   gimp_param_spec_rgb ("color",
+                                                        NULL, NULL,
+                                                        TRUE, &black,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_VIEWABLE,
+                                   g_param_spec_object ("viewable",
+                                                        NULL, NULL,
+                                                        GIMP_TYPE_VIEWABLE,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_ELLIPSIZE,
+                                   g_param_spec_enum ("ellipsize",
+                                                      NULL, NULL,
+                                                      PANGO_TYPE_ELLIPSIZE_MODE,
+                                                      PANGO_ELLIPSIZE_NONE,
+                                                      GIMP_PARAM_READWRITE));
+
+  g_object_class_install_property (object_class, PROP_MAX_WIDTH_CHARS,
+                                   g_param_spec_int ("max-width-chars",
+                                                     NULL, NULL,
+                                                     -1, G_MAXINT, -1,
+                                                     GIMP_PARAM_READWRITE));
+}
+
+static void
+gimp_action_impl_init (GimpActionImpl *impl)
+{
+  impl->ellipsize       = PANGO_ELLIPSIZE_NONE;
+  impl->max_width_chars = -1;
+}
+
+static void
+gimp_action_impl_finalize (GObject *object)
+{
+  GimpActionImpl *impl = GIMP_ACTION_IMPL (object);
+
+  g_clear_object (&impl->context);
+  g_clear_pointer (&impl->color, g_free);
+  g_clear_object (&impl->viewable);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gimp_action_impl_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  GimpActionImpl *impl = GIMP_ACTION_IMPL (object);
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      g_value_set_object (value, impl->context);
+      break;
+
+    case PROP_COLOR:
+      g_value_set_boxed (value, impl->color);
+      break;
+
+    case PROP_VIEWABLE:
+      g_value_set_object (value, impl->viewable);
+      break;
+
+    case PROP_ELLIPSIZE:
+      g_value_set_enum (value, impl->ellipsize);
+      break;
+
+    case PROP_MAX_WIDTH_CHARS:
+      g_value_set_int (value, impl->max_width_chars);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_action_impl_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  GimpActionImpl *impl      = GIMP_ACTION_IMPL (object);
+  gboolean        set_proxy = FALSE;
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      g_set_object (&impl->context, g_value_get_object (value));
+      break;
+
+    case PROP_COLOR:
+      g_clear_pointer (&impl->color, g_free);
+      impl->color = g_value_dup_boxed (value);
+      set_proxy = TRUE;
+      break;
+
+    case PROP_VIEWABLE:
+      g_set_object  (&impl->viewable, g_value_get_object (value));
+      set_proxy = TRUE;
+      break;
+
+    case PROP_ELLIPSIZE:
+      impl->ellipsize = g_value_get_enum (value);
+      set_proxy = TRUE;
+      break;
+
+    case PROP_MAX_WIDTH_CHARS:
+      impl->max_width_chars = g_value_get_int (value);
+      set_proxy = TRUE;
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+
+  if (set_proxy)
+    {
+      GSList *list;
+
+      for (list = gtk_action_get_proxies (GTK_ACTION (impl));
+           list;
+           list = g_slist_next (list))
+        {
+          gimp_action_impl_set_proxy (impl, list->data);
+        }
+    }
+}
+
+static void
+gimp_action_impl_activate (GtkAction *action)
+{
+  if (GTK_ACTION_CLASS (parent_class)->activate)
+    GTK_ACTION_CLASS (parent_class)->activate (action);
+
+  gimp_action_history_action_activated (GIMP_ACTION (action));
+}
+
+static void
+gimp_action_impl_connect_proxy (GtkAction *action,
+                                GtkWidget *proxy)
+{
+  GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
+
+  gimp_action_impl_set_proxy (GIMP_ACTION_IMPL (action), proxy);
+
+  gimp_action_set_proxy (GIMP_ACTION (action), proxy);
+}
+
+
+/*  public functions  */
+
+GimpAction *
+gimp_action_impl_new (const gchar *name,
+                      const gchar *label,
+                      const gchar *tooltip,
+                      const gchar *icon_name,
+                      const gchar *help_id)
+{
+  GimpAction *action;
+
+  action = g_object_new (GIMP_TYPE_ACTION_IMPL,
+                         "name",      name,
+                         "label",     label,
+                         "tooltip",   tooltip,
+                         "icon-name", icon_name,
+                         NULL);
+
+  gimp_action_set_help_id (action, help_id);
+
+  return action;
+}
+
+
+/*  private functions  */
+
+static void
+gimp_action_impl_set_proxy (GimpActionImpl *impl,
+                            GtkWidget      *proxy)
+{
+  if (! GTK_IS_IMAGE_MENU_ITEM (proxy))
+    return;
+
+  if (impl->color)
+    {
+      GtkWidget *area;
+
+      area = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
+
+      if (GIMP_IS_COLOR_AREA (area))
+        {
+          gimp_color_area_set_color (GIMP_COLOR_AREA (area), impl->color);
+        }
+      else
+        {
+          gint width, height;
+
+          area = gimp_color_area_new (impl->color,
+                                      GIMP_COLOR_AREA_SMALL_CHECKS, 0);
+          gimp_color_area_set_draw_border (GIMP_COLOR_AREA (area), TRUE);
+
+          if (impl->context)
+            gimp_color_area_set_color_config (GIMP_COLOR_AREA (area),
+                                              impl->context->gimp->config->color_management);
+
+          gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (proxy),
+                                             GTK_ICON_SIZE_MENU,
+                                             &width, &height);
+
+          gtk_widget_set_size_request (area, width, height);
+          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), area);
+          gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (proxy),
+                                                     TRUE);
+          gtk_widget_show (area);
+        }
+    }
+  else if (impl->viewable)
+    {
+      GtkWidget *view;
+
+      view = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
+
+      if (GIMP_IS_VIEW (view) &&
+          g_type_is_a (G_TYPE_FROM_INSTANCE (impl->viewable),
+                       GIMP_VIEW (view)->renderer->viewable_type))
+        {
+          gimp_view_set_viewable (GIMP_VIEW (view), impl->viewable);
+        }
+      else
+        {
+          GtkIconSize size;
+          gint        width, height;
+          gint        border_width;
+
+          if (GIMP_IS_IMAGEFILE (impl->viewable))
+            {
+              size         = GTK_ICON_SIZE_LARGE_TOOLBAR;
+              border_width = 0;
+            }
+          else
+            {
+              size         = GTK_ICON_SIZE_MENU;
+              border_width = 1;
+            }
+
+          gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (proxy),
+                                             size, &width, &height);
+
+          view = gimp_view_new_full (impl->context, impl->viewable,
+                                     width, height, border_width,
+                                     FALSE, FALSE, FALSE);
+          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), view);
+          gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (proxy),
+                                                     TRUE);
+          gtk_widget_show (view);
+        }
+    }
+  else
+    {
+      GtkWidget *image;
+
+      image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (proxy));
+
+      if (GIMP_IS_VIEW (image) || GIMP_IS_COLOR_AREA (image))
+        {
+          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (proxy), NULL);
+          gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (proxy),
+                                                     FALSE);
+          g_object_notify (G_OBJECT (impl), "icon-name");
+        }
+    }
+
+  {
+    GtkWidget *child = gtk_bin_get_child (GTK_BIN (proxy));
+
+    if (GTK_IS_BOX (child))
+      child = g_object_get_data (G_OBJECT (proxy), "gimp-menu-item-label");
+
+    if (GTK_IS_LABEL (child))
+      {
+        GtkLabel *label = GTK_LABEL (child);
+
+        gtk_label_set_ellipsize (label, impl->ellipsize);
+        gtk_label_set_max_width_chars (label, impl->max_width_chars);
+      }
+  }
+}
diff --git a/app/widgets/gimpactionimpl.h b/app/widgets/gimpactionimpl.h
new file mode 100644
index 0000000000..cd6e7a5fad
--- /dev/null
+++ b/app/widgets/gimpactionimpl.h
@@ -0,0 +1,61 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpactionimpl.h
+ * Copyright (C) 2004-2019 Michael Natterer <mitch gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_ACTION_IMPL_H__
+#define __GIMP_ACTION_IMPL_H__
+
+
+#define GIMP_TYPE_ACTION_IMPL            (gimp_action_impl_get_type ())
+#define GIMP_ACTION_IMPL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_ACTION_IMPL, 
GimpActionImpl))
+#define GIMP_ACTION_IMPL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_ACTION_IMPL, 
GimpActionImplClass))
+#define GIMP_IS_ACTION_IMPL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_ACTION_IMPL))
+#define GIMP_IS_ACTION_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GIMP_TYPE_ACTION_IMPL))
+#define GIMP_ACTION_IMPL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GIMP_TYPE_ACTION_IMPL, 
GimpActionImplClass))
+
+typedef struct _GimpActionImpl      GimpActionImpl;
+typedef struct _GimpActionImplClass GimpActionImplClass;
+
+struct _GimpActionImpl
+{
+  GtkAction           parent_instance;
+
+  GimpContext        *context;
+
+  GimpRGB            *color;
+  GimpViewable       *viewable;
+  PangoEllipsizeMode  ellipsize;
+  gint                max_width_chars;
+};
+
+struct _GimpActionImplClass
+{
+  GtkActionClass parent_class;
+};
+
+GType         gimp_action_impl_get_type       (void) G_GNUC_CONST;
+
+GimpAction  * gimp_action_impl_new            (const gchar   *name,
+                                               const gchar   *label,
+                                               const gchar   *tooltip,
+                                               const gchar   *icon_name,
+                                               const gchar   *help_id);
+
+
+#endif  /* __GIMP_ACTION_IMPL_H__ */
diff --git a/app/widgets/gimpactionview.c b/app/widgets/gimpactionview.c
index 362f24a12f..36c2e988fd 100644
--- a/app/widgets/gimpactionview.c
+++ b/app/widgets/gimpactionview.c
@@ -99,7 +99,7 @@ gimp_action_view_dispose (GObject *object)
         {
           GtkAccelGroup *group;
 
-          group = gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (view->manager));
+          group = gimp_ui_manager_get_accel_group (view->manager);
 
           g_signal_handlers_disconnect_by_func (group,
                                                 gimp_action_view_accel_changed,
@@ -203,7 +203,7 @@ gimp_action_view_new (GimpUIManager *manager,
 
   store = gtk_tree_store_new (GIMP_ACTION_VIEW_N_COLUMNS,
                               G_TYPE_BOOLEAN,         /* COLUMN_VISIBLE        */
-                              GTK_TYPE_ACTION,        /* COLUMN_ACTION         */
+                              GIMP_TYPE_ACTION,       /* COLUMN_ACTION         */
                               G_TYPE_STRING,          /* COLUMN_ICON_NAME      */
                               G_TYPE_STRING,          /* COLUMN_LABEL          */
                               G_TYPE_STRING,          /* COLUMN_LABEL_CASEFOLD */
@@ -212,9 +212,9 @@ gimp_action_view_new (GimpUIManager *manager,
                               GDK_TYPE_MODIFIER_TYPE, /* COLUMN_ACCEL_MASK     */
                               G_TYPE_CLOSURE);        /* COLUMN_ACCEL_CLOSURE  */
 
-  accel_group = gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (manager));
+  accel_group = gimp_ui_manager_get_accel_group (manager);
 
-  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
+  for (list = gimp_ui_manager_get_action_groups (manager);
        list;
        list = g_list_next (list))
     {
@@ -230,15 +230,15 @@ gimp_action_view_new (GimpUIManager *manager,
                           GIMP_ACTION_VIEW_COLUMN_LABEL,     group->label,
                           -1);
 
-      actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
+      actions = gimp_action_group_list_actions (group);
 
       actions = g_list_sort (actions, (GCompareFunc) gimp_action_name_compare);
 
       for (list2 = actions; list2; list2 = g_list_next (list2))
         {
-          GtkAction       *action        = list2->data;
-          const gchar     *name          = gtk_action_get_name (action);
-          const gchar     *icon_name     = gtk_action_get_icon_name (action);
+          GimpAction      *action        = list2->data;
+          const gchar     *name          = gimp_action_get_name (action);
+          const gchar     *icon_name     = gimp_action_get_icon_name (action);
           gchar           *label;
           gchar           *label_casefold;
           guint            accel_key     = 0;
@@ -249,7 +249,7 @@ gimp_action_view_new (GimpUIManager *manager,
           if (gimp_action_is_gui_blacklisted (name))
             continue;
 
-          label = gimp_strip_uline (gtk_action_get_label (action));
+          label = gimp_strip_uline (gimp_action_get_label (action));
 
           if (! (label && strlen (label)))
             {
@@ -261,7 +261,7 @@ gimp_action_view_new (GimpUIManager *manager,
 
           if (show_shortcuts)
             {
-              accel_closure = gtk_action_get_accel_closure (action);
+              accel_closure = gimp_action_get_accel_closure (action);
 
               if (accel_closure)
                 {
@@ -634,7 +634,7 @@ gimp_action_view_conflict_response (GtkWidget   *dialog,
 
 static void
 gimp_action_view_conflict_confirm (GimpActionView  *view,
-                                   GtkAction       *action,
+                                   GimpAction      *action,
                                    guint            accel_key,
                                    GdkModifierType  accel_mask,
                                    const gchar     *accel_path)
@@ -648,7 +648,7 @@ gimp_action_view_conflict_confirm (GimpActionView  *view,
 
   g_object_get (action, "action-group", &group, NULL);
 
-  label = gimp_strip_uline (gtk_action_get_label (action));
+  label = gimp_strip_uline (gimp_action_get_label (action));
 
   accel_string = gtk_accelerator_get_label (accel_key, accel_mask);
 
@@ -701,7 +701,7 @@ gimp_action_view_conflict_confirm (GimpActionView  *view,
 static const gchar *
 gimp_action_view_get_accel_action (GimpActionView  *view,
                                    const gchar     *path_string,
-                                   GtkAction      **action_return,
+                                   GimpAction     **action_return,
                                    guint           *action_accel_key,
                                    GdkModifierType *action_accel_mask)
 {
@@ -717,7 +717,7 @@ gimp_action_view_get_accel_action (GimpActionView  *view,
 
   if (gtk_tree_model_get_iter (model, &iter, path))
     {
-      GtkAction *action;
+      GimpAction *action;
 
       gtk_tree_model_get (model, &iter,
                           GIMP_ACTION_VIEW_COLUMN_ACTION,     &action,
@@ -733,7 +733,7 @@ gimp_action_view_get_accel_action (GimpActionView  *view,
 
       *action_return = action;
 
-      return gtk_action_get_accel_path (action);
+      return gimp_action_get_accel_path (action);
     }
 
  done:
@@ -750,7 +750,7 @@ gimp_action_view_accel_edited (GtkCellRendererAccel *accel,
                                guint                 hardware_keycode,
                                GimpActionView       *view)
 {
-  GtkAction       *action;
+  GimpAction      *action;
   guint            action_accel_key;
   GdkModifierType  action_accel_mask;
   const gchar     *accel_path;
@@ -805,7 +805,7 @@ gimp_action_view_accel_edited (GtkCellRendererAccel *accel,
                                          accel_key, accel_mask, FALSE))
     {
       GtkTreeModel *model;
-      GtkAction    *conflict_action = NULL;
+      GimpAction   *conflict_action = NULL;
       GtkTreeIter   iter;
       gboolean      iter_valid;
 
@@ -875,7 +875,7 @@ gimp_action_view_accel_cleared (GtkCellRendererAccel *accel,
                                 const char           *path_string,
                                 GimpActionView       *view)
 {
-  GtkAction       *action;
+  GimpAction      *action;
   guint            action_accel_key;
   GdkModifierType  action_accel_mask;
   const gchar     *accel_path;
diff --git a/app/widgets/gimpcontrollereditor.c b/app/widgets/gimpcontrollereditor.c
index e21dcdd662..d43325b8f5 100644
--- a/app/widgets/gimpcontrollereditor.c
+++ b/app/widgets/gimpcontrollereditor.c
@@ -34,6 +34,7 @@
 
 #include "core/gimpcontext.h"
 
+#include "gimpaction.h"
 #include "gimpactioneditor.h"
 #include "gimpactionview.h"
 #include "gimpcontrollereditor.h"
@@ -316,12 +317,12 @@ gimp_controller_editor_constructed (GObject *object)
 
       if (event_action)
         {
-          GtkAction *action;
+          GimpAction *action;
 
           action = gimp_ui_manager_find_action (ui_manager, NULL, event_action);
 
           if (action)
-            icon_name = gtk_action_get_icon_name (action);
+            icon_name = gimp_action_get_icon_name (action);
         }
 
       gtk_list_store_append (store, &iter);
diff --git a/app/widgets/gimpcontrollers.c b/app/widgets/gimpcontrollers.c
index 08bbe9976c..fd96946c28 100644
--- a/app/widgets/gimpcontrollers.c
+++ b/app/widgets/gimpcontrollers.c
@@ -32,6 +32,8 @@
 #include "core/gimp.h"
 #include "core/gimplist.h"
 
+#include "gimpaction.h"
+#include "gimpactiongroup.h"
 #include "gimpcontrollerinfo.h"
 #include "gimpcontrollers.h"
 #include "gimpcontrollerkeyboard.h"
@@ -337,17 +339,16 @@ gimp_controllers_event_mapped (GimpControllerInfo        *info,
                                const gchar               *action_name,
                                GimpControllerManager     *manager)
 {
-  GtkUIManager *ui_manager = GTK_UI_MANAGER (manager->ui_manager);
-  GList        *list;
+  GList *list;
 
-  for (list = gtk_ui_manager_get_action_groups (ui_manager);
+  for (list = gimp_ui_manager_get_action_groups (manager->ui_manager);
        list;
        list = g_list_next (list))
     {
-      GtkActionGroup *group = list->data;
-      GtkAction      *action;
+      GimpActionGroup *group = list->data;
+      GimpAction      *action;
 
-      action = gtk_action_group_get_action (group, action_name);
+      action = gimp_action_group_get_action (group, action_name);
 
       if (action)
         {
@@ -369,7 +370,7 @@ gimp_controllers_event_mapped (GimpControllerInfo        *info,
 
             case GIMP_CONTROLLER_EVENT_TRIGGER:
             default:
-              gtk_action_activate (action);
+              gimp_action_activate (action);
               break;
             }
 
diff --git a/app/widgets/gimpdashboard.c b/app/widgets/gimpdashboard.c
index e11d76b39c..f4347075a5 100644
--- a/app/widgets/gimpdashboard.c
+++ b/app/widgets/gimpdashboard.c
@@ -70,6 +70,7 @@
 #include "gimphighlightablebutton.h"
 #include "gimpmeter.h"
 #include "gimpsessioninfo-aux.h"
+#include "gimptoggleaction.h"
 #include "gimpuimanager.h"
 #include "gimpwidgets-utils.h"
 #include "gimpwindowstrategy.h"
@@ -265,21 +266,21 @@ struct _FieldData
 
 struct _GroupData
 {
-  gint             n_fields;
-  gint             n_meter_values;
+  gint              n_fields;
+  gint              n_meter_values;
 
-  gboolean         active;
-  gdouble          limit;
+  gboolean          active;
+  gdouble           limit;
 
-  GtkToggleAction *action;
-  GtkExpander     *expander;
-  GtkLabel        *header_values_label;
-  GtkButton       *menu_button;
-  GtkMenu         *menu;
-  GimpMeter       *meter;
-  GtkTable        *table;
+  GimpToggleAction *action;
+  GtkExpander      *expander;
+  GtkLabel         *header_values_label;
+  GtkButton        *menu_button;
+  GtkMenu          *menu;
+  GimpMeter        *meter;
+  GtkTable         *table;
 
-  FieldData       *fields;
+  FieldData        *fields;
 };
 
 struct _GimpDashboardPrivate
@@ -338,7 +339,7 @@ static gboolean   gimp_dashboard_group_expander_button_press    (GimpDashboard
                                                                  GtkWidget           *widget);
 
 static void       gimp_dashboard_group_action_toggled           (GimpDashboard       *dashboard,
-                                                                 GtkToggleAction     *action);
+                                                                 GimpToggleAction    *action);
 static void       gimp_dashboard_field_menu_item_toggled        (GimpDashboard       *dashboard,
                                                                  GtkCheckMenuItem    *item);
 
@@ -1255,7 +1256,7 @@ gimp_dashboard_constructed (GObject *object)
   GimpDashboardPrivate *priv = dashboard->priv;
   GimpUIManager        *ui_manager;
   GimpActionGroup      *action_group;
-  GtkAction            *action;
+  GimpAction           *action;
   GtkWidget            *button;
   GtkWidget            *alignment;
   GtkWidget            *box;
@@ -1285,7 +1286,7 @@ gimp_dashboard_constructed (GObject *object)
                                             &entry, 1);
 
       action = gimp_ui_manager_find_action (ui_manager, "dashboard", entry.name);
-      group_data->action = GTK_TOGGLE_ACTION (action);
+      group_data->action = GIMP_TOGGLE_ACTION (action);
 
       g_object_set_data (G_OBJECT (action),
                          "gimp-dashboard-group", GINT_TO_POINTER (group));
@@ -1309,8 +1310,8 @@ gimp_dashboard_constructed (GObject *object)
                                           gimp_get_extend_selection_mask (),
                                           NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (action_group),
-                                        "dashboard-log-add-marker");
+  action = gimp_action_group_get_action (action_group,
+                                         "dashboard-log-add-marker");
   g_object_bind_property (action, "sensitive",
                           button, "visible",
                           G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
@@ -1337,8 +1338,8 @@ gimp_dashboard_constructed (GObject *object)
   button = gimp_editor_add_action_button (GIMP_EDITOR (dashboard), "dashboard",
                                           "dashboard-reset", NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (action_group),
-                                        "dashboard-reset");
+  action = gimp_action_group_get_action (action_group,
+                                         "dashboard-reset");
   g_object_bind_property (action, "sensitive",
                           button, "visible",
                           G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
@@ -1680,8 +1681,8 @@ gimp_dashboard_group_expander_button_press (GimpDashboard  *dashboard,
 }
 
 static void
-gimp_dashboard_group_action_toggled (GimpDashboard   *dashboard,
-                                     GtkToggleAction *action)
+gimp_dashboard_group_action_toggled (GimpDashboard    *dashboard,
+                                     GimpToggleAction *action)
 {
   GimpDashboardPrivate *priv = dashboard->priv;
   Group                 group;
@@ -1691,7 +1692,7 @@ gimp_dashboard_group_action_toggled (GimpDashboard   *dashboard,
                                                    "gimp-dashboard-group"));
   group_data = &priv->groups[group];
 
-  group_data->active = gtk_toggle_action_get_active (action);
+  group_data->active = gimp_toggle_action_get_active (action);
 
   gimp_dashboard_update_group (dashboard, group);
 }
@@ -2987,7 +2988,7 @@ gimp_dashboard_group_set_active (GimpDashboard *dashboard,
                                            gimp_dashboard_group_action_toggled,
                                            dashboard);
 
-          gtk_toggle_action_set_active (group_data->action, active);
+          gimp_toggle_action_set_active (group_data->action, active);
 
           g_signal_handlers_unblock_by_func (group_data->action,
                                              gimp_dashboard_group_action_toggled,
@@ -4745,7 +4746,7 @@ gimp_dashboard_menu_setup (GimpUIManager *manager,
   g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
   g_return_if_fail (ui_path != NULL);
 
-  merge_id = gtk_ui_manager_new_merge_id (GTK_UI_MANAGER (manager));
+  merge_id = gimp_ui_manager_new_merge_id (manager);
 
   for (group = FIRST_GROUP; group < N_GROUPS; group++)
     {
@@ -4756,10 +4757,10 @@ gimp_dashboard_menu_setup (GimpUIManager *manager,
       action_name = g_strdup_printf ("dashboard-group-%s", group_info->name);
       action_path = g_strdup_printf ("%s/Groups/Groups", ui_path);
 
-      gtk_ui_manager_add_ui (GTK_UI_MANAGER (manager), merge_id,
-                             action_path, action_name, action_name,
-                             GTK_UI_MANAGER_MENUITEM,
-                             FALSE);
+      gimp_ui_manager_add_ui (manager, merge_id,
+                              action_path, action_name, action_name,
+                              GTK_UI_MANAGER_MENUITEM,
+                              FALSE);
 
       g_free (action_name);
       g_free (action_path);
diff --git a/app/widgets/gimpdockbook.c b/app/widgets/gimpdockbook.c
index 283d660a0f..2c7485b8c7 100644
--- a/app/widgets/gimpdockbook.c
+++ b/app/widgets/gimpdockbook.c
@@ -35,6 +35,7 @@
 #include "core/gimpcontext.h"
 #include "core/gimpmarshal.h"
 
+#include "gimpactiongroup.h"
 #include "gimpdialogfactory.h"
 #include "gimpdnd.h"
 #include "gimpdock.h"
@@ -466,14 +467,14 @@ gimp_dockbook_menu_position (GtkMenu  *menu,
 static gboolean
 gimp_dockbook_show_menu (GimpDockbook *dockbook)
 {
-  GimpUIManager *dockbook_ui_manager = NULL;
-  GimpUIManager *dialog_ui_manager   = NULL;
-  const gchar   *dialog_ui_path      = NULL;
-  gpointer       dialog_popup_data   = FALSE;
-  GtkWidget     *parent_menu_widget  = NULL;
-  GtkAction     *parent_menu_action  = NULL;
-  GimpDockable  *dockable            = NULL;
-  gint           page_num            = -1;
+  GimpUIManager *dockbook_ui_manager;
+  GimpUIManager *dialog_ui_manager;
+  const gchar   *dialog_ui_path;
+  gpointer       dialog_popup_data;
+  GtkWidget     *parent_menu_widget;
+  GimpAction    *parent_menu_action;
+  GimpDockable  *dockable;
+  gint           page_num;
 
   dockbook_ui_manager = gimp_dockbook_get_ui_manager (dockbook);
 
@@ -481,11 +482,11 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook)
     return FALSE;
 
   parent_menu_widget =
-    gtk_ui_manager_get_widget (GTK_UI_MANAGER (dockbook_ui_manager),
-                               "/dockable-popup/dockable-menu");
+    gimp_ui_manager_get_widget (dockbook_ui_manager,
+                                "/dockable-popup/dockable-menu");
   parent_menu_action =
-    gtk_ui_manager_get_action (GTK_UI_MANAGER (dockbook_ui_manager),
-                               "/dockable-popup/dockable-menu");
+    gimp_ui_manager_get_action (dockbook_ui_manager,
+                                "/dockable-popup/dockable-menu");
 
   if (! parent_menu_widget || ! parent_menu_action)
     return FALSE;
@@ -503,13 +504,12 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook)
 
   if (dialog_ui_manager && dialog_ui_path)
     {
-      GtkWidget *child_menu_widget;
-      GtkAction *child_menu_action;
-      gchar     *label;
+      GtkWidget  *child_menu_widget;
+      GimpAction *child_menu_action;
+      gchar      *label;
 
       child_menu_widget =
-        gtk_ui_manager_get_widget (GTK_UI_MANAGER (dialog_ui_manager),
-                                   dialog_ui_path);
+        gimp_ui_manager_get_widget (dialog_ui_manager, dialog_ui_path);
 
       if (! child_menu_widget)
         {
@@ -519,8 +519,8 @@ gimp_dockbook_show_menu (GimpDockbook *dockbook)
         }
 
       child_menu_action =
-        gtk_ui_manager_get_action (GTK_UI_MANAGER (dialog_ui_manager),
-                                   dialog_ui_path);
+        gimp_ui_manager_get_action (dialog_ui_manager,
+                                    dialog_ui_path);
 
       if (! child_menu_action)
         {
@@ -600,8 +600,7 @@ gimp_dockbook_menu_end (GimpDockable *dockable)
   if (dialog_ui_manager && dialog_ui_path)
     {
       GtkWidget *child_menu_widget =
-        gtk_ui_manager_get_widget (GTK_UI_MANAGER (dialog_ui_manager),
-                                   dialog_ui_path);
+        gimp_ui_manager_get_widget (dialog_ui_manager, dialog_ui_path);
 
       if (child_menu_widget)
         gtk_menu_detach (GTK_MENU (child_menu_widget));
@@ -1109,7 +1108,7 @@ gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
 {
   GtkWidget      *tab_widget;
   GimpDockWindow *dock_window;
-  GtkAction      *action = NULL;
+  GimpAction     *action = NULL;
 
   tab_widget =
     gimp_dockable_create_event_box_tab_widget (dockable,
@@ -1142,7 +1141,7 @@ gimp_dockbook_create_tab_widget (GimpDockbook *dockbook,
               GList *actions;
               GList *list;
 
-              actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
+              actions = gimp_action_group_list_actions (group);
 
               for (list = actions; list; list = g_list_next (list))
                 {
diff --git a/app/widgets/gimpdockwindow.c b/app/widgets/gimpdockwindow.c
index 18ad2fc4ae..e8d955609c 100644
--- a/app/widgets/gimpdockwindow.c
+++ b/app/widgets/gimpdockwindow.c
@@ -325,8 +325,7 @@ gimp_dock_window_constructed (GObject *object)
                                    dock_window->p->ui_manager_name,
                                    dock_window,
                                    config->tearoff_menus);
-  accel_group =
-    gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (dock_window->p->ui_manager));
+  accel_group = gimp_ui_manager_get_accel_group (dock_window->p->ui_manager);
   gtk_window_add_accel_group (GTK_WINDOW (dock_window), accel_group);
 
   g_signal_connect_object (dock_window->p->context, "display-changed",
diff --git a/app/widgets/gimpeditor.c b/app/widgets/gimpeditor.c
index f79fc9c1df..47a866a36c 100644
--- a/app/widgets/gimpeditor.c
+++ b/app/widgets/gimpeditor.c
@@ -31,11 +31,14 @@
 
 #include "core/gimp.h"
 
+#include "gimpaction.h"
+#include "gimpactiongroup.h"
 #include "gimpdocked.h"
 #include "gimpeditor.h"
 #include "gimpdnd.h"
 #include "gimphighlightablebutton.h"
 #include "gimpmenufactory.h"
+#include "gimptoggleaction.h"
 #include "gimpuimanager.h"
 #include "gimpwidgets-utils.h"
 
@@ -582,7 +585,7 @@ gimp_editor_add_icon_box (GimpEditor  *editor,
 typedef struct
 {
   GdkModifierType  mod_mask;
-  GtkAction       *action;
+  GimpAction      *action;
 } ExtendedAction;
 
 static void
@@ -609,9 +612,9 @@ gimp_editor_button_extended_clicked (GtkWidget       *button,
       ExtendedAction *ext = list->data;
 
       if ((ext->mod_mask & mask) == ext->mod_mask &&
-          gtk_action_get_sensitive (ext->action))
+          gimp_action_get_sensitive (ext->action))
         {
-          gtk_action_activate (ext->action);
+          gimp_action_activate (ext->action);
           break;
         }
     }
@@ -624,7 +627,7 @@ gimp_editor_add_action_button (GimpEditor  *editor,
                                ...)
 {
   GimpActionGroup *group;
-  GtkAction       *action;
+  GimpAction      *action;
   GtkWidget       *button;
   GtkWidget       *old_child;
   GtkWidget       *image;
@@ -645,22 +648,21 @@ gimp_editor_add_action_button (GimpEditor  *editor,
 
   g_return_val_if_fail (group != NULL, NULL);
 
-  action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                        action_name);
+  action = gimp_action_group_get_action (group, action_name);
 
   g_return_val_if_fail (action != NULL, NULL);
 
   button_icon_size = gimp_editor_ensure_button_box (editor, &button_relief);
 
-  if (GTK_IS_TOGGLE_ACTION (action))
+  if (GIMP_IS_TOGGLE_ACTION (action))
     button = gtk_toggle_button_new ();
   else
     button = gimp_highlightable_button_new ();
 
   gtk_button_set_relief (GTK_BUTTON (button), button_relief);
 
-  icon_name = gtk_action_get_icon_name (action);
-  tooltip   = g_strdup (gtk_action_get_tooltip (action));
+  icon_name = gimp_action_get_icon_name (action);
+  tooltip   = g_strdup (gimp_action_get_tooltip (action));
   help_id   = g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID);
 
   old_child = gtk_bin_get_child (GTK_BIN (button));
@@ -672,7 +674,8 @@ gimp_editor_add_action_button (GimpEditor  *editor,
   gtk_container_add (GTK_CONTAINER (button), image);
   gtk_widget_show (image);
 
-  gtk_activatable_set_related_action (GTK_ACTIVATABLE (button), action);
+  gtk_activatable_set_related_action (GTK_ACTIVATABLE (button),
+                                      GTK_ACTION (action));
   gtk_box_pack_start (GTK_BOX (editor->priv->button_box), button,
                       TRUE, TRUE, 0);
   gtk_widget_show (button);
@@ -687,8 +690,7 @@ gimp_editor_add_action_button (GimpEditor  *editor,
 
       mod_mask = va_arg (args, GdkModifierType);
 
-      action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                            action_name);
+      action = gimp_action_group_get_action (group, action_name);
 
       if (action && mod_mask)
         {
@@ -701,7 +703,7 @@ gimp_editor_add_action_button (GimpEditor  *editor,
 
           if (tooltip)
             {
-              const gchar *ext_tooltip = gtk_action_get_tooltip (action);
+              const gchar *ext_tooltip = gimp_action_get_tooltip (action);
 
               if (ext_tooltip)
                 {
diff --git a/app/widgets/gimpenumaction.c b/app/widgets/gimpenumaction.c
index 67421cde42..a0f6a82265 100644
--- a/app/widgets/gimpenumaction.c
+++ b/app/widgets/gimpenumaction.c
@@ -26,6 +26,7 @@
 
 #include "core/gimpmarshal.h"
 
+#include "gimpaction.h"
 #include "gimpenumaction.h"
 
 
@@ -55,7 +56,8 @@ static void   gimp_enum_action_get_property (GObject      *object,
 static void   gimp_enum_action_activate     (GtkAction    *action);
 
 
-G_DEFINE_TYPE (GimpEnumAction, gimp_enum_action, GIMP_TYPE_ACTION)
+G_DEFINE_TYPE (GimpEnumAction, gimp_enum_action, GIMP_TYPE_ACTION_IMPL)
+
 
 #define parent_class gimp_enum_action_parent_class
 
@@ -99,8 +101,6 @@ gimp_enum_action_class_init (GimpEnumActionClass *klass)
 static void
 gimp_enum_action_init (GimpEnumAction *action)
 {
-  action->value          = 0;
-  action->value_variable = FALSE;
 }
 
 static void
@@ -152,17 +152,24 @@ gimp_enum_action_new (const gchar *name,
                       const gchar *label,
                       const gchar *tooltip,
                       const gchar *icon_name,
+                      const gchar *help_id,
                       gint         value,
                       gboolean     value_variable)
 {
-  return g_object_new (GIMP_TYPE_ENUM_ACTION,
-                       "name",           name,
-                       "label",          label,
-                       "tooltip",        tooltip,
-                       "icon-name",      icon_name,
-                       "value",          value,
-                       "value-variable", value_variable,
-                       NULL);
+  GimpEnumAction *action;
+
+  action = g_object_new (GIMP_TYPE_ENUM_ACTION,
+                         "name",           name,
+                         "label",          label,
+                         "tooltip",        tooltip,
+                         "icon-name",      icon_name,
+                         "value",          value,
+                         "value-variable", value_variable,
+                         NULL);
+
+  gimp_action_set_help_id (GIMP_ACTION (action), help_id);
+
+  return action;
 }
 
 static void
diff --git a/app/widgets/gimpenumaction.h b/app/widgets/gimpenumaction.h
index 6afdf9b50f..6a350902cf 100644
--- a/app/widgets/gimpenumaction.h
+++ b/app/widgets/gimpenumaction.h
@@ -22,7 +22,7 @@
 #define __GIMP_ENUM_ACTION_H__
 
 
-#include "gimpaction.h"
+#include "gimpactionimpl.h"
 
 
 #define GIMP_TYPE_ENUM_ACTION            (gimp_enum_action_get_type ())
@@ -37,7 +37,7 @@ typedef struct _GimpEnumActionClass GimpEnumActionClass;
 
 struct _GimpEnumAction
 {
-  GimpAction parent_instance;
+  GimpActionImpl parent_instance;
 
   gint       value;
   gboolean   value_variable;
@@ -45,7 +45,7 @@ struct _GimpEnumAction
 
 struct _GimpEnumActionClass
 {
-  GimpActionClass parent_class;
+  GimpActionImplClass parent_class;
 
   void (* selected) (GimpEnumAction *action,
                      gint            value);
@@ -58,8 +58,10 @@ GimpEnumAction * gimp_enum_action_new      (const gchar    *name,
                                             const gchar    *label,
                                             const gchar    *tooltip,
                                             const gchar    *icon_name,
+                                            const gchar    *help_id,
                                             gint            value,
                                             gboolean        value_variable);
+
 void             gimp_enum_action_selected (GimpEnumAction *action,
                                             gint            value);
 
diff --git a/app/widgets/gimpitemtreeview.c b/app/widgets/gimpitemtreeview.c
index 04c4b4f06f..ad6f66f3d0 100644
--- a/app/widgets/gimpitemtreeview.c
+++ b/app/widgets/gimpitemtreeview.c
@@ -45,6 +45,7 @@
 
 #include "vectors/gimpvectors.h"
 
+#include "gimpaction.h"
 #include "gimpcontainertreestore.h"
 #include "gimpcontainerview.h"
 #include "gimpdnd.h"
@@ -1219,7 +1220,7 @@ gimp_item_tree_view_new_dropped (GtkWidget    *widget,
   if (item_view_class->new_default_action &&
       viewable && gimp_container_view_lookup (view, viewable))
     {
-      GtkAction *action;
+      GimpAction *action;
 
       action = gimp_ui_manager_find_action (gimp_editor_get_ui_manager (GIMP_EDITOR (view)),
                                             item_view_class->action_group,
@@ -1228,7 +1229,7 @@ gimp_item_tree_view_new_dropped (GtkWidget    *widget,
       if (action)
         {
           g_object_set (action, "viewable", viewable, NULL);
-          gtk_action_activate (action);
+          gimp_action_activate (action);
           g_object_set (action, "viewable", NULL, NULL);
         }
     }
diff --git a/app/widgets/gimpmenufactory.c b/app/widgets/gimpmenufactory.c
index a26201cd05..d7bfc477b4 100644
--- a/app/widgets/gimpmenufactory.c
+++ b/app/widgets/gimpmenufactory.c
@@ -31,7 +31,9 @@
 
 #include "core/gimp.h"
 
+#include "gimpaction.h"
 #include "gimpactionfactory.h"
+#include "gimpactiongroup.h"
 #include "gimpmenufactory.h"
 #include "gimpuimanager.h"
 
@@ -190,11 +192,11 @@ gimp_menu_factory_get_registered_menus (GimpMenuFactory *factory)
 
 static void
 gimp_menu_factory_manager_action_added (GimpActionGroup *group,
-                                        GtkAction       *action,
+                                        GimpAction      *action,
                                         GtkAccelGroup   *accel_group)
 {
-  gtk_action_set_accel_group (action, accel_group);
-  gtk_action_connect_accelerator (action);
+  gimp_action_set_accel_group (action, accel_group);
+  gimp_action_connect_accelerator (action);
 }
 
 GimpUIManager *
@@ -222,7 +224,7 @@ gimp_menu_factory_manager_new (GimpMenuFactory *factory,
           gtk_ui_manager_set_add_tearoffs (GTK_UI_MANAGER (manager),
                                            create_tearoff);
 
-          accel_group = gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (manager));
+          accel_group = gimp_ui_manager_get_accel_group (manager);
 
           for (list = entry->action_groups; list; list = g_list_next (list))
             {
@@ -234,14 +236,14 @@ gimp_menu_factory_manager_new (GimpMenuFactory *factory,
                                                      (const gchar *) list->data,
                                                      callback_data);
 
-              actions = gtk_action_group_list_actions (GTK_ACTION_GROUP (group));
+              actions = gimp_action_group_list_actions (group);
 
               for (list2 = actions; list2; list2 = g_list_next (list2))
                 {
-                  GtkAction *action = list2->data;
+                  GimpAction *action = list2->data;
 
-                  gtk_action_set_accel_group (action, accel_group);
-                  gtk_action_connect_accelerator (action);
+                  gimp_action_set_accel_group (action, accel_group);
+                  gimp_action_connect_accelerator (action);
                 }
 
               g_list_free (actions);
@@ -250,10 +252,7 @@ gimp_menu_factory_manager_new (GimpMenuFactory *factory,
                                        G_CALLBACK (gimp_menu_factory_manager_action_added),
                                        accel_group, 0);
 
-              gtk_ui_manager_insert_action_group (GTK_UI_MANAGER (manager),
-                                                  GTK_ACTION_GROUP (group),
-                                                  -1);
-
+              gimp_ui_manager_insert_action_group (manager, group, -1);
               g_object_unref (group);
             }
 
diff --git a/app/widgets/gimpprocedureaction.c b/app/widgets/gimpprocedureaction.c
index b70d561392..f0ee7aa9b5 100644
--- a/app/widgets/gimpprocedureaction.c
+++ b/app/widgets/gimpprocedureaction.c
@@ -29,6 +29,7 @@
 
 #include "pdb/gimpprocedure.h"
 
+#include "gimpaction.h"
 #include "gimpprocedureaction.h"
 
 
@@ -60,7 +61,8 @@ static void   gimp_procedure_action_connect_proxy (GtkAction    *action,
                                                    GtkWidget    *proxy);
 
 
-G_DEFINE_TYPE (GimpProcedureAction, gimp_procedure_action, GIMP_TYPE_ACTION)
+G_DEFINE_TYPE (GimpProcedureAction, gimp_procedure_action,
+               GIMP_TYPE_ACTION_IMPL)
 
 #define parent_class gimp_procedure_action_parent_class
 
@@ -100,7 +102,6 @@ gimp_procedure_action_class_init (GimpProcedureActionClass *klass)
 static void
 gimp_procedure_action_init (GimpProcedureAction *action)
 {
-  action->procedure = NULL;
 }
 
 static void
@@ -223,15 +224,22 @@ gimp_procedure_action_new (const gchar   *name,
                            const gchar   *label,
                            const gchar   *tooltip,
                            const gchar   *icon_name,
+                           const gchar   *help_id,
                            GimpProcedure *procedure)
 {
-  return g_object_new (GIMP_TYPE_PROCEDURE_ACTION,
-                       "name",       name,
-                       "label",      label,
-                       "tooltip",    tooltip,
-                       "icon-name",  icon_name,
-                       "procedure",  procedure,
-                       NULL);
+  GimpProcedureAction *action;
+
+  action = g_object_new (GIMP_TYPE_PROCEDURE_ACTION,
+                         "name",       name,
+                         "label",      label,
+                         "tooltip",    tooltip,
+                         "icon-name",  icon_name,
+                         "procedure",  procedure,
+                         NULL);
+
+  gimp_action_set_help_id (GIMP_ACTION (action), help_id);
+
+  return action;
 }
 
 void
diff --git a/app/widgets/gimpprocedureaction.h b/app/widgets/gimpprocedureaction.h
index a882bc3648..77f97ff449 100644
--- a/app/widgets/gimpprocedureaction.h
+++ b/app/widgets/gimpprocedureaction.h
@@ -22,7 +22,7 @@
 #define __GIMP_PROCEDURE_ACTION_H__
 
 
-#include "gimpaction.h"
+#include "gimpactionimpl.h"
 
 
 #define GIMP_TYPE_PROCEDURE_ACTION            (gimp_procedure_action_get_type ())
@@ -37,14 +37,14 @@ typedef struct _GimpProcedureActionClass GimpProcedureActionClass;
 
 struct _GimpProcedureAction
 {
-  GimpAction     parent_instance;
+  GimpActionImpl  parent_instance;
 
-  GimpProcedure *procedure;
+  GimpProcedure  *procedure;
 };
 
 struct _GimpProcedureActionClass
 {
-  GimpActionClass parent_class;
+  GimpActionImplClass parent_class;
 
   void (* selected) (GimpProcedureAction *action,
                      GimpProcedure       *procedure);
@@ -57,7 +57,9 @@ GimpProcedureAction * gimp_procedure_action_new      (const gchar         *name,
                                                       const gchar         *label,
                                                       const gchar         *tooltip,
                                                       const gchar         *icon_name,
+                                                      const gchar         *help_id,
                                                       GimpProcedure       *procedure);
+
 void                  gimp_procedure_action_selected (GimpProcedureAction *action,
                                                       GimpProcedure       *procedure);
 
diff --git a/app/widgets/gimpradioaction.c b/app/widgets/gimpradioaction.c
index fe766d49ca..c48f4c8822 100644
--- a/app/widgets/gimpradioaction.c
+++ b/app/widgets/gimpradioaction.c
@@ -28,19 +28,17 @@
 
 #include "widgets-types.h"
 
+#include "gimpaction.h"
 #include "gimpradioaction.h"
 
 
-static void   gimp_radio_action_connect_proxy     (GtkAction        *action,
-                                                   GtkWidget        *proxy);
-static void   gimp_radio_action_set_proxy_tooltip (GimpRadioAction  *action,
-                                                   GtkWidget        *proxy);
-static void   gimp_radio_action_tooltip_notify    (GimpRadioAction  *action,
-                                                   const GParamSpec *pspec,
-                                                   gpointer          data);
+static void   gimp_radio_action_connect_proxy (GtkAction *action,
+                                               GtkWidget *proxy);
 
 
-G_DEFINE_TYPE (GimpRadioAction, gimp_radio_action, GTK_TYPE_RADIO_ACTION)
+G_DEFINE_TYPE_WITH_CODE (GimpRadioAction, gimp_radio_action,
+                         GTK_TYPE_RADIO_ACTION,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_ACTION, NULL))
 
 #define parent_class gimp_radio_action_parent_class
 
@@ -56,9 +54,7 @@ gimp_radio_action_class_init (GimpRadioActionClass *klass)
 static void
 gimp_radio_action_init (GimpRadioAction *action)
 {
-  g_signal_connect (action, "notify::tooltip",
-                    G_CALLBACK (gimp_radio_action_tooltip_notify),
-                    NULL);
+  gimp_action_init (GIMP_ACTION (action));
 }
 
 static void
@@ -67,7 +63,7 @@ gimp_radio_action_connect_proxy (GtkAction *action,
 {
   GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
 
-  gimp_radio_action_set_proxy_tooltip (GIMP_RADIO_ACTION (action), proxy);
+  gimp_action_set_proxy (GIMP_ACTION (action), proxy);
 }
 
 
@@ -78,6 +74,7 @@ gimp_radio_action_new (const gchar *name,
                        const gchar *label,
                        const gchar *tooltip,
                        const gchar *icon_name,
+                       const gchar *help_id,
                        gint         value)
 {
   GtkRadioAction *action;
@@ -90,36 +87,20 @@ gimp_radio_action_new (const gchar *name,
                          "value",     value,
                          NULL);
 
+  gimp_action_set_help_id (GIMP_ACTION (action), help_id);
+
   return action;
 }
 
-
-/*  private functions  */
-
-
-static void
-gimp_radio_action_set_proxy_tooltip (GimpRadioAction *action,
-                                     GtkWidget       *proxy)
+void
+gimp_radio_action_set_current_value (GimpRadioAction *action,
+                                     gint              value)
 {
-  const gchar *tooltip = gtk_action_get_tooltip (GTK_ACTION (action));
-
-  if (tooltip)
-    gimp_help_set_help_data (proxy, tooltip,
-                             g_object_get_qdata (G_OBJECT (proxy),
-                                                 GIMP_HELP_ID));
+  gtk_radio_action_set_current_value ((GtkRadioAction *) action, value);
 }
 
-static void
-gimp_radio_action_tooltip_notify (GimpRadioAction  *action,
-                                  const GParamSpec *pspec,
-                                  gpointer          data)
+gint
+gimp_radio_action_get_current_value (GimpRadioAction *action)
 {
-  GSList *list;
-
-  for (list = gtk_action_get_proxies (GTK_ACTION (action));
-       list;
-       list = g_slist_next (list))
-    {
-      gimp_radio_action_set_proxy_tooltip (action, list->data);
-    }
+  return gtk_radio_action_get_current_value ((GtkRadioAction *) action);
 }
diff --git a/app/widgets/gimpradioaction.h b/app/widgets/gimpradioaction.h
index 7522c5674a..406be1bf0a 100644
--- a/app/widgets/gimpradioaction.h
+++ b/app/widgets/gimpradioaction.h
@@ -45,13 +45,18 @@ struct _GimpRadioActionClass
 };
 
 
-GType            gimp_radio_action_get_type (void) G_GNUC_CONST;
-
-GtkRadioAction * gimp_radio_action_new      (const gchar *name,
-                                             const gchar *label,
-                                             const gchar *tooltip,
-                                             const gchar *icon_name,
-                                             gint         value);
+GType            gimp_radio_action_get_type          (void) G_GNUC_CONST;
+
+GtkRadioAction * gimp_radio_action_new               (const gchar *name,
+                                                      const gchar *label,
+                                                      const gchar *tooltip,
+                                                      const gchar *icon_name,
+                                                      const gchar *help_id,
+                                                      gint         value);
+
+void             gimp_radio_action_set_current_value (GimpRadioAction *action,
+                                                      gint              value);
+gint             gimp_radio_action_get_current_value (GimpRadioAction *action);
 
 
 #endif  /* __GIMP_RADIO_ACTION_H__ */
diff --git a/app/widgets/gimpsearchpopup.c b/app/widgets/gimpsearchpopup.c
index 5e45ca1e35..fb43477101 100644
--- a/app/widgets/gimpsearchpopup.c
+++ b/app/widgets/gimpsearchpopup.c
@@ -35,6 +35,7 @@
 #include "gimpaction.h"
 #include "gimppopup.h"
 #include "gimpsearchpopup.h"
+#include "gimptoggleaction.h"
 #include "gimpuimanager.h"
 
 #include "gimp-intl.h"
@@ -109,7 +110,7 @@ static void       gimp_search_popup_run_selected         (GimpSearchPopup   *pop
 static void       gimp_search_popup_setup_results        (GtkWidget        **results_list,
                                                           GtkWidget        **list_view);
 
-static gchar    * gimp_search_popup_find_accel_label     (GtkAction         *action);
+static gchar    * gimp_search_popup_find_accel_label     (GimpAction        *action);
 static gboolean   gimp_search_popup_view_accel_find_func (GtkAccelKey       *key,
                                                           GClosure          *closure,
                                                           gpointer           data);
@@ -216,7 +217,7 @@ gimp_search_popup_new (Gimp                    *gimp,
 /**
  * gimp_search_popup_add_result:
  * @popup:   the #GimpSearchPopup.
- * @action:  a #GtkAction to add in results list.
+ * @action:  a #GimpAction to add in results list.
  * @section: the section to add @action.
  *
  * Adds @action in the @popup's results at @section.
@@ -225,7 +226,7 @@ gimp_search_popup_new (Gimp                    *gimp,
  */
 void
 gimp_search_popup_add_result (GimpSearchPopup *popup,
-                              GtkAction       *action,
+                              GimpAction      *action,
                               gint             section)
 {
   GtkTreeIter   iter;
@@ -244,7 +245,7 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
   gchar        *escaped_tooltip = NULL;
   gboolean      has_tooltip  = FALSE;
 
-  label = g_strstrip (gimp_strip_uline (gtk_action_get_label (action)));
+  label = g_strstrip (gimp_strip_uline (gimp_action_get_label (action)));
 
   if (! label || strlen (label) == 0)
     {
@@ -254,16 +255,16 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
 
   escaped_label = g_markup_escape_text (label, -1);
 
-  if (GTK_IS_TOGGLE_ACTION (action))
+  if (GIMP_IS_TOGGLE_ACTION (action))
     {
-      if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
+      if (gimp_toggle_action_get_active (GIMP_TOGGLE_ACTION (action)))
         icon_name = "gtk-ok";
       else
         icon_name = "gtk-no";
     }
   else
     {
-      icon_name = gtk_action_get_icon_name (action);
+      icon_name = gimp_action_get_icon_name (action);
     }
 
   accel_string = gimp_search_popup_find_accel_label (action);
@@ -273,7 +274,7 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
       has_shortcut = TRUE;
     }
 
-  tooltip = gtk_action_get_tooltip (action);
+  tooltip = gimp_action_get_tooltip (action);
   if (tooltip != NULL)
     {
       escaped_tooltip = g_markup_escape_text (tooltip, -1);
@@ -287,7 +288,7 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
                             has_tooltip ? "\n" : "",
                             has_tooltip ? escaped_tooltip : "");
 
-  action_name = g_markup_escape_text (gtk_action_get_name (action), -1);
+  action_name = g_markup_escape_text (gimp_action_get_name (action), -1);
 
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (popup->priv->results_list));
   store = GTK_LIST_STORE (model);
@@ -322,7 +323,7 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
                       COLUMN_TOOLTIP,   action_name,
                       COLUMN_ACTION,    action,
                       COLUMN_SECTION,   section,
-                      COLUMN_SENSITIVE, gtk_action_is_sensitive (action),
+                      COLUMN_SENSITIVE, gimp_action_is_sensitive (action),
                       -1);
 
   g_free (accel_string);
@@ -656,16 +657,16 @@ gimp_search_popup_run_selected (GimpSearchPopup *popup)
 
   if (gtk_tree_selection_get_selected (selection, &model, &iter))
     {
-      GtkAction *action;
+      GimpAction *action;
 
       gtk_tree_model_get (model, &iter, COLUMN_ACTION, &action, -1);
 
-      if (gtk_action_is_sensitive (action))
+      if (gimp_action_is_sensitive (action))
         {
           /* Close the search popup on activation. */
           GIMP_POPUP_CLASS (parent_class)->cancel (GIMP_POPUP (popup));
 
-          gtk_action_activate (action);
+          gimp_action_activate (action);
         }
 
       g_object_unref (action);
@@ -686,7 +687,7 @@ gimp_search_popup_setup_results (GtkWidget **results_list,
                               G_TYPE_STRING,
                               G_TYPE_STRING,
                               G_TYPE_STRING,
-                              GTK_TYPE_ACTION,
+                              GIMP_TYPE_ACTION,
                               G_TYPE_BOOLEAN,
                               G_TYPE_INT);
   *results_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
@@ -721,7 +722,7 @@ gimp_search_popup_setup_results (GtkWidget **results_list,
 }
 
 static gchar *
-gimp_search_popup_find_accel_label (GtkAction *action)
+gimp_search_popup_find_accel_label (GimpAction *action)
 {
   guint            accel_key     = 0;
   GdkModifierType  accel_mask    = 0;
@@ -731,8 +732,8 @@ gimp_search_popup_find_accel_label (GtkAction *action)
   GimpUIManager   *manager;
 
   manager       = gimp_ui_managers_from_name ("<Image>")->data;
-  accel_group   = gtk_ui_manager_get_accel_group (GTK_UI_MANAGER (manager));
-  accel_closure = gtk_action_get_accel_closure (action);
+  accel_group   = gimp_ui_manager_get_accel_group (manager);
+  accel_closure = gimp_action_get_accel_closure (action);
 
   if (accel_closure)
     {
diff --git a/app/widgets/gimpsearchpopup.h b/app/widgets/gimpsearchpopup.h
index c1804d900f..d995115ff0 100644
--- a/app/widgets/gimpsearchpopup.h
+++ b/app/widgets/gimpsearchpopup.h
@@ -68,7 +68,7 @@ GtkWidget * gimp_search_popup_new        (Gimp                    *gimp,
                                           gpointer                 callback_data);
 
 void        gimp_search_popup_add_result (GimpSearchPopup *popup,
-                                          GtkAction       *action,
+                                          GimpAction      *action,
                                           gint             section);
 
 #endif  /*  __GIMP_SEARCH_POPUP_H__  */
diff --git a/app/widgets/gimpstringaction.c b/app/widgets/gimpstringaction.c
index d2c844f253..327d0a5414 100644
--- a/app/widgets/gimpstringaction.c
+++ b/app/widgets/gimpstringaction.c
@@ -26,6 +26,7 @@
 
 #include "core/gimpmarshal.h"
 
+#include "gimpaction.h"
 #include "gimpstringaction.h"
 
 
@@ -55,7 +56,7 @@ static void   gimp_string_action_get_property (GObject      *object,
 static void   gimp_string_action_activate     (GtkAction    *action);
 
 
-G_DEFINE_TYPE (GimpStringAction, gimp_string_action, GIMP_TYPE_ACTION)
+G_DEFINE_TYPE (GimpStringAction, gimp_string_action, GIMP_TYPE_ACTION_IMPL)
 
 #define parent_class gimp_string_action_parent_class
 
@@ -94,7 +95,6 @@ gimp_string_action_class_init (GimpStringActionClass *klass)
 static void
 gimp_string_action_init (GimpStringAction *action)
 {
-  action->value = NULL;
 }
 
 static void
@@ -151,6 +151,7 @@ gimp_string_action_new (const gchar *name,
                         const gchar *label,
                         const gchar *tooltip,
                         const gchar *icon_name,
+                        const gchar *help_id,
                         const gchar *value)
 {
   GimpStringAction *action;
@@ -163,6 +164,8 @@ gimp_string_action_new (const gchar *name,
                          "value",     value,
                          NULL);
 
+  gimp_action_set_help_id (GIMP_ACTION (action), help_id);
+
   return action;
 }
 
diff --git a/app/widgets/gimpstringaction.h b/app/widgets/gimpstringaction.h
index 5edddbf937..63749af7ec 100644
--- a/app/widgets/gimpstringaction.h
+++ b/app/widgets/gimpstringaction.h
@@ -22,7 +22,7 @@
 #define __GIMP_STRING_ACTION_H__
 
 
-#include "gimpaction.h"
+#include "gimpactionimpl.h"
 
 
 #define GIMP_TYPE_STRING_ACTION            (gimp_string_action_get_type ())
@@ -37,14 +37,14 @@ typedef struct _GimpStringActionClass GimpStringActionClass;
 
 struct _GimpStringAction
 {
-  GimpAction  parent_instance;
+  GimpActionImpl  parent_instance;
 
   gchar      *value;
 };
 
 struct _GimpStringActionClass
 {
-  GimpActionClass parent_class;
+  GimpActionImplClass parent_class;
 
   void (* selected) (GimpStringAction *action,
                      const gchar      *value);
@@ -57,7 +57,9 @@ GimpStringAction * gimp_string_action_new      (const gchar      *name,
                                                 const gchar      *label,
                                                 const gchar      *tooltip,
                                                 const gchar      *icon_name,
+                                                const gchar      *help_id,
                                                 const gchar      *value);
+
 void               gimp_string_action_selected (GimpStringAction *action,
                                                 const gchar      *value);
 
diff --git a/app/widgets/gimptexteditor.c b/app/widgets/gimptexteditor.c
index b90fc5dd41..d983b32a70 100644
--- a/app/widgets/gimptexteditor.c
+++ b/app/widgets/gimptexteditor.c
@@ -176,8 +176,8 @@ gimp_text_editor_new (const gchar     *title,
 
   content_area = gtk_dialog_get_content_area (GTK_DIALOG (editor));
 
-  toolbar = gtk_ui_manager_get_widget (GTK_UI_MANAGER (editor->ui_manager),
-                                       "/text-editor-toolbar");
+  toolbar = gimp_ui_manager_get_widget (editor->ui_manager,
+                                        "/text-editor-toolbar");
 
   if (toolbar)
     {
diff --git a/app/widgets/gimptoggleaction.c b/app/widgets/gimptoggleaction.c
index d27b36033a..e8afe46182 100644
--- a/app/widgets/gimptoggleaction.c
+++ b/app/widgets/gimptoggleaction.c
@@ -28,19 +28,17 @@
 
 #include "widgets-types.h"
 
+#include "gimpaction.h"
 #include "gimptoggleaction.h"
 
 
-static void   gimp_toggle_action_connect_proxy     (GtkAction        *action,
-                                                    GtkWidget        *proxy);
-static void   gimp_toggle_action_set_proxy_tooltip (GimpToggleAction *action,
-                                                    GtkWidget        *proxy);
-static void   gimp_toggle_action_tooltip_notify    (GimpToggleAction *action,
-                                                    const GParamSpec *pspec,
-                                                    gpointer          data);
+static void   gimp_toggle_action_connect_proxy (GtkAction *action,
+                                                GtkWidget *proxy);
 
 
-G_DEFINE_TYPE (GimpToggleAction, gimp_toggle_action, GTK_TYPE_TOGGLE_ACTION)
+G_DEFINE_TYPE_WITH_CODE (GimpToggleAction, gimp_toggle_action,
+                         GTK_TYPE_TOGGLE_ACTION,
+                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_ACTION, NULL))
 
 #define parent_class gimp_toggle_action_parent_class
 
@@ -56,9 +54,7 @@ gimp_toggle_action_class_init (GimpToggleActionClass *klass)
 static void
 gimp_toggle_action_init (GimpToggleAction *action)
 {
-  g_signal_connect (action, "notify::tooltip",
-                    G_CALLBACK (gimp_toggle_action_tooltip_notify),
-                    NULL);
+  gimp_action_init (GIMP_ACTION (action));
 }
 
 static void
@@ -67,7 +63,7 @@ gimp_toggle_action_connect_proxy (GtkAction *action,
 {
   GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
 
-  gimp_toggle_action_set_proxy_tooltip (GIMP_TOGGLE_ACTION (action), proxy);
+  gimp_action_set_proxy (GIMP_ACTION (action), proxy);
 }
 
 
@@ -77,7 +73,8 @@ GtkToggleAction *
 gimp_toggle_action_new (const gchar *name,
                         const gchar *label,
                         const gchar *tooltip,
-                        const gchar *icon_name)
+                        const gchar *icon_name,
+                        const gchar *help_id)
 {
   GtkToggleAction *action;
 
@@ -88,36 +85,20 @@ gimp_toggle_action_new (const gchar *name,
                          "icon-name", icon_name,
                          NULL);
 
+  gimp_action_set_help_id (GIMP_ACTION (action), help_id);
+
   return action;
 }
 
-
-/*  private functions  */
-
-
-static void
-gimp_toggle_action_set_proxy_tooltip (GimpToggleAction *action,
-                                      GtkWidget        *proxy)
+void
+gimp_toggle_action_set_active (GimpToggleAction *action,
+                               gboolean          active)
 {
-  const gchar *tooltip = gtk_action_get_tooltip (GTK_ACTION (action));
-
-  if (tooltip)
-    gimp_help_set_help_data (proxy, tooltip,
-                             g_object_get_qdata (G_OBJECT (proxy),
-                                                 GIMP_HELP_ID));
+  return gtk_toggle_action_set_active ((GtkToggleAction *) action, active);
 }
 
-static void
-gimp_toggle_action_tooltip_notify (GimpToggleAction *action,
-                                   const GParamSpec *pspec,
-                                   gpointer          data)
+gboolean
+gimp_toggle_action_get_active (GimpToggleAction *action)
 {
-  GSList *list;
-
-  for (list = gtk_action_get_proxies (GTK_ACTION (action));
-       list;
-       list = g_slist_next (list))
-    {
-      gimp_toggle_action_set_proxy_tooltip (action, list->data);
-    }
+  return gtk_toggle_action_get_active ((GtkToggleAction *) action);
 }
diff --git a/app/widgets/gimptoggleaction.h b/app/widgets/gimptoggleaction.h
index bb41c3a69a..1406e7e895 100644
--- a/app/widgets/gimptoggleaction.h
+++ b/app/widgets/gimptoggleaction.h
@@ -45,12 +45,17 @@ struct _GimpToggleActionClass
 };
 
 
-GType             gimp_toggle_action_get_type (void) G_GNUC_CONST;
+GType             gimp_toggle_action_get_type  (void) G_GNUC_CONST;
 
-GtkToggleAction * gimp_toggle_action_new      (const gchar *name,
-                                               const gchar *label,
-                                               const gchar *tooltip,
-                                               const gchar *icon_name);
+GtkToggleAction * gimp_toggle_action_new       (const gchar *name,
+                                                const gchar *label,
+                                                const gchar *tooltip,
+                                                const gchar *icon_name,
+                                                const gchar *help_id);
+
+void              gimp_toggle_action_set_active (GimpToggleAction *action,
+                                                 gboolean          active);
+gboolean          gimp_toggle_action_get_active (GimpToggleAction *action);
 
 
 #endif  /* __GIMP_TOGGLE_ACTION_H__ */
diff --git a/app/widgets/gimptoolbox-color-area.c b/app/widgets/gimptoolbox-color-area.c
index ab2b72ea03..92db0fd156 100644
--- a/app/widgets/gimptoolbox-color-area.c
+++ b/app/widgets/gimptoolbox-color-area.c
@@ -29,6 +29,7 @@
 #include "core/gimp.h"
 #include "core/gimpcontext.h"
 
+#include "gimpaction.h"
 #include "gimpcolordialog.h"
 #include "gimpdialogfactory.h"
 #include "gimpfgbgeditor.h"
@@ -278,7 +279,7 @@ color_area_tooltip (GimpFgBgEditor *editor,
                     GimpToolbox    *toolbox)
 {
   GimpUIManager *manager = gimp_dock_get_ui_manager (GIMP_DOCK (toolbox));
-  GtkAction     *action  = NULL;
+  GimpAction    *action  = NULL;
   const gchar   *text    = NULL;
 
   switch (target)
@@ -296,13 +297,13 @@ color_area_tooltip (GimpFgBgEditor *editor,
     case GIMP_FG_BG_TARGET_SWAP:
       action = gimp_ui_manager_find_action (manager, "context",
                                             "context-colors-swap");
-      text = gtk_action_get_tooltip (action);
+      text = gimp_action_get_tooltip (action);
       break;
 
     case GIMP_FG_BG_TARGET_DEFAULT:
       action = gimp_ui_manager_find_action (manager, "context",
                                             "context-colors-default");
-      text = gtk_action_get_tooltip (action);
+      text = gimp_action_get_tooltip (action);
       break;
 
     default:
@@ -319,7 +320,7 @@ color_area_tooltip (GimpFgBgEditor *editor,
           GClosure      *accel_closure;
           GtkAccelKey   *accel_key;
 
-          accel_closure = gtk_action_get_accel_closure (action);
+          accel_closure = gimp_action_get_accel_closure (action);
           accel_group   = gtk_accel_group_from_accel_closure (accel_closure);
 
           accel_key = gtk_accel_group_find (accel_group,
diff --git a/app/widgets/gimptooloptionseditor.c b/app/widgets/gimptooloptionseditor.c
index 9e2da813da..c721929cc2 100644
--- a/app/widgets/gimptooloptionseditor.c
+++ b/app/widgets/gimptooloptionseditor.c
@@ -393,8 +393,8 @@ gimp_tool_options_editor_menu_popup (GimpToolOptionsEditor *editor,
 {
   GimpEditor *gimp_editor = GIMP_EDITOR (editor);
 
-  gtk_ui_manager_get_widget (GTK_UI_MANAGER (gimp_editor_get_ui_manager (gimp_editor)),
-                             gimp_editor_get_ui_path (gimp_editor));
+  gimp_ui_manager_get_widget (gimp_editor_get_ui_manager (gimp_editor),
+                              gimp_editor_get_ui_path (gimp_editor));
   gimp_ui_manager_update (gimp_editor_get_ui_manager (gimp_editor),
                           gimp_editor_get_popup_data (gimp_editor));
 
diff --git a/app/widgets/gimptoolpalette.c b/app/widgets/gimptoolpalette.c
index 33fbca4201..f7c6ef670a 100644
--- a/app/widgets/gimptoolpalette.c
+++ b/app/widgets/gimptoolpalette.c
@@ -255,7 +255,7 @@ gimp_tool_palette_hierarchy_changed (GtkWidget *widget,
         {
           GimpToolInfo  *tool_info = list->data;
           GtkToolItem   *item;
-          GtkAction     *action;
+          GimpAction    *action;
           const gchar   *identifier;
           gchar         *tmp;
           gchar         *name;
diff --git a/app/widgets/gimpuimanager.c b/app/widgets/gimpuimanager.c
index fdae2faf68..8e768aa7a3 100644
--- a/app/widgets/gimpuimanager.c
+++ b/app/widgets/gimpuimanager.c
@@ -35,9 +35,11 @@
 #include "core/gimp.h"
 #include "core/gimpmarshal.h"
 
+#include "gimpaction.h"
 #include "gimpactiongroup.h"
 #include "gimphelp.h"
 #include "gimphelp-ids.h"
+#include "gimptoggleaction.h"
 #include "gimpuimanager.h"
 
 #include "gimp-intl.h"
@@ -73,9 +75,9 @@ static void       gimp_ui_manager_get_property        (GObject        *object,
 static void       gimp_ui_manager_connect_proxy       (GtkUIManager   *manager,
                                                        GtkAction      *action,
                                                        GtkWidget      *proxy);
-static GtkWidget *gimp_ui_manager_get_widget          (GtkUIManager   *manager,
+static GtkWidget *gimp_ui_manager_get_widget_impl     (GtkUIManager   *manager,
                                                        const gchar    *path);
-static GtkAction *gimp_ui_manager_get_action          (GtkUIManager   *manager,
+static GtkAction *gimp_ui_manager_get_action_impl     (GtkUIManager   *manager,
                                                        const gchar    *path);
 static void       gimp_ui_manager_real_update         (GimpUIManager  *manager,
                                                        gpointer        update_data);
@@ -133,8 +135,8 @@ gimp_ui_manager_class_init (GimpUIManagerClass *klass)
   object_class->get_property   = gimp_ui_manager_get_property;
 
   manager_class->connect_proxy = gimp_ui_manager_connect_proxy;
-  manager_class->get_widget    = gimp_ui_manager_get_widget;
-  manager_class->get_action    = gimp_ui_manager_get_action;
+  manager_class->get_widget    = gimp_ui_manager_get_widget_impl;
+  manager_class->get_action    = gimp_ui_manager_get_action_impl;
 
   klass->update                = gimp_ui_manager_real_update;
 
@@ -343,8 +345,8 @@ gimp_ui_manager_connect_proxy (GtkUIManager *manager,
 }
 
 static GtkWidget *
-gimp_ui_manager_get_widget (GtkUIManager *manager,
-                            const gchar  *path)
+gimp_ui_manager_get_widget_impl (GtkUIManager *manager,
+                                 const gchar  *path)
 {
   GimpUIManagerUIEntry *entry;
 
@@ -362,8 +364,8 @@ gimp_ui_manager_get_widget (GtkUIManager *manager,
 }
 
 static GtkAction *
-gimp_ui_manager_get_action (GtkUIManager *manager,
-                            const gchar  *path)
+gimp_ui_manager_get_action_impl (GtkUIManager *manager,
+                                 const gchar  *path)
 {
   if (gimp_ui_manager_entry_ensure (GIMP_UI_MANAGER (manager), path))
     return GTK_UI_MANAGER_CLASS (parent_class)->get_action (manager, path);
@@ -377,7 +379,7 @@ gimp_ui_manager_real_update (GimpUIManager *manager,
 {
   GList *list;
 
-  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
+  for (list = gimp_ui_manager_get_action_groups (manager);
        list;
        list = g_list_next (list))
     {
@@ -436,6 +438,16 @@ gimp_ui_manager_update (GimpUIManager *manager,
   g_signal_emit (manager, manager_signals[UPDATE], 0, update_data);
 }
 
+void
+gimp_ui_manager_insert_action_group (GimpUIManager   *manager,
+                                     GimpActionGroup *group,
+                                     gint             pos)
+{
+  gtk_ui_manager_insert_action_group ((GtkUIManager *) manager,
+                                      (GtkActionGroup *) group,
+                                      pos);
+}
+
 GimpActionGroup *
 gimp_ui_manager_get_action_group (GimpUIManager *manager,
                                   const gchar   *name)
@@ -445,26 +457,91 @@ gimp_ui_manager_get_action_group (GimpUIManager *manager,
   g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL);
   g_return_val_if_fail (name != NULL, NULL);
 
-  for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
+  for (list = gimp_ui_manager_get_action_groups (manager);
        list;
        list = g_list_next (list))
     {
       GimpActionGroup *group = list->data;
 
-      if (! strcmp (name, gtk_action_group_get_name (GTK_ACTION_GROUP (group))))
+      if (! strcmp (name, gimp_action_group_get_name (group)))
         return group;
     }
 
   return NULL;
 }
 
-GtkAction *
+GList *
+gimp_ui_manager_get_action_groups (GimpUIManager *manager)
+{
+  return gtk_ui_manager_get_action_groups ((GtkUIManager *) manager);
+}
+
+GtkAccelGroup *
+gimp_ui_manager_get_accel_group (GimpUIManager *manager)
+{
+  return gtk_ui_manager_get_accel_group ((GtkUIManager *) manager);
+}
+
+GtkWidget *
+gimp_ui_manager_get_widget (GimpUIManager *manager,
+                            const gchar   *path)
+{
+  return gtk_ui_manager_get_widget ((GtkUIManager *) manager, path);
+}
+
+gchar *
+gimp_ui_manager_get_ui (GimpUIManager *manager)
+{
+  return gtk_ui_manager_get_ui ((GtkUIManager *) manager);
+}
+
+guint
+gimp_ui_manager_new_merge_id (GimpUIManager *manager)
+{
+  return gtk_ui_manager_new_merge_id ((GtkUIManager *) manager);
+}
+
+void
+gimp_ui_manager_add_ui (GimpUIManager        *manager,
+                        guint                 merge_id,
+                        const gchar          *path,
+                        const gchar          *name,
+                        const gchar          *action,
+                        GtkUIManagerItemType  type,
+                        gboolean              top)
+{
+  gtk_ui_manager_add_ui ((GtkUIManager *) manager, merge_id,
+                         path, name, action, type, top);
+}
+
+void
+gimp_ui_manager_remove_ui (GimpUIManager *manager,
+                           guint          merge_id)
+{
+  gtk_ui_manager_remove_ui ((GtkUIManager *) manager, merge_id);
+}
+
+void
+gimp_ui_manager_ensure_update (GimpUIManager *manager)
+{
+  gtk_ui_manager_ensure_update ((GtkUIManager *) manager);
+}
+
+GimpAction *
+gimp_ui_manager_get_action (GimpUIManager *manager,
+                            const gchar   *path)
+{
+  return (GimpAction *) gtk_ui_manager_get_action ((GtkUIManager *) manager,
+                                                   path);
+}
+
+GimpAction *
 gimp_ui_manager_find_action (GimpUIManager *manager,
                              const gchar   *group_name,
                              const gchar   *action_name)
 {
   GimpActionGroup *group;
-  GtkAction       *action = NULL;
+  GimpAction      *action = NULL;
 
   g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), NULL);
   g_return_val_if_fail (action_name != NULL, NULL);
@@ -474,21 +551,19 @@ gimp_ui_manager_find_action (GimpUIManager *manager,
       group = gimp_ui_manager_get_action_group (manager, group_name);
 
       if (group)
-        action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                              action_name);
+        action = gimp_action_group_get_action (group, action_name);
     }
   else
     {
       GList *list;
 
-      for (list = gtk_ui_manager_get_action_groups (GTK_UI_MANAGER (manager));
+      for (list = gimp_ui_manager_get_action_groups (manager);
            list;
            list = g_list_next (list))
         {
           group = list->data;
 
-          action = gtk_action_group_get_action (GTK_ACTION_GROUP (group),
-                                                action_name);
+          action = gimp_action_group_get_action (group, action_name);
 
           if (action)
             break;
@@ -503,7 +578,7 @@ gimp_ui_manager_activate_action (GimpUIManager *manager,
                                  const gchar   *group_name,
                                  const gchar   *action_name)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), FALSE);
   g_return_val_if_fail (action_name != NULL, FALSE);
@@ -511,7 +586,7 @@ gimp_ui_manager_activate_action (GimpUIManager *manager,
   action = gimp_ui_manager_find_action (manager, group_name, action_name);
 
   if (action)
-    gtk_action_activate (action);
+    gimp_action_activate (action);
 
   return (action != NULL);
 }
@@ -522,18 +597,18 @@ gimp_ui_manager_toggle_action (GimpUIManager *manager,
                                const gchar   *action_name,
                                gboolean       active)
 {
-  GtkAction *action;
+  GimpAction *action;
 
   g_return_val_if_fail (GIMP_IS_UI_MANAGER (manager), FALSE);
   g_return_val_if_fail (action_name != NULL, FALSE);
 
   action = gimp_ui_manager_find_action (manager, group_name, action_name);
 
-  if (GTK_IS_TOGGLE_ACTION (action))
-    gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
-                                  active ? TRUE : FALSE);
+  if (GIMP_IS_TOGGLE_ACTION (action))
+    gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action),
+                                   active ? TRUE : FALSE);
 
-  return GTK_IS_TOGGLE_ACTION (action);
+  return GIMP_IS_TOGGLE_ACTION (action);
 }
 
 void
@@ -593,7 +668,7 @@ gimp_ui_manager_ui_popup (GimpUIManager        *manager,
   g_return_if_fail (ui_path != NULL);
   g_return_if_fail (parent == NULL || GTK_IS_WIDGET (parent));
 
-  widget = gtk_ui_manager_get_widget (GTK_UI_MANAGER (manager), ui_path);
+  widget = gimp_ui_manager_get_widget (manager, ui_path);
 
   if (GTK_IS_MENU_ITEM (widget))
     widget = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget));
@@ -948,7 +1023,7 @@ gimp_ui_manager_menu_item_select (GtkWidget     *widget,
 
   if (action)
     {
-      const gchar *tooltip = gtk_action_get_tooltip (action);
+      const gchar *tooltip = gimp_action_get_tooltip (GIMP_ACTION (action));
 
       if (tooltip)
         g_signal_emit (manager, manager_signals[SHOW_TOOLTIP], 0, tooltip);
diff --git a/app/widgets/gimpuimanager.h b/app/widgets/gimpuimanager.h
index f4098b33b9..a0cb2f03bb 100644
--- a/app/widgets/gimpuimanager.h
+++ b/app/widgets/gimpuimanager.h
@@ -80,10 +80,37 @@ GList         * gimp_ui_managers_from_name  (const gchar            *name);
 
 void            gimp_ui_manager_update      (GimpUIManager          *manager,
                                              gpointer                update_data);
-GimpActionGroup * gimp_ui_manager_get_action_group (GimpUIManager   *manager,
-                                                    const gchar     *name);
 
-GtkAction     * gimp_ui_manager_find_action     (GimpUIManager      *manager,
+void            gimp_ui_manager_insert_action_group (GimpUIManager   *manager,
+                                                     GimpActionGroup *group,
+                                                     gint             pos);
+GimpActionGroup * gimp_ui_manager_get_action_group  (GimpUIManager   *manager,
+                                                     const gchar     *name);
+GList         * gimp_ui_manager_get_action_groups   (GimpUIManager   *manager);
+
+GtkAccelGroup * gimp_ui_manager_get_accel_group (GimpUIManager      *manager);
+
+GtkWidget     * gimp_ui_manager_get_widget      (GimpUIManager      *manager,
+                                                 const gchar        *path);
+
+gchar          * gimp_ui_manager_get_ui         (GimpUIManager      *manager);
+
+guint            gimp_ui_manager_new_merge_id   (GimpUIManager      *manager);
+void             gimp_ui_manager_add_ui         (GimpUIManager      *manager,
+                                                 guint               merge_id,
+                                                 const gchar        *path,
+                                                 const gchar        *name,
+                                                 const gchar        *action,
+                                                 GtkUIManagerItemType type,
+                                                 gboolean            top);
+void            gimp_ui_manager_remove_ui       (GimpUIManager      *manager,
+                                                 guint               merge_id);
+
+void            gimp_ui_manager_ensure_update   (GimpUIManager      *manager);
+
+GimpAction    * gimp_ui_manager_get_action      (GimpUIManager      *manager,
+                                                 const gchar        *path);
+GimpAction    * gimp_ui_manager_find_action     (GimpUIManager      *manager,
                                                  const gchar        *group_name,
                                                  const gchar        *action_name);
 gboolean        gimp_ui_manager_activate_action (GimpUIManager      *manager,
diff --git a/app/widgets/gimpwidgets-utils.c b/app/widgets/gimpwidgets-utils.c
index a460fa938d..ce821ab228 100644
--- a/app/widgets/gimpwidgets-utils.c
+++ b/app/widgets/gimpwidgets-utils.c
@@ -47,6 +47,7 @@
 
 #include "gegl/gimp-babl.h"
 
+#include "gimpaction.h"
 #include "gimpdialogfactory.h"
 #include "gimpdock.h"
 #include "gimpdockcontainer.h"
@@ -1099,15 +1100,15 @@ gimp_widget_accel_changed (GtkAccelGroup   *accel_group,
 
   if (accel_closure == widget_closure)
     {
-      GtkAction   *action;
+      GimpAction  *action;
       GtkAccelKey *accel_key;
       const gchar *tooltip;
       const gchar *help_id;
 
       action = g_object_get_data (G_OBJECT (widget), "gimp-accel-action");
 
-      tooltip = gtk_action_get_tooltip (action);
-      help_id = g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID);
+      tooltip = gimp_action_get_tooltip (action);
+      help_id = gimp_action_get_help_id (action);
 
       accel_key = gtk_accel_group_find (accel_group,
                                         gimp_widget_accel_find_func,
@@ -1159,8 +1160,8 @@ gimp_accel_help_widget_weak_notify (gpointer  accel_group,
 }
 
 void
-gimp_widget_set_accel_help (GtkWidget *widget,
-                            GtkAction *action)
+gimp_widget_set_accel_help (GtkWidget  *widget,
+                            GimpAction *action)
 {
   GtkAccelGroup *accel_group;
   GClosure      *accel_closure;
@@ -1181,7 +1182,7 @@ gimp_widget_set_accel_help (GtkWidget *widget,
       g_object_set_data (G_OBJECT (widget), "gimp-accel-group", NULL);
     }
 
-  accel_closure = gtk_action_get_accel_closure (action);
+  accel_closure = gimp_action_get_accel_closure (action);
 
   if (accel_closure)
     {
@@ -1212,13 +1213,10 @@ gimp_widget_set_accel_help (GtkWidget *widget,
     }
   else
     {
-      const gchar *tooltip;
-      const gchar *help_id;
-
-      tooltip = gtk_action_get_tooltip (action);
-      help_id = g_object_get_qdata (G_OBJECT (action), GIMP_HELP_ID);
+      gimp_help_set_help_data (widget,
+                               gimp_action_get_tooltip (action),
+                               gimp_action_get_help_id (action));
 
-      gimp_help_set_help_data (widget, tooltip, help_id);
     }
 }
 
diff --git a/app/widgets/gimpwidgets-utils.h b/app/widgets/gimpwidgets-utils.h
index 1e5c1ff221..dfdca55001 100644
--- a/app/widgets/gimpwidgets-utils.h
+++ b/app/widgets/gimpwidgets-utils.h
@@ -83,7 +83,7 @@ guint32           gimp_window_get_native_id        (GtkWindow            *window
 void              gimp_window_set_transient_for    (GtkWindow            *window,
                                                     guint32               parent_ID);
 void              gimp_widget_set_accel_help       (GtkWidget            *widget,
-                                                    GtkAction            *action);
+                                                    GimpAction           *action);
 
 const gchar     * gimp_get_message_icon_name       (GimpMessageSeverity   severity);
 gboolean          gimp_get_color_tag_color         (GimpColorTag          color_tag,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]