diff --git a/app/app.c b/app/app.c index 7c621cd281..609aa33270 100644 --- a/app/app.c +++ b/app/app.c @@ -70,12 +70,20 @@ /* local prototypes */ -static void app_init_update_noop (const gchar *text1, - const gchar *text2, - gdouble percentage); -static gboolean app_exit_after_callback (Gimp *gimp, - gboolean kill_it, - GMainLoop **loop); +static void app_init_update_noop (const gchar *text1, + const gchar *text2, + gdouble percentage); +static void app_restore_after_callback (Gimp *gimp, + GimpInitStatusFunc status_callback); +static gboolean app_exit_after_callback (Gimp *gimp, + gboolean kill_it, + GMainLoop **loop); + + +/* local variables */ + +static GObject *initial_screen = NULL; +static gint initial_monitor = 0; /* public functions */ @@ -224,6 +232,14 @@ app_run (const gchar *full_prog_name, /* initialize lowlevel stuff */ gimp_gegl_init (gimp); + /* Connect our restore_after callback before gui_init() connects + * theirs, so ours runs first and can grab the initial monitor + * before the GUI's restore_after callback resets it. + */ + g_signal_connect_after (gimp, "restore", + G_CALLBACK (app_restore_after_callback), + NULL); + #ifndef GIMP_CONSOLE_COMPILATION if (! no_interface) update_status_func = gui_init (gimp, no_splash); @@ -262,8 +278,8 @@ app_run (const gchar *full_prog_name, { if (run_loop) file_open_from_command_line (gimp, filenames[i], as_new, - NULL, /* FIXME monitor */ - 0 /* FIXME monitor */); + initial_screen, + initial_monitor); } } @@ -298,6 +314,18 @@ app_init_update_noop (const gchar *text1, /* deliberately do nothing */ } +static void +app_restore_after_callback (Gimp *gimp, + GimpInitStatusFunc status_callback) +{ + /* Getting the display name for a -1 display returns the initial + * monitor during startup. Need to call this from a restore_after + * callback, because before restore(), the GUI can't return anything, + * after after restore() the initial monitor gets reset. + */ + g_free (gimp_get_display_name (gimp, -1, &initial_screen, &initial_monitor)); +} + static gboolean app_exit_after_callback (Gimp *gimp, gboolean kill_it, diff --git a/app/core/gimp-gui.c b/app/core/gimp-gui.c index 27e1c050ec..71ff90cbf4 100644 --- a/app/core/gimp-gui.c +++ b/app/core/gimp-gui.c @@ -214,17 +214,20 @@ gimp_get_program_class (Gimp *gimp) } gchar * -gimp_get_display_name (Gimp *gimp, - gint display_ID, - gint *monitor_number) +gimp_get_display_name (Gimp *gimp, + gint display_ID, + GObject **screen, + gint *monitor) { g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); - g_return_val_if_fail (monitor_number != NULL, NULL); + g_return_val_if_fail (screen != NULL, NULL); + g_return_val_if_fail (monitor != NULL, NULL); if (gimp->gui.get_display_name) - return gimp->gui.get_display_name (gimp, display_ID, monitor_number); + return gimp->gui.get_display_name (gimp, display_ID, screen, monitor); - *monitor_number = 0; + *screen = NULL; + *monitor = 0; return NULL; } diff --git a/app/core/gimp-gui.h b/app/core/gimp-gui.h index be6225c1f2..9d371f2680 100644 --- a/app/core/gimp-gui.h +++ b/app/core/gimp-gui.h @@ -44,7 +44,8 @@ struct _GimpGui const gchar * (* get_program_class) (Gimp *gimp); gchar * (* get_display_name) (Gimp *gimp, gint display_ID, - gint *monitor_number); + GObject **screen, + gint *monitor); guint32 (* get_user_time) (Gimp *gimp); const gchar * (* get_theme_dir) (Gimp *gimp); @@ -144,7 +145,8 @@ void gimp_free_progress (Gimp *gimp, const gchar * gimp_get_program_class (Gimp *gimp); gchar * gimp_get_display_name (Gimp *gimp, gint display_ID, - gint *monitor_number); + GObject **screen, + gint *monitor); guint32 gimp_get_user_time (Gimp *gimp); const gchar * gimp_get_theme_dir (Gimp *gimp); diff --git a/app/display/gimpdisplay.c b/app/display/gimpdisplay.c index c94b8ab5c1..06b8abe869 100644 --- a/app/display/gimpdisplay.c +++ b/app/display/gimpdisplay.c @@ -453,7 +453,9 @@ gimp_display_new (Gimp *gimp, /* create the shell for the image */ private->shell = gimp_display_shell_new (display, unit, scale, - popup_manager); + popup_manager, + screen, + monitor); shell = gimp_display_get_shell (display); diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 8e9726194f..ee78cd9ca4 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -96,6 +96,8 @@ enum { PROP_0, PROP_POPUP_MANAGER, + PROP_INITIAL_SCREEN, + PROP_INITIAL_MONITOR, PROP_DISPLAY, PROP_UNIT, PROP_TITLE, @@ -257,6 +259,20 @@ gimp_display_shell_class_init (GimpDisplayShellClass *klass) GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_INITIAL_SCREEN, + g_param_spec_object ("initial-screen", + NULL, NULL, + GDK_TYPE_SCREEN, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_INITIAL_MONITOR, + g_param_spec_int ("initial-monitor", + NULL, NULL, + 0, 16, 0, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_object ("display", NULL, NULL, GIMP_TYPE_DISPLAY, @@ -370,7 +386,6 @@ gimp_display_shell_constructed (GObject *object) GtkWidget *lower_hbox; GtkWidget *inner_table; GtkWidget *gtk_image; - GdkScreen *screen; GtkAction *action; gint image_width; gint image_height; @@ -402,12 +417,10 @@ gimp_display_shell_constructed (GObject *object) shell->dot_for_dot = config->default_dot_for_dot; - screen = gtk_widget_get_screen (GTK_WIDGET (shell)); - if (config->monitor_res_from_gdk) { - gimp_get_monitor_resolution (screen, /* FIXME monitor */ - 0, /* FIXME monitor */ + gimp_get_monitor_resolution (shell->initial_screen, + shell->initial_monitor, &shell->monitor_xres, &shell->monitor_yres); } else @@ -908,6 +921,12 @@ gimp_display_shell_set_property (GObject *object, case PROP_POPUP_MANAGER: shell->popup_manager = g_value_get_object (value); break; + case PROP_INITIAL_SCREEN: + shell->initial_screen = g_value_get_object (value); + break; + case PROP_INITIAL_MONITOR: + shell->initial_monitor = g_value_get_int (value); + break; case PROP_DISPLAY: shell->display = g_value_get_object (value); break; @@ -947,6 +966,12 @@ gimp_display_shell_get_property (GObject *object, case PROP_POPUP_MANAGER: g_value_set_object (value, shell->popup_manager); break; + case PROP_INITIAL_SCREEN: + g_value_set_object (value, shell->initial_screen); + break; + case PROP_INITIAL_MONITOR: + g_value_set_int (value, shell->initial_monitor); + break; case PROP_DISPLAY: g_value_set_object (value, shell->display); break; @@ -1176,18 +1201,23 @@ gimp_display_shell_transform_overlay (GimpDisplayShell *shell, /* public functions */ GtkWidget * -gimp_display_shell_new (GimpDisplay *display, - GimpUnit unit, - gdouble scale, - GimpUIManager *popup_manager) +gimp_display_shell_new (GimpDisplay *display, + GimpUnit unit, + gdouble scale, + GimpUIManager *popup_manager, + GdkScreen *screen, + gint monitor) { g_return_val_if_fail (GIMP_IS_DISPLAY (display), NULL); g_return_val_if_fail (GIMP_IS_UI_MANAGER (popup_manager), NULL); + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); return g_object_new (GIMP_TYPE_DISPLAY_SHELL, - "popup-manager", popup_manager, - "display", display, - "unit", unit, + "popup-manager", popup_manager, + "initial-screen", screen, + "initial-monitor", monitor, + "display", display, + "unit", unit, NULL); } diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index e5074bb885..d459b8a739 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -52,6 +52,8 @@ struct _GimpDisplayShell GimpDisplay *display; GimpUIManager *popup_manager; + GdkScreen *initial_screen; + gint initial_monitor; GimpDisplayOptions *options; GimpDisplayOptions *fullscreen_options; @@ -214,7 +216,9 @@ GType gimp_display_shell_get_type (void) G_GNUC_CONST; GtkWidget * gimp_display_shell_new (GimpDisplay *display, GimpUnit unit, gdouble scale, - GimpUIManager *popup_manager); + GimpUIManager *popup_manager, + GdkScreen *screen, + gint monitor); void gimp_display_shell_add_overlay (GimpDisplayShell *shell, GtkWidget *child, diff --git a/app/gui/gui-vtable.c b/app/gui/gui-vtable.c index b9648764a8..426e94bf50 100644 --- a/app/gui/gui-vtable.c +++ b/app/gui/gui-vtable.c @@ -72,6 +72,7 @@ #include "menus/menus.h" +#include "gui.h" #include "gui-message.h" #include "gui-vtable.h" #include "themes.h" @@ -92,7 +93,8 @@ static void gui_help (Gimp *gimp, static const gchar * gui_get_program_class (Gimp *gimp); static gchar * gui_get_display_name (Gimp *gimp, gint display_ID, - gint *monitor_number); + GObject **screen, + gint *monitor); static guint32 gui_get_user_time (Gimp *gimp); static const gchar * gui_get_theme_dir (Gimp *gimp); static GimpObject * gui_get_window_strategy (Gimp *gimp); @@ -233,13 +235,13 @@ gui_get_program_class (Gimp *gimp) } static gchar * -gui_get_display_name (Gimp *gimp, - gint display_ID, - gint *monitor_number) +gui_get_display_name (Gimp *gimp, + gint display_ID, + GObject **screen, + gint *monitor) { - GimpDisplay *display = NULL; - GdkScreen *screen; - gint monitor; + GimpDisplay *display = NULL; + GdkScreen *my_screen = NULL; if (display_ID > 0) display = gimp_display_get_by_ID (gimp, display_ID); @@ -249,18 +251,21 @@ gui_get_display_name (Gimp *gimp, GimpDisplayShell *shell = gimp_display_get_shell (display); GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (shell)); - screen = gtk_widget_get_screen (GTK_WIDGET (shell)); - monitor = gdk_screen_get_monitor_at_window (screen, window); + my_screen = gtk_widget_get_screen (GTK_WIDGET (shell)); + *monitor = gdk_screen_get_monitor_at_window (my_screen, window); } else { - monitor = gimp_get_monitor_at_pointer (&screen); + *monitor = gui_get_initial_monitor (gimp, &my_screen); + + if (*monitor == -1) + *monitor = gimp_get_monitor_at_pointer (&my_screen); } - *monitor_number = monitor; + *screen = G_OBJECT (my_screen); - if (screen) - return gdk_screen_make_display_name (screen); + if (my_screen) + return gdk_screen_make_display_name (my_screen); return NULL; } diff --git a/app/gui/gui-vtable.h b/app/gui/gui-vtable.h index d0108c3e63..b23f0dba93 100644 --- a/app/gui/gui-vtable.h +++ b/app/gui/gui-vtable.h @@ -19,7 +19,13 @@ #define __GUI_VTABLE_H__ -void gui_vtable_init (Gimp *gimp); +void gui_vtable_init (Gimp *gimp); + +/* this function lives in gui.c but must only be used from gui-vtable.c; + * also, gui.h can't contain any Gdk types. + */ +gint gui_get_initial_monitor (Gimp *gimp, + GdkScreen **screen); #endif /* __GUI_VTABLE_H__ */ diff --git a/app/gui/gui.c b/app/gui/gui.c index 0ad2b704d0..25f96b2074 100644 --- a/app/gui/gui.c +++ b/app/gui/gui.c @@ -141,7 +141,7 @@ static Gimp *the_gui_gimp = NULL; static GimpUIManager *image_ui_manager = NULL; static GimpUIConfigurer *ui_configurer = NULL; static GdkScreen *initial_screen = NULL; -static gint initial_monitor = 0; +static gint initial_monitor = -1; /* public functions */ @@ -264,6 +264,18 @@ gui_init (Gimp *gimp, return status_callback; } +gint +gui_get_initial_monitor (Gimp *gimp, + GdkScreen **screen) +{ + g_return_val_if_fail (GIMP_IS_GIMP (gimp), 0); + g_return_val_if_fail (screen != NULL, 0); + + *screen = initial_screen; + + return initial_monitor; +} + /* private functions */ @@ -300,7 +312,6 @@ gui_sanity_check (void) return NULL; } - static void gui_help_func (const gchar *help_id, gpointer help_data) @@ -595,6 +606,10 @@ gui_restore_after_callback (Gimp *gimp, /* indicate that the application has finished loading */ gdk_notify_startup_complete (); + + /* clear startup monitor variables */ + initial_screen = NULL; + initial_monitor = -1; } static gboolean diff --git a/app/plug-in/gimppluginmanager-call.c b/app/plug-in/gimppluginmanager-call.c index c16adf698f..a85112e712 100644 --- a/app/plug-in/gimppluginmanager-call.c +++ b/app/plug-in/gimppluginmanager-call.c @@ -161,6 +161,7 @@ gimp_plug_in_manager_call_run (GimpPlugInManager *manager, GPConfig config; GPProcRun proc_run; gint display_ID; + GObject *screen; gint monitor; if (! gimp_plug_in_open (plug_in, GIMP_PLUG_IN_CALL_RUN, FALSE)) @@ -203,7 +204,8 @@ gimp_plug_in_manager_call_run (GimpPlugInManager *manager, config.app_name = (gchar *) g_get_application_name (); config.wm_class = (gchar *) gimp_get_program_class (manager->gimp); config.display_name = gimp_get_display_name (manager->gimp, - display_ID, &monitor); + display_ID, + &screen, &monitor); config.monitor_number = monitor; config.timestamp = gimp_get_user_time (manager->gimp);