This should be a fair bit faster as the word is only even fetched only if its length would match the clickpos one's, in case the `strcmp()` would have failed anyway. And as we know the length, we can use `strncmp()` and then any pointer (without necessarily a trailing `\0`).
Also, the gap is not very likely to be in the middle of a word, so unlikely to have to move. And anyway, would move at worse once.
---
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany-plugins/commit/2c481661d22cb16fc1b6c62e4331d…
Not considering monitors is easy, sure. Considering them only when Geany doesn't span several monitors sounds a lot more complex though, would require checking which monitors Geany spans on, compute the bounding box and use that. And in any other case, I really think trying to fit in the monitor seem more sensible to me.
Anyway, if someone really wants a screen-level logic, why not, but I'd like it to be smart enough not to mess up the most common situation where your Geany is on a single monitor and you want to keep it that way :)
---
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/406#issuecomment-186011457
@b4n, if the user has geany spread across two monitors then clearly they are happy with that, so why not make the menu do the same? Reduces the menu jumping up and down depending how long it is.
Just suggesting, seemed like only a change of calls for the size, but anyway if its too complex forget it.
---
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/406#issuecomment-186010591
@elextr meh… do you really want a menu spanning several monitors? Also, it would only make some sense with vertical spanning, as the menu is not likely to be wider than the monitor, but rather (possibly) taller. And even then, I think it's best to at least consider the monitor not to put a half of an entry in the next monitor in the screen -- so IMO the only possible moment where you'd really consider spanning multiple monitors is if you can't fit in the current one, not before.
Finally, all this is pretty theoretical when it comes to a list taller than the monitor, if you really get to this in real situation you'll have other worries I'm afraid :)
---
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/406#issuecomment-186009513
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
Hum, actually on GTK 3.18 `push_in=FALSE` is slightly better for our case, because it pushes the menu (yes, it does), but just moving it instead of scrolling it, so the whole menu is visible.
---
Reply to this email directly or view it on GitHub:
https://github.com/geany/geany/pull/406#issuecomment-185985795