From c9c3967f421872ec064b53ea43f040af73047f7d Mon Sep 17 00:00:00 2001 From: dmitry Date: Thu, 26 Aug 2010 23:25:31 +0000 Subject: [PATCH] carbon: implement keyboard processing before menu fire event (LCL compatible). fixes #17205 and probably some other issues git-svn-id: trunk@27207 - --- lcl/interfaces/carbon/carbonmenus.pp | 2 -- lcl/interfaces/carbon/carbonobject.inc | 19 ++++++++----- lcl/interfaces/carbon/carbonprivate.pp | 2 +- lcl/interfaces/carbon/carbonprivatewindow.inc | 28 ++++++++++++++++++- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/lcl/interfaces/carbon/carbonmenus.pp b/lcl/interfaces/carbon/carbonmenus.pp index 5505e6c5ed..0a86900320 100644 --- a/lcl/interfaces/carbon/carbonmenus.pp +++ b/lcl/interfaces/carbon/carbonmenus.pp @@ -84,7 +84,6 @@ type function CheckMenu(const Menu: HMENU; const AMethodName: String; AParamName: String = ''): Boolean; - implementation {------------------------------------------------------------------------------ @@ -769,6 +768,5 @@ begin Result:=AnsiChar(KeyValue); end; - end. diff --git a/lcl/interfaces/carbon/carbonobject.inc b/lcl/interfaces/carbon/carbonobject.inc index c6cd9d2867..cd88d38183 100644 --- a/lcl/interfaces/carbon/carbonobject.inc +++ b/lcl/interfaces/carbon/carbonobject.inc @@ -205,7 +205,7 @@ begin { Another possible solution of the problem, is to Post another custom event } { to the loop, and report LCL about Menu pressed after the event arrives, } { though it might seem, like interface is lagging } - if (HotChar<>#0) then + if (CarbonMenu.Parent.Dismissed<>kHIMenuDismissedBySelection) and (HotChar<>#0) then begin AllowMenu := True; Focused:=GetFocus; @@ -215,17 +215,22 @@ begin if not AllowMenu then begin Result:=eventNotHandledErr; + CarbonMenu.Parent.Dismissed:=0; Exit; end; end; end; - FillChar(Msg, SizeOf(Msg), 0); - Msg.msg := LM_ACTIVATE; - CarbonMenu.LCLMenuItem.Dispatch(Msg); - - Result := noErr; - Exit; + if CarbonMenu.Parent.Dismissed=kHIMenuDismissedBySelection then begin + FillChar(Msg, SizeOf(Msg), 0); + Msg.msg := LM_ACTIVATE; + CarbonMenu.LCLMenuItem.Dispatch(Msg); + CarbonMenu.Parent.Dismissed:=0; + Result := noErr; + Exit; + end else + Result:=CallNextEventHandler(ANextHandler, AEvent); + end; end; end; diff --git a/lcl/interfaces/carbon/carbonprivate.pp b/lcl/interfaces/carbon/carbonprivate.pp index 8884077cf6..51f4650876 100644 --- a/lcl/interfaces/carbon/carbonprivate.pp +++ b/lcl/interfaces/carbon/carbonprivate.pp @@ -36,7 +36,7 @@ uses // widgetset WSControls, WSLCLClasses, WSProc, // LCL Carbon - CarbonDef, CarbonGDIObjects, + CarbonDef, CarbonGDIObjects, CarbonMenus, // LCL LMessages, LCLMessageGlue, LCLProc, LCLType, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, Menus; diff --git a/lcl/interfaces/carbon/carbonprivatewindow.inc b/lcl/interfaces/carbon/carbonprivatewindow.inc index 9dae87953f..c574670990 100644 --- a/lcl/interfaces/carbon/carbonprivatewindow.inc +++ b/lcl/interfaces/carbon/carbonprivatewindow.inc @@ -19,6 +19,24 @@ // H A N D L E R S // ================================================================== + +procedure SendMenuActivate(AMenu: MenuRef; MenuIdx: MenuItemIndex); +var + CarbonMenu : TCarbonMenu; + Msg : TLMessage; + S : ByteCount; +begin + if GetMenuItemProperty(AMenu, MenuIdx, LAZARUS_FOURCC, + WIDGETINFO_FOURCC, SizeOf(TCarbonMenu), S, @CarbonMenu) = noErr then + begin + FillChar(Msg, SizeOf(Msg), 0); + Msg.msg := LM_ACTIVATE; + CarbonMenu.LCLMenuItem.Dispatch(Msg); + end; +end; + + + {------------------------------------------------------------------------------ Name: CarbonWindow_Close ------------------------------------------------------------------------------} @@ -679,6 +697,9 @@ const KeyMsg: TLMKeyDown; CharMsg: TLMChar; OrigChar: AnsiString; + + Menu: MenuRef; + MenuIdx: MenuItemIndex; begin Result:=EventNotHandledErr; {$IFDEF VerboseKeyboard} @@ -778,10 +799,15 @@ const if CharMsg.CharCode<>ord(KeyChar) then LCLCharToMacEvent(Char(CharMsg.CharCode)); - if Result<>noErr then Result:=CallNextEventHandler(ANextHandler, AEvent); + if IsMenuKeyEvent(nil, GetCurrentEvent, kMenuEventQueryOnly, @Menu, @MenuIdx) then + begin + // re-handling menu + SendMenuActivate(Menu, MenuIdx); + end; + //Send a LM_(SYS)CHAR if IsSysKey then begin