/* Determine where to pop up menu (if not activated by a mouse event) */ static void place_menu(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) { TilemDisasmView *dv = data; GtkTreePath *path; GdkRectangle rect; GdkWindow *win; GdkScreen *screen; int n; win = gtk_tree_view_get_bin_window(GTK_TREE_VIEW(dv)); gdk_window_get_origin(win, x, y); gtk_tree_view_get_cursor(GTK_TREE_VIEW(dv), &path, NULL); if (path) { gtk_tree_view_get_cell_area(GTK_TREE_VIEW(dv), path, NULL, &rect); gtk_tree_path_free(path); *y += rect.y + rect.height; } screen = gdk_drawable_get_screen(win); n = gdk_screen_get_monitor_at_point(screen, *x, *y); gtk_menu_set_monitor(menu, n); *push_in = FALSE; }
/* If the menu is popped up in response to a keystroke, center it * immediately below the toolbar. */ static void tm_popup_position_func(GtkMenu * menu, gint * x, gint * y, gboolean * push_in, gpointer user_data) { GtkWidget *toolbar = GTK_WIDGET(user_data); GdkScreen *screen = gtk_widget_get_screen(toolbar); GtkRequisition req; gint monitor_num; GdkRectangle monitor; GtkAllocation allocation; g_return_if_fail(gtk_widget_get_window(toolbar)); gdk_window_get_origin(gtk_widget_get_window(toolbar), x, y); gtk_widget_get_preferred_size(GTK_WIDGET(menu), NULL, &req); gtk_widget_get_allocation(toolbar, &allocation); *x += (allocation.width - req.width) / 2; *y += allocation.height; monitor_num = gdk_screen_get_monitor_at_point(screen, *x, *y); gtk_menu_set_monitor(menu, monitor_num); gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor); *x = CLAMP(*x, monitor.x, monitor.x + MAX(0, monitor.width - req.width)); *y = CLAMP(*y, monitor.y, monitor.y + MAX(0, monitor.height - req.height)); *push_in = FALSE; }
static void menu_position_func (GtkMenu * menu, gint * x, gint * y, gboolean* push_in, gpointer user_data) { GtkRequisition requisition; GtkAllocation allocation; GdkRectangle monitor_geometry; GdkScreen * screen; int monitor; screen = gtk_widget_get_screen (GTK_WIDGET (menu)); gtk_widget_get_allocation (user_data, &allocation); gtk_widget_size_request (GTK_WIDGET (menu), &requisition); gdk_window_get_root_coords (gtk_widget_get_parent_window (user_data), allocation.x, allocation.y, &allocation.x, &allocation.y); monitor = gdk_screen_get_monitor_at_window (screen, GTK_WIDGET (user_data)->window); gtk_menu_set_monitor (menu, monitor); gdk_screen_get_monitor_geometry (screen, monitor, &monitor_geometry); if (allocation.y >= monitor_geometry.y && allocation.y + allocation.height + requisition.height <= monitor_geometry.y + monitor_geometry.height) { *y = allocation.y + allocation.height; } else if (allocation.y - requisition.height >= monitor_geometry.y && allocation.y <= monitor_geometry.y + monitor_geometry.height) { *y = allocation.y - requisition.height; } else { g_warning ("implement menu somewhere else"); *y = allocation.y; } switch (gtk_widget_get_direction (user_data)) { case GTK_TEXT_DIR_RTL: *x = allocation.x + allocation.width - requisition.width; break; case GTK_TEXT_DIR_LTR: case GTK_TEXT_DIR_NONE: *x = allocation.x; break; default: g_warn_if_reached (); *x = allocation.x; break; } }
/* makes the menu appear next to the widget [user_data] * instead off right under the cursor */ static void position_menu ( GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) { GtkWidget *widget = GTK_WIDGET (user_data); GdkScreen *screen; gint twidth, theight, tx, ty; GtkTextDirection direction; GdkRectangle monitor; gint monitor_num; g_return_if_fail (menu != NULL); g_return_if_fail (x != NULL); g_return_if_fail (y != NULL); if (push_in) *push_in = FALSE; direction = gtk_widget_get_direction (widget); twidth = GTK_WIDGET (menu)->requisition.width; theight = GTK_WIDGET (menu)->requisition.height; screen = gtk_widget_get_screen (GTK_WIDGET (menu)); monitor_num = gdk_screen_get_monitor_at_window (screen, widget->window); if (monitor_num < 0) monitor_num = 0; gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); if (!gdk_window_get_origin (widget->window, &tx, &ty)) { g_warning ("Menu not on screen"); return; } tx += widget->allocation.x; ty += widget->allocation.y; if (direction == GTK_TEXT_DIR_RTL) tx += widget->allocation.width - twidth; if ((ty + widget->allocation.height + theight) <= monitor.y + monitor.height) ty += widget->allocation.height; else if ((ty - theight) >= monitor.y) ty -= theight; else if (monitor.y + monitor.height - (ty + widget->allocation.height) > ty) ty += widget->allocation.height; else ty -= theight; *x = CLAMP (tx, monitor.x, MAX (monitor.x, monitor.x + monitor.width - twidth)); *y = ty; gtk_menu_set_monitor (menu, monitor_num); }
int clip_GTK_MENUSETMONITOR(ClipMachine * ClipMachineMemory) { C_widget *cmnu = _fetch_cw_arg(ClipMachineMemory); guint monitor_num = _clip_parni(ClipMachineMemory, 2); CHECKCWID(cmnu, GTK_IS_MENU); CHECKARG(2, NUMERIC_type_of_ClipVarType); gtk_menu_set_monitor(GTK_MENU(cmnu->widget), monitor_num); return 0; err: return 1; }
void gul_gui_sanitise_popup_position (GtkMenu *menu, GtkWidget *widget, gint *x, gint *y) { GdkScreen *screen = gtk_widget_get_screen (widget); gint monitor_num; GdkRectangle monitor; GtkRequisition req; g_return_if_fail (widget != NULL); gtk_widget_size_request (GTK_WIDGET (menu), &req); monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y); gtk_menu_set_monitor (menu, monitor_num); gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor); *x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width)); *y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height)); }
static void popup_position_func (GtkMenu * menu, gint * x, gint * y, gboolean * push_in, gpointer user_data) { GtkRequisition req; GdkPoint *pos; gint monitor; GdkScreen *screen; pos = user_data; gtk_widget_size_request (GTK_WIDGET (menu), &req); if (pos->x >= 0) { *x = pos->x; *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); } else { *x = (gdk_screen_width () - req.width) / 2; } if (pos->x >= 0) { *y = pos->y; *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); } else { *y = (gdk_screen_height () - req.height) / 2; } screen = gtk_widget_get_screen (GTK_WIDGET(menu)); monitor = gdk_screen_get_monitor_at_point (screen, *x, *y); gtk_menu_set_monitor (GTK_MENU (menu), monitor); g_free (user_data); }
static void popup_position_func (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer user_data) { GtkWidget *widget; GtkRequisition req; gint root_x, root_y; GdkScreen *screen; GdkWindow *window; GdkRectangle monitor; gint monitor_num; widget = GTK_WIDGET (user_data); g_return_if_fail (gtk_widget_get_realized (widget)); window = gtk_widget_get_window (widget); screen = gtk_widget_get_screen (widget); monitor_num = gdk_screen_get_monitor_at_window (screen, window); if (monitor_num < 0) monitor_num = 0; gtk_menu_set_monitor (menu, monitor_num); gdk_window_get_origin (window, &root_x, &root_y); gtk_widget_get_preferred_size (GTK_WIDGET (menu), &req, NULL); /* Put corner of menu centered on swatch */ *x = root_x + gtk_widget_get_allocated_width (widget) / 2; *y = root_y + gtk_widget_get_allocated_height (widget) / 2; /* Ensure sanity */ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor); *x = CLAMP (*x, monitor.x, MAX (monitor.x, monitor.width - req.width)); *y = CLAMP (*y, monitor.y, MAX (monitor.y, monitor.height - req.height)); }