mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 18:19:34 +02:00
cocoa: adding additional tracking for menus. If Modal window is called, all main menu tracking is being cancelled
(cherry picked from commit 3c3b14de01
)
This commit is contained in:
parent
927f2884d3
commit
30d615e33a
@ -831,6 +831,8 @@ begin
|
||||
|
||||
if not Assigned(Modals) then Modals := TList.Create;
|
||||
|
||||
MenuTrackCancelAll();
|
||||
|
||||
// If a modal menu has it's menu, then SetMainMenu has already been called
|
||||
// (Show is called for modal windows prior to ShowModal. Show triggers Activate and Active is doing MainMenu)
|
||||
if not hasMenu then begin
|
||||
|
@ -91,6 +91,7 @@ type
|
||||
// of the menu. While LCL allows to modify the menu contents when the submenu
|
||||
// is about to be activated.
|
||||
procedure menuNeedsUpdate(AMenu: NSMenu); message 'menuNeedsUpdate:';
|
||||
procedure menuDidClose(AMenu: NSMenu); message 'menuDidClose:';
|
||||
//procedure menuDidClose(AMenu: NSMenu); message 'menuDidClose:';
|
||||
function worksWhenModal: LCLObjCBoolean; message 'worksWhenModal';
|
||||
end;
|
||||
@ -171,18 +172,75 @@ function AllocCocoaMenu(const atitle: string = ''): TCocoaMenu;
|
||||
function LCLMenuItemInit(item: NSMenuItem; const atitle: string; ashortCut: TShortCut): id;
|
||||
function LCLMenuItemInit(item: NSMenuItem; const atitle: string; VKKey: Word = 0; State: TShiftState = []): id;
|
||||
|
||||
procedure MenuTrackStarted(mn: NSMenu);
|
||||
procedure MenuTrackEnded(mn: NSMenu);
|
||||
procedure MenuTrackCancelAll;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
CocoaInt;
|
||||
|
||||
var
|
||||
isMenuEnabled : Boolean = true;
|
||||
// menuTrack is needed due to the LCL architecture vs Cocoa menu handling.
|
||||
//
|
||||
// (below "Modal" refers to LCL "modal" state. Not verified with Cocoa modal)
|
||||
//
|
||||
// All Menu hangling in Cocoa is done within a "tracking" loop. (similar to Modal even loop)
|
||||
// The major issue, is that WS code never knows that a menu was clicked,
|
||||
// outside of the tracking loop. (The delegate is being notified already within the loop)
|
||||
//
|
||||
// If LCL handler is calling for any modal window at the time,
|
||||
// the menu tracking should stop, and the model window is the only be processed
|
||||
//
|
||||
// In order to track "opened" menus, menuTrack list is used.
|
||||
// If modal window is called MenuTrackCancelAll() will terminate all openned sub-menus
|
||||
//
|
||||
// The issue of the conflict between "Menu tracking" and "Modal tracking"
|
||||
// is only affecting Node-Menus (menu items with submenus)
|
||||
// because we call LM_ACTIVATE within tracking loop.
|
||||
// The Leaf-menuitems (menu items w/o submenuis) are calling "itemSElected" (LM_ACTIVATE)
|
||||
// when the tracking loop is over
|
||||
//
|
||||
// See topic: https://forum.lazarus.freepascal.org/index.php/topic,56419.0.html
|
||||
menuTrack : TList = nil;
|
||||
|
||||
procedure MenuTrackStarted(mn: NSMenu);
|
||||
begin
|
||||
if not Assigned(menuTrack) then menuTrack:=TList.Create;
|
||||
menuTrack.Add(mn);
|
||||
end;
|
||||
|
||||
procedure MenuTrackEnded(mn: NSMenu);
|
||||
var
|
||||
i : integer;
|
||||
begin
|
||||
i := menuTrack.IndexOf(mn);
|
||||
if i>=0 then
|
||||
menuTrack.Delete(i);
|
||||
end;
|
||||
|
||||
procedure MenuTrackCancelAll;
|
||||
var
|
||||
i : integer;
|
||||
mn : NSMenu;
|
||||
begin
|
||||
if not Assigned(menuTrack) then Exit;
|
||||
for i:=menuTrack.Count-1 downto 0 do begin
|
||||
mn := NSMenu(menuTrack[i]);
|
||||
if Assigned(mn) then
|
||||
mn.cancelTracking;
|
||||
end;
|
||||
menuTrack.Clear;
|
||||
end;
|
||||
|
||||
function LCLMenuItemInit(item: NSMenuItem; const atitle: string; ashortCut: TShortCut): id;
|
||||
var
|
||||
key : NSString;
|
||||
mask : NSUInteger;
|
||||
begin
|
||||
ShortcutToKeyEquivalent(ashortCut, key, mask);
|
||||
|
||||
Result := item.initWithTitle_action_keyEquivalent(
|
||||
ControlTitleToNSStr(Atitle),
|
||||
objcselector('lclItemSelected:'), // Selector is Hard-coded, that's why it's LCLMenuItemInit
|
||||
@ -406,6 +464,10 @@ end;
|
||||
procedure TCocoaMenuItem.menuNeedsUpdate(AMenu: NSMenu);
|
||||
begin
|
||||
if not Assigned(menuItemCallback) then Exit;
|
||||
if not isMenuEnabled then Exit;
|
||||
|
||||
MenuTrackStarted(AMenu);
|
||||
|
||||
if (menu.isKindOfClass(TCocoaMenu)) then
|
||||
begin
|
||||
// Issue #37789
|
||||
@ -419,6 +481,11 @@ begin
|
||||
menuItemCallback.ItemSelected;
|
||||
end;
|
||||
|
||||
procedure TCocoaMenuItem.menuDidClose(AMenu: NSMenu);
|
||||
begin
|
||||
MenuTrackEnded(AMenu);
|
||||
end;
|
||||
|
||||
function TCocoaMenuItem.worksWhenModal: LCLObjCBoolean;
|
||||
begin
|
||||
// refer to NSMenuItem.target (Apple) documentation
|
||||
@ -968,9 +1035,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
isMenuEnabled : Boolean = true;
|
||||
|
||||
function ToggleAppMenu(ALogicalEnabled: Boolean): Boolean;
|
||||
begin
|
||||
Result := isMenuEnabled;
|
||||
@ -978,4 +1042,10 @@ begin
|
||||
isMenuEnabled := ALogicalEnabled;
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
finalization
|
||||
MenuTrackCancelAll;
|
||||
if Assigned(menuTrack) then menuTrack.Free;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user