View Issue Details

IDProjectCategoryView StatusLast Update
0035929LazarusLCLpublic2019-08-10 20:10
ReporterBlakeAssigned ToDmitry Boyarintsev 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformOSmacOSOS Version10.14.6
Product Version2.0.3 (SVN)Product Build61618 
Target VersionFixed in Version 
Summary0035929: TMenuItem.OnClick is not called from a submenu, if TPopupMenu.PopUp occurs during a modal dialog
DescriptionWhen showing a popup menu during a modal dialog, the OnClick event is not called for any sub-menu TMenuItem.
If the exact same procedure occurs without any modal dialog (ie just from a normal floating window), then the OnClick event is called properly.
This appears to be a bug in cocoa. It was working fine in carbon.
Steps To Reproduce1. make a form and call form.ShowModal
2. create TPopupMenu, and add some items with OnClick event assigned
3. add sub-menu items with OnClick event assigned
4. TPopMenu.popup
5. click on any submenu items, and the OnClick event is not called

Do the same steps but call form.Show in step 1, and the submenus work ok.
See attached demonstration project.
Additional InformationPerhaps related:
https://bugs.freepascal.org/view.php?id=21997
TagsNo tags attached.
Fixed in Revision61674
LazTarget-
WidgetsetCocoa
Attached Files

Activities

Blake

2019-08-04 20:52

reporter  

testingModalPopups.zip (113,878 bytes)

Blake

2019-08-04 23:22

reporter   ~0117567

When a submenu item OnClick fails to be called (because modal dialog is active), the item's parent DoClicked > Click is called instead.

(menuitem.inc)

procedure TMenuItem.DoClicked(var msg);

Blake

2019-08-07 05:53

reporter   ~0117585

Last edited: 2019-08-07 05:53

View 2 revisions

Suggested fix in cocoawsmenus.pas (small section "find the sub->sub->sub... highlighted item"):

class procedure TCocoaWSPopupMenu.Popup(const APopupMenu: TPopupMenu; const X,
  Y: Integer);
var
  res : Boolean;
  mnu : NSMenuItem;
  view : NSView;
  w : NSWindow;
  px, py: Integer;
begin
  if Assigned(APopupMenu) and (APopupMenu.Handle<>0) then
  begin
    // old method which doesn't consider position but supports 10.0+ (useless since we target 10.6+)
    {w:=NSApp.keyWindow;
    if Assigned(w) then
    begin
      NSMenu.popUpContextMenu_withEvent_forView( TCocoaMenu(APopupMenu.Handle),
        NSApp.currentEvent, NSView(w.contentView));
    end;}

    // New method for 10.6+
    px := x;
    py := y;
    view := nil;
    w :=NSApp.keyWindow;
    if Assigned(w) then
    begin
      view := w.contentView;
      if Assigned(view) then
      begin
        view.lclScreenToLocal(px, py);
        py := Round(view.frame.size.height - py);
      end;
    end;
    res := TCocoaMenu(APopupMenu.Handle).popUpMenuPositioningItem_atLocation_inView(
      nil, NSMakePoint(px, py), view);

    // for whatever reason a context menu will not fire the "action"
    // of the specified target. Thus we're doing it here manually. :(
    // It seems a typical behaviour for all versions of macOS
    // todo: find out why. (calling runModalSession makes no difference)
    if Assigned(CocoaWidgetSet.Modals) and (CocoaWidgetSet.Modals.Count>0) then
    begin
      mnu := TCocoaMenu(APopupMenu.Handle).highlightedItem;

      // find the sub->sub->sub... highlighted item
     while (mnu.submenu <> nil) and (mnu.submenu.highlightedItem <> nil) do
       mnu := mnu.submenu.highlightedItem;

      if res and Assigned(mnu) then
      begin
        if mnu.respondsToSelector(ObjCSelector('lclItemSelected:')) then
          TCocoaMenuItem(mnu).lclItemSelected(mnu);
      end;
    end;

    APopupMenu.Close; // notify LCL popup menu
  end;
end;

Dmitry Boyarintsev

2019-08-09 03:32

developer   ~0117597

please test and close if ok

Blake

2019-08-10 07:50

reporter   ~0117618

Tested with 61676 and it works great, thanks!

Issue History

Date Modified Username Field Change
2019-08-04 20:52 Blake New Issue
2019-08-04 20:52 Blake File Added: testingModalPopups.zip
2019-08-04 23:22 Blake Note Added: 0117567
2019-08-07 05:53 Blake Note Added: 0117585
2019-08-07 05:53 Blake Note Edited: 0117585 View Revisions
2019-08-09 03:32 Dmitry Boyarintsev Assigned To => Dmitry Boyarintsev
2019-08-09 03:32 Dmitry Boyarintsev Status new => resolved
2019-08-09 03:32 Dmitry Boyarintsev Resolution open => fixed
2019-08-09 03:32 Dmitry Boyarintsev Fixed in Revision => 61674
2019-08-09 03:32 Dmitry Boyarintsev LazTarget => -
2019-08-09 03:32 Dmitry Boyarintsev Widgetset Cocoa => Cocoa
2019-08-09 03:32 Dmitry Boyarintsev Note Added: 0117597
2019-08-10 07:50 Blake Note Added: 0117618
2019-08-10 20:10 Dmitry Boyarintsev Status resolved => closed