diff options
author | Caolán McNamara <caolanm@redhat.com> | 2016-03-03 14:04:05 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2016-03-03 14:04:05 +0000 |
commit | daa7754026ba5b025076b90f7a4427cd5820e736 (patch) | |
tree | 539856efe7c9d06a3e2374679d0fa4540ff03b35 /vcl | |
parent | fbea89b6b2a4a91fecc4200d59bf03166c3f8908 (diff) |
gtk3: position the native popup menus exactly where we want them
Change-Id: I2594925cba1f7c9c90178906d9c782024ad1cf4f
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/gtk/gtksalmenu.cxx | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/vcl/unx/gtk/gtksalmenu.cxx b/vcl/unx/gtk/gtksalmenu.cxx index ff92eacfe5db..722d24269381 100644 --- a/vcl/unx/gtk/gtksalmenu.cxx +++ b/vcl/unx/gtk/gtksalmenu.cxx @@ -361,8 +361,24 @@ void GtkSalMenu::UpdateFull() ImplUpdate(true, !pMenu->mbMenuBar); } -bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& /*rRect*/, - FloatWinPopupFlags /*nFlags*/) +#if GTK_CHECK_VERSION(3,0,0) +static void MenuPositionFunc(GtkMenu* menu, gint* x, gint* y, gboolean* push_in, gpointer user_data) +{ + Point *pPos = static_cast<Point*>(user_data); + *x = pPos->X(); + if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL) + { + GtkRequisition natural_size; + gtk_widget_get_preferred_size(GTK_WIDGET(menu), nullptr, &natural_size); + *x -= natural_size.width; + } + *y = pPos->Y(); + *push_in = false; +} +#endif + +bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& rRect, + FloatWinPopupFlags nFlags) { #if GTK_CHECK_VERSION(3,0,0) guint nButton; @@ -383,7 +399,14 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& /*rR nTime = gtk_get_current_event_time(); } - mpFrame = static_cast<GtkSalFrame*>(pWin->ImplGetWindowImpl()->mpRealParent->ImplGetFrame()); + VclPtr<vcl::Window> xParent = pWin->ImplGetWindowImpl()->mpRealParent; + mpFrame = static_cast<GtkSalFrame*>(xParent->ImplGetFrame()); + + // do the same strange semantics as vcl popup windows to arrive at a frame geometry + // in mirrored UI case; best done by actually executing the same code + sal_uInt16 nArrangeIndex; + Point aPos = FloatingWindow::ImplCalcPos(pWin, rRect, nFlags, nArrangeIndex); + aPos = FloatingWindow::ImplConvertToAbsPos(xParent, aPos); GLOActionGroup* pActionGroup = g_lo_action_group_new(static_cast<gpointer>(mpFrame)); g_lo_action_group_set_top_menu(pActionGroup, static_cast<gpointer>(this)); @@ -404,7 +427,8 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& /*rR //until the gtk menu is destroyed GMainLoop* pLoop = g_main_loop_new(nullptr, true); g_signal_connect_swapped(G_OBJECT(pWidget), "deactivate", G_CALLBACK(g_main_loop_quit), pLoop); - gtk_menu_popup(GTK_MENU(pWidget), nullptr, nullptr, nullptr, nullptr, nButton, nTime); + gtk_menu_popup(GTK_MENU(pWidget), nullptr, nullptr, MenuPositionFunc, + &aPos, nButton, nTime); if (g_main_loop_is_running(pLoop)) { gdk_threads_leave(); @@ -422,6 +446,8 @@ bool GtkSalMenu::ShowNativePopupMenu(FloatingWindow* pWin, const Rectangle& /*rR return true; #else (void)pWin; + (void)rRect; + (void)nFlags; return false; #endif } |