[Github-comments] [geany] If more tags are found during tag definition/declaration goto, let user select which one to use (#406)

Colomban Wendling notifications at xxxxx
Fri Feb 19 01:15:43 UTC 2016


If you want a more sensible popup placement, it's doable:
```C

/* positions a popup at the caret from the ScintillaObject in @p data */
static void goto_popup_position_func(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data)
{
	ScintillaObject *sci = data;
	GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(sci));
	gint pos = sci_get_current_position(sci);
	gint line = sci_get_line_from_position(sci, pos);
	gint line_height = scintilla_send_message(sci, SCI_TEXTHEIGHT, line, 0);
	gint pos_x = scintilla_send_message(sci, SCI_POINTXFROMPOSITION, 0, pos);
	gint pos_y = scintilla_send_message(sci, SCI_POINTYFROMPOSITION, 0, pos);
	GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET(menu));
	gint monitor_num;
	GdkRectangle monitor;
	GtkRequisition req;

	gdk_window_get_origin(window, x, y);
	monitor_num = gdk_screen_get_monitor_at_point(screen, *x + pos_x, *y + pos_y);

#if GTK_CHECK_VERSION(3, 0, 0)
	gtk_widget_get_preferred_size(GTK_WIDGET(menu), NULL, &req);
#else
	gtk_widget_size_request(GTK_WIDGET(menu), &req);
#endif

#if GTK_CHECK_VERSION(3, 4, 0)
	gdk_screen_get_monitor_workarea(screen, monitor_num, &monitor);
#else
	gdk_screen_get_monitor_geometry(screen, monitor_num, &monitor);
#endif

	/* put at the X position, but within the monitor */
	if (gtk_widget_get_direction(GTK_WIDGET(menu)) == GTK_TEXT_DIR_RTL)
		*x = MAX(monitor.x, *x + pos_x - req.width);
	else
	{
		if (*x + pos_x + req.width <= monitor.x + monitor.width)
			*x = MAX(monitor.x, *x + pos_x);
		else
			*x = monitor.x + MAX(0, monitor.width - req.width);
	}

	/* try to put, in order:
	 * 1. below the Y position, under the line
	 * 2. above the Y position
	 * 3. within the monitor */
	if (*y + pos_y + line_height + req.height <= monitor.y + monitor.height)
		*y = MAX(monitor.y, *y + pos_y + line_height);
	else if (*y + pos_y - req.height >= monitor.y)
		*y = *y + pos_y - req.height;
	else
		*y = monitor.y + MAX(0, monitor.height - req.height);

	*push_in = FALSE;
}
```
It's a fair bit more complex, but more accurate without getting into too much details.  Basically, it puts the popup below if it fits, otherwise tries above, else puts it as far low as possible within the monitor.  For the X position, puts it on the natural side, but inside the monitor.

It's not exactly what "natural" is for GTK, which would put preferably a corner next to the popup point, and otherwise chose the side with the most space, but implementing this is a little more work for not much gain.

---
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/406#issuecomment-186001747
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.geany.org/pipermail/github-comments/attachments/20160218/0c301ecc/attachment.html>


More information about the Github-comments mailing list