* * *

Author Topic: [Solved] How can I call NSWindow.togglefullscreen?  (Read 1533 times)

Clover

  • New member
  • *
  • Posts: 37
[Solved] How can I call NSWindow.togglefullscreen?
« on: February 22, 2018, 04:19:30 pm »
I'm porting my carbon app to cocoa 64-bit.

I notice that MacOS adds "Enter Full Screen" automatically to my View main menu item and enables the special green traffic light button, for toggling in and out of fullscreen mode. These two methods work great. But it would be nice to also start in full screen mode if that's how the user left the app.

Unfortunately setting full screen in code by setting WindowState := wsFullScreen causes big problems: popup menus no longer appear, the main menu no longer unhides itself, it's impossible to return to wsNormal mode and the app has to be force quit.

I was wondering if instead I could invoke the "Enter Full Screen" item that MacOS adds to my View menu.

I see that https://developer.apple.com/library/content/documentation/General/Conceptual/MOSXAppProgrammingGuide/FullScreenApp/FullScreenApp.html shows that the NSWindow API contains a simple togglefullscreen function. How would I call that from my Lazarus code?
« Last Edit: February 26, 2018, 06:27:34 pm by Clover »

Phil

  • Hero Member
  • *****
  • Posts: 2749
Re: How can I call NSWindow.togglefullscreen?
« Reply #1 on: February 22, 2018, 04:27:28 pm »
Unfortunately setting full screen in code by setting WindowState := wsFullScreen causes big problems: popup menus no longer appear, the main menu no longer unhides itself, it's impossible to return to wsNormal mode and the app has to be force quit.

Are you using trunk code? If not, test with it - appears to have support for this. If still a problem, file a bug report for the Cocoa widgetset with a small reproducible example (project source files).


Clover

  • New member
  • *
  • Posts: 37
Re: How can I call NSWindow.togglefullscreen?
« Reply #2 on: February 22, 2018, 06:45:27 pm »
Yes indeed, I'm using trunk code after following your excellent directions at https://macpgmr.github.io/MacXPlatform/UsingCocoaFromTrunk.html

I am filing bug reports as I go and I've just filed one for this.

Clover

  • New member
  • *
  • Posts: 37
Re: How can I call NSWindow.togglefullscreen?
« Reply #3 on: February 23, 2018, 06:44:22 pm »
Since it could be a while for this to be fixed in trunk, and a MacOS will be released in a couple of weeks that will start warning about 32-bit apps, can anyone assist with my question, which was: How can I call the NSWindow.togglefullscreen (or invoke the "Enter Full Screen" menu item added by MacOS) from my Lazarus code? Thanks!

Phil

  • Hero Member
  • *****
  • Posts: 2749
Re: How can I call NSWindow.togglefullscreen?
« Reply #4 on: February 23, 2018, 09:22:17 pm »
Since it could be a while for this to be fixed in trunk, and a MacOS will be released in a couple of weeks that will start warning about 32-bit apps, can anyone assist with my question, which was: How can I call the NSWindow.togglefullscreen (or invoke the "Enter Full Screen" menu item added by MacOS) from my Lazarus code? Thanks!

If you look at TCocoaWidgetSet.ShowWindow in cocoawinapi.inc, you can see how it currently does it. And the code that leaves fullscreen mode is commented out, apparently because it crashes.

Using exit/enterFullScreenMode methods like Cocoa widgetset does is the old way of doing it. The new way, which you link to, using toggleFullScreen, is presumably what the Cocoa-added View menu item uses. But toggleFullScreen was added in 10.7, but FPC CocoaAll is based on parsing of 10.6, I believe, hence it has no toggleFullScreen. You would need to add this to NSWindow, perhaps via a category, then call it similar to the way TCocoaWidgetSet.ShowWindow calls NSWindow methods.

You could also try sending the shortcut key, per these approaches:

https://stackoverflow.com/questions/4705748/send-a-keyboard-shortcut-to-a-mac-os-x-window

I hope you're not using the Cocoa widgetset for production code. I don't consider it suitable for that.

Clover

  • New member
  • *
  • Posts: 37
Re: How can I call NSWindow.togglefullscreen?
« Reply #5 on: February 26, 2018, 02:49:52 pm »
Thanks for the suggestions, Phil.

Quote
I hope you're not using the Cocoa widgetset for production code. I don't consider it suitable for that.

Hmm, well it's a tough situation given the impending doom of 32-bit apps. It's actually a game I'm converting to 64-bit Cocoa. I have been able to work around the deficiencies quite well so far and not far off completing. Is there something in particular you're concerned about?

Clover

  • New member
  • *
  • Posts: 37
Re: How can I call NSWindow.togglefullscreen?
« Reply #6 on: February 26, 2018, 05:51:37 pm »
Thanks to your help Phil, I managed to add the proper NSWindow.toggleFullScreen which now appears to work great, just like the MacOS version:

In lcl/interfaces/cocoa/cocoa_extras.pas I added:

Code: Pascal  [Select]
  1. NSWindowFix = objccategory external (NSWindow)
  2.   procedure toggleFullScreen (sender: id); message 'toggleFullScreen:';
  3. end
  4.  

and changed cocoawinapi.inc to:

Code: Pascal  [Select]
  1.    // Fullscreen status change
  2.     if (nCmdShow <> SW_MINIMIZE) and (nCmdShow <> SW_HIDE) then
  3.     begin
  4.       // getting out of fullscreen
  5.       if (nCmdShow <> SW_SHOWFULLSCREEN) {and lWinContent.isInFullScreenMode()} then
  6.       begin
  7.         win.toggleFullScreen(nil);
  8.         // lWinContent.exitFullScreenModeWithOptions(nil); <-- THIS CAUSES A CRASH!!!
  9.       end
  10.       // getting into fullscreen mode
  11.       else if (nCmdShow = SW_SHOWFULLSCREEN) and not lWinContent.isInFullScreenMode() then
  12.       begin
  13.         win.toggleFullScreen(nil);
  14.         // lWinContent.enterFullScreenMode_withOptions(NSScreen.mainScreen, nil);
  15.       end;
  16.     end;
  17.  

I commented out the first test for lWinContent.isInFullScreenMode() as I think it's now redundant and was stopping the transition back to Normal.

Phil

  • Hero Member
  • *****
  • Posts: 2749
Re: How can I call NSWindow.togglefullscreen?
« Reply #7 on: February 26, 2018, 06:26:21 pm »
Thanks to your help Phil, I managed to add the proper NSWindow.toggleFullScreen which now appears to work great, just like the MacOS version:

Good work.

Why don't you post that as a bug report (mark it "Cocoa" in bug report title to be noticeable)?

Looking at the other fixes via categories at the top of cocoa_extra.pas, it looks like the minimum version for Cocoa widgetset is already at least 10.7 (NSView.fittingSize was added in 10.7), so there shouldn't be any objection to your patches on the basis of version.

Not sure what minimum version they have in mind. In general, I would not target less than 10.10 since that's no more than 5% of users per netmarketshare.com, although you can't set FPC switch -WM higher than 10.9 if you use the LCL printer support (Carbon and Cocoa both) because of linker problems.

Clover

  • New member
  • *
  • Posts: 37
Re: [Solved] How can I call NSWindow.togglefullscreen?
« Reply #8 on: February 26, 2018, 06:39:20 pm »
Thanks again for your assistance. I have updated bug reports #33210 and #32050 so it should get noticed.

No, shouldn't be a big issue supporting 10.7 and higher.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus