2006-12-09 21:33:38 +00:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2001-04-15 20:12:16 +00:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2009-01-17 22:28:01 +00:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2001-04-15 20:12:16 +00:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-17 22:28:01 +00:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2001-04-15 20:12:16 +00:00
|
|
|
* (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
|
2018-07-11 23:27:07 +02:00
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
2001-04-15 20:12:16 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2001-11-17 16:32:34 +00:00
|
|
|
#include <stdlib.h>
|
2001-04-15 20:12:16 +00:00
|
|
|
|
2008-10-09 20:24:04 +00:00
|
|
|
#include <gegl.h>
|
2001-04-15 20:12:16 +00:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2001-07-04 19:31:35 +00:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2001-04-15 20:12:16 +00:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
2003-05-23 18:27:05 +00:00
|
|
|
#include "libgimpwidgets/gimpwidgets-private.h"
|
2001-04-15 20:12:16 +00:00
|
|
|
|
2001-10-13 12:52:30 +00:00
|
|
|
#include "gui-types.h"
|
app: cleanup MR !734.
- app_activate_callback() moved with other private functions.
- Removing the `if (app)` test in app_activate_callback() as we don't
set it to NULL anymore. The app variable is always set.
- As a consequence of the previous point, change signature of
app_exit_after_callback() which doesn't have to change the value of
app anymore.
- Don't emit direcly the "exit" signal from app_activate_callback(). We
must call `gimp_exit (gimp, TRUE);` instead, which does more than just
emitting this signal. It also takes care of cleaning any remaining
images without a display. If we don't do this, we are leaking
GeglBuffer when opening images from command lines while quitting
immediately with --quit.
- Get rid of gimp_core_app_set_values() which was completely bypassing
the fact that all the properties of a GimpCoreApp were construct-only.
Instead make these proper properties. I use a trick used in other
interface, creating a gimp_container_view_install_properties() which
is called from child classes.
The point of GimpCoreApp is not just to share a common interface, it's
rather to weakly simulate some kind of multi-inheritance in GObject.
Since we want both GimpApp and GimpConsoleApp to inherit from a same
parent class while we also want them to inherit either from
GtkApplication and GApplication respectively (yet without linking to
GTK in this second case), we are stuck as far as normal GObject
inheritance goes. This is why we use an interface to which we add a
private struct through a GQuark trick. We want the property settings
and function implementations to also be part of this shared code.
- Get rid of all the abstract methods of GimpCoreApp of the form
get_*(). These are useless as we don't expect these to have different
implementation depending on the actual child class. Once again, our
main goal was to simulate multiple inheritance rather than actually
have an interface with various implementations.
- Make "no-splash" a property of GimpApp, because it's cleaner this way.
- Fix gimp_core_app_private_finalize().
- don't use #pragma once, it's not standard. Just use include guards.
- Fix includes: order was wrong, include from the source, not other
headers, etc.
- Clean various other details, coding styles, fix several more bugs and
more…
2022-10-06 20:44:06 +02:00
|
|
|
#include "gimpapp.h"
|
2001-04-15 20:12:16 +00:00
|
|
|
|
2002-11-18 20:50:31 +00:00
|
|
|
#include "config/gimpguiconfig.h"
|
|
|
|
|
2001-07-05 15:34:26 +00:00
|
|
|
#include "core/gimp.h"
|
2001-07-07 18:16:18 +00:00
|
|
|
#include "core/gimpcontainer.h"
|
2001-07-05 15:34:26 +00:00
|
|
|
#include "core/gimpcontext.h"
|
2001-07-07 12:17:23 +00:00
|
|
|
#include "core/gimpimage.h"
|
2004-06-28 13:18:00 +00:00
|
|
|
#include "core/gimptoolinfo.h"
|
2001-07-05 15:34:26 +00:00
|
|
|
|
2006-04-28 22:26:51 +00:00
|
|
|
#include "plug-in/gimpenvirontable.h"
|
|
|
|
#include "plug-in/gimppluginmanager.h"
|
|
|
|
|
2001-09-25 23:23:09 +00:00
|
|
|
#include "display/gimpdisplay.h"
|
2001-10-13 12:52:30 +00:00
|
|
|
#include "display/gimpdisplay-foreach.h"
|
2001-10-31 21:20:09 +00:00
|
|
|
#include "display/gimpdisplayshell.h"
|
2006-03-09 16:06:32 +00:00
|
|
|
#include "display/gimpstatusbar.h"
|
2003-10-02 11:26:26 +00:00
|
|
|
|
|
|
|
#include "tools/gimp-tools.h"
|
2018-11-22 16:17:19 +01:00
|
|
|
#include "tools/gimptool.h"
|
|
|
|
#include "tools/tool_manager.h"
|
2001-09-25 23:23:09 +00:00
|
|
|
|
2019-07-02 03:54:38 +02:00
|
|
|
#include "widgets/gimpaction.h"
|
|
|
|
#include "widgets/gimpactiongroup.h"
|
2014-02-18 20:10:24 +01:00
|
|
|
#include "widgets/gimpaction-history.h"
|
2004-07-07 14:38:23 +00:00
|
|
|
#include "widgets/gimpclipboard.h"
|
2006-11-03 17:28:52 +00:00
|
|
|
#include "widgets/gimpcolorselectorpalette.h"
|
2004-06-15 22:59:26 +00:00
|
|
|
#include "widgets/gimpcontrollers.h"
|
2001-12-07 17:39:51 +00:00
|
|
|
#include "widgets/gimpdevices.h"
|
2001-04-17 16:00:27 +00:00
|
|
|
#include "widgets/gimpdialogfactory.h"
|
2003-11-03 23:24:32 +00:00
|
|
|
#include "widgets/gimpdnd.h"
|
2005-07-19 20:42:14 +00:00
|
|
|
#include "widgets/gimprender.h"
|
2003-05-25 12:13:57 +00:00
|
|
|
#include "widgets/gimphelp.h"
|
2003-08-22 01:42:57 +00:00
|
|
|
#include "widgets/gimphelp-ids.h"
|
2003-01-10 17:55:53 +00:00
|
|
|
#include "widgets/gimpmenufactory.h"
|
2004-08-25 17:58:52 +00:00
|
|
|
#include "widgets/gimpmessagebox.h"
|
2023-09-05 22:35:06 +00:00
|
|
|
#include "widgets/gimpradioaction.h"
|
2003-10-10 15:59:12 +00:00
|
|
|
#include "widgets/gimpsessioninfo.h"
|
2004-04-29 12:52:29 +00:00
|
|
|
#include "widgets/gimpuimanager.h"
|
2001-12-01 21:02:34 +00:00
|
|
|
#include "widgets/gimpwidgets-utils.h"
|
2013-07-20 14:51:13 +09:00
|
|
|
#include "widgets/gimplanguagestore-parser.h"
|
2001-04-17 16:00:27 +00:00
|
|
|
|
2004-04-27 10:23:35 +00:00
|
|
|
#include "actions/actions.h"
|
2008-05-10 16:21:37 +00:00
|
|
|
#include "actions/windows-commands.h"
|
2004-04-20 13:25:55 +00:00
|
|
|
|
2004-05-06 07:41:53 +00:00
|
|
|
#include "menus/menus.h"
|
|
|
|
|
2004-09-13 15:15:23 +00:00
|
|
|
#include "dialogs/dialogs.h"
|
|
|
|
|
2009-10-04 02:09:53 +02:00
|
|
|
#include "gimpuiconfigurer.h"
|
2001-04-15 20:12:16 +00:00
|
|
|
#include "gui.h"
|
2008-07-11 09:40:09 +00:00
|
|
|
#include "gui-unique.h"
|
2003-10-02 11:26:26 +00:00
|
|
|
#include "gui-vtable.h"
|
2015-12-08 14:52:12 -05:00
|
|
|
#include "icon-themes.h"
|
2022-07-26 19:21:56 +02:00
|
|
|
#include "modifiers.h"
|
2001-04-15 20:12:16 +00:00
|
|
|
#include "session.h"
|
2003-10-02 11:26:26 +00:00
|
|
|
#include "splash.h"
|
2003-09-10 23:42:59 +00:00
|
|
|
#include "themes.h"
|
2016-12-28 16:12:33 +01:00
|
|
|
|
2023-10-15 14:14:06 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
#include <windef.h>
|
|
|
|
#include <winbase.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
2007-09-12 16:26:04 +00:00
|
|
|
#ifdef GDK_WINDOWING_QUARTZ
|
2014-09-05 23:18:13 +02:00
|
|
|
#import <AppKit/AppKit.h>
|
2016-12-28 16:12:33 +01:00
|
|
|
|
|
|
|
/* Forward declare since we are building against old SDKs. */
|
|
|
|
#if !defined(MAC_OS_X_VERSION_10_12) || \
|
|
|
|
MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12
|
|
|
|
|
|
|
|
@interface NSWindow(ForwardDeclarations)
|
|
|
|
+ (void)setAllowsAutomaticWindowTabbing:(BOOL)allow;
|
|
|
|
@end
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2007-09-12 16:26:04 +00:00
|
|
|
#endif /* GDK_WINDOWING_QUARTZ */
|
2001-04-15 20:12:16 +00:00
|
|
|
|
2003-03-25 16:38:19 +00:00
|
|
|
#include "gimp-intl.h"
|
2001-04-15 20:12:16 +00:00
|
|
|
|
|
|
|
|
2001-07-05 15:34:26 +00:00
|
|
|
/* local function prototypes */
|
2001-04-15 20:12:16 +00:00
|
|
|
|
2004-07-12 13:22:28 +00:00
|
|
|
static gchar * gui_sanity_check (void);
|
2003-10-02 11:26:26 +00:00
|
|
|
static void gui_help_func (const gchar *help_id,
|
|
|
|
gpointer help_data);
|
|
|
|
static gboolean gui_get_background_func (GimpRGB *color);
|
|
|
|
static gboolean gui_get_foreground_func (GimpRGB *color);
|
|
|
|
|
|
|
|
static void gui_initialize_after_callback (Gimp *gimp,
|
|
|
|
GimpInitStatusFunc callback);
|
|
|
|
|
|
|
|
static void gui_restore_callback (Gimp *gimp,
|
2003-11-13 14:14:20 +00:00
|
|
|
GimpInitStatusFunc callback);
|
2003-10-02 11:26:26 +00:00
|
|
|
static void gui_restore_after_callback (Gimp *gimp,
|
2003-11-13 14:14:20 +00:00
|
|
|
GimpInitStatusFunc callback);
|
2003-10-02 11:26:26 +00:00
|
|
|
|
|
|
|
static gboolean gui_exit_callback (Gimp *gimp,
|
2003-11-30 16:05:56 +00:00
|
|
|
gboolean force);
|
2003-10-02 11:26:26 +00:00
|
|
|
static gboolean gui_exit_after_callback (Gimp *gimp,
|
2003-11-30 16:05:56 +00:00
|
|
|
gboolean force);
|
2003-10-02 11:26:26 +00:00
|
|
|
|
2004-10-04 16:21:52 +00:00
|
|
|
static void gui_show_help_button_notify (GimpGuiConfig *gui_config,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
Gimp *gimp);
|
2009-02-26 22:58:19 +00:00
|
|
|
static void gui_user_manual_notify (GimpGuiConfig *gui_config,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
Gimp *gimp);
|
2009-10-04 02:09:53 +02:00
|
|
|
static void gui_single_window_mode_notify (GimpGuiConfig *gui_config,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
GimpUIConfigurer *ui_configurer);
|
2003-10-02 11:26:26 +00:00
|
|
|
|
2016-09-17 17:39:54 +02:00
|
|
|
static void gui_clipboard_changed (Gimp *gimp);
|
2005-09-21 14:35:51 +00:00
|
|
|
|
2006-03-09 16:06:32 +00:00
|
|
|
static void gui_menu_show_tooltip (GimpUIManager *manager,
|
|
|
|
const gchar *tooltip,
|
|
|
|
Gimp *gimp);
|
|
|
|
static void gui_menu_hide_tooltip (GimpUIManager *manager,
|
|
|
|
Gimp *gimp);
|
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
static void gui_display_changed (GimpContext *context,
|
|
|
|
GimpDisplay *display,
|
|
|
|
Gimp *gimp);
|
2001-07-05 15:34:26 +00:00
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
static void gui_check_unique_accelerators (Gimp *gimp);
|
2016-11-21 16:52:52 +01:00
|
|
|
|
2001-07-05 15:34:26 +00:00
|
|
|
|
2001-07-07 18:16:18 +00:00
|
|
|
/* private variables */
|
|
|
|
|
2009-10-04 02:09:53 +02:00
|
|
|
static Gimp *the_gui_gimp = NULL;
|
|
|
|
static GimpUIConfigurer *ui_configurer = NULL;
|
2018-04-29 17:27:47 +02:00
|
|
|
static GdkMonitor *initial_monitor = NULL;
|
2003-01-10 17:55:53 +00:00
|
|
|
|
2001-07-07 18:16:18 +00:00
|
|
|
|
2001-04-15 20:12:16 +00:00
|
|
|
/* public functions */
|
|
|
|
|
2005-02-08 22:57:24 +00:00
|
|
|
void
|
|
|
|
gui_libs_init (GOptionContext *context)
|
2001-11-17 16:32:34 +00:00
|
|
|
{
|
2005-02-08 22:57:24 +00:00
|
|
|
g_return_if_fail (context != NULL);
|
2004-07-12 13:22:28 +00:00
|
|
|
|
2005-02-08 22:57:24 +00:00
|
|
|
g_option_context_add_group (context, gtk_get_option_group (TRUE));
|
2019-08-29 11:25:35 +02:00
|
|
|
|
|
|
|
/* make the GimpDisplay type known by name early, needed for the PDB */
|
|
|
|
g_type_class_ref (GIMP_TYPE_DISPLAY);
|
2004-03-30 11:32:21 +00:00
|
|
|
}
|
2003-10-26 20:25:34 +00:00
|
|
|
|
2004-03-30 11:32:21 +00:00
|
|
|
void
|
|
|
|
gui_abort (const gchar *abort_message)
|
|
|
|
{
|
2004-08-25 17:58:52 +00:00
|
|
|
GtkWidget *dialog;
|
|
|
|
GtkWidget *box;
|
|
|
|
|
2004-03-30 11:32:21 +00:00
|
|
|
g_return_if_fail (abort_message != NULL);
|
2003-10-26 20:25:34 +00:00
|
|
|
|
2004-08-25 17:58:52 +00:00
|
|
|
dialog = gimp_dialog_new (_("GIMP Message"), "gimp-abort",
|
|
|
|
NULL, GTK_DIALOG_MODAL, NULL, NULL,
|
2017-02-12 16:06:34 +01:00
|
|
|
|
|
|
|
_("_OK"), GTK_RESPONSE_OK,
|
|
|
|
|
2004-08-25 17:58:52 +00:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
|
|
|
|
|
|
|
|
box = g_object_new (GIMP_TYPE_MESSAGE_BOX,
|
2017-03-05 16:01:59 +01:00
|
|
|
"icon-name", GIMP_ICON_WILBER_EEK,
|
2005-08-03 09:34:55 +00:00
|
|
|
"border-width", 12,
|
2004-08-25 17:58:52 +00:00
|
|
|
NULL);
|
|
|
|
|
2008-11-04 12:33:09 +00:00
|
|
|
gimp_message_box_set_text (GIMP_MESSAGE_BOX (box), "%s", abort_message);
|
2004-08-25 17:58:52 +00:00
|
|
|
|
2010-10-30 14:56:00 +02:00
|
|
|
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
|
|
|
|
box, TRUE, TRUE, 0);
|
2004-08-25 17:58:52 +00:00
|
|
|
gtk_widget_show (box);
|
|
|
|
|
|
|
|
gimp_dialog_run (GIMP_DIALOG (dialog));
|
|
|
|
|
2004-07-12 14:32:31 +00:00
|
|
|
exit (EXIT_FAILURE);
|
2001-11-17 16:32:34 +00:00
|
|
|
}
|
|
|
|
|
2021-10-23 01:43:57 +02:00
|
|
|
/**
|
|
|
|
* gui_init:
|
|
|
|
* @gimp:
|
|
|
|
* @no_splash:
|
|
|
|
* @test_base_dir: a base prefix directory.
|
|
|
|
*
|
|
|
|
* @test_base_dir should be set to %NULL in all our codebase except for
|
|
|
|
* unit testing calls.
|
|
|
|
*/
|
2003-10-02 11:26:26 +00:00
|
|
|
GimpInitStatusFunc
|
2021-12-19 18:09:28 +01:00
|
|
|
gui_init (Gimp *gimp,
|
|
|
|
gboolean no_splash,
|
2022-02-07 10:02:19 +00:00
|
|
|
GimpApp *app,
|
2021-12-19 18:09:28 +01:00
|
|
|
const gchar *test_base_dir)
|
2002-11-25 00:04:26 +00:00
|
|
|
{
|
2003-11-01 20:06:01 +00:00
|
|
|
GimpInitStatusFunc status_callback = NULL;
|
2005-02-08 22:57:24 +00:00
|
|
|
gchar *abort_message;
|
2003-09-10 23:42:59 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
|
|
|
g_return_val_if_fail (the_gui_gimp == NULL, NULL);
|
2022-02-07 10:02:19 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_APP (app) || app == NULL, NULL);
|
2002-11-25 00:04:26 +00:00
|
|
|
|
2005-02-08 22:57:24 +00:00
|
|
|
abort_message = gui_sanity_check ();
|
|
|
|
if (abort_message)
|
|
|
|
gui_abort (abort_message);
|
|
|
|
|
2008-09-25 08:56:58 +00:00
|
|
|
the_gui_gimp = gimp;
|
|
|
|
|
2014-01-16 15:50:58 +13:00
|
|
|
/* Normally this should have been taken care of during command line
|
|
|
|
* parsing as a post-parse hook of gtk_get_option_group(), using the
|
|
|
|
* system locales.
|
2018-07-14 07:15:26 -04:00
|
|
|
* But user config may have overridden the language, therefore we must
|
2014-01-16 15:50:58 +13:00
|
|
|
* check the widget directions again.
|
2013-12-09 19:31:48 +13:00
|
|
|
*/
|
2014-01-16 15:50:58 +13:00
|
|
|
gtk_widget_set_default_direction (gtk_get_locale_direction ());
|
2013-12-09 19:31:48 +13:00
|
|
|
|
2008-09-25 08:56:58 +00:00
|
|
|
gui_unique_init (gimp);
|
2013-07-20 14:51:13 +09:00
|
|
|
gimp_language_store_parser_init ();
|
2008-09-25 08:56:58 +00:00
|
|
|
|
2015-12-12 19:32:11 +01:00
|
|
|
/* initialize icon themes before gimp_widgets_init() so we avoid
|
|
|
|
* setting the configured theme twice
|
|
|
|
*/
|
|
|
|
icon_themes_init (gimp);
|
|
|
|
|
2005-02-08 22:57:24 +00:00
|
|
|
gimp_widgets_init (gui_help_func,
|
|
|
|
gui_get_foreground_func,
|
|
|
|
gui_get_background_func,
|
2021-10-23 01:43:57 +02:00
|
|
|
NULL, test_base_dir);
|
2005-02-08 22:57:24 +00:00
|
|
|
|
|
|
|
g_type_class_ref (GIMP_TYPE_COLOR_SELECT);
|
|
|
|
|
2008-03-27 06:58:29 +00:00
|
|
|
/* disable automatic startup notification */
|
|
|
|
gtk_window_set_auto_startup_notification (FALSE);
|
|
|
|
|
2016-12-28 16:12:33 +01:00
|
|
|
#ifdef GDK_WINDOWING_QUARTZ
|
|
|
|
/* Before the first window is created (typically the splash window),
|
|
|
|
* we need to disable automatic tabbing behavior introduced on Sierra.
|
|
|
|
* This is known to cause all kinds of weird issues (see for instance
|
|
|
|
* Bugzilla #776294) and needs proper GTK+ support if we would want to
|
|
|
|
* enable it.
|
|
|
|
*/
|
|
|
|
if ([NSWindow respondsToSelector:@selector(setAllowsAutomaticWindowTabbing:)])
|
|
|
|
[NSWindow setAllowsAutomaticWindowTabbing:NO];
|
|
|
|
#endif /* GDK_WINDOWING_QUARTZ */
|
|
|
|
|
2003-11-03 23:24:32 +00:00
|
|
|
gimp_dnd_init (gimp);
|
|
|
|
|
2003-09-10 23:42:59 +00:00
|
|
|
themes_init (gimp);
|
2001-08-04 14:10:58 +00:00
|
|
|
|
2018-04-29 17:27:47 +02:00
|
|
|
initial_monitor = gimp_get_monitor_at_pointer ();
|
removed the gimp_busy boolean, check whether user_installation is needed
2001-07-10 Michael Natterer <mitch@gimp.org>
* app/app_procs.[ch]: removed the gimp_busy boolean, check whether
user_installation is needed here, not in user_install.c, parse
gtkrc an friends only if(!no_interface), create the Gimp object
before parsing gimp's rc files an pas it to the parse functions,
many other cleanups.
* app/appenums.h: added MessageHandlerType and StackTraceMode.
* app/appenv.h: removed MessageHandlerType, declare all global
variables from main.c (no more hidden global stuff please).
* app/errors.[ch]: added the fatal message func here (from main.c),
removed the StackTraceMode enum.
* app/gimprc.[ch]: renamed functions to gimprc_*(), pass a Gimp
pointer to some functions.
* app/gimpunit.c
* app/unitrc.h: ok, this is ugly: renamed all functions to
_gimp_unit_*() and made them public. The unit list is part
of the Gimp object now, so pass a Gimp* to all functions.
* app/libgimp_glue.[ch]: added EEKy wrappers for all gimp_unit_*()
functions which are used by widgets.
* app/main.c: cleaned up the global variables, removed the fatal
message handler, call app_init() directly, not via the
user_install stuff, misc. cleanups.
* app/user_install.[ch]: removed the check if user_installation is
needed (done by app_procs.c now).
* app/core/gimp.[ch]: added the user_unit list and the "busy"
boolean. Moved gimp_[set|unset]_busy() here. Added
gimp_initialize() which is called after unitrc and gimprc are
parsed.
* app/batch.c
* app/colormaps.c
* app/devices.c
* app/disp_callbacks.c
* app/gdisplay_ops.c
* app/gimphelp.c
* app/module_db.c
* app/nav_window.c
* app/plug_in.c
* app/core/gimpcontext.c
* app/core/gimpdatafiles.c
* app/core/gimpimage-convert.c
* app/core/gimpimage-duplicate.c
* app/core/gimpimage.c
* app/core/gimpparasite.c
* app/core/gimpparasitelist.h
* app/gui/file-open-dialog.c
* app/gui/gui.[ch]
* app/gui/info-dialog.c
* app/gui/info-window.c
* app/gui/preferences-dialog.c
* app/gui/session.c
* app/gui/tips-dialog.c
* app/gui/toolbox.c
* app/tools/gimpblendtool.c
* app/tools/gimpbucketfilltool.c
* app/tools/gimpcolorpickertool.c
* app/tools/gimpfuzzyselecttool.c
* app/tools/gimptransformtool.c
* app/tools/tool_manager.c
* app/widgets/gimpcolorpanel.c
* app/widgets/gimpcursor.c
* app/xcf/xcf-load.c
* app/xcf/xcf-save.c
* app/xcf/xcf.c
* tools/pdbgen/Makefile.am
* tools/pdbgen/app.pl
* tools/pdbgen/enums.pl
* tools/pdbgen/pdb/image.pdb
* tools/pdbgen/pdb/message.pdb
* tools/pdbgen/pdb/unit.pdb
* app/pdb/image_cmds.c
* app/pdb/message_cmds.c
* app/pdb/unit_cmds.c: changed accordingly, minor cleanups.
2001-07-10 19:16:16 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
if (! no_splash)
|
2001-07-04 19:31:35 +00:00
|
|
|
{
|
2021-12-19 18:09:28 +01:00
|
|
|
splash_create (gimp, gimp->be_verbose, initial_monitor, app);
|
2003-10-02 11:26:26 +00:00
|
|
|
status_callback = splash_update;
|
2001-07-04 19:31:35 +00:00
|
|
|
}
|
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
g_signal_connect_after (gimp, "initialize",
|
|
|
|
G_CALLBACK (gui_initialize_after_callback),
|
|
|
|
NULL);
|
2001-10-22 17:27:46 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
g_signal_connect (gimp, "restore",
|
|
|
|
G_CALLBACK (gui_restore_callback),
|
|
|
|
NULL);
|
|
|
|
g_signal_connect_after (gimp, "restore",
|
|
|
|
G_CALLBACK (gui_restore_after_callback),
|
|
|
|
NULL);
|
2001-04-15 20:12:16 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
g_signal_connect (gimp, "exit",
|
|
|
|
G_CALLBACK (gui_exit_callback),
|
|
|
|
NULL);
|
|
|
|
g_signal_connect_after (gimp, "exit",
|
|
|
|
G_CALLBACK (gui_exit_after_callback),
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
return status_callback;
|
2001-04-15 20:12:16 +00:00
|
|
|
}
|
|
|
|
|
2018-03-22 19:29:35 +01:00
|
|
|
/*
|
|
|
|
* gui_recover:
|
|
|
|
* @n_recoveries: number of recovered files.
|
|
|
|
*
|
|
|
|
* Query the user interactively if files were saved from a previous
|
|
|
|
* crash, asking whether to try and recover or discard them.
|
|
|
|
*
|
|
|
|
* Returns: TRUE if answer is to try and recover, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gui_recover (gint n_recoveries)
|
|
|
|
{
|
|
|
|
GtkWidget *dialog;
|
|
|
|
GtkWidget *box;
|
|
|
|
gboolean recover;
|
|
|
|
|
2018-03-23 20:35:01 +01:00
|
|
|
dialog = gimp_dialog_new (_("Image Recovery"), "gimp-recovery",
|
2018-03-22 19:29:35 +01:00
|
|
|
NULL, GTK_DIALOG_MODAL, NULL, NULL,
|
|
|
|
_("_Discard"), GTK_RESPONSE_CANCEL,
|
|
|
|
_("_Recover"), GTK_RESPONSE_OK,
|
|
|
|
NULL);
|
|
|
|
gtk_dialog_set_default_response (GTK_DIALOG (dialog),
|
|
|
|
GTK_RESPONSE_OK);
|
|
|
|
|
|
|
|
box = gimp_message_box_new (GIMP_ICON_WILBER_EEK);
|
|
|
|
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
|
|
|
|
box, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (box);
|
|
|
|
|
|
|
|
gimp_message_box_set_primary_text (GIMP_MESSAGE_BOX (box),
|
|
|
|
_("Eeek! It looks like GIMP recovered from a crash!"));
|
|
|
|
|
|
|
|
gimp_message_box_set_text (GIMP_MESSAGE_BOX (box),
|
2018-03-24 02:59:02 +01:00
|
|
|
/* TRANSLATORS: even if English singular form does
|
|
|
|
* not use %d, you can use %d for translation in
|
|
|
|
* any singular/plural form of your language if
|
|
|
|
* suited. It will just work and be replaced by the
|
|
|
|
* number of images as expected.
|
|
|
|
*/
|
|
|
|
ngettext ("An image was salvaged from the crash. "
|
2018-03-22 19:29:35 +01:00
|
|
|
"Do you want to try and recover it?",
|
|
|
|
"%d images were salvaged from the crash. "
|
|
|
|
"Do you want to try and recover them?",
|
|
|
|
n_recoveries), n_recoveries);
|
|
|
|
|
|
|
|
recover = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
|
|
|
|
gtk_widget_destroy (dialog);
|
|
|
|
|
|
|
|
return recover;
|
|
|
|
}
|
|
|
|
|
2018-04-29 17:27:47 +02:00
|
|
|
GdkMonitor *
|
|
|
|
gui_get_initial_monitor (Gimp *gimp)
|
2014-05-03 00:54:20 +02:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_GIMP (gimp), 0);
|
|
|
|
|
|
|
|
return initial_monitor;
|
|
|
|
}
|
|
|
|
|
2001-04-15 20:12:16 +00:00
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
2004-07-12 13:22:28 +00:00
|
|
|
static gchar *
|
|
|
|
gui_sanity_check (void)
|
|
|
|
{
|
2010-10-15 09:56:27 +02:00
|
|
|
#define GTK_REQUIRED_MAJOR 3
|
2023-05-21 10:33:17 +02:00
|
|
|
#define GTK_REQUIRED_MINOR 24
|
|
|
|
#define GTK_REQUIRED_MICRO 0
|
2004-07-12 13:22:28 +00:00
|
|
|
|
2008-01-23 12:22:09 +00:00
|
|
|
const gchar *mismatch = gtk_check_version (GTK_REQUIRED_MAJOR,
|
|
|
|
GTK_REQUIRED_MINOR,
|
|
|
|
GTK_REQUIRED_MICRO);
|
2004-07-12 13:22:28 +00:00
|
|
|
|
|
|
|
if (mismatch)
|
2007-01-19 14:50:13 +00:00
|
|
|
{
|
|
|
|
return g_strdup_printf
|
|
|
|
("%s\n\n"
|
2022-06-29 17:40:55 +02:00
|
|
|
"GIMP requires GTK version %d.%d.%d or later.\n"
|
|
|
|
"Installed GTK version is %d.%d.%d.\n\n"
|
2007-01-19 14:50:13 +00:00
|
|
|
"Somehow you or your software packager managed\n"
|
2022-06-29 17:40:55 +02:00
|
|
|
"to install GIMP with an older GTK version.\n\n"
|
|
|
|
"Please upgrade to GTK version %d.%d.%d or later.",
|
2007-01-19 14:50:13 +00:00
|
|
|
mismatch,
|
|
|
|
GTK_REQUIRED_MAJOR, GTK_REQUIRED_MINOR, GTK_REQUIRED_MICRO,
|
|
|
|
gtk_major_version, gtk_minor_version, gtk_micro_version,
|
|
|
|
GTK_REQUIRED_MAJOR, GTK_REQUIRED_MINOR, GTK_REQUIRED_MICRO);
|
|
|
|
}
|
2011-04-07 23:47:27 +02:00
|
|
|
|
2004-07-12 13:22:28 +00:00
|
|
|
#undef GTK_REQUIRED_MAJOR
|
|
|
|
#undef GTK_REQUIRED_MINOR
|
|
|
|
#undef GTK_REQUIRED_MICRO
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-05-25 12:13:57 +00:00
|
|
|
static void
|
2003-08-23 19:35:05 +00:00
|
|
|
gui_help_func (const gchar *help_id,
|
|
|
|
gpointer help_data)
|
2003-05-25 12:13:57 +00:00
|
|
|
{
|
2003-10-02 11:26:26 +00:00
|
|
|
g_return_if_fail (GIMP_IS_GIMP (the_gui_gimp));
|
|
|
|
|
2008-06-10 09:54:54 +00:00
|
|
|
gimp_help (the_gui_gimp, NULL, NULL, help_id);
|
2003-05-25 12:13:57 +00:00
|
|
|
}
|
|
|
|
|
2003-05-25 14:23:43 +00:00
|
|
|
static gboolean
|
|
|
|
gui_get_foreground_func (GimpRGB *color)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (color != NULL, FALSE);
|
2003-10-02 11:26:26 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_GIMP (the_gui_gimp), FALSE);
|
2003-05-25 14:23:43 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
gimp_context_get_foreground (gimp_get_user_context (the_gui_gimp), color);
|
2003-05-25 14:23:43 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gui_get_background_func (GimpRGB *color)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (color != NULL, FALSE);
|
2003-10-02 11:26:26 +00:00
|
|
|
g_return_val_if_fail (GIMP_IS_GIMP (the_gui_gimp), FALSE);
|
2003-05-25 14:23:43 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
gimp_context_get_background (gimp_get_user_context (the_gui_gimp), color);
|
2003-05-25 14:23:43 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2001-11-17 16:32:34 +00:00
|
|
|
static void
|
2003-10-02 11:26:26 +00:00
|
|
|
gui_initialize_after_callback (Gimp *gimp,
|
|
|
|
GimpInitStatusFunc status_callback)
|
2001-11-17 16:32:34 +00:00
|
|
|
{
|
2003-10-02 11:26:26 +00:00
|
|
|
const gchar *name = NULL;
|
2001-11-17 16:32:34 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
2001-11-17 16:32:34 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
if (gimp->be_verbose)
|
2008-02-19 13:38:24 +00:00
|
|
|
g_print ("INIT: %s\n", G_STRFUNC);
|
2001-12-01 21:02:34 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
#if defined (GDK_WINDOWING_X11)
|
|
|
|
name = "DISPLAY";
|
|
|
|
#elif defined (GDK_WINDOWING_DIRECTFB) || defined (GDK_WINDOWING_FB)
|
|
|
|
name = "GDK_DISPLAY";
|
|
|
|
#endif
|
2001-12-01 21:02:34 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
/* TODO: Need to care about display migration with GTK+ 2.2 at some point */
|
|
|
|
|
|
|
|
if (name)
|
|
|
|
{
|
2018-04-29 17:27:47 +02:00
|
|
|
const gchar *display = gdk_display_get_name (gdk_display_get_default ());
|
2003-10-02 11:26:26 +00:00
|
|
|
|
2006-04-28 22:26:51 +00:00
|
|
|
gimp_environ_table_add (gimp->plug_in_manager->environ_table,
|
|
|
|
name, display, NULL);
|
2003-10-02 11:26:26 +00:00
|
|
|
}
|
2001-12-01 21:02:34 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
gimp_tools_init (gimp);
|
2004-06-28 13:18:00 +00:00
|
|
|
|
|
|
|
gimp_context_set_tool (gimp_get_user_context (gimp),
|
|
|
|
gimp_tool_info_get_standard (gimp));
|
2001-12-01 21:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-10-02 11:26:26 +00:00
|
|
|
gui_restore_callback (Gimp *gimp,
|
2003-11-13 14:14:20 +00:00
|
|
|
GimpInitStatusFunc status_callback)
|
2001-12-01 21:02:34 +00:00
|
|
|
{
|
2003-11-08 18:16:25 +00:00
|
|
|
GimpDisplayConfig *display_config = GIMP_DISPLAY_CONFIG (gimp->config);
|
|
|
|
GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (gimp->config);
|
2003-06-13 14:37:00 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
if (gimp->be_verbose)
|
2008-02-19 13:38:24 +00:00
|
|
|
g_print ("INIT: %s\n", G_STRFUNC);
|
2003-06-13 14:37:00 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
gui_vtable_init (gimp);
|
2003-06-13 14:37:00 +00:00
|
|
|
|
2004-10-04 16:21:52 +00:00
|
|
|
gimp_dialogs_show_help_button (gui_config->use_help &&
|
|
|
|
gui_config->show_help_button);
|
|
|
|
|
|
|
|
g_signal_connect (gui_config, "notify::use-help",
|
|
|
|
G_CALLBACK (gui_show_help_button_notify),
|
|
|
|
gimp);
|
2009-02-26 22:58:19 +00:00
|
|
|
g_signal_connect (gui_config, "notify::user-manual-online",
|
|
|
|
G_CALLBACK (gui_user_manual_notify),
|
|
|
|
gimp);
|
2004-10-04 16:21:52 +00:00
|
|
|
g_signal_connect (gui_config, "notify::show-help-button",
|
|
|
|
G_CALLBACK (gui_show_help_button_notify),
|
|
|
|
gimp);
|
|
|
|
|
2005-05-27 16:51:39 +00:00
|
|
|
g_signal_connect (gimp_get_user_context (gimp), "display-changed",
|
2006-04-12 12:49:29 +00:00
|
|
|
G_CALLBACK (gui_display_changed),
|
|
|
|
gimp);
|
2001-12-01 21:02:34 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
/* make sure the monitor resolution is valid */
|
|
|
|
if (display_config->monitor_res_from_gdk ||
|
|
|
|
display_config->monitor_xres < GIMP_MIN_RESOLUTION ||
|
|
|
|
display_config->monitor_yres < GIMP_MIN_RESOLUTION)
|
|
|
|
{
|
|
|
|
gdouble xres, yres;
|
2001-07-05 15:34:26 +00:00
|
|
|
|
2018-04-29 17:27:47 +02:00
|
|
|
gimp_get_monitor_resolution (initial_monitor, &xres, &yres);
|
2001-07-05 15:34:26 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
g_object_set (gimp->config,
|
2006-04-12 12:49:29 +00:00
|
|
|
"monitor-xresolution", xres,
|
|
|
|
"monitor-yresolution", yres,
|
|
|
|
"monitor-resolution-from-windowing-system", TRUE,
|
|
|
|
NULL);
|
2003-10-02 11:26:26 +00:00
|
|
|
}
|
2001-07-05 15:34:26 +00:00
|
|
|
|
2004-04-27 10:23:35 +00:00
|
|
|
actions_init (gimp);
|
2023-03-07 18:23:38 +01:00
|
|
|
menus_init (gimp);
|
2005-07-19 20:42:14 +00:00
|
|
|
gimp_render_init (gimp);
|
2001-10-31 21:20:09 +00:00
|
|
|
|
2023-03-07 18:23:38 +01:00
|
|
|
dialogs_init (gimp);
|
2003-03-20 11:31:33 +00:00
|
|
|
|
2004-07-07 14:38:23 +00:00
|
|
|
gimp_clipboard_init (gimp);
|
2016-09-19 20:14:21 +02:00
|
|
|
if (gimp_get_clipboard_image (gimp))
|
|
|
|
gimp_clipboard_set_image (gimp, gimp_get_clipboard_image (gimp));
|
|
|
|
else
|
|
|
|
gimp_clipboard_set_buffer (gimp, gimp_get_clipboard_buffer (gimp));
|
2005-09-21 14:35:51 +00:00
|
|
|
|
2016-09-17 17:39:54 +02:00
|
|
|
g_signal_connect (gimp, "clipboard-changed",
|
|
|
|
G_CALLBACK (gui_clipboard_changed),
|
2005-09-21 14:35:51 +00:00
|
|
|
NULL);
|
|
|
|
|
2011-02-28 12:57:15 +01:00
|
|
|
gimp_devices_init (gimp);
|
2004-06-15 22:59:26 +00:00
|
|
|
gimp_controllers_init (gimp);
|
2022-07-26 19:21:56 +02:00
|
|
|
modifiers_init (gimp);
|
2003-10-02 11:26:26 +00:00
|
|
|
session_init (gimp);
|
2001-07-05 15:34:26 +00:00
|
|
|
|
2006-11-03 17:28:52 +00:00
|
|
|
g_type_class_unref (g_type_class_ref (GIMP_TYPE_COLOR_SELECTOR_PALETTE));
|
|
|
|
|
2008-03-24 11:11:15 +00:00
|
|
|
status_callback (NULL, _("Tool Options"), 1.0);
|
2003-10-02 11:26:26 +00:00
|
|
|
gimp_tools_restore (gimp);
|
2003-09-10 22:06:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2003-10-02 11:26:26 +00:00
|
|
|
gui_restore_after_callback (Gimp *gimp,
|
2003-11-13 14:14:20 +00:00
|
|
|
GimpInitStatusFunc status_callback)
|
2003-09-10 22:06:45 +00:00
|
|
|
{
|
2003-11-08 18:16:25 +00:00
|
|
|
GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (gimp->config);
|
2023-03-07 18:23:38 +01:00
|
|
|
GimpUIManager *image_ui_manager;
|
2008-03-25 10:00:33 +00:00
|
|
|
GimpDisplay *display;
|
2023-10-15 14:14:06 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
STARTUPINFO StartupInfo;
|
|
|
|
|
|
|
|
GetStartupInfo (&StartupInfo);
|
|
|
|
#endif
|
2003-09-10 22:06:45 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
if (gimp->be_verbose)
|
2008-02-19 13:38:24 +00:00
|
|
|
g_print ("INIT: %s\n", G_STRFUNC);
|
2003-09-10 22:06:45 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
gimp->message_handler = GIMP_MESSAGE_BOX;
|
2003-09-10 22:06:45 +00:00
|
|
|
|
2014-07-04 20:01:08 +02:00
|
|
|
/* load the recent documents after gimp_real_restore() because we
|
|
|
|
* need the mime-types implemented by plug-ins
|
|
|
|
*/
|
|
|
|
status_callback (NULL, _("Documents"), 0.9);
|
|
|
|
gimp_recent_list_load (gimp);
|
|
|
|
|
2014-05-07 21:31:28 +02:00
|
|
|
/* enable this to always have icons everywhere */
|
2014-06-06 23:45:00 +02:00
|
|
|
if (g_getenv ("GIMP_ICONS_LIKE_A_BOSS"))
|
|
|
|
{
|
|
|
|
GdkScreen *screen = gdk_screen_get_default ();
|
|
|
|
|
|
|
|
g_object_set (G_OBJECT (gtk_settings_get_for_screen (screen)),
|
|
|
|
"gtk-button-images", TRUE,
|
|
|
|
"gtk-menu-images", TRUE,
|
|
|
|
NULL);
|
|
|
|
}
|
2014-05-07 15:30:38 +02:00
|
|
|
|
2009-10-04 02:09:53 +02:00
|
|
|
ui_configurer = g_object_new (GIMP_TYPE_UI_CONFIGURER,
|
|
|
|
"gimp", gimp,
|
|
|
|
NULL);
|
|
|
|
|
2023-03-07 18:23:38 +01:00
|
|
|
image_ui_manager = menus_get_image_manager_singleton (gimp);
|
2011-07-20 16:31:03 +02:00
|
|
|
gimp_ui_manager_update (image_ui_manager, gimp);
|
2014-07-29 12:28:18 +02:00
|
|
|
|
2023-04-07 13:42:08 +02:00
|
|
|
if (gui_config->restore_accels)
|
|
|
|
menus_restore (gimp);
|
|
|
|
|
2016-11-21 16:52:52 +01:00
|
|
|
/* Check that every accelerator is unique. */
|
2023-02-06 17:50:14 +01:00
|
|
|
gui_check_unique_accelerators (gimp);
|
2016-11-21 16:52:52 +01:00
|
|
|
|
2014-07-29 12:28:18 +02:00
|
|
|
gimp_action_history_init (gimp);
|
2007-08-30 11:19:00 +00:00
|
|
|
|
2009-10-04 02:09:53 +02:00
|
|
|
g_signal_connect_object (gui_config, "notify::single-window-mode",
|
|
|
|
G_CALLBACK (gui_single_window_mode_notify),
|
|
|
|
ui_configurer, 0);
|
2006-03-09 16:06:32 +00:00
|
|
|
g_signal_connect (image_ui_manager, "show-tooltip",
|
|
|
|
G_CALLBACK (gui_menu_show_tooltip),
|
|
|
|
gimp);
|
|
|
|
g_signal_connect (image_ui_manager, "hide-tooltip",
|
|
|
|
G_CALLBACK (gui_menu_hide_tooltip),
|
|
|
|
gimp);
|
2003-09-10 22:06:45 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
gimp_devices_restore (gimp);
|
2004-06-15 22:59:26 +00:00
|
|
|
gimp_controllers_restore (gimp, image_ui_manager);
|
2022-07-26 19:21:56 +02:00
|
|
|
modifiers_restore (gimp);
|
2003-09-10 22:06:45 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
if (status_callback == splash_update)
|
|
|
|
splash_destroy ();
|
|
|
|
|
2009-09-08 19:26:57 +02:00
|
|
|
if (gimp_get_show_gui (gimp))
|
|
|
|
{
|
2009-10-05 19:58:03 +02:00
|
|
|
GimpDisplayShell *shell;
|
2014-05-02 21:15:01 +02:00
|
|
|
GtkWidget *toplevel;
|
2009-10-05 19:58:03 +02:00
|
|
|
|
2009-09-08 19:26:57 +02:00
|
|
|
/* create the empty display */
|
2014-05-02 20:20:46 +02:00
|
|
|
display = GIMP_DISPLAY (gimp_create_display (gimp, NULL,
|
|
|
|
GIMP_UNIT_PIXEL, 1.0,
|
2018-04-29 17:27:47 +02:00
|
|
|
G_OBJECT (initial_monitor)));
|
2009-09-08 19:26:57 +02:00
|
|
|
|
2009-10-05 19:58:03 +02:00
|
|
|
shell = gimp_display_get_shell (display);
|
|
|
|
|
2009-09-08 19:26:57 +02:00
|
|
|
if (gui_config->restore_session)
|
2018-04-29 17:27:47 +02:00
|
|
|
session_restore (gimp, initial_monitor);
|
2008-03-20 15:22:57 +00:00
|
|
|
|
2014-05-02 21:15:01 +02:00
|
|
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
|
2020-02-18 20:38:18 +01:00
|
|
|
|
2023-10-15 14:14:06 +00:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
/* Prevents window from reappearing on start-up if the user
|
|
|
|
* requested it to be minimized via window hints
|
|
|
|
*/
|
|
|
|
if (StartupInfo.wShowWindow != SW_SHOWMINIMIZED &&
|
|
|
|
StartupInfo.wShowWindow != SW_SHOWMINNOACTIVE &&
|
|
|
|
StartupInfo.wShowWindow != SW_MINIMIZE)
|
|
|
|
#endif
|
2020-01-10 14:52:57 +00:00
|
|
|
/* move keyboard focus to the display */
|
2014-05-02 21:15:01 +02:00
|
|
|
gtk_window_present (GTK_WINDOW (toplevel));
|
2009-09-08 19:26:57 +02:00
|
|
|
}
|
2008-03-27 06:58:29 +00:00
|
|
|
|
|
|
|
/* indicate that the application has finished loading */
|
|
|
|
gdk_notify_startup_complete ();
|
2014-05-03 00:54:20 +02:00
|
|
|
|
|
|
|
/* clear startup monitor variables */
|
2018-04-29 17:27:47 +02:00
|
|
|
initial_monitor = NULL;
|
2003-09-10 22:06:45 +00:00
|
|
|
}
|
|
|
|
|
2002-12-05 15:49:59 +00:00
|
|
|
static gboolean
|
|
|
|
gui_exit_callback (Gimp *gimp,
|
2003-11-30 16:05:56 +00:00
|
|
|
gboolean force)
|
2002-12-05 15:49:59 +00:00
|
|
|
{
|
2018-11-22 16:17:19 +01:00
|
|
|
GimpGuiConfig *gui_config = GIMP_GUI_CONFIG (gimp->config);
|
|
|
|
GimpTool *active_tool;
|
2003-09-22 15:31:54 +00:00
|
|
|
|
2003-10-02 11:26:26 +00:00
|
|
|
if (gimp->be_verbose)
|
2008-02-19 13:38:24 +00:00
|
|
|
g_print ("EXIT: %s\n", G_STRFUNC);
|
2003-10-02 11:26:26 +00:00
|
|
|
|
2003-11-30 16:05:56 +00:00
|
|
|
if (! force && gimp_displays_dirty (gimp))
|
2002-12-05 15:49:59 +00:00
|
|
|
{
|
2018-05-03 00:55:44 +02:00
|
|
|
GimpContext *context = gimp_get_user_context (gimp);
|
|
|
|
GimpDisplay *display = gimp_context_get_display (context);
|
|
|
|
GdkMonitor *monitor = gimp_get_monitor_at_pointer ();
|
|
|
|
GtkWidget *parent = NULL;
|
2014-05-02 03:01:23 +02:00
|
|
|
|
2018-05-03 00:55:44 +02:00
|
|
|
if (display)
|
|
|
|
{
|
|
|
|
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
|
|
|
|
|
|
|
parent = GTK_WIDGET (gimp_display_shell_get_window (shell));
|
|
|
|
}
|
2014-05-02 03:01:23 +02:00
|
|
|
|
2010-02-28 23:20:57 +01:00
|
|
|
gimp_dialog_factory_dialog_raise (gimp_dialog_factory_get_singleton (),
|
2018-05-03 00:55:44 +02:00
|
|
|
monitor, parent, "gimp-quit-dialog", -1);
|
2002-12-05 15:49:59 +00:00
|
|
|
|
|
|
|
return TRUE; /* stop exit for now */
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp->message_handler = GIMP_CONSOLE;
|
|
|
|
|
2008-07-11 09:40:09 +00:00
|
|
|
gui_unique_exit ();
|
2007-01-19 14:50:13 +00:00
|
|
|
|
2018-11-22 16:17:19 +01:00
|
|
|
/* If any modifier is set when quitting (typically when exiting with
|
|
|
|
* Ctrl-q for instance!), when serializing the tool options, it will
|
|
|
|
* save any alternate value instead of the main one. Make sure that
|
|
|
|
* any modifier is reset before saving options.
|
|
|
|
*/
|
|
|
|
active_tool = tool_manager_get_active (gimp);
|
|
|
|
if (active_tool && active_tool->focus_display)
|
|
|
|
gimp_tool_set_modifier_state (active_tool, 0, active_tool->focus_display);
|
|
|
|
|
2003-09-22 15:31:54 +00:00
|
|
|
if (gui_config->save_session_info)
|
2004-07-21 16:11:31 +00:00
|
|
|
session_save (gimp, FALSE);
|
2003-09-22 15:31:54 +00:00
|
|
|
|
|
|
|
if (gui_config->save_device_status)
|
2004-07-21 16:11:31 +00:00
|
|
|
gimp_devices_save (gimp, FALSE);
|
2002-12-05 15:49:59 +00:00
|
|
|
|
2004-06-15 22:59:26 +00:00
|
|
|
if (TRUE /* gui_config->save_controllers */)
|
|
|
|
gimp_controllers_save (gimp);
|
|
|
|
|
2022-07-26 19:21:56 +02:00
|
|
|
modifiers_save (gimp, FALSE);
|
|
|
|
|
2007-06-02 12:51:59 +00:00
|
|
|
g_signal_handlers_disconnect_by_func (gimp_get_user_context (gimp),
|
|
|
|
gui_display_changed,
|
|
|
|
gimp);
|
|
|
|
|
2008-04-05 20:32:24 +00:00
|
|
|
gimp_displays_delete (gimp);
|
2002-12-05 15:49:59 +00:00
|
|
|
|
2016-11-25 04:25:41 +01:00
|
|
|
if (gui_config->save_accels)
|
|
|
|
menus_save (gimp, FALSE);
|
|
|
|
|
2005-04-11 21:17:59 +00:00
|
|
|
gimp_tools_save (gimp, gui_config->save_tool_options, FALSE);
|
2003-10-02 11:26:26 +00:00
|
|
|
gimp_tools_exit (gimp);
|
|
|
|
|
2013-07-20 14:51:13 +09:00
|
|
|
gimp_language_store_parser_clean ();
|
|
|
|
|
2002-12-05 15:49:59 +00:00
|
|
|
return FALSE; /* continue exiting */
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2003-10-02 11:26:26 +00:00
|
|
|
gui_exit_after_callback (Gimp *gimp,
|
2003-11-30 16:05:56 +00:00
|
|
|
gboolean force)
|
2002-12-05 15:49:59 +00:00
|
|
|
{
|
2003-10-02 11:26:26 +00:00
|
|
|
if (gimp->be_verbose)
|
2008-02-19 13:38:24 +00:00
|
|
|
g_print ("EXIT: %s\n", G_STRFUNC);
|
2003-10-02 11:26:26 +00:00
|
|
|
|
2004-10-04 16:21:52 +00:00
|
|
|
g_signal_handlers_disconnect_by_func (gimp->config,
|
|
|
|
gui_show_help_button_notify,
|
|
|
|
gimp);
|
2009-02-26 22:58:19 +00:00
|
|
|
g_signal_handlers_disconnect_by_func (gimp->config,
|
|
|
|
gui_user_manual_notify,
|
|
|
|
gimp);
|
2003-02-26 16:17:10 +00:00
|
|
|
|
2014-07-29 12:28:18 +02:00
|
|
|
gimp_action_history_exit (gimp);
|
2014-02-18 20:10:24 +01:00
|
|
|
|
2010-06-24 22:57:25 +02:00
|
|
|
g_object_unref (ui_configurer);
|
|
|
|
ui_configurer = NULL;
|
|
|
|
|
2014-06-10 01:35:30 +02:00
|
|
|
/* exit the clipboard before shutting down the GUI because it runs
|
|
|
|
* a whole lot of code paths. See bug #731389.
|
|
|
|
*/
|
|
|
|
g_signal_handlers_disconnect_by_func (gimp,
|
2016-09-17 17:39:54 +02:00
|
|
|
G_CALLBACK (gui_clipboard_changed),
|
2014-06-10 01:35:30 +02:00
|
|
|
NULL);
|
|
|
|
gimp_clipboard_exit (gimp);
|
|
|
|
|
2004-07-21 16:11:31 +00:00
|
|
|
session_exit (gimp);
|
2002-12-05 15:49:59 +00:00
|
|
|
menus_exit (gimp);
|
2004-04-27 10:23:35 +00:00
|
|
|
actions_exit (gimp);
|
2005-07-19 20:42:14 +00:00
|
|
|
gimp_render_exit (gimp);
|
2002-12-05 15:49:59 +00:00
|
|
|
|
2004-06-15 22:59:26 +00:00
|
|
|
gimp_controllers_exit (gimp);
|
2022-07-26 19:21:56 +02:00
|
|
|
modifiers_exit (gimp);
|
2002-12-05 15:49:59 +00:00
|
|
|
gimp_devices_exit (gimp);
|
2010-06-18 09:11:14 +02:00
|
|
|
dialogs_exit (gimp);
|
2003-09-10 23:42:59 +00:00
|
|
|
themes_exit (gimp);
|
2002-12-05 15:49:59 +00:00
|
|
|
|
|
|
|
g_type_class_unref (g_type_class_peek (GIMP_TYPE_COLOR_SELECT));
|
|
|
|
|
|
|
|
return FALSE; /* continue exiting */
|
|
|
|
}
|
|
|
|
|
2004-10-04 16:21:52 +00:00
|
|
|
static void
|
|
|
|
gui_show_help_button_notify (GimpGuiConfig *gui_config,
|
|
|
|
GParamSpec *param_spec,
|
|
|
|
Gimp *gimp)
|
|
|
|
{
|
|
|
|
gimp_dialogs_show_help_button (gui_config->use_help &&
|
|
|
|
gui_config->show_help_button);
|
|
|
|
}
|
|
|
|
|
2009-02-26 22:58:19 +00:00
|
|
|
static void
|
|
|
|
gui_user_manual_notify (GimpGuiConfig *gui_config,
|
|
|
|
GParamSpec *param_spec,
|
|
|
|
Gimp *gimp)
|
|
|
|
{
|
|
|
|
gimp_help_user_manual_changed (gimp);
|
|
|
|
}
|
|
|
|
|
2009-10-04 02:09:53 +02:00
|
|
|
static void
|
|
|
|
gui_single_window_mode_notify (GimpGuiConfig *gui_config,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
GimpUIConfigurer *ui_configurer)
|
|
|
|
{
|
|
|
|
gimp_ui_configurer_configure (ui_configurer,
|
|
|
|
gui_config->single_window_mode);
|
|
|
|
}
|
2004-05-17 13:38:03 +00:00
|
|
|
|
2005-09-21 14:35:51 +00:00
|
|
|
static void
|
2016-09-17 17:39:54 +02:00
|
|
|
gui_clipboard_changed (Gimp *gimp)
|
2005-09-21 14:35:51 +00:00
|
|
|
{
|
2016-09-19 20:14:21 +02:00
|
|
|
if (gimp_get_clipboard_image (gimp))
|
|
|
|
gimp_clipboard_set_image (gimp, gimp_get_clipboard_image (gimp));
|
|
|
|
else
|
|
|
|
gimp_clipboard_set_buffer (gimp, gimp_get_clipboard_buffer (gimp));
|
2005-09-21 14:35:51 +00:00
|
|
|
}
|
|
|
|
|
2006-03-09 16:06:32 +00:00
|
|
|
static void
|
|
|
|
gui_menu_show_tooltip (GimpUIManager *manager,
|
|
|
|
const gchar *tooltip,
|
|
|
|
Gimp *gimp)
|
|
|
|
{
|
|
|
|
GimpContext *context = gimp_get_user_context (gimp);
|
|
|
|
GimpDisplay *display = gimp_context_get_display (context);
|
|
|
|
|
|
|
|
if (display)
|
|
|
|
{
|
2009-10-04 19:56:39 +02:00
|
|
|
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
2009-10-04 15:31:38 +02:00
|
|
|
GimpStatusbar *statusbar = gimp_display_shell_get_statusbar (shell);
|
2006-03-09 16:06:32 +00:00
|
|
|
|
2009-10-04 15:31:38 +02:00
|
|
|
gimp_statusbar_push (statusbar, "menu-tooltip",
|
|
|
|
NULL, "%s", tooltip);
|
2006-03-09 16:06:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gui_menu_hide_tooltip (GimpUIManager *manager,
|
|
|
|
Gimp *gimp)
|
|
|
|
{
|
|
|
|
GimpContext *context = gimp_get_user_context (gimp);
|
|
|
|
GimpDisplay *display = gimp_context_get_display (context);
|
|
|
|
|
|
|
|
if (display)
|
|
|
|
{
|
2009-10-04 19:56:39 +02:00
|
|
|
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
2009-10-04 15:31:38 +02:00
|
|
|
GimpStatusbar *statusbar = gimp_display_shell_get_statusbar (shell);
|
2009-09-29 21:44:43 +02:00
|
|
|
|
2009-10-04 15:31:38 +02:00
|
|
|
gimp_statusbar_pop (statusbar, "menu-tooltip");
|
2006-03-09 16:06:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-07 12:17:23 +00:00
|
|
|
static void
|
|
|
|
gui_display_changed (GimpContext *context,
|
2006-04-12 12:49:29 +00:00
|
|
|
GimpDisplay *display,
|
|
|
|
Gimp *gimp)
|
2001-07-07 12:17:23 +00:00
|
|
|
{
|
2004-11-24 16:41:52 +00:00
|
|
|
if (! display)
|
|
|
|
{
|
|
|
|
GimpImage *image = gimp_context_get_image (context);
|
|
|
|
|
|
|
|
if (image)
|
|
|
|
{
|
|
|
|
GList *list;
|
|
|
|
|
2008-11-02 21:34:14 +00:00
|
|
|
for (list = gimp_get_display_iter (gimp);
|
2004-11-24 16:41:52 +00:00
|
|
|
list;
|
|
|
|
list = g_list_next (list))
|
|
|
|
{
|
|
|
|
GimpDisplay *display2 = list->data;
|
|
|
|
|
2009-10-06 19:20:44 +02:00
|
|
|
if (gimp_display_get_image (display2) == image)
|
2004-11-24 16:41:52 +00:00
|
|
|
{
|
|
|
|
gimp_context_set_display (context, display2);
|
2005-02-08 17:58:28 +00:00
|
|
|
|
2006-12-18 11:57:29 +00:00
|
|
|
/* stop the emission of the original signal
|
|
|
|
* (the emission of the recursive signal is finished)
|
2005-02-08 17:58:28 +00:00
|
|
|
*/
|
|
|
|
g_signal_stop_emission_by_name (context, "display-changed");
|
2004-11-24 16:41:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_context_set_image (context, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-07 18:23:38 +01:00
|
|
|
gimp_ui_manager_update (menus_get_image_manager_singleton (gimp),
|
|
|
|
display);
|
2001-07-07 12:17:23 +00:00
|
|
|
}
|
2016-11-21 16:52:52 +01:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const gchar *path;
|
|
|
|
guint key;
|
|
|
|
GdkModifierType mods;
|
|
|
|
}
|
|
|
|
accelData;
|
|
|
|
|
|
|
|
static void
|
2023-02-06 17:50:14 +01:00
|
|
|
gui_check_unique_accelerators (Gimp *gimp)
|
2016-11-21 16:52:52 +01:00
|
|
|
{
|
2023-02-06 17:50:14 +01:00
|
|
|
gchar **actions;
|
2016-11-21 16:52:52 +01:00
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
actions = g_action_group_list_actions (G_ACTION_GROUP (gimp->app));
|
2017-12-05 01:10:13 +01:00
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
for (gint i = 0; actions[i] != NULL; i++)
|
2017-12-05 01:10:13 +01:00
|
|
|
{
|
2023-09-05 22:35:06 +00:00
|
|
|
gchar **accels;
|
|
|
|
gchar *detailed_name;
|
|
|
|
GimpAction *action;
|
|
|
|
gint value;
|
|
|
|
|
|
|
|
action = (GimpAction *) g_action_map_lookup_action (G_ACTION_MAP (gimp->app), actions[i]);
|
|
|
|
|
|
|
|
if (GIMP_IS_RADIO_ACTION (action))
|
|
|
|
{
|
|
|
|
g_object_get ((GObject *) action,
|
|
|
|
"value", &value,
|
|
|
|
NULL);
|
|
|
|
detailed_name = g_strdup_printf ("app.%s(%i)", actions[i],
|
|
|
|
value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
detailed_name = g_strdup_printf ("app.%s", actions[i]);
|
|
|
|
}
|
2019-07-02 03:54:38 +02:00
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
accels = gtk_application_get_accels_for_action (GTK_APPLICATION (gimp->app),
|
|
|
|
detailed_name);
|
2023-05-23 00:11:23 +02:00
|
|
|
g_free (detailed_name);
|
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
for (gint j = 0; accels[j] != NULL; j++)
|
2017-12-05 01:10:13 +01:00
|
|
|
{
|
2023-02-06 17:50:14 +01:00
|
|
|
for (gint k = i + 1; actions[k] != NULL; k++)
|
2017-12-05 01:10:13 +01:00
|
|
|
{
|
2023-09-05 22:35:06 +00:00
|
|
|
gchar **accels2;
|
|
|
|
gchar *detailed_name2;
|
|
|
|
GimpAction *action2;
|
|
|
|
|
|
|
|
action2 = (GimpAction *) g_action_map_lookup_action (G_ACTION_MAP (gimp->app), actions[k]);
|
|
|
|
|
|
|
|
if (GIMP_IS_RADIO_ACTION (action2))
|
|
|
|
{
|
|
|
|
g_object_get ((GObject *) action2,
|
|
|
|
"value", &value,
|
|
|
|
NULL);
|
|
|
|
detailed_name2 = g_strdup_printf ("app.%s(%i)", actions[k],
|
|
|
|
value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
detailed_name2 = g_strdup_printf ("app.%s", actions[k]);
|
|
|
|
}
|
2023-02-06 17:50:14 +01:00
|
|
|
|
|
|
|
accels2 = gtk_application_get_accels_for_action (GTK_APPLICATION (gimp->app),
|
|
|
|
detailed_name2);
|
2023-05-23 00:11:23 +02:00
|
|
|
g_free (detailed_name2);
|
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
for (gint l = 0; accels2[l] != NULL; l++)
|
|
|
|
{
|
|
|
|
if (g_strcmp0 (accels[j], accels2[l]) == 0)
|
|
|
|
{
|
|
|
|
GAction *action;
|
|
|
|
gchar *disabled_action;
|
|
|
|
gchar **disabled_accels;
|
|
|
|
gint len;
|
|
|
|
gint remove;
|
2023-10-04 00:02:53 +02:00
|
|
|
gboolean print_warning = TRUE;
|
2023-02-06 17:50:14 +01:00
|
|
|
|
2023-10-04 00:02:53 +02:00
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (gimp->app),
|
|
|
|
actions[i]);
|
2023-02-06 17:50:14 +01:00
|
|
|
/* Just keep the first one (no reason other than we have
|
|
|
|
* to choose), unless it's a secondary shortcut, and the
|
|
|
|
* second is a primary shortcut.
|
|
|
|
*/
|
2023-10-04 00:02:53 +02:00
|
|
|
if ((l == 0 && j != 0) ||
|
|
|
|
/* If the first action is one of "view-zoom-1-*" and
|
|
|
|
* the shortcut default, we assume it's because of our
|
|
|
|
* trick to transform `Shift+num` shortcuts based on
|
|
|
|
* layout and we happen to be on a layout where it
|
|
|
|
* clashes with other shortcuts. In this case, we
|
|
|
|
* drop the duplicate shortcut on the zoom action. See
|
|
|
|
* special code in
|
|
|
|
* gimp_action_group_add_action_with_accel()
|
|
|
|
*/
|
|
|
|
(g_str_has_prefix (actions[i], "view-zoom-1-") &&
|
|
|
|
gimp_action_is_default_accel (GIMP_ACTION (action), accels[j])))
|
2023-02-06 17:50:14 +01:00
|
|
|
{
|
|
|
|
disabled_action = actions[i];
|
|
|
|
disabled_accels = accels;
|
|
|
|
remove = j;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
disabled_action = actions[k];
|
|
|
|
disabled_accels = accels2;
|
|
|
|
remove = l;
|
|
|
|
}
|
2023-10-04 00:02:53 +02:00
|
|
|
|
|
|
|
action = g_action_map_lookup_action (G_ACTION_MAP (gimp->app),
|
|
|
|
disabled_action);
|
|
|
|
|
|
|
|
if (g_str_has_prefix (disabled_action, "view-zoom-1-") &&
|
|
|
|
gimp_action_is_default_accel (GIMP_ACTION (action), disabled_accels[remove]))
|
|
|
|
/* We drop the shortcut **silently** because it will be
|
|
|
|
* a case where we have 2 default accelerators clashing
|
|
|
|
* (because of the conversion code) while not being a
|
|
|
|
* real bug. Clashes with custom accelerators are
|
|
|
|
* handled by shortcuts_action_deserialize().
|
|
|
|
*/
|
|
|
|
print_warning = FALSE;
|
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
/* Remove only the duplicate shortcut but keep others. */
|
|
|
|
len = g_strv_length (disabled_accels);
|
|
|
|
g_free (disabled_accels[remove]);
|
|
|
|
memmove (&disabled_accels[remove],
|
|
|
|
&disabled_accels[remove + 1],
|
|
|
|
sizeof (char *) * (len - remove));
|
|
|
|
|
2023-10-04 00:02:53 +02:00
|
|
|
if (print_warning)
|
|
|
|
g_printerr ("Actions \"%s\" and \"%s\" use the same accelerator.\n"
|
|
|
|
" Disabling the accelerator on \"%s\".\n",
|
|
|
|
actions[i], actions[k], disabled_action);
|
2023-02-06 17:50:14 +01:00
|
|
|
|
|
|
|
gimp_action_set_accels (GIMP_ACTION (action),
|
|
|
|
(const gchar **) disabled_accels);
|
|
|
|
}
|
|
|
|
}
|
2023-05-23 00:11:23 +02:00
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
g_strfreev (accels2);
|
2017-12-05 01:10:13 +01:00
|
|
|
}
|
|
|
|
}
|
2023-05-23 00:11:23 +02:00
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
g_strfreev (accels);
|
2017-12-05 01:10:13 +01:00
|
|
|
}
|
2023-05-23 00:11:23 +02:00
|
|
|
|
2023-02-06 17:50:14 +01:00
|
|
|
g_strfreev (actions);
|
2017-12-05 01:10:13 +01:00
|
|
|
}
|