1
0
Fork 0

Fix: [OSX] Quitting in fullscreen mode would loose the original window size.

This replicates the behaviour on e.g. Windows, which saves the original window size.
pull/8491/head
Michael Lutz 2021-01-03 15:23:08 +01:00
parent c860a247d3
commit 4ce53cb851
4 changed files with 61 additions and 32 deletions

View File

@ -11,10 +11,16 @@
#define VIDEO_COCOA_H #define VIDEO_COCOA_H
#include "../video_driver.hpp" #include "../video_driver.hpp"
#include "../../core/geometry_type.hpp"
extern bool _cocoa_video_started; extern bool _cocoa_video_started;
class VideoDriver_Cocoa : public VideoDriver { class VideoDriver_Cocoa : public VideoDriver {
private:
bool fullscreen_on_mainloop; ///< Switch to fullscreen once the main loop is running?
Dimension orig_res; ///< Saved window size for non-fullscreen mode.
public: public:
const char *Start(const StringList &param) override; const char *Start(const StringList &param) override;
@ -59,6 +65,16 @@ public:
* @return driver name * @return driver name
*/ */
const char *GetName() const override { return "cocoa"; } const char *GetName() const override { return "cocoa"; }
/* --- The following methods should be private, but can't be due to Obj-C limitations. --- */
/** Main game loop. */
void GameLoop(); // In event.mm.
private:
friend class WindowQuartzSubdriver;
void GameSizeChanged();
}; };
class FVideoDriver_Cocoa : public DriverFactoryBase { class FVideoDriver_Cocoa : public DriverFactoryBase {
@ -190,10 +206,6 @@ extern CocoaSubdriver *_cocoa_subdriver;
CocoaSubdriver *QZ_CreateWindowQuartzSubdriver(int width, int height, int bpp); CocoaSubdriver *QZ_CreateWindowQuartzSubdriver(int width, int height, int bpp);
void QZ_GameSizeChanged();
void QZ_GameLoop();
uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_id, int display_depth); uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_id, int display_depth);
#endif /* VIDEO_COCOA_H */ #endif /* VIDEO_COCOA_H */

View File

@ -143,25 +143,6 @@ static void QZ_UpdateVideoModes()
} }
} }
/**
* Handle a change of the display area.
*/
void QZ_GameSizeChanged()
{
if (_cocoa_subdriver == NULL) return;
/* Tell the game that the resolution has changed */
_screen.width = _cocoa_subdriver->GetWidth();
_screen.height = _cocoa_subdriver->GetHeight();
_screen.pitch = _cocoa_subdriver->GetWidth();
_screen.dst_ptr = _cocoa_subdriver->GetPixelBuffer();
_fullscreen = _cocoa_subdriver->IsFullscreen();
BlitterFactory::GetCurrentBlitter()->PostResize();
GameSizeChanged();
}
/** /**
* Find a suitable cocoa subdriver. * Find a suitable cocoa subdriver.
* *
@ -175,7 +156,6 @@ void QZ_GameSizeChanged()
static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool fullscreen, bool fallback) static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool fullscreen, bool fallback)
{ {
CocoaSubdriver *ret = QZ_CreateWindowQuartzSubdriver(width, height, bpp); CocoaSubdriver *ret = QZ_CreateWindowQuartzSubdriver(width, height, bpp);
if (ret != nullptr && fullscreen) ret->ToggleFullscreen(fullscreen);
if (ret != nullptr) return ret; if (ret != nullptr) return ret;
if (!fallback) return nullptr; if (!fallback) return nullptr;
@ -219,6 +199,7 @@ const char *VideoDriver_Cocoa::Start(const StringList &parm)
/* Don't create a window or enter fullscreen if we're just going to show a dialog. */ /* Don't create a window or enter fullscreen if we're just going to show a dialog. */
if (!CocoaSetupApplication()) return NULL; if (!CocoaSetupApplication()) return NULL;
this->orig_res = _cur_resolution;
int width = _cur_resolution.width; int width = _cur_resolution.width;
int height = _cur_resolution.height; int height = _cur_resolution.height;
int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
@ -228,13 +209,16 @@ const char *VideoDriver_Cocoa::Start(const StringList &parm)
return "The cocoa quartz subdriver only supports 8 and 32 bpp."; return "The cocoa quartz subdriver only supports 8 and 32 bpp.";
} }
/* Defer fullscreen toggle until the main loop is running,
* as otherwise a grey bar will be stuck on top of the window. */
this->fullscreen_on_mainloop = _fullscreen;
_cocoa_subdriver = QZ_CreateSubdriver(width, height, bpp, _fullscreen, true); _cocoa_subdriver = QZ_CreateSubdriver(width, height, bpp, _fullscreen, true);
if (_cocoa_subdriver == NULL) { if (_cocoa_subdriver == NULL) {
Stop(); Stop();
return "Could not create subdriver"; return "Could not create subdriver";
} }
QZ_GameSizeChanged(); this->GameSizeChanged();
QZ_UpdateVideoModes(); QZ_UpdateVideoModes();
return NULL; return NULL;
@ -281,7 +265,7 @@ bool VideoDriver_Cocoa::ChangeResolution(int w, int h)
bool ret = _cocoa_subdriver->ChangeResolution(w, h, BlitterFactory::GetCurrentBlitter()->GetScreenDepth()); bool ret = _cocoa_subdriver->ChangeResolution(w, h, BlitterFactory::GetCurrentBlitter()->GetScreenDepth());
QZ_GameSizeChanged(); this->GameSizeChanged();
QZ_UpdateVideoModes(); QZ_UpdateVideoModes();
return ret; return ret;
@ -320,6 +304,29 @@ void VideoDriver_Cocoa::EditBoxLostFocus()
HandleTextInput(NULL, true); HandleTextInput(NULL, true);
} }
/**
* Handle a change of the display area.
*/
void VideoDriver_Cocoa::GameSizeChanged()
{
if (_cocoa_subdriver == nullptr) return;
/* Tell the game that the resolution has changed */
_screen.width = _cocoa_subdriver->GetWidth();
_screen.height = _cocoa_subdriver->GetHeight();
_screen.pitch = _cocoa_subdriver->GetWidth();
_screen.dst_ptr = _cocoa_subdriver->GetPixelBuffer();
/* Store old window size if we entered fullscreen mode. */
bool fullscreen = _cocoa_subdriver->IsFullscreen();
if (fullscreen && !_fullscreen) this->orig_res = _cur_resolution;
_fullscreen = fullscreen;
BlitterFactory::GetCurrentBlitter()->PostResize();
::GameSizeChanged();
}
class WindowQuartzSubdriver; class WindowQuartzSubdriver;
/* Subclass of OTTD_CocoaView to fix Quartz rendering */ /* Subclass of OTTD_CocoaView to fix Quartz rendering */
@ -825,7 +832,7 @@ bool WindowQuartzSubdriver::WindowResized()
} }
} }
QZ_GameSizeChanged(); static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance())->GameSizeChanged();
/* Redraw screen */ /* Redraw screen */
this->num_dirty_rects = MAX_DIRTY_RECTS; this->num_dirty_rects = MAX_DIRTY_RECTS;

View File

@ -73,7 +73,7 @@ static OTTDMain *_ottd_main;
[ _cocoa_subdriver->cocoaview resetCursorRects ]; [ _cocoa_subdriver->cocoaview resetCursorRects ];
/* Hand off to main application code. */ /* Hand off to main application code. */
QZ_GameLoop(); static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance())->GameLoop();
/* We are done, thank you for playing. */ /* We are done, thank you for playing. */
[ self performSelectorOnMainThread:@selector(stopEngine) withObject:nil waitUntilDone:FALSE ]; [ self performSelectorOnMainThread:@selector(stopEngine) withObject:nil waitUntilDone:FALSE ];

View File

@ -617,7 +617,7 @@ static bool QZ_PollEvent()
} }
void QZ_GameLoop() void VideoDriver_Cocoa::GameLoop()
{ {
uint32 cur_ticks = GetTick(); uint32 cur_ticks = GetTick();
uint32 last_cur_ticks = cur_ticks; uint32 last_cur_ticks = cur_ticks;
@ -633,7 +633,7 @@ void QZ_GameLoop()
_cocoa_subdriver->Draw(true); _cocoa_subdriver->Draw(true);
CSleep(1); CSleep(1);
for (int i = 0; i < 2; i++) GameLoop(); for (int i = 0; i < 2; i++) ::GameLoop();
UpdateWindows(); UpdateWindows();
QZ_CheckPaletteAnim(); QZ_CheckPaletteAnim();
@ -652,7 +652,17 @@ void QZ_GameLoop()
while (QZ_PollEvent()) {} while (QZ_PollEvent()) {}
if (_exit_game) break; /* If we do that right after window creation, a grey bar will be left at the top. */
if (this->fullscreen_on_mainloop) {
this->fullscreen_on_mainloop = false;
_cocoa_subdriver->ToggleFullscreen(true);
}
if (_exit_game) {
/* Restore saved resolution if in fullscreen mode. */
if (_cocoa_subdriver->IsFullscreen()) _cur_resolution = this->orig_res;
break;
}
#if defined(_DEBUG) #if defined(_DEBUG)
if (_current_mods & NSShiftKeyMask) if (_current_mods & NSShiftKeyMask)
@ -678,7 +688,7 @@ void QZ_GameLoop()
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged(); if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
GameLoop(); ::GameLoop();
UpdateWindows(); UpdateWindows();
QZ_CheckPaletteAnim(); QZ_CheckPaletteAnim();