Recent

Author Topic: [Solved] Toggle Fullscreen mode  (Read 460 times)

Hi im Pascal

  • New member
  • *
  • Posts: 24
[Solved] Toggle Fullscreen mode
« on: January 01, 2019, 02:35:30 am »
Hello,

I'm trying to implement fullscreen on F11. Unfortunately, after setting WindowStyle to wsFullScreen, when I read WindowStyle the next time it still contains wsNormal. After reading it a second time then it reads wsFullscreen. I tried Update and SetFocus and so on after setting wsFullScreen, it didn't help.

Code: Pascal  [Select]
  1. procedure TForm1.ToggleFullscreenActionExecute(Sender: TObject);
  2. begin
  3.   if WindowState = wsFullScreen then begin
  4.     WindowState := wsNormal;
  5.     ToggleFullscreenAction.Caption := 'Fullscreen';
  6.   end
  7.   else begin
  8.     WindowState := wsFullScreen;
  9.     ToggleFullscreenAction.Caption := 'Exit Fullscreen';
  10.   end;
  11. end;

I press F11 -> application goes fullscreen -> I press F11 second time -> application stays fullscreen -> I press F11 third time -> application goes back to normal.

Any ideas what is going wrong?
« Last Edit: January 01, 2019, 05:09:31 pm by Hi im Pascal »

lucamar

  • Hero Member
  • *****
  • Posts: 734
Re: Toggle Fullscreen mode
« Reply #1 on: January 01, 2019, 02:52:30 am »
It shouldn't be needed and I'm not sure it will help but add:
  Application.ProcessMessages;
at the end of the procedure and see if it helps. If it does, something may be wrong in the WindowsState setter.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4/FPC 3.0.4 on:
(K)Ubuntu 12..16, Windows XP SP3 (Home/Prof.) and various DOS incarnations.

Hi im Pascal

  • New member
  • *
  • Posts: 24
Re: Toggle Fullscreen mode
« Reply #2 on: January 01, 2019, 03:01:55 am »
It shouldn't be needed and I'm not sure it will help but add:
  Application.ProcessMessages;
at the end of the procedure and see if it helps. If it does, something may be wrong in the WindowsState setter.

Hi,

didn't help. Can someone reproduce my error? Start an empty project, slap a button on the form and put this code in it:
Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   if WindowState = wsFullScreen then begin
  4.     BorderStyle := bsSizeable;
  5.     WindowState := wsNormal;
  6.   end
  7.   else begin
  8.     BorderStyle := bsNone;
  9.     WindowState := wsFullScreen;
  10.   end;
  11. end;

Same thing windows and Manjaro Linux (Gnome Desktop).

engkin

  • Hero Member
  • *****
  • Posts: 2194
Re: Toggle Fullscreen mode
« Reply #3 on: January 01, 2019, 03:25:41 am »
I see the problem here (Win32). It cycles between wsNormal, wsMaximized and wsFullScreen. I temporarily can overcome the problem with:
Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   if WindowState in [wsFullScreen,wsMaximized] then begin
  4.     WindowState := wsNormal;
  5.     BorderStyle := bsSizeable;
  6.   end
  7.   else begin
  8.     WindowState := wsFullScreen;
  9.     BorderStyle := bsNone;
  10.   end;
  11. end;

still I see other problems.

jamie

  • Hero Member
  • *****
  • Posts: 1123
Re: Toggle Fullscreen mode
« Reply #4 on: January 01, 2019, 03:28:10 am »
There is no "wsFullScreen" mode in widows, its a made up thing in Lazarus..

Even the SetWindow API in the widget diverts to a Maximize state when it detects wsFullScreen
constant.
 so if you read it, chances the state may actually be at Maximize and not FullScreen..

Maybe you want to test for both...

 If WindowsState in [wsMaximize, wsFullScreen] then.....


Damn! I got beat to it this time! LOL

Hi im Pascal

  • New member
  • *
  • Posts: 24
Re: Toggle Fullscreen mode
« Reply #5 on: January 01, 2019, 03:30:23 am »
OK yeah I noticed I have to set borderStyle to bsNone as well. This version is better for windows (remembers window dimensions and position):
Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.     if WindowState in [wsFullScreen,wsMaximized] then begin
  4.     BorderStyle := bsSizeable;
  5.     WindowState := wsNormal;
  6.     Width := lastWidth;
  7.     Height := lastHeight;
  8.     Left := lastLeft;
  9.     Top := lastTop;
  10.   end
  11.   else begin
  12.     lastWidth := Width;
  13.     lastHeight := Height;
  14.     lastLeft := Left;
  15.     lastTop := Top;
  16.     BorderStyle := bsNone;
  17.     WindowState := wsFullScreen;
  18.   end;
  19. end;

Gonna test it on Linux again now.
Edit:
To make it work on my Manjaro + GNOME:
Code: Pascal  [Select]
  1.   if isFullscreen then begin
  2.     isFullscreen := false;
  3.     WindowState := wsNormal;
  4.     WindowState := wsFullScreen;
  5.     WindowState := wsNormal;
  6.     ToggleFullscreenAction.Caption := 'Fullscreen';
  7.   end
  8.   else begin
  9.     ToggleFullscreenAction.Caption := 'Exit Fullscreen';
  10.     WindowState := wsFullScreen;
  11.     isFullscreen := true;
  12.   end;
isFullscreen is a member variable for Form1. I can't check for wsFullScreen or wsMaximized, because it reads as wsNormal the first time around after setting it to fullScreen.

Complete Windows 10 and Manjaro Linux GNOME compatible code (I hope):
Code: Pascal  [Select]
  1.   if isFullscreen then begin
  2.     isFullscreen := false;
  3.     WindowState := wsNormal;
  4.     WindowState := wsFullScreen;
  5.     WindowState := wsNormal;
  6. {$IFDEF WINDOWS}
  7.     BorderStyle := bsSizeable;
  8. {$ENDIF}
  9.     ToggleFullscreenAction.Caption := 'Fullscreen';
  10.     Width := lastWidth;
  11.     Height := lastHeight;
  12.     Left := lastLeft;
  13.     Top := lastTop;
  14.   end
  15.   else begin
  16.     lastWidth := Width;
  17.     lastHeight := Height;
  18.     lastLeft := Left;
  19.     lastTop := Top;
  20.     ToggleFullscreenAction.Caption := 'Exit Fullscreen';
  21. {$IFDEF WINDOWS}
  22.     BorderStyle := bsNone;
  23. {$ENDIF}
  24.     WindowState := wsFullScreen;
  25.     isFullscreen := true;
  26.   end;

wsFullScreen seems to be buggy with GNOME on my Linux machine, as well as BorderStyle in Kombination with wsFullScreen.
« Last Edit: January 01, 2019, 04:05:10 am by Hi im Pascal »

User137

  • Hero Member
  • *****
  • Posts: 1767
    • Nxpascal home
Re: Toggle Fullscreen mode
« Reply #6 on: January 01, 2019, 11:00:32 am »
This looks good on Windows 10:
Code: Pascal  [Select]
  1. var FullScreen: boolean;
  2.  
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. begin
  5.   if FullScreen then begin
  6.     WindowState := wsNormal;
  7.     BorderStyle := bsSizeable;
  8.   end else begin
  9.     BorderStyle := bsNone;
  10.     WindowState:=wsMaximized; // Or WindowState:=wsFullscreen;
  11.   end;
  12.   FullScreen:=not FullScreen;
  13. end;

The order of lines do matter, other way around it loses the original window size and remains maximized:
Code: Pascal  [Select]
  1.     WindowState := wsNormal;
  2.     BorderStyle := bsSizeable;
« Last Edit: January 01, 2019, 11:02:09 am by User137 »

Hi im Pascal

  • New member
  • *
  • Posts: 24
Re: Toggle Fullscreen mode
« Reply #7 on: January 01, 2019, 01:06:55 pm »
When I started, I was expecting something like
Code: [Select]
Form1.Fullscreen := True given my experience with Lazarus so far ^^ Maybe a worthy addition to the LCL?

lucamar

  • Hero Member
  • *****
  • Posts: 734
Re: Toggle Fullscreen mode
« Reply #8 on: January 01, 2019, 01:09:06 pm »
This version is better for windows (remembers window dimensions and position):

You don't need to "remember" them yourself: TCustomForm aready keeps properties for this. Look for RestoredLeft, RestoredTop, RestoredWidth and RestoredHeight.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 1.8.4/FPC 3.0.4 on:
(K)Ubuntu 12..16, Windows XP SP3 (Home/Prof.) and various DOS incarnations.

Hi im Pascal

  • New member
  • *
  • Posts: 24
Re: Toggle Fullscreen mode
« Reply #9 on: January 01, 2019, 05:07:20 pm »
@lucamar Ah cool, that's good to know, thanks!

I did realize that indeed the window dimensions are correctly preserved if you change the order like User137 suggested. I wasn't sure how to toggle in Pascal, but your method is cleaner than writing isFullscreen in two separate places as well. So this is my current state for the record:
Code: Pascal  [Select]
  1. procedure TForm1.ToggleFullscreen;
  2. begin
  3.   if isFullscreen then begin
  4.     // go to normal -> fullscreen -> normal/restored so it works in GNOME for me
  5.     WindowState := wsNormal;
  6.     WindowState := wsFullScreen;
  7.     WindowState := RestoredWindowState;
  8.     BorderStyle := RestoredBorderStyle;
  9.   end
  10.   else begin
  11.     RestoredBorderStyle := BorderStyle;
  12.     RestoredWindowState := WindowState;
  13.   {$IFDEF WINDOWS}
  14.     BorderStyle := bsNone;
  15.   {$ENDIF}
  16.     WindowState := wsFullScreen;
  17.   end;
  18.   isFullscreen := not isFullscreen;
  19. end;

Thanks again for your help and suggestions.

P.S.: There is another improvement: When the window is maximized, and you go into fullscreen, it is restored as wsNormal instead of being wsMaximized again. Additionally, probably it's a good idea to store the BorderStyle, too. I edited my code appropriately.

There is also this: http://wiki.freepascal.org/Application_full_screen_mode. You need 'uses LCLIntf' for ShowWindow function.

P.P.S.: After further testing, I have come to the conclusion that even using RestoredLeft and RestoredTop, the result is for me not satisfactory: If you really want to window to always end up in the position it was before, store your own Left/Top. (For example if you use poDesktopCenter etc. the window won't go back to the side, if you had it all the way on the side)
« Last Edit: January 02, 2019, 05:22:18 pm by Hi im Pascal »