static void
setup_tooltip_window_position(gpointer data, int w, int h)
{
	int sig;
	int scr_w, scr_h, x, y, dy;
	int mon_num;
	GdkScreen *screen = NULL;
	GdkRectangle mon_size;
	GtkWidget *tipwindow = pidgin_tooltip.tipwindow;
	
	gdk_display_get_pointer(gdk_display_get_default(), &screen, &x, &y, NULL);
	mon_num = gdk_screen_get_monitor_at_point(screen, x, y);
	gdk_screen_get_monitor_geometry(screen, mon_num, &mon_size);

	scr_w = mon_size.width + mon_size.x;
	scr_h = mon_size.height + mon_size.y;

	dy = gdk_display_get_default_cursor_size(gdk_display_get_default()) / 2;

	if (w > mon_size.width)
		w = mon_size.width - 10;

	if (h > mon_size.height)
		h = mon_size.height - 10;

	x -= ((w >> 1) + 4);

	if ((y + h + 4) > scr_h)
		y = y - h - dy - 5;
	else
		y = y + dy + 6;

	if (y < mon_size.y)
		y = mon_size.y;

	if (y != mon_size.y) {
		if ((x + w) > scr_w)
			x -= (x + w + 5) - scr_w;
		else if (x < mon_size.x)
			x = mon_size.x;
	} else {
		x -= (w / 2 + 10);
		if (x < mon_size.x)
			x = mon_size.x;
	}

	gtk_widget_set_size_request(tipwindow, w, h);
	gtk_window_move(GTK_WINDOW(tipwindow), x, y);
	gtk_widget_show(tipwindow);

	g_signal_connect(G_OBJECT(tipwindow), "expose_event",
			G_CALLBACK(pidgin_tooltip_expose_event), data);

	/* Hide the tooltip when the widget is destroyed */
	sig = g_signal_connect(G_OBJECT(pidgin_tooltip.widget), "destroy", G_CALLBACK(pidgin_tooltip_destroy), NULL);
	g_signal_connect_swapped(G_OBJECT(tipwindow), "destroy", G_CALLBACK(g_source_remove), GINT_TO_POINTER(sig));
}
/*                                                                                                                                                       
 * Class:     com_sun_glass_ui_gtk_GtkCursor
 * Method:    _getBestSize                                                                                                                 
 * Signature: (II)Lcom.sun.glass.ui.Size
 */
JNIEXPORT jobject JNICALL Java_com_sun_glass_ui_gtk_GtkCursor__1getBestSize
        (JNIEnv *env, jclass jCursorClass, jint width, jint height)                                                                              
{
    int size = gdk_display_get_default_cursor_size(gdk_display_get_default());

    return env->NewObject(
            env->FindClass("com/sun/glass/ui/Size"),
            jSizeInit,
            size,
            size);
}
示例#3
0
/*                                                                                                                                                       
 * Class:     com_sun_glass_ui_gtk_GtkCursor
 * Method:    _getBestSize                                                                                                                 
 * Signature: (II)Lcom.sun.glass.ui.Size
 */
JNIEXPORT jobject JNICALL Java_com_sun_glass_ui_gtk_GtkCursor__1getBestSize
        (JNIEnv *env, jclass jCursorClass, jint width, jint height)                                                                              
{
    int size = gdk_display_get_default_cursor_size(gdk_display_get_default());

    jclass jc = env->FindClass("com/sun/glass/ui/Size");
    if (env->ExceptionCheck()) return NULL;
    jobject jo =  env->NewObject(
            jc,
            jSizeInit,
            size,
            size);
    EXCEPTION_OCCURED(env);
    return jo;
}
示例#4
0
int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
{
    GdkWindow *window = NULL;
    if (win)
        window = gtk_widget_get_window(win->GetHandle());

    switch (index)
    {
        case wxSYS_BORDER_X:
        case wxSYS_BORDER_Y:
        case wxSYS_EDGE_X:
        case wxSYS_EDGE_Y:
        case wxSYS_FRAMESIZE_X:
        case wxSYS_FRAMESIZE_Y:
            if (win)
            {
                wxTopLevelWindow *tlw = wxDynamicCast(win, wxTopLevelWindow);
                if (!tlw)
                    return GetBorderWidth(index, win);
                else if (window)
                {
                    // Get the frame extents from the windowmanager.
                    // In most cases the top extent is the titlebar, so we use the bottom extent
                    // for the heights.
                    int right, bottom;
                    if (wxGetFrameExtents(window, NULL, &right, NULL, &bottom))
                    {
                        switch (index)
                        {
                            case wxSYS_BORDER_X:
                            case wxSYS_EDGE_X:
                            case wxSYS_FRAMESIZE_X:
                                return right; // width of right extent
                            default:
                                return bottom; // height of bottom extent
                        }
                    }
                }
            }

            return -1; // no window specified

        case wxSYS_CURSOR_X:
        case wxSYS_CURSOR_Y:
                return gdk_display_get_default_cursor_size(
                            window ? gdk_window_get_display(window)
                                   : gdk_display_get_default());

        case wxSYS_DCLICK_X:
        case wxSYS_DCLICK_Y:
            gint dclick_distance;
            g_object_get(GetSettingsForWindowScreen(window),
                            "gtk-double-click-distance", &dclick_distance, NULL);

            return dclick_distance * 2;

        case wxSYS_DCLICK_MSEC:
            gint dclick;
            g_object_get(GetSettingsForWindowScreen(window),
                            "gtk-double-click-time", &dclick, NULL);
            return dclick;

        case wxSYS_DRAG_X:
        case wxSYS_DRAG_Y:
            gint drag_threshold;
            g_object_get(GetSettingsForWindowScreen(window),
                            "gtk-dnd-drag-threshold", &drag_threshold, NULL);

            // The correct thing here would be to double the value
            // since that is what the API wants. But the values
            // are much bigger under GNOME than under Windows and
            // just seem to much in many cases to be useful.
            // drag_threshold *= 2;

            return drag_threshold;

        case wxSYS_ICON_X:
        case wxSYS_ICON_Y:
            return 32;

        case wxSYS_SCREEN_X:
            if (window)
                return gdk_screen_get_width(gdk_window_get_screen(window));
            else
                return gdk_screen_width();

        case wxSYS_SCREEN_Y:
            if (window)
                return gdk_screen_get_height(gdk_window_get_screen(window));
            else
                return gdk_screen_height();

        case wxSYS_HSCROLL_Y:
        case wxSYS_VSCROLL_X:
            return 15;

        case wxSYS_CAPTION_Y:
            if (!window)
                // No realized window specified, and no implementation for that case yet.
                return -1;

            wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow),
                          wxT("Asking for caption height of a non toplevel window") );

            // Get the height of the top windowmanager border.
            // This is the titlebar in most cases. The titlebar might be elsewhere, and
            // we could check which is the thickest wm border to decide on which side the
            // titlebar is, but this might lead to interesting behaviours in used code.
            // Reconsider when we have a way to report to the user on which side it is.
            {
                int top;
                if (wxGetFrameExtents(window, NULL, NULL, &top, NULL))
                {
                    return top; // top frame extent
                }
            }

            // Try a default approach without a window pointer, if possible
            // ...

            return -1;

        case wxSYS_PENWINDOWS_PRESENT:
            // No MS Windows for Pen computing extension available in X11 based gtk+.
            return 0;

        default:
            return -1;   // metric is unknown
    }
}
示例#5
0
文件: gtktooltip.c 项目: aswinas/gtk-
static void
gtk_tooltip_position (GtkTooltip *tooltip,
		      GdkDisplay *display,
		      GtkWidget  *new_tooltip_widget)
{
  gint x, y, width, height;
  GdkScreen *screen;
  gint monitor_num;
  GdkRectangle monitor;
  guint cursor_size;
  GdkRectangle bounds;

#define MAX_DISTANCE 32

  gtk_widget_realize (GTK_WIDGET (tooltip->current_window));

  tooltip->tooltip_widget = new_tooltip_widget;

  screen = gtk_widget_get_screen (new_tooltip_widget);

  width = gtk_widget_get_allocated_width (GTK_WIDGET (tooltip->current_window));
  height = gtk_widget_get_allocated_height (GTK_WIDGET (tooltip->current_window));

  monitor_num = gdk_screen_get_monitor_at_point (screen,
                                                 tooltip->last_x,
                                                 tooltip->last_y);
  gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);

  get_bounding_box (new_tooltip_widget, &bounds);

  /* Position the tooltip */

  cursor_size = gdk_display_get_default_cursor_size (display);

  /* Try below */
  x = bounds.x + bounds.width / 2 - width / 2;
  y = bounds.y + bounds.height + 4;

  if (y + height <= monitor.y + monitor.height)
    {
      if (tooltip->keyboard_mode_enabled)
        goto found;

      if (y <= tooltip->last_y + cursor_size + MAX_DISTANCE)
        {
          if (tooltip->last_x + cursor_size + MAX_DISTANCE < x)
            x = tooltip->last_x + cursor_size + MAX_DISTANCE;
          else if (x + width < tooltip->last_x - MAX_DISTANCE)
            x = tooltip->last_x - MAX_DISTANCE - width;

          goto found;
        }
   }

  /* Try above */
  x = bounds.x + bounds.width / 2 - width / 2;
  y = bounds.y - height - 4;

  if (y >= monitor.y)
    {
      if (tooltip->keyboard_mode_enabled)
        goto found;

      if (y + height >= tooltip->last_y - MAX_DISTANCE)
        {
          if (tooltip->last_x + cursor_size + MAX_DISTANCE < x)
            x = tooltip->last_x + cursor_size + MAX_DISTANCE;
          else if (x + width < tooltip->last_x - MAX_DISTANCE)
            x = tooltip->last_x - MAX_DISTANCE - width;

          goto found;
        }
    }

  /* Try right FIXME: flip on rtl ? */
  x = bounds.x + bounds.width + 4;
  y = bounds.y + bounds.height / 2 - height / 2;

  if (x + width <= monitor.x + monitor.width)
    {
      if (tooltip->keyboard_mode_enabled)
        goto found;

      if (x <= tooltip->last_x + cursor_size + MAX_DISTANCE)
        {
          if (tooltip->last_y + cursor_size + MAX_DISTANCE < y)
            y = tooltip->last_y + cursor_size + MAX_DISTANCE;
          else if (y + height < tooltip->last_y - MAX_DISTANCE)
            y = tooltip->last_y - MAX_DISTANCE - height;

          goto found;
        }
    }

  /* Try left FIXME: flip on rtl ? */
  x = bounds.x - width - 4;
  y = bounds.y + bounds.height / 2 - height / 2;

  if (x >= monitor.x)
    {
      if (tooltip->keyboard_mode_enabled)
        goto found;

      if (x + width >= tooltip->last_x - MAX_DISTANCE)
        {
          if (tooltip->last_y + cursor_size + MAX_DISTANCE < y)
            y = tooltip->last_y + cursor_size + MAX_DISTANCE;
          else if (y + height < tooltip->last_y - MAX_DISTANCE)
            y = tooltip->last_y - MAX_DISTANCE - height;

          goto found;
        }
    }

   /* Fallback */
  if (tooltip->keyboard_mode_enabled)
    {
      x = bounds.x + bounds.width / 2 - width / 2;
      y = bounds.y + bounds.height + 4;
    }
  else
    {
      /* At cursor */
      x = tooltip->last_x + cursor_size * 3 / 4;
      y = tooltip->last_y + cursor_size * 3 / 4;
    }

found:
  /* Show it */
  if (tooltip->current_window)
    {
      if (x + width > monitor.x + monitor.width)
        x -= x - (monitor.x + monitor.width) + width;
      else if (x < monitor.x)
        x = monitor.x;

      if (y + height > monitor.y + monitor.height)
        y -= y - (monitor.y + monitor.height) + height;
      else if (y < monitor.y)
        y = monitor.y;

      if (!tooltip->keyboard_mode_enabled)
        {
          /* don't pop up under the pointer */
          if (x <= tooltip->last_x && tooltip->last_x < x + width &&
              y <= tooltip->last_y && tooltip->last_y < y + height)
            y = tooltip->last_y - height - 2;
        }

#ifdef GDK_WINDOWING_WAYLAND
      /* set the transient parent on the tooltip when running with the Wayland
       * backend to allow correct positioning of the tooltip windows */
      if (GDK_IS_WAYLAND_DISPLAY (display))
        {
          GtkWidget *toplevel;

          toplevel = gtk_widget_get_toplevel (tooltip->tooltip_widget);
          if (GTK_IS_WINDOW (toplevel))
            gtk_window_set_transient_for (GTK_WINDOW (tooltip->current_window),
                                          GTK_WINDOW (toplevel));
        }
#endif

      gtk_window_move (GTK_WINDOW (tooltip->current_window), x, y);
      gtk_widget_show (GTK_WIDGET (tooltip->current_window));
    }
}
示例#6
0
static void
gtk_tooltip_position (GtkTooltip *tooltip,
		      GdkDisplay *display,
		      GtkWidget  *new_tooltip_widget)
{
  gint x, y;
  GdkScreen *screen;

  tooltip->tooltip_widget = new_tooltip_widget;

  /* Position the tooltip */
  /* FIXME: should we swap this when RTL is enabled? */
  if (tooltip->keyboard_mode_enabled)
    {
      GdkRectangle bounds;

      get_bounding_box (new_tooltip_widget, &bounds);

      /* For keyboard mode we position the tooltip below the widget,
       * right of the center of the widget.
       */
      x = bounds.x + bounds.width / 2;
      y = bounds.y + bounds.height + 4;
    }
  else
    {
      guint cursor_size;

      x = tooltip->last_x;
      y = tooltip->last_y;

      /* For mouse mode, we position the tooltip right of the cursor,
       * a little below the cursor's center.
       */
      cursor_size = gdk_display_get_default_cursor_size (display);
      x += cursor_size / 2;
      y += cursor_size / 2;
    }

  screen = gtk_widget_get_screen (new_tooltip_widget);

  /* Show it */
  if (tooltip->current_window)
    {
      gint monitor_num;
      GdkRectangle monitor;
      GtkRequisition requisition;

      gtk_widget_size_request (GTK_WIDGET (tooltip->current_window),
                               &requisition);

      monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
      gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);

      if (x + requisition.width > monitor.x + monitor.width)
        x -= x - (monitor.x + monitor.width) + requisition.width;
      else if (x < monitor.x)
        x = monitor.x;

      if (y + requisition.height > monitor.y + monitor.height)
        y -= y - (monitor.y + monitor.height) + requisition.height;
  
      if (!tooltip->keyboard_mode_enabled)
        {
          /* don't pop up under the pointer */
          if (x <= tooltip->last_x && tooltip->last_x < x + requisition.width &&
              y <= tooltip->last_y && tooltip->last_y < y + requisition.height)
            y = tooltip->last_y - requisition.height - 2;
        }
  
      gtk_window_move (GTK_WINDOW (tooltip->current_window), x, y);
      gtk_widget_show (GTK_WIDGET (tooltip->current_window));
    }
}
示例#7
0
static VALUE
rg_default_cursor_size(VALUE self)
{
    return UINT2NUM(gdk_display_get_default_cursor_size(_SELF(self)));
}
示例#8
0
int wxSystemSettingsNative::GetMetric( wxSystemMetric index, wxWindow* win )
{
    guchar *data = NULL;
    Atom type;
    int format;
    gulong nitems;
    GdkWindow *window = NULL;
    if(win && GTK_WIDGET_REALIZED(win->GetHandle()))
        window = win->GetHandle()->window;

    switch (index)
    {
        case wxSYS_BORDER_X:
        case wxSYS_BORDER_Y:
        case wxSYS_EDGE_X:
        case wxSYS_EDGE_Y:
        case wxSYS_FRAMESIZE_X:
        case wxSYS_FRAMESIZE_Y:
            // If a window is specified/realized, and it is a toplevel window, we can query from wm.
            // The returned border thickness is outside the client area in that case.
            if (window)
            {
                wxTopLevelWindow *tlw = wxDynamicCast(win, wxTopLevelWindow);
                if (!tlw)
                    return -1; // not a tlw, not sure how to approach
                else
                {
                    // Check if wm supports frame extents - we can't know
                    // the border widths if it does not.
#if GTK_CHECK_VERSION(2,2,0)
                    if (!gtk_check_version(2,2,0))
                    {
                        if (!gdk_x11_screen_supports_net_wm_hint(
                                gdk_drawable_get_screen(window),
                                gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) )
                            return -1;
                    }
                    else
#endif
                    {
                        if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
                            return -1;
                    }

                    // Get the frame extents from the windowmanager.
                    // In most cases the top extent is the titlebar, so we use the bottom extent
                    // for the heights.
                    if (wxXGetWindowProperty(window, type, format, nitems, data))
                    {
                        int border_return = -1;

                        if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 4) && (data))
                        {
                            switch(index)
                            {
                                case wxSYS_BORDER_X:
                                case wxSYS_EDGE_X:
                                case wxSYS_FRAMESIZE_X:
                                    border_return = ((long*)data)[1]; // width of right extent
                                    break;
                                default:
                                    border_return = ((long*)data)[3]; // height of bottom extent
                                    break;
                            }
                        }

                        if (data)
                            XFree(data);

                        return border_return;
                    }
                }
            }

            return -1; // no window specified

        case wxSYS_CURSOR_X:
        case wxSYS_CURSOR_Y:
#ifdef __WXGTK24__
            if (!gtk_check_version(2,4,0))
            {
                if (window)
                    return gdk_display_get_default_cursor_size(gdk_drawable_get_display(window));
                else
                    return gdk_display_get_default_cursor_size(gdk_display_get_default());
            }
            else
#endif
                return 16;

        case wxSYS_DCLICK_X:
        case wxSYS_DCLICK_Y:
            gint dclick_distance;
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
                g_object_get(gtk_settings_get_for_screen(gdk_drawable_get_screen(window)),
                                "gtk-double-click-distance", &dclick_distance, NULL);
            else
#endif
                g_object_get(gtk_settings_get_default(),
                                "gtk-double-click-distance", &dclick_distance, NULL);

            return dclick_distance * 2;

        case wxSYS_DRAG_X:
        case wxSYS_DRAG_Y:
            gint drag_threshold;
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
            {
                g_object_get(
                        gtk_settings_get_for_screen(gdk_drawable_get_screen(window)),
                        "gtk-dnd-drag-threshold",
                        &drag_threshold, NULL);
            }
            else
#endif
            {
                g_object_get(gtk_settings_get_default(),
                             "gtk-dnd-drag-threshold", &drag_threshold, NULL);
            }

            // The correct thing here would be to double the value
            // since that is what the API wants. But the values
            // are much bigger under GNOME than under Windows and
            // just seem to much in many cases to be useful.
            // drag_threshold *= 2;

            return drag_threshold;

        // MBN: ditto for icons
        case wxSYS_ICON_X:     return 32;
        case wxSYS_ICON_Y:     return 32;

        case wxSYS_SCREEN_X:
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
                return gdk_screen_get_width(gdk_drawable_get_screen(window));
            else
#endif
                return gdk_screen_width();

        case wxSYS_SCREEN_Y:
#if GTK_CHECK_VERSION(2,2,0)
            if (window && !gtk_check_version(2,2,0))
                return gdk_screen_get_height(gdk_drawable_get_screen(window));
            else
#endif
                return gdk_screen_height();

        case wxSYS_HSCROLL_Y:  return 15;
        case wxSYS_VSCROLL_X:  return 15;

        case wxSYS_CAPTION_Y:
            if (!window)
                // No realized window specified, and no implementation for that case yet.
                return -1;

            // Check if wm supports frame extents - we can't know the caption height if it does not.
#if GTK_CHECK_VERSION(2,2,0)
            if (!gtk_check_version(2,2,0))
            {
                if (!gdk_x11_screen_supports_net_wm_hint(
                        gdk_drawable_get_screen(window),
                        gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) )
                    return -1;
            }
            else
#endif
            {
                if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false)))
                    return -1;
            }

            wxASSERT_MSG( wxDynamicCast(win, wxTopLevelWindow),
                          wxT("Asking for caption height of a non toplevel window") );

            // Get the height of the top windowmanager border.
            // This is the titlebar in most cases. The titlebar might be elsewhere, and
            // we could check which is the thickest wm border to decide on which side the
            // titlebar is, but this might lead to interesting behaviours in used code.
            // Reconsider when we have a way to report to the user on which side it is.
            if (wxXGetWindowProperty(window, type, format, nitems, data))
            {
                int caption_height = -1;

                if ((type == XA_CARDINAL) && (format == 32) && (nitems >= 3) && (data))
                {
                    caption_height = ((long*)data)[2]; // top frame extent
                }

                if (data)
                    XFree(data);

                return caption_height;
            }

            // Try a default approach without a window pointer, if possible
            // ...

            return -1;

        case wxSYS_PENWINDOWS_PRESENT:
            // No MS Windows for Pen computing extension available in X11 based gtk+.
            return 0;

        default:
            return -1;   // metric is unknown
    }
}