summaryrefslogtreecommitdiff
path: root/src/video/cocoa
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2021-01-03 15:23:08 +0100
committerMichael Lutz <michi@icosahedron.de>2021-01-03 21:20:28 +0100
commit4ce53cb85113956be318c12801d5663a26e3fef9 (patch)
treee2136e9f73b0611f08a5c946a6288abdf5881868 /src/video/cocoa
parentc860a247d3e21628a0ac799d4d99ae178bb8a4a3 (diff)
downloadopenttd-4ce53cb85113956be318c12801d5663a26e3fef9.tar.xz
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.
Diffstat (limited to 'src/video/cocoa')
-rw-r--r--src/video/cocoa/cocoa_v.h20
-rw-r--r--src/video/cocoa/cocoa_v.mm53
-rw-r--r--src/video/cocoa/cocoa_wnd.mm2
-rw-r--r--src/video/cocoa/event.mm18
4 files changed, 61 insertions, 32 deletions
diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h
index 52d26c847..f3e484b01 100644
--- a/src/video/cocoa/cocoa_v.h
+++ b/src/video/cocoa/cocoa_v.h
@@ -11,10 +11,16 @@
#define VIDEO_COCOA_H
#include "../video_driver.hpp"
+#include "../../core/geometry_type.hpp"
+
extern bool _cocoa_video_started;
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:
const char *Start(const StringList &param) override;
@@ -59,6 +65,16 @@ public:
* @return driver name
*/
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 {
@@ -190,10 +206,6 @@ extern CocoaSubdriver *_cocoa_subdriver;
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);
#endif /* VIDEO_COCOA_H */
diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm
index 0f3c4c32c..c7c5a308e 100644
--- a/src/video/cocoa/cocoa_v.mm
+++ b/src/video/cocoa/cocoa_v.mm
@@ -144,25 +144,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.
*
* @param width Width of display area.
@@ -175,7 +156,6 @@ void QZ_GameSizeChanged()
static CocoaSubdriver *QZ_CreateSubdriver(int width, int height, int bpp, bool fullscreen, bool fallback)
{
CocoaSubdriver *ret = QZ_CreateWindowQuartzSubdriver(width, height, bpp);
- if (ret != nullptr && fullscreen) ret->ToggleFullscreen(fullscreen);
if (ret != nullptr) return ret;
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. */
if (!CocoaSetupApplication()) return NULL;
+ this->orig_res = _cur_resolution;
int width = _cur_resolution.width;
int height = _cur_resolution.height;
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.";
}
+ /* 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);
if (_cocoa_subdriver == NULL) {
Stop();
return "Could not create subdriver";
}
- QZ_GameSizeChanged();
+ this->GameSizeChanged();
QZ_UpdateVideoModes();
return NULL;
@@ -281,7 +265,7 @@ bool VideoDriver_Cocoa::ChangeResolution(int w, int h)
bool ret = _cocoa_subdriver->ChangeResolution(w, h, BlitterFactory::GetCurrentBlitter()->GetScreenDepth());
- QZ_GameSizeChanged();
+ this->GameSizeChanged();
QZ_UpdateVideoModes();
return ret;
@@ -320,6 +304,29 @@ void VideoDriver_Cocoa::EditBoxLostFocus()
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;
/* 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 */
this->num_dirty_rects = MAX_DIRTY_RECTS;
diff --git a/src/video/cocoa/cocoa_wnd.mm b/src/video/cocoa/cocoa_wnd.mm
index a2854adaf..8c16dd1ef 100644
--- a/src/video/cocoa/cocoa_wnd.mm
+++ b/src/video/cocoa/cocoa_wnd.mm
@@ -73,7 +73,7 @@ static OTTDMain *_ottd_main;
[ _cocoa_subdriver->cocoaview resetCursorRects ];
/* Hand off to main application code. */
- QZ_GameLoop();
+ static_cast<VideoDriver_Cocoa *>(VideoDriver::GetInstance())->GameLoop();
/* We are done, thank you for playing. */
[ self performSelectorOnMainThread:@selector(stopEngine) withObject:nil waitUntilDone:FALSE ];
diff --git a/src/video/cocoa/event.mm b/src/video/cocoa/event.mm
index cb3c753ac..642149858 100644
--- a/src/video/cocoa/event.mm
+++ b/src/video/cocoa/event.mm
@@ -617,7 +617,7 @@ static bool QZ_PollEvent()
}
-void QZ_GameLoop()
+void VideoDriver_Cocoa::GameLoop()
{
uint32 cur_ticks = GetTick();
uint32 last_cur_ticks = cur_ticks;
@@ -633,7 +633,7 @@ void QZ_GameLoop()
_cocoa_subdriver->Draw(true);
CSleep(1);
- for (int i = 0; i < 2; i++) GameLoop();
+ for (int i = 0; i < 2; i++) ::GameLoop();
UpdateWindows();
QZ_CheckPaletteAnim();
@@ -652,7 +652,17 @@ void QZ_GameLoop()
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 (_current_mods & NSShiftKeyMask)
@@ -678,7 +688,7 @@ void QZ_GameLoop()
if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
- GameLoop();
+ ::GameLoop();
UpdateWindows();
QZ_CheckPaletteAnim();