Recent

Author Topic: Creating Cocoa window after app.run  (Read 942 times)

mullich

  • Newbie
  • Posts: 2
Creating Cocoa window after app.run
« on: July 11, 2018, 02:22:09 pm »
Hi,

I'm trying to show a window on button click. If I create a window beforehand (line 57 in the code below), everything OK. But if I create a window after calling NSApp.run, it hides. Here is the code:
Code: Pascal  [Select]
  1. program cocoa1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch objectivec1}
  5.  
  6. uses
  7.   CocoaAll, classes, sysutils;  
  8.  
  9. type
  10.   { TMyDelegate }
  11.   TMyDelegate = objcclass(NSObject, NSWindowDelegateProtocol)
  12.   public
  13.     procedure HandleButtonClick_A(sender: id); message 'HandleButtonClick_A:';
  14.   end;  
  15.  
  16. var  
  17.   window: NSWindow;
  18.   window2: NSWindow;  
  19.   lButton: NSButton;
  20.   lDelegate: TMyDelegate;  
  21.  
  22. procedure Make2ndWnd;
  23. begin
  24.   window2 := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 600, 600),
  25.     NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask or NSResizableWindowMask,
  26.     NSBackingStoreBuffered, False).autorelease;  
  27.  
  28.   window2.center;      
  29.   window2.settitle(NSSTR('2ndwnd'));        
  30. end;
  31.      
  32. procedure TMyDelegate.HandleButtonClick_A(sender: id);
  33. begin      
  34.   if window2=nil then Make2ndwnd;  
  35.   window2.makeKeyAndorderfront(nil);    
  36. end;    
  37.  
  38. begin      
  39.   NSApp := NSApplication.sharedApplication;
  40.   NSApp.setActivationPolicy(NSApplicationActivationPolicyRegular);
  41.   window := NSWindow.alloc.initWithContentRect_styleMask_backing_defer(NSMakeRect(0, 0, 600, 600),
  42.     NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask or NSResizableWindowMask,
  43.     NSBackingStoreBuffered, False).autorelease;    
  44.  
  45.   lDelegate := TMyDelegate.alloc.init;  
  46.   window.setdelegate(lDelegate);      
  47.  
  48.   lButton:=NSButton.alloc.initWithFrame(NSMakeRect(50, 100, 120, 50)).autorelease;
  49.   window.contentView.addSubview(lButton);
  50.   lButton.setTitle(NSSTR('Show wnd'));
  51.   lButton.setButtonType(NSMomentaryLightButton);
  52.   lButton.setBezelStyle(NSRoundedBezelStyle);  
  53.   lButton.setTarget(lDelegate);
  54.   lButton.setAction(ObjCSelector(lDelegate.HandleButtonClick_A));  
  55.  
  56.   //if NSWindow is created before NSApp.Run, then it shows; if it is created after NSApp.Run, then if hides
  57.   //Make2ndwnd;  
  58.   window.center;
  59.   window.setTitle(NSSTR('1stwnd'));
  60.   window.makeKeyAndOrderFront(nil);
  61.   NSApp.activateIgnoringOtherApps(true);  
  62.   NSApp.run;
  63. end.                                        

Am i doing something wrong? How I can create and show new window in a runtime?

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: Creating Cocoa window after app.run
« Reply #1 on: July 11, 2018, 06:04:00 pm »
Am i doing something wrong? How I can create and show new window in a runtime?

Probably the autorelease call on window2 is causing the window to be released prematurely. By default, I believe, the window will be released when it is closed. As a result of that, you probably also don't want the check for nil in your button handler - it needs to be created each time since the previously created windows was released when closed.

Do you want to show window2 modally? If so use NSApp.runModalForWindow / NSApp.stopModal or NSApp.beginSheet_modalForWindow_... / NSApp.endSheet. Or look at the code in Lazarus LCL implementation for Cocoa (cocoawsforms.pp) for the various ways contemplated there.

Inevitable questions:

Why are trying to roll your own instead of using...

(1) Lazarus LCL with Cocoa widgetset
(2) Xcode with Pascal (see ProjectXC here: https://macpgmr.github.io)

mullich

  • Newbie
  • Posts: 2
Re: Creating Cocoa window after app.run
« Reply #2 on: July 12, 2018, 01:40:03 pm »
Quote
Probably the autorelease call on window2 is causing the window to be released prematurely.

Thank you so much! That settles it. Everything works now.

As for you questions, I'm making a multiwindow app with my own controls, some windows will be modal, some not, and each will have a OpenGlView on it. I've tried using runmodalforwindow method, but for some reason, OpenGl doesn't work with it.

Phil

  • Hero Member
  • *****
  • Posts: 2750
Re: Creating Cocoa window after app.run
« Reply #3 on: July 12, 2018, 02:14:21 pm »
I've tried using runmodalforwindow method, but for some reason, OpenGl doesn't work with it.

I'm not familiar with OpenGL. One thing you could test would be a modal Lazarus LCL form with your OpenGL code in it, just to see if it's any different. Be sure to compile for the Cocoa widgetset and Lazarus trunk SVN code would be ideal.