From 8356003fa2abdf93b92c8f708d99edc756bcce10 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sat, 3 May 2014 00:54:20 +0200 Subject: [PATCH] app: pass the startup monitor to displays opened from the copmmand line Change gimp_get_display_name() to also return the screen, and its implementation in the GUI to return the initial monitor during startup. Retrieve that information in app.c using a weird callback construct and pass the monitor to file_open_from_command_line(). Half-related, add screen and monitor parameters to GimpDisplayShell and use these initial values for calculating the canvas's initial extents. The image windows still don't position themselves correctly though because we have no mechanism for that whatsoever just yet, but we now at least pass the needed monitor information to the right objects. --- app/app.c | 44 ++++++++++++++++++----- app/core/gimp-gui.c | 15 ++++---- app/core/gimp-gui.h | 6 ++-- app/display/gimpdisplay.c | 4 ++- app/display/gimpdisplayshell.c | 54 +++++++++++++++++++++------- app/display/gimpdisplayshell.h | 6 +++- app/gui/gui-vtable.c | 31 +++++++++------- app/gui/gui-vtable.h | 8 ++++- app/gui/gui.c | 19 ++++++++-- app/plug-in/gimppluginmanager-call.c | 4 ++- 10 files changed, 144 insertions(+), 47 deletions(-) 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);