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); }
/* * 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; }
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 } }
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)); } }
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)); } }
static VALUE rg_default_cursor_size(VALUE self) { return UINT2NUM(gdk_display_get_default_cursor_size(_SELF(self))); }
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 } }