racket/gui gtk: make `on-demand' for menus work better

There appears to be no way to make `on-demand' work right for the
Unity window manager's global menu bar, since there's no notificiation
when the menu bar is clicked. We approximate the correct behavior
by calling `on-demand' when a containing frame loses the keyboard
focus, which might be because the menu bar was clicked; that may be
too late (because the menu has already been shown), but it should
work most of the time.

Closes PR 13347.

Relevant to PR 13395, but DrRacket will have to change to work
around the remaining limitations of `on-demand'.
This commit is contained in:
Matthew Flatt 2013-01-01 14:34:53 -07:00
parent 0e763f5b01
commit 55f98a15d4
4 changed files with 26 additions and 3 deletions

View File

@ -404,9 +404,14 @@
(set! reported-activate on?)
(on-activate on?)))))))
(define treat-focus-out-as-menu-click? #f)
(define/public (treat-focus-out-as-menu-click)
(set! treat-focus-out-as-menu-click? #t))
(define focus-here? #f)
(define/override (on-focus? on?)
(unless on? (on-menu-click))
(when (and (not on?) treat-focus-out-as-menu-click?)
(on-menu-click))
(on-focus-child on?)
(cond
[on?

View File

@ -26,6 +26,9 @@
(define-gtk gtk_widget_set_usize (_fun _GtkWidget _int _int -> _void))
(define-gtk ubuntu_menu_proxy_get _fpointer
#:fail (lambda () #f))
(define (fixup-mnemonic title)
(mnemonic-string (regexp-replace #rx"\t.*$" title "")))
@ -92,6 +95,8 @@
(define/public (set-top-window top)
(set! top-wx top)
(when ubuntu_menu_proxy_get
(send top treat-focus-out-as-menu-click))
(install-widget-parent top)
(fix-menu-height))

View File

@ -72,6 +72,7 @@ Normally called when the user clicks on the menu bar containing the
item (before the user sees any menu items), just before the popup
menu containing the item is popped up, or just before inspecting the
menu bar containing the item for a shortcut key binding.
See @xmethod[menu-item-container<%> on-demand] for further details.
A @xmethod[menu-item-container<%> on-demand] method can be overridden
in such a way that the container does not call the

View File

@ -21,11 +21,12 @@ Returns a list of the items in the menu, popup menu, or menu bar. The
@methspec{
Called when the user clicks on the container as a menu bar (before the
user sees any menu items), just before the container as a popup menu
user sees any menu items, except with Unity's global menu bar as
noted below), just before the container as a popup menu
is popped up, or just before inspecting the menu bar containing the
item for a shortcut key binding.
If the container is not a menu bar or a popup menu, this method is
If the container is not a @tech{menu bar} or a @tech{popup menu}, this method is
normally called via the @method[menu-item-container<%> on-demand]
method of the container's owning menu bar or popup menu, because the
default implementation of the method chains to the
@ -34,6 +35,17 @@ If the container is not a menu bar or a popup menu, this method is
it does not call the @method[labelled-menu-item<%> on-demand] method
of its items.
On Unix with the Unity window manager using the global menu bar (which
is the default on Ubuntu), @racket[racket/gui/base] receives no
notification when the user clicks the menu bar. To approximate
@method[menu-item-container<%> on-demand] triggered by user clicks of
the menu bar, @method[menu-item-container<%> on-demand] is called for
a @tech{menu bar} whenever its @racket[frame%] object loses the
keyboard focus. Beware that if keyboard focus was lost because a menu
was clicked, then items added to the clicked menu during an
@method[menu-item-container<%> on-demand] invocation may not appear
for the user.
}
@methimpl{