GtkWidget * gimp_session_info_get_widget (GimpSessionInfo *info) { g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE); return info->p->widget; }
GimpDialogFactoryEntry * gimp_session_info_get_factory_entry (GimpSessionInfo *info) { g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE); return info->p->factory_entry; }
gint gimp_session_info_get_height (GimpSessionInfo *info) { g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), 0); return info->p->height; }
void gimp_session_info_get_info (GimpSessionInfo *info) { g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WIDGET (info->p->widget)); gimp_session_info_read_geometry (info, NULL /*cevent*/); if (GIMP_IS_SESSION_MANAGED (info->p->widget)) info->p->aux_info = gimp_session_managed_get_aux_info (GIMP_SESSION_MANAGED (info->p->widget)); if (GIMP_IS_DOCK_CONTAINER (info->p->widget)) { GimpDockContainer *dock_container = GIMP_DOCK_CONTAINER (info->p->widget); GList *iter = NULL; GList *docks; docks = gimp_dock_container_get_docks (dock_container); for (iter = docks; iter; iter = g_list_next (iter)) { GimpDock *dock = GIMP_DOCK (iter->data); info->p->docks = g_list_append (info->p->docks, gimp_session_info_dock_from_widget (dock)); } g_list_free (docks); } }
gboolean gimp_session_info_get_open (GimpSessionInfo *info) { g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE); return info->p->open; }
void gimp_session_info_set_factory_entry (GimpSessionInfo *info, GimpDialogFactoryEntry *entry) { g_return_if_fail (GIMP_IS_SESSION_INFO (info)); info->p->factory_entry = entry; }
gboolean gimp_session_info_get_remember_if_open (GimpSessionInfo *info) { g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE); return (gimp_session_info_is_for_dock_window (info) || (info->p->factory_entry && info->p->factory_entry->remember_if_open)); }
gboolean gimp_session_info_is_session_managed (GimpSessionInfo *info) { g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE); return (gimp_session_info_is_for_dock_window (info) || (info->p->factory_entry && info->p->factory_entry->session_managed)); }
gboolean gimp_session_info_is_singleton (GimpSessionInfo *info) { g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE); return (! gimp_session_info_is_for_dock_window (info) && info->p->factory_entry && info->p->factory_entry->singleton); }
void gimp_session_info_restore (GimpSessionInfo *info, GimpDialogFactory *factory) { GtkWidget *dialog = NULL; GdkDisplay *display = NULL; GdkScreen *screen = NULL; GimpRestoreDocksData *data = NULL; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_object_ref (info); display = gdk_display_get_default (); if (info->p->screen != DEFAULT_SCREEN) screen = gdk_display_get_screen (display, info->p->screen); if (! screen) screen = gdk_display_get_default_screen (display); info->p->open = FALSE; info->p->screen = DEFAULT_SCREEN; if (info->p->factory_entry && info->p->factory_entry->restore_func) { dialog = info->p->factory_entry->restore_func (factory, screen, info); } if (GIMP_IS_SESSION_MANAGED (dialog) && info->p->aux_info) gimp_session_managed_set_aux_info (GIMP_SESSION_MANAGED (dialog), info->p->aux_info); /* In single-window mode, gimp_session_managed_set_aux_info() * will set the size of the dock areas at the sides. If we don't * wait for those areas to get their size-allocation, we can't * properly restore the docks inside them, so do that in an idle * callback. */ /* Objects are unreffed again in the callback */ data = g_slice_new0 (GimpRestoreDocksData); data->info = g_object_ref (info); data->factory = g_object_ref (factory); data->screen = g_object_ref (screen); data->dialog = g_object_ref (dialog); g_idle_add ((GSourceFunc) gimp_session_info_restore_docks, data); g_object_unref (info); }
void gimp_session_info_set_widget (GimpSessionInfo *info, GtkWidget *widget) { g_return_if_fail (GIMP_IS_SESSION_INFO (info)); if (GTK_IS_WINDOW (info->p->widget)) g_signal_handlers_disconnect_by_func (info->p->widget, gimp_session_info_dialog_show, info); info->p->widget = widget; }
/** * gimp_session_info_get_info_with_widget: * @info: * @widget: #GtkWidget to use * * Temporarily sets @widget on @info and calls * gimp_session_info_get_info(), then restores the old widget that was * set. **/ void gimp_session_info_get_info_with_widget (GimpSessionInfo *info, GtkWidget *widget) { GtkWidget *old_widget; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WIDGET (widget)); old_widget = gimp_session_info_get_widget (info); gimp_session_info_set_widget (info, widget); gimp_session_info_get_info (info); gimp_session_info_set_widget (info, old_widget); }
void gimp_session_info_restore (GimpSessionInfo *info, GimpDialogFactory *factory, GdkMonitor *monitor) { GtkWidget *dialog = NULL; GimpRestoreDocksData *data; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GIMP_IS_DIALOG_FACTORY (factory)); g_return_if_fail (GDK_IS_MONITOR (monitor)); g_object_ref (info); info->p->open = FALSE; if (info->p->factory_entry && info->p->factory_entry->restore_func) { dialog = info->p->factory_entry->restore_func (factory, monitor, info); } else g_printerr ("EEEEK\n"); if (GIMP_IS_SESSION_MANAGED (dialog) && info->p->aux_info) gimp_session_managed_set_aux_info (GIMP_SESSION_MANAGED (dialog), info->p->aux_info); /* In single-window mode, gimp_session_managed_set_aux_info() * will set the size of the dock areas at the sides. If we don't * wait for those areas to get their size-allocation, we can't * properly restore the docks inside them, so do that in an idle * callback. */ /* Objects are unreffed again in the callback */ data = g_slice_new0 (GimpRestoreDocksData); data->info = g_object_ref (info); data->factory = g_object_ref (factory); data->monitor = g_object_ref (monitor); data->dialog = dialog ? g_object_ref (dialog) : NULL; g_idle_add ((GSourceFunc) gimp_session_info_restore_docks, data); g_object_unref (info); }
void gimp_session_info_clear_info (GimpSessionInfo *info) { g_return_if_fail (GIMP_IS_SESSION_INFO (info)); if (info->p->aux_info) { g_list_free_full (info->p->aux_info, (GDestroyNotify) gimp_session_info_aux_free); info->p->aux_info = NULL; } if (info->p->docks) { g_list_free_full (info->p->docks, (GDestroyNotify) gimp_session_info_dock_free); info->p->docks = NULL; } }
/** * gimp_session_info_apply_geometry: * @info: * @monitor: * @current_monitor: * * Apply the geometry stored in the session info object to the * associated widget. **/ void gimp_session_info_apply_geometry (GimpSessionInfo *info, GdkMonitor *current_monitor, gboolean apply_stored_monitor) { GdkMonitor *monitor; GdkRectangle rect; GdkRectangle work_rect; GdkGravity gravity; GdkWindowHints hints; gint width; gint height; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WINDOW (info->p->widget)); g_return_if_fail (GDK_IS_MONITOR (current_monitor)); monitor = current_monitor; if (apply_stored_monitor) { GdkDisplay *display = gdk_monitor_get_display (current_monitor); gint n_monitors; n_monitors = gdk_display_get_n_monitors (display); if (info->p->monitor != DEFAULT_MONITOR && monitor_number (info->p->monitor) < n_monitors) { monitor = info->p->monitor; } else { monitor = gdk_display_get_primary_monitor (display); } } gdk_monitor_get_geometry (monitor, &rect); gdk_monitor_get_workarea (monitor, &work_rect); info->p->x += rect.x; info->p->y += rect.y; if (gimp_session_info_get_remember_size (info) && info->p->width > 0 && info->p->height > 0) { width = info->p->width; height = info->p->height; } else { GtkRequisition requisition; gtk_widget_get_preferred_size (info->p->widget, NULL, &requisition); width = requisition.width; height = requisition.height; } info->p->x = CLAMP (info->p->x, work_rect.x, work_rect.x + work_rect.width - width); info->p->y = CLAMP (info->p->y, work_rect.y, work_rect.y + work_rect.height - height); if (gimp_session_info_get_remember_size (info) && info->p->width > 0 && info->p->height > 0) { /* This used to call gtk_window_set_default_size() which worked * fine in gtk2 and should continue to work, but doesn't for * dock windows. gtk_window_resize() seems to work fine for all * windows. Leave this comment here until we figured what's * going on... * * XXX If we end up updating this code, also do the same to the * gtk_window_resize() call in gimp_session_info_dialog_show() * signal handler. */ #if 1 gtk_window_resize (GTK_WINDOW (info->p->widget), info->p->width, info->p->height); #else gtk_window_set_default_size (GTK_WINDOW (info->p->widget), info->p->width, info->p->height); #endif } gtk_window_get_size (GTK_WINDOW (info->p->widget), &width, &height); gravity = GDK_GRAVITY_NORTH_WEST; if (info->p->right_align && info->p->bottom_align) { gravity = GDK_GRAVITY_SOUTH_EAST; } else if (info->p->right_align) { gravity = GDK_GRAVITY_NORTH_EAST; } else if (info->p->bottom_align) { gravity = GDK_GRAVITY_SOUTH_WEST; } if (gravity == GDK_GRAVITY_SOUTH_EAST || gravity == GDK_GRAVITY_NORTH_EAST) info->p->x = work_rect.x + work_rect.width - width; if (gravity == GDK_GRAVITY_SOUTH_WEST || gravity == GDK_GRAVITY_SOUTH_EAST) info->p->y = work_rect.y + work_rect.height - height; gtk_window_set_gravity (GTK_WINDOW (info->p->widget), gravity); gtk_window_move (GTK_WINDOW (info->p->widget), info->p->x, info->p->y); hints = GDK_HINT_USER_POS; if (gimp_session_info_get_remember_size (info)) hints |= GDK_HINT_USER_SIZE; gtk_window_set_geometry_hints (GTK_WINDOW (info->p->widget), NULL, NULL, hints); /* Window managers and windowing systems suck. They have their own * ideas about WM standards and when it's appropriate to honor * user/application-set window positions and when not. Therefore, * use brute force and "manually" position dialogs whenever they * are shown. This is important especially for transient dialogs, * because window managers behave even "smarter" then... */ if (GTK_IS_WINDOW (info->p->widget)) g_signal_connect (info->p->widget, "show", G_CALLBACK (gimp_session_info_dialog_show), info); }
/** * gimp_session_info_read_geometry: * @info: A #GimpSessionInfo * @cevent A #GdkEventConfigure. If set, use the size from here * instead of from the window allocation. * * Read geometry related information from the associated widget. **/ void gimp_session_info_read_geometry (GimpSessionInfo *info, GdkEventConfigure *cevent) { GdkWindow *window; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WINDOW (info->p->widget)); window = gtk_widget_get_window (info->p->widget); if (window) { gint x, y; gdk_window_get_root_origin (window, &x, &y); /* Don't write negative values to the sessionrc, they are * interpreted as relative to the right, respective bottom edge * of the screen. */ info->p->x = MAX (0, x); info->p->y = MAX (0, y); if (gimp_session_info_get_remember_size (info)) { int width; int height; if (cevent) { width = cevent->width; height = cevent->height; } else { GtkAllocation allocation; gtk_widget_get_allocation (info->p->widget, &allocation); width = allocation.width; height = allocation.height; } info->p->width = width; info->p->height = height; } else { info->p->width = 0; info->p->height = 0; } } info->p->open = FALSE; if (gimp_session_info_get_remember_if_open (info)) { GimpDialogVisibilityState visibility; visibility = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info->p->widget), GIMP_DIALOG_VISIBILITY_KEY)); switch (visibility) { case GIMP_DIALOG_VISIBILITY_UNKNOWN: info->p->open = gtk_widget_get_visible (info->p->widget); break; case GIMP_DIALOG_VISIBILITY_INVISIBLE: info->p->open = FALSE; break; case GIMP_DIALOG_VISIBILITY_HIDDEN: case GIMP_DIALOG_VISIBILITY_VISIBLE: /* Even if a dialog is hidden (with Windows->Hide docks) it * is still considered open. It will be restored the next * time GIMP starts */ info->p->open = TRUE; break; } } info->p->screen = DEFAULT_SCREEN; if (info->p->open) { GdkDisplay *display = gtk_widget_get_display (info->p->widget); GdkScreen *screen = gtk_widget_get_screen (info->p->widget); if (screen != gdk_display_get_default_screen (display)) info->p->screen = gdk_screen_get_number (screen); } }
/** * gimp_session_info_apply_geometry: * @info: * * Apply the geometry stored in the session info object to the * associated widget. **/ void gimp_session_info_apply_geometry (GimpSessionInfo *info) { GdkScreen *screen; GdkRectangle rect; gchar geom[32]; gint monitor; gboolean use_size; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WINDOW (info->p->widget)); screen = gtk_widget_get_screen (info->p->widget); use_size = (gimp_session_info_get_remember_size (info) && info->p->width > 0 && info->p->height > 0); if (use_size) { monitor = gimp_session_info_get_appropriate_monitor (screen, info->p->x, info->p->y, info->p->width, info->p->height); } else { monitor = gdk_screen_get_monitor_at_point (screen, info->p->x, info->p->y); } gdk_screen_get_monitor_geometry (screen, monitor, &rect); info->p->x = CLAMP (info->p->x, rect.x, rect.x + rect.width - (info->p->width > 0 ? info->p->width : 128)); info->p->y = CLAMP (info->p->y, rect.y, rect.y + rect.height - (info->p->height > 0 ? info->p->height : 128)); if (info->p->right_align && info->p->bottom_align) { g_strlcpy (geom, "-0-0", sizeof (geom)); } else if (info->p->right_align) { g_snprintf (geom, sizeof (geom), "-0%+d", info->p->y); } else if (info->p->bottom_align) { g_snprintf (geom, sizeof (geom), "%+d-0", info->p->x); } else { g_snprintf (geom, sizeof (geom), "%+d%+d", info->p->x, info->p->y); } gtk_window_parse_geometry (GTK_WINDOW (info->p->widget), geom); if (use_size) gtk_window_set_default_size (GTK_WINDOW (info->p->widget), info->p->width, info->p->height); /* Window managers and windowing systems suck. They have their own * ideas about WM standards and when it's appropriate to honor * user/application-set window positions and when not. Therefore, * use brute force and "manually" position dialogs whenever they * are shown. This is important especially for transient dialog, * because window managers behave even "smarter" then... */ if (GTK_IS_DIALOG (info->p->widget)) g_signal_connect (info->p->widget, "show", G_CALLBACK (gimp_session_info_dialog_show), info); }
/** * gimp_session_info_read_geometry: * @info: A #GimpSessionInfo * @cevent A #GdkEventConfigure. If set, use the size from here * instead of from the window allocation. * * Read geometry related information from the associated widget. **/ void gimp_session_info_read_geometry (GimpSessionInfo *info, GdkEventConfigure *cevent) { GdkWindow *window; GdkDisplay *display; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WINDOW (info->p->widget)); window = gtk_widget_get_window (info->p->widget); display = gtk_widget_get_display (info->p->widget); if (window) { gint x, y; GdkMonitor *monitor; GdkRectangle geometry; gtk_window_get_position (GTK_WINDOW (info->p->widget), &x, &y); /* Don't write negative values to the sessionrc, they are * interpreted as relative to the right, respective bottom edge * of the display. */ info->p->x = MAX (0, x); info->p->y = MAX (0, y); monitor = gdk_display_get_monitor_at_point (display, info->p->x, info->p->y); gdk_monitor_get_geometry (monitor, &geometry); /* Always store window coordinates relative to the monitor */ info->p->x -= geometry.x; info->p->y -= geometry.y; if (gimp_session_info_get_remember_size (info)) { gtk_window_get_size (GTK_WINDOW (info->p->widget), &info->p->width, &info->p->height); } else { info->p->width = 0; info->p->height = 0; } info->p->monitor = DEFAULT_MONITOR; if (monitor != gdk_display_get_primary_monitor (display)) info->p->monitor = monitor; } info->p->open = FALSE; if (gimp_session_info_get_remember_if_open (info)) { GimpDialogVisibilityState visibility; visibility = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info->p->widget), GIMP_DIALOG_VISIBILITY_KEY)); switch (visibility) { case GIMP_DIALOG_VISIBILITY_UNKNOWN: info->p->open = gtk_widget_get_visible (info->p->widget); break; case GIMP_DIALOG_VISIBILITY_INVISIBLE: info->p->open = FALSE; break; case GIMP_DIALOG_VISIBILITY_HIDDEN: case GIMP_DIALOG_VISIBILITY_VISIBLE: /* Even if a dialog is hidden (with Windows->Hide docks) it * is still considered open. It will be restored the next * time GIMP starts */ info->p->open = TRUE; break; } } }
/** * gimp_session_info_apply_geometry: * @info: * @screen: * @current_monitor: * * Apply the geometry stored in the session info object to the * associated widget. **/ void gimp_session_info_apply_geometry (GimpSessionInfo *info, GdkScreen *screen, gint current_monitor, gboolean apply_stored_monitor) { GdkRectangle rect; GdkRectangle work_rect; gchar geom[32]; gint monitor; gint width; gint height; g_return_if_fail (GIMP_IS_SESSION_INFO (info)); g_return_if_fail (GTK_IS_WINDOW (info->p->widget)); g_return_if_fail (GDK_IS_SCREEN (screen)); monitor = current_monitor; if (apply_stored_monitor) { gint n_monitors; n_monitors = gdk_screen_get_n_monitors (screen); if (info->p->monitor != DEFAULT_MONITOR && info->p->monitor < n_monitors) { monitor = info->p->monitor; } else { monitor = gdk_screen_get_primary_monitor (screen); } } gdk_screen_get_monitor_geometry (screen, monitor, &rect); gdk_screen_get_monitor_workarea (screen, monitor, &work_rect); info->p->x += rect.x; info->p->y += rect.y; if (gimp_session_info_get_remember_size (info) && info->p->width > 0 && info->p->height > 0) { width = info->p->width; height = info->p->height; } else { GtkRequisition requisition; gtk_widget_size_request (info->p->widget, &requisition); width = requisition.width; height = requisition.height; } info->p->x = CLAMP (info->p->x, work_rect.x, work_rect.x + work_rect.width - width); info->p->y = CLAMP (info->p->y, work_rect.y, work_rect.y + work_rect.height - height); if (info->p->right_align && info->p->bottom_align) { g_strlcpy (geom, "-0-0", sizeof (geom)); } else if (info->p->right_align) { g_snprintf (geom, sizeof (geom), "-0%+d", info->p->y); } else if (info->p->bottom_align) { g_snprintf (geom, sizeof (geom), "%+d-0", info->p->x); } else { g_snprintf (geom, sizeof (geom), "%+d%+d", info->p->x, info->p->y); } gtk_window_parse_geometry (GTK_WINDOW (info->p->widget), geom); if (gimp_session_info_get_remember_size (info) && info->p->width > 0 && info->p->height > 0) { gtk_window_set_default_size (GTK_WINDOW (info->p->widget), info->p->width, info->p->height); } /* Window managers and windowing systems suck. They have their own * ideas about WM standards and when it's appropriate to honor * user/application-set window positions and when not. Therefore, * use brute force and "manually" position dialogs whenever they * are shown. This is important especially for transient dialogs, * because window managers behave even "smarter" then... */ if (GTK_IS_DIALOG (info->p->widget)) g_signal_connect (info->p->widget, "show", G_CALLBACK (gimp_session_info_dialog_show), info); }