Recent

Author Topic: [Solved] menu not accessible after window creation osx  (Read 4633 times)

Key-Real

  • Full Member
  • ***
  • Posts: 189
[Solved] menu not accessible after window creation osx
« on: October 05, 2021, 10:33:45 am »
I create a window:
Code: Pascal  [Select][+][-]
  1.  
  2. var
  3.    window:NSWindow;
  4.    screenwidth,screenheight:dword;
  5.  
  6. type
  7.  
  8.     TCocoaAppDelegate = objcclass (NSObject, NSApplicationDelegateProtocol)
  9.     end;
  10.  
  11.     TCocoaApp = objcclass (NSApplication)
  12.       procedure poll; message 'poll';
  13.   end;
  14.  
  15.  
  16.   TCocoaWindow = objcclass (NSWindow)
  17.         function initWithContentRect_styleMask_backing_defer (contentRect: NSRect; aStyle: NSUInteger; bufferingType: NSBackingStoreType; flag: boolean): id; message 'initWithContentRect:styleMask:backing:defer:';
  18.     procedure dealloc; override;
  19.  
  20.     function windowShouldClose (notification: NSNotification):boolean; message 'windowShouldClose:';
  21.     procedure screenParametersChanged (notification: NSNotification); message 'screenParametersChanged:';
  22.     end;
  23.  
  24.  
  25.  
  26.  
  27. procedure TCocoaWindow.screenParametersChanged (notification: NSNotification);
  28. var theframe:NSRect;
  29. begin
  30.   theframe := NSMakeRect(0,0,screenwidth,screenheight); // NSScreen.mainScreen.frame;
  31.     setFrame_display(theframe, true);
  32. end;
  33.  
  34. function TCocoaWindow.windowShouldClose (notification: NSNotification):boolean;
  35. begin
  36.   gfxDone:=true;
  37.   result:=true;
  38. end;
  39.  
  40.  
  41. procedure TCocoaWindow.dealloc;
  42. begin
  43.   NSNotificationCenter.defaultCenter.removeObserver(self);
  44.   inherited dealloc;
  45. end;
  46.  
  47.  
  48. function TCocoaWindow.initWithContentRect_styleMask_backing_defer (contentRect: NSRect; aStyle: NSUInteger; bufferingType: NSBackingStoreType; flag: boolean): id;
  49. begin
  50.   result := inherited initWithContentRect_styleMask_backing_defer(contentRect, aStyle, bufferingType, flag);
  51.   if result <> nil then
  52.     NSNotificationCenter(NSNotificationCenter.defaultCenter).addObserver_selector_name_object(result, objcselector('screenParametersChanged:'), NSApplicationDidChangeScreenParametersNotification, nil);
  53. end;
  54.  
  55.  
  56.  
  57. procedure TCocoaApp.poll;
  58. var
  59.   event: NSEvent;
  60.   pool: NSAutoreleasePool;
  61.   myType:longint;
  62.   mySendEvent : boolean;
  63.   myKeyCode:longint;
  64.   myMouseX,myMouseY:longint;
  65. begin
  66.   pool := NSAutoreleasePool.alloc.init;
  67.   event := nextEventMatchingMask_untilDate_inMode_dequeue(NSAnyEventMask, {NSDate.distantPast}nil, NSDefaultRunLoopMode, true);
  68.  
  69.  
  70.   if event<>nil then begin
  71.       fillchar(gfxMessanger^,sizeof(longint)*4,0);
  72.  
  73.       myType:=event.type_;
  74.  
  75.       mySendEvent:=true;
  76.  
  77.       if (myType = NSKeyDown) or (myType = NSKeyUp) then begin myKeyCode:=event.keycode; mySendEvent:=false; end;
  78.       if myType = NSMouseMoved then myMouseX:=round(event.locationInWindow.x);
  79.       if myType = NSMouseMoved then myMouseY:=round(vscreen.height-event.locationInWindow.y);
  80.  
  81.       system.move(myType,gfxMessanger^,sizeof(longint));
  82.       system.move(myKeyCode,(gfxMessanger+sizeof(longint))^,sizeof(longint));
  83.       system.move(myMouseX,(gfxMessanger+sizeof(longint)*2)^,sizeof(longint));
  84.       system.move(myMouseY,(gfxMessanger+sizeof(longint)*3)^,sizeof(longint));
  85.  
  86.       if mySendEvent then begin
  87.         sendEvent(event);
  88.         updateWindows;
  89.       end;
  90.  
  91.  
  92.   end;
  93.  
  94.  
  95.   pool.release;
  96. end;
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103. procedure cocoaCreateWindow(width,height:dword;title:string;fullscreen:boolean);
  104. var
  105.   windowFlags: NSUInteger = 0;
  106.   frame:NSRect;
  107.  
  108.   bar : NSMenu;
  109.   appmenu:NSMenu;
  110.   menuItem: NSMenuItem;
  111. begin
  112.  
  113. screenwidth:=width;
  114. screenheight:=height;
  115.  
  116.  
  117. // frame := NSMakeRect(0,0,NSScreen.mainScreen.frame.size.width,NSScreen.mainScreen.frame.size.height);
  118.  
  119. frame := NSMakeRect(0,0,screenwidth,screenheight);
  120.  
  121.  
  122. if fullscreen then windowFlags:=NSBorderlessWindowMask;
  123. if not fullscreen then windowFlags:=NSTitledWindowMask or NSClosableWindowMask; // or NSMiniaturizableWindowMask; //or NSResizableWindowMask;
  124.  
  125.  
  126.  window := TCocoaWindow.alloc.initWithContentRect_styleMask_backing_defer(frame,windowFlags,NSBackingStoreBuffered,false);
  127.  
  128.  
  129.  
  130.  window.setTitle(NSSTR(title));
  131.  
  132.  
  133.  
  134. if fullscreen then window.setCollectionBehavior(NSWindowCollectionBehaviorStationary or NSWindowCollectionBehaviorCanJoinAllSpaces or NSWindowCollectionBehaviorFullScreenPrimary  );
  135. if not fullscreen then window.setCollectionBehavior(NSWindowCollectionBehaviorManaged);
  136.  
  137.  
  138. if fullscreen then window.toggleFullscreen(nil);
  139.  
  140.  
  141. if fullscreen then NSApp.setPresentationOptions(NSApplicationPresentationFullScreen or  NSApplicationPresentationHideDock or NSApplicationPresentationHideMenuBar);
  142. if not fullscreen then NSApp.setPresentationOptions(NSApplicationPresentationDefault);
  143.  
  144.  
  145.  
  146.  
  147.  
  148. window.makeKeyAndOrderFront(nil);
  149.  
  150. window.setAcceptsMouseMovedEvents(true);
  151.  
  152. end;
  153.  
  154.  
  155.  
  156. procedure Cocoa_PollEvents;
  157. begin
  158.   TCocoaApp(TCocoaApp.sharedApplication).poll;
  159.   //NSApp.performSelectorOnMainThread_withObject_waitUntilDone(objcselector('poll'), nil, true);
  160. end;
  161.  
  162.  
  163.  
  164.  
  165. procedure CocoaInit;
  166. var
  167.   app: TCocoaApp;
  168.   delegate: TCocoaAppDelegate;
  169. begin
  170.   app := TCocoaApp(TCocoaApp.sharedApplication);
  171.   delegate := TCocoaAppDelegate.alloc.init;
  172.   app.setDelegate(delegate);
  173.  
  174.   NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);
  175.   NSApp.activateIgnoringOtherApps(true);
  176.   NSApp.finishLaunching;
  177. end;
  178.  
  179.  
  180.  
  181.  
  182.  
  183. procedure CocoaClose;
  184. begin
  185.  window.close;
  186.  Cocoa_PollEvents;
  187. end;
  188.  
  189.  
It is possible to switch in fullscreen mode with this code, but i mean window mode.

The window ist shown. But If i click on the menu (the apple menu at the top of the Screen) it does not react. I have to click away from my created window or click on another App, and when i select my window again now i can access the menu.

What to do?
« Last Edit: March 14, 2022, 08:47:47 am by Key-Real »

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: menu not accessible after window creation osx
« Reply #1 on: October 08, 2021, 12:32:07 am »
Can you attach a minimal compilable project showing the issue? (Use Lazarus > Project > Publish Project).

Key-Real

  • Full Member
  • ***
  • Posts: 189
Re: menu not accessible after window creation osx
« Reply #2 on: October 10, 2021, 11:58:59 am »
Here the minimal compilable program:

Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$modeswitch objectivec1}
  3. uses CocoaAll, ctypes, MacOSAll, sysutils;
  4.  
  5. var
  6.    window:NSWindow;
  7.    done:boolean = false;
  8.  
  9.  
  10. type
  11.  
  12.     TCocoaAppDelegate = objcclass (NSObject, NSApplicationDelegateProtocol)
  13.     end;
  14.  
  15.     TCocoaApp = objcclass (NSApplication)
  16.       procedure poll; message 'poll';
  17.     end;
  18.  
  19.  
  20.     TCocoaWindow = objcclass (NSWindow)
  21.       function initWithContentRect_styleMask_backing_defer (contentRect: NSRect; aStyle: NSUInteger; bufferingType: NSBackingStoreType; flag: boolean): id; message 'initWithContentRect:styleMask:backing:defer:';
  22.       procedure dealloc; override;
  23.  
  24.       function windowShouldClose (notification: NSNotification):boolean; message 'windowShouldClose:';
  25.     end;
  26.  
  27.  
  28. function TCocoaWindow.windowShouldClose (notification: NSNotification):boolean;
  29. begin
  30.   done:=true;
  31.   result:=true;
  32. end;
  33.  
  34.  
  35. procedure TCocoaWindow.dealloc;
  36. begin
  37.   NSNotificationCenter.defaultCenter.removeObserver(self);
  38.   inherited dealloc;
  39. end;
  40.  
  41.  
  42. function TCocoaWindow.initWithContentRect_styleMask_backing_defer (contentRect: NSRect; aStyle: NSUInteger; bufferingType: NSBackingStoreType; flag: boolean): id;
  43. begin
  44.   result := inherited initWithContentRect_styleMask_backing_defer(contentRect, aStyle, bufferingType, flag);
  45.   if result <> nil then
  46.     NSNotificationCenter(NSNotificationCenter.defaultCenter).addObserver_selector_name_object(result, objcselector('screenParametersChanged:'), NSApplicationDidChangeScreenParametersNotification, nil);
  47. end;
  48.  
  49.  
  50. procedure TCocoaApp.poll;
  51. var
  52.   event: NSEvent;
  53.   pool: NSAutoreleasePool;
  54. begin
  55.   pool := NSAutoreleasePool.alloc.init;
  56.   event := nextEventMatchingMask_untilDate_inMode_dequeue(NSAnyEventMask, {NSDate.distantPast}nil, NSDefaultRunLoopMode, true);
  57.  
  58.   if event<>nil then begin
  59.       sendEvent(event);
  60.       updateWindows;
  61.   end;
  62.  
  63.   pool.release;
  64. end;
  65.  
  66.  
  67. procedure CocoaCreateWindow(width,height:dword;title:string);
  68. var
  69.   windowFlags: NSUInteger = 0;
  70.   frame:NSRect;
  71. begin
  72.  frame := NSMakeRect(0,0,width,height);
  73.  
  74.  windowFlags:=NSTitledWindowMask or NSClosableWindowMask; // or NSMiniaturizableWindowMask; //or NSResizableWindowMask;
  75.  window := TCocoaWindow.alloc.initWithContentRect_styleMask_backing_defer(frame,windowFlags,NSBackingStoreBuffered,false);
  76.  
  77.  window.setTitle(NSSTR(title));
  78.  
  79.  window.setCollectionBehavior(NSWindowCollectionBehaviorManaged);
  80.  NSApp.setPresentationOptions(NSApplicationPresentationDefault);
  81.  
  82.  window.makeKeyAndOrderFront(nil);
  83.  window.setAcceptsMouseMovedEvents(true);
  84. end;
  85.  
  86.  
  87. procedure CocoaPollEvents;
  88. begin
  89.   TCocoaApp(TCocoaApp.sharedApplication).poll;
  90. end;
  91.  
  92.  
  93. procedure CocoaInit;
  94. var
  95.   app: TCocoaApp;
  96.   delegate: TCocoaAppDelegate;
  97. begin
  98.   app := TCocoaApp(TCocoaApp.sharedApplication);
  99.   delegate := TCocoaAppDelegate.alloc.init;
  100.   app.setDelegate(delegate);
  101.  
  102.   NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);
  103.   NSApp.activateIgnoringOtherApps(true);
  104.   NSApp.finishLaunching;
  105. end;
  106.  
  107.  
  108. procedure CocoaClose;
  109. begin
  110.  window.close;
  111.  CocoaPollEvents;
  112. end;
  113.  
  114.  
  115.  
  116.  
  117. begin
  118.  CocoaInit;
  119.  CocoaCreateWindow(640,480,'test');
  120.  
  121.  repeat
  122.   CocoaPollEvents;
  123.  until done;
  124.  
  125.  CocoaClose;
  126. end.
  127.  

Key-Real

  • Full Member
  • ***
  • Posts: 189
Re: menu not accessible after window creation osx
« Reply #3 on: March 10, 2022, 12:13:10 pm »
I tested whis Code on
MacOS 10.13.4 (Intel)
MacOS 11.6 (Aarch64)
MacOS 12.2.1 (Intel)
All Same behaviour.

Is this an Apple Bug?
Or is the code wrong?

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: menu not accessible after window creation osx
« Reply #4 on: March 11, 2022, 11:18:50 pm »
Your program does not compile:

Quote
Free Pascal Compiler version 3.3.1 [2022/01/07] for aarch64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Darwin for AArch64
Compiling project1.pas
project1.pas(21,16) Error: Inherited methods can only be overridden in Objective-C and Java, add "override" (inherited method defined in NSWindow)
project1.pas(128) Fatal: There were 1 errors compiling module, stopping
Fatal: Compilation aborted
Error: /usr/local/bin/ppca64 returned an error exitcode

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: menu not accessible after window creation osx
« Reply #5 on: March 11, 2022, 11:27:08 pm »
Ok, I added the override directive and now it compiles. It looks fine to me. There is no menu because you have not coded one :-)

Please go read the Lazarus Wiki article Writing a Cocoa app without the LCL for how to add a menu.
« Last Edit: March 11, 2022, 11:31:52 pm by trev »

Key-Real

  • Full Member
  • ***
  • Posts: 189
Re: menu not accessible after window creation osx
« Reply #6 on: March 12, 2022, 11:16:21 am »
the program in the posted link shows the same behavier.

If I start it, I can not click on the menu (nothing hapens), than I click on another window (my prog looses focus), than I click back on my window app, now I can click on the menu.

macOS 11.6.4


l attach the screen recording as evidence:

http://www.sistavip.com/pub/screen.zip
« Last Edit: March 12, 2022, 11:34:43 am by Key-Real »

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: menu not accessible after window creation osx
« Reply #7 on: March 13, 2022, 12:24:24 am »
If you are creating a GUI executable, then you need to wrap it in an application bundle. You can execute the bundle with:

Code: [Select]
open mybundle.app
or

Code: [Select]
./mybundle.app/Contents/MacOS/mybundle
and  if you do that, then the menu items are accessible.

Key-Real

  • Full Member
  • ***
  • Posts: 189
Re: menu not accessible after window creation osx
« Reply #8 on: March 13, 2022, 02:04:35 pm »
Thx,
now I create a Bundle and everything works well.

But
I toke the Info.plist from the Lazarus link above
Code: XML  [Select][+][-]
  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
  3. <plist version="1.0">
  4. <dict>
  5.   <key>CFBundleDevelopmentRegion</key>
  6.   <string>English</string>
  7.   <key>CFBundleExecutable</key>
  8.   <string>test</string>
  9.   <key>CFBundleIconFile</key>
  10.   <string>macicon.icns</string>
  11.   <key>CFBundleIdentifier</key>
  12.   <string>org.magnifier.magnifier</string>
  13.   <key>CFBundleInfoDictionaryVersion</key>
  14.   <string>6.0</string>
  15.   <key>CFBundlePackageType</key>
  16.   <string>APPL</string>
  17.   <key>CFBundleSignature</key>
  18.   <string>MAG#</string>
  19.   <key>CFBundleVersion</key>
  20.   <string>1.0</string>
  21. </dict>
  22. </plist>
  23.  

he trows my a parsing error.
I removed this file from the bundle, everything works

Do I need this file?

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: menu not accessible after window creation osx
« Reply #9 on: March 13, 2022, 11:59:52 pm »
I just used the script to create an Info.plist file and then checked it by using the property list utility thus:

Code: Bash  [Select][+][-]
  1. trev@macmini7 [/Users/trev] $ cd Magnifier.app/
  2. trev@macmini7 [/Users/trev/Magnifier.app] $ cd Contents/
  3. trev@macmini7 [/Users/trev/Magnifier.app/Contents] $ plutil Info.plist
  4. Info.plist: OK

and as you can see it is parsed as OK. I also opened it in Xcode's PlistEditor plugin and no parsing error was detected.

Looking at the file you pasted into your post, the error is on line 2 where you have a trailing ' (single quotation mark) character.

Yes, the Info.plist file is a required application bundle file.

Key-Real

  • Full Member
  • ***
  • Posts: 189
Re: menu not accessible after window creation osx
« Reply #10 on: March 14, 2022, 08:47:09 am »
yes, thx

and sorry for my lameness

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: [Solved] menu not accessible after window creation osx
« Reply #11 on: March 14, 2022, 10:49:37 am »
No worries, we have all had to start at the beginning of the journey of knowledge. I'm glad I've been able to help you on your way.

 

TinyPortal © 2005-2018