<p>If you want a more sensible popup placement, it's doable:</p>

<div class="highlight highlight-source-c"><pre>
<span class="pl-c">/* positions a popup at the caret from the ScintillaObject in @p data */</span>
<span class="pl-k">static</span> <span class="pl-k">void</span> <span class="pl-en">goto_popup_position_func</span>(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data)
{
    ScintillaObject *sci = data;
    GdkWindow *window = <span class="pl-c1">gtk_widget_get_window</span>(<span class="pl-c1">GTK_WIDGET</span>(sci));
    gint pos = <span class="pl-c1">sci_get_current_position</span>(sci);
    gint line = <span class="pl-c1">sci_get_line_from_position</span>(sci, pos);
    gint line_height = <span class="pl-c1">scintilla_send_message</span>(sci, SCI_TEXTHEIGHT, line, <span class="pl-c1">0</span>);
    gint pos_x = <span class="pl-c1">scintilla_send_message</span>(sci, SCI_POINTXFROMPOSITION, <span class="pl-c1">0</span>, pos);
    gint pos_y = <span class="pl-c1">scintilla_send_message</span>(sci, SCI_POINTYFROMPOSITION, <span class="pl-c1">0</span>, pos);
    GdkScreen *screen = <span class="pl-c1">gtk_widget_get_screen</span>(<span class="pl-c1">GTK_WIDGET</span>(menu));
    gint monitor_num;
    GdkRectangle monitor;
    GtkRequisition req;

    <span class="pl-c1">gdk_window_get_origin</span>(window, x, y);
    monitor_num = <span class="pl-c1">gdk_screen_get_monitor_at_point</span>(screen, *x + pos_x, *y + pos_y);

#<span class="pl-k">if</span> GTK_CHECK_VERSION(3, 0, 0)
    <span class="pl-c1">gtk_widget_get_preferred_size</span>(<span class="pl-c1">GTK_WIDGET</span>(menu), <span class="pl-c1">NULL</span>, &req);
#<span class="pl-k">else</span>
    <span class="pl-c1">gtk_widget_size_request</span>(<span class="pl-c1">GTK_WIDGET</span>(menu), &req);
#<span class="pl-k">endif</span>

#<span class="pl-k">if</span> GTK_CHECK_VERSION(3, 4, 0)
    <span class="pl-c1">gdk_screen_get_monitor_workarea</span>(screen, monitor_num, &monitor);
#<span class="pl-k">else</span>
    <span class="pl-c1">gdk_screen_get_monitor_geometry</span>(screen, monitor_num, &monitor);
#<span class="pl-k">endif</span>

    <span class="pl-c">/* put at the X position, but within the monitor */</span>
    <span class="pl-k">if</span> (<span class="pl-c1">gtk_widget_get_direction</span>(<span class="pl-c1">GTK_WIDGET</span>(menu)) == GTK_TEXT_DIR_RTL)
        *x = <span class="pl-c1">MAX</span>(monitor.<span class="pl-smi">x</span>, *x + pos_x - req.<span class="pl-smi">width</span>);
    <span class="pl-k">else</span>
    {
        <span class="pl-k">if</span> (*x + pos_x + req.<span class="pl-smi">width</span> <= monitor.<span class="pl-smi">x</span> + monitor.<span class="pl-smi">width</span>)
            *x = <span class="pl-c1">MAX</span>(monitor.<span class="pl-smi">x</span>, *x + pos_x);
        <span class="pl-k">else</span>
            *x = monitor.<span class="pl-smi">x</span> + <span class="pl-c1">MAX</span>(<span class="pl-c1">0</span>, monitor.<span class="pl-smi">width</span> - req.<span class="pl-smi">width</span>);
    }

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

    *push_in = <span class="pl-c1">FALSE</span>;
}</pre></div>

<p>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.</p>

<p>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.</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br>Reply to this email directly or <a href="https://github.com/geany/geany/pull/406#issuecomment-186001747">view it on GitHub</a>.<img alt="" height="1" src="https://github.com/notifications/beacon/ABDrJ40jBqNBzgtoQ501L7S0BK8sZINjks5plmQ_gaJpZM4DUzez.gif" width="1" /></p>
<div itemscope itemtype="http://schema.org/EmailMessage">
<div itemprop="action" itemscope itemtype="http://schema.org/ViewAction">
  <link itemprop="url" href="https://github.com/geany/geany/pull/406#issuecomment-186001747"></link>
  <meta itemprop="name" content="View Pull Request"></meta>
</div>
<meta itemprop="description" content="View this Pull Request on GitHub"></meta>
</div>