Пример #1
0
GtkWidget *
gimp_session_info_get_widget (GimpSessionInfo *info)
{
  g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE);

  return info->p->widget;
}
Пример #2
0
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;
}
Пример #3
0
gint
gimp_session_info_get_height (GimpSessionInfo *info)
{
  g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), 0);

  return info->p->height;
}
Пример #4
0
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);
    }
}
Пример #5
0
gboolean
gimp_session_info_get_open (GimpSessionInfo *info)
{
  g_return_val_if_fail (GIMP_IS_SESSION_INFO (info), FALSE);

  return info->p->open;
}
Пример #6
0
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;
}
Пример #7
0
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));
}
Пример #8
0
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));
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
/**
 * 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);
}
Пример #13
0
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);
}
Пример #14
0
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;
    }
}
Пример #15
0
/**
 * 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);
}
Пример #16
0
/**
 * 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);
    }
}
Пример #17
0
/**
 * 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);
}
Пример #18
0
/**
 * 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;
        }
    }
}
Пример #19
0
/**
 * 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);
}