void
cb_media_image_widget_calc_size (CbMediaImageWidget *self)
{
  GdkSurface *surface;
  GdkMonitor *monitor;
  GdkRectangle workarea;
  int win_width;
  int win_height;

  g_assert (GTK_IS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))));

  /* :( */
  gtk_widget_realize (gtk_widget_get_toplevel (GTK_WIDGET (self)));

  surface = gtk_widget_get_surface (gtk_widget_get_toplevel (GTK_WIDGET (self)));
  g_assert_nonnull (surface);

  monitor = gdk_display_get_monitor_at_surface (gdk_display_get_default (),
                                                surface);

  if (!monitor)
    {
       g_warning (G_STRLOC ": monitor is NULL");
       return;
    }

  gdk_monitor_get_workarea (monitor, &workarea);

  win_width  = MIN ((int)(workarea.width * 0.95), self->img_width);
  win_height = MIN ((int)(workarea.height * 0.95), self->img_height);

  if (win_width >= self->img_width)
    g_object_set ((GObject *)self, "hscrollbar-policy", GTK_POLICY_NEVER, NULL);

  if (win_height >= self->img_height)
    g_object_set ((GObject *)self, "vscrollbar-policy", GTK_POLICY_NEVER, NULL);

  gtk_widget_set_size_request ((GtkWidget *)self, win_width, win_height);
}
Beispiel #2
0
/**
 * bt_gtk_workarea_size:
 * @max_width: destination for the width or %NULL
 * @max_height: destination for the heigth or %NULL
 *
 * Gets the potitial max size the window could occupy. This can be used to
 * hint the content size for #GtkScrelledWindow.
 */
void
bt_gtk_workarea_size (gint * max_width, gint * max_height)
{
#if GTK_CHECK_VERSION (3, 22, 0)
  GdkRectangle area;
  gdk_monitor_get_workarea (
      gdk_display_get_primary_monitor (gdk_display_get_default ()),
      &area);
  if (max_width)
    *max_width = area.width;
  if (max_height)
    *max_height = area.height;
#else
  GdkScreen *screen = gdk_screen_get_default ();
  /* TODO(ensonjc): these constances below are arbitrary
   * look at http://standards.freedesktop.org/wm-spec/1.3/ar01s05.html#id2523368
   * search for _NET_WM_STRUT_PARTIAL
   */
  if (max_width)
    *max_width = gdk_screen_get_width (screen) - 16;
  if (max_height)
    *max_height = gdk_screen_get_height (screen) - 80;
#endif
}
void
gimp_display_shell_set_initial_scale (GimpDisplayShell *shell,
                                      gdouble           scale,
                                      gint             *display_width,
                                      gint             *display_height)
{
  GimpImage    *image;
  GdkRectangle  workarea;
  gint          image_width;
  gint          image_height;
  gint          monitor_width;
  gint          monitor_height;
  gint          shell_width;
  gint          shell_height;

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  image = gimp_display_get_image (shell->display);

  gdk_monitor_get_workarea (shell->initial_monitor, &workarea);

  image_width  = gimp_image_get_width  (image);
  image_height = gimp_image_get_height (image);

  monitor_width  = workarea.width  * 0.75;
  monitor_height = workarea.height * 0.75;

  /* We need to zoom before we use SCALE[XY] */
  gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale);

  shell_width  = SCALEX (shell, image_width);
  shell_height = SCALEY (shell, image_height);

  if (shell->display->config->initial_zoom_to_fit)
    {
      /*  Limit to the size of the monitor...  */
      if (shell_width > monitor_width || shell_height > monitor_height)
        {
          gdouble new_scale;
          gdouble current = gimp_zoom_model_get_factor (shell->zoom);

          new_scale = current * MIN (((gdouble) monitor_height) / shell_height,
                                     ((gdouble) monitor_width)  / shell_width);

          new_scale = gimp_zoom_model_zoom_step (GIMP_ZOOM_OUT, new_scale, 0.0);

          /*  Since zooming out might skip a zoom step we zoom in
           *  again and test if we are small enough.
           */
          gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO,
                                gimp_zoom_model_zoom_step (GIMP_ZOOM_IN,
                                                           new_scale, 0.0));

          if (SCALEX (shell, image_width)  > monitor_width ||
              SCALEY (shell, image_height) > monitor_height)
            gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, new_scale);

          shell_width  = SCALEX (shell, image_width);
          shell_height = SCALEY (shell, image_height);
        }
    }
  else
    {
      /*  Set up size like above, but do not zoom to fit. Useful when
       *  working on large images.
       */
      shell_width  = MIN (shell_width,  monitor_width);
      shell_height = MIN (shell_height, monitor_height);
    }

  if (display_width)  *display_width  = shell_width;
  if (display_height) *display_height = shell_height;
}
Beispiel #4
0
gboolean
_gdk_win32_display_init_monitors (GdkWin32Display *win32_display)
{
  GdkDisplay *display = GDK_DISPLAY (win32_display);
  GPtrArray *new_monitors;
  gint i;
  gboolean changed = FALSE;
  GdkWin32Monitor *primary_to_move = NULL;

  for (i = 0; i < win32_display->monitors->len; i++)
    GDK_WIN32_MONITOR (g_ptr_array_index (win32_display->monitors, i))->remove = TRUE;

  new_monitors = _gdk_win32_display_get_monitor_list (win32_display);

  for (i = 0; i < new_monitors->len; i++)
    {
      GdkWin32Monitor *w32_m;
      GdkMonitor *m;
      GdkWin32Monitor *w32_ex_monitor;
      GdkMonitor *ex_monitor;
      GdkRectangle geometry, ex_geometry;
      GdkRectangle workarea, ex_workarea;

      w32_m = GDK_WIN32_MONITOR (g_ptr_array_index (new_monitors, i));
      m = GDK_MONITOR (w32_m);
      ex_monitor = _gdk_win32_display_find_matching_monitor (win32_display, m);
      w32_ex_monitor = GDK_WIN32_MONITOR (ex_monitor);

      if (ex_monitor == NULL)
        {
          w32_m->add = TRUE;
          changed = TRUE;
          continue;
        }

      w32_ex_monitor->remove = FALSE;

      if (i == 0)
        primary_to_move = w32_ex_monitor;

      gdk_monitor_get_geometry (m, &geometry);
      gdk_monitor_get_geometry (ex_monitor, &ex_geometry);
      gdk_monitor_get_workarea (m, &workarea);
      gdk_monitor_get_workarea (ex_monitor, &ex_workarea);

      if (memcmp (&workarea, &ex_workarea, sizeof (GdkRectangle)) != 0)
        {
          w32_ex_monitor->work_rect = workarea;
          changed = TRUE;
        }

      if (memcmp (&geometry, &ex_geometry, sizeof (GdkRectangle)) != 0)
        {
          gdk_monitor_set_size (ex_monitor, geometry.width, geometry.height);
          gdk_monitor_set_position (ex_monitor, geometry.x, geometry.y);
          changed = TRUE;
        }

      if (gdk_monitor_get_width_mm (m) != gdk_monitor_get_width_mm (ex_monitor) ||
          gdk_monitor_get_height_mm (m) != gdk_monitor_get_height_mm (ex_monitor))
        {
          gdk_monitor_set_physical_size (ex_monitor,
                                         gdk_monitor_get_width_mm (m),
                                         gdk_monitor_get_height_mm (m));
          changed = TRUE;
        }

      if (g_strcmp0 (gdk_monitor_get_model (m), gdk_monitor_get_model (ex_monitor)) != 0)
        {
          gdk_monitor_set_model (ex_monitor,
                                 gdk_monitor_get_model (m));
          changed = TRUE;
        }

      if (g_strcmp0 (gdk_monitor_get_manufacturer (m), gdk_monitor_get_manufacturer (ex_monitor)) != 0)
        {
          gdk_monitor_set_manufacturer (ex_monitor,
                                        gdk_monitor_get_manufacturer (m));
          changed = TRUE;
        }

      if (gdk_monitor_get_refresh_rate (m) != gdk_monitor_get_refresh_rate (ex_monitor))
        {
          gdk_monitor_set_refresh_rate (ex_monitor, gdk_monitor_get_refresh_rate (m));
          changed = TRUE;
        }

      if (gdk_monitor_get_scale_factor (m) != gdk_monitor_get_scale_factor (ex_monitor))
        {
          gdk_monitor_set_scale_factor (ex_monitor, gdk_monitor_get_scale_factor (m));
          changed = TRUE;
        }

      if (gdk_monitor_get_subpixel_layout (m) != gdk_monitor_get_subpixel_layout (ex_monitor))
        {
          gdk_monitor_set_subpixel_layout (ex_monitor, gdk_monitor_get_subpixel_layout (m));
          changed = TRUE;
        }
    }

  for (i = win32_display->monitors->len - 1; i >= 0; i--)
    {
      GdkWin32Monitor *w32_ex_monitor;
      GdkMonitor *ex_monitor;

      w32_ex_monitor = GDK_WIN32_MONITOR (g_ptr_array_index (win32_display->monitors, i));
      ex_monitor = GDK_MONITOR (w32_ex_monitor);

      if (!w32_ex_monitor->remove)
        continue;

      changed = TRUE;
      gdk_display_monitor_removed (display, ex_monitor);
      g_ptr_array_remove_index (win32_display->monitors, i);
    }

  for (i = 0; i < new_monitors->len; i++)
    {
      GdkWin32Monitor *w32_m;
      GdkMonitor *m;

      w32_m = GDK_WIN32_MONITOR (g_ptr_array_index (new_monitors, i));
      m = GDK_MONITOR (w32_m);

      if (!w32_m->add)
        continue;

      gdk_display_monitor_added (display, m);

      if (i == 0)
        g_ptr_array_insert (win32_display->monitors, 0, g_object_ref (w32_m));
      else
        g_ptr_array_add (win32_display->monitors, g_object_ref (w32_m));
    }

  g_ptr_array_free (new_monitors, TRUE);

  if (primary_to_move)
    {
      g_ptr_array_remove (win32_display->monitors, g_object_ref (primary_to_move));
      g_ptr_array_insert (win32_display->monitors, 0, primary_to_move);
      changed = TRUE;
    }
  return changed;
}
Beispiel #5
0
static void
gimp_operation_tool_add_gui (GimpOperationTool *op_tool)
{
  GtkSizeGroup   *size_group  = NULL;
  GtkWidget      *options_gui;
  GtkWidget      *options_box;
  GtkWidget      *options_sw;
  GtkWidget      *shell;
  GdkRectangle    workarea;
  GtkRequisition  minimum;
  GList          *list;
  gboolean        scrolling;

  options_gui = g_weak_ref_get (&op_tool->options_gui_ref);
  options_box = g_weak_ref_get (&op_tool->options_box_ref);
  options_sw  = g_weak_ref_get (&op_tool->options_sw_ref);
  g_return_if_fail (options_gui && options_box && options_sw);

  for (list = op_tool->aux_inputs; list; list = g_list_next (list))
    {
      AuxInput  *input = list->data;
      GtkWidget *toggle;

      if (! size_group)
        size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);

      toggle =
        gimp_buffer_source_box_get_toggle (GIMP_BUFFER_SOURCE_BOX (input->box));

      gtk_size_group_add_widget (size_group, toggle);

      gtk_box_pack_start (GTK_BOX (options_box), input->box,
                          FALSE, FALSE, 0);
      gtk_widget_show (input->box);
    }

  if (size_group)
    g_object_unref (size_group);

  gtk_box_pack_start (GTK_BOX (options_box), options_gui, TRUE, TRUE, 0);
  gtk_widget_show (options_gui);

  shell = GTK_WIDGET (gimp_display_get_shell (GIMP_TOOL (op_tool)->display));
  gdk_monitor_get_workarea (gimp_widget_get_monitor (shell), &workarea);
  gtk_widget_get_preferred_size (options_box, &minimum, NULL);

  scrolling = minimum.height > workarea.height / 2;

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (options_sw),
                                  GTK_POLICY_NEVER,
                                  scrolling ?
                                  GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER);

  if (scrolling)
    gtk_widget_set_size_request (options_sw, -1, workarea.height / 2);
  else
    gtk_widget_set_size_request (options_sw, -1, -1);

  g_object_unref (options_gui);
  g_object_unref (options_box);
  g_object_unref (options_sw);
}
Beispiel #6
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);
}