diff --git a/CHANGELOG.md b/CHANGELOG.md index fd762a82ac..66f5868589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -157,6 +157,7 @@ Feature #6600: Support NiSortAdjustNode Feature #6684: Support NiFltAnimationNode Feature #6699: Ignored flag + Feature #6700: Support windowed fullscreen Feature #6706: Save the size of the Options window Feature #6721: [OpenMW-CS] Add option to open records in new window Task #6201: Remove the "Note: No relevant classes found. No output generated" warnings diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index e6d857a943..5a57be0e53 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -42,7 +42,7 @@ Launcher::GraphicsPage::GraphicsPage(QWidget *parent) customWidthSpinBox->setMaximum(res.width()); customHeightSpinBox->setMaximum(res.height()); - connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int))); + connect(windowModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotFullScreenChanged(int))); connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool))); connect(screenComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(screenChanged(int))); connect(framerateLimitCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotFramerateLimitToggled(bool))); @@ -94,8 +94,10 @@ bool Launcher::GraphicsPage::loadSettings() if (Settings::Manager::getBool("vsync", "Video")) vSyncCheckBox->setCheckState(Qt::Checked); - if (Settings::Manager::getBool("fullscreen", "Video")) - fullScreenCheckBox->setCheckState(Qt::Checked); + size_t windowMode = static_cast(Settings::Manager::getInt("window mode", "Video")); + if (windowMode > static_cast(Settings::WindowMode::Windowed)) + windowMode = 0; + windowModeComboBox->setCurrentIndex(windowMode); if (Settings::Manager::getBool("window border", "Video")) windowBorderCheckBox->setCheckState(Qt::Checked); @@ -183,9 +185,9 @@ void Launcher::GraphicsPage::saveSettings() if (cVSync != Settings::Manager::getBool("vsync", "Video")) Settings::Manager::setBool("vsync", "Video", cVSync); - bool cFullScreen = fullScreenCheckBox->checkState(); - if (cFullScreen != Settings::Manager::getBool("fullscreen", "Video")) - Settings::Manager::setBool("fullscreen", "Video", cFullScreen); + int cWindowMode = windowModeComboBox->currentIndex(); + if (cWindowMode != Settings::Manager::getInt("window mode", "Video")) + Settings::Manager::setInt("window mode", "Video", cWindowMode); bool cWindowBorder = windowBorderCheckBox->checkState(); if (cWindowBorder != Settings::Manager::getBool("window border", "Video")) @@ -355,9 +357,9 @@ void Launcher::GraphicsPage::screenChanged(int screen) } } -void Launcher::GraphicsPage::slotFullScreenChanged(int state) +void Launcher::GraphicsPage::slotFullScreenChanged(int mode) { - if (state == Qt::Checked) { + if (mode == static_cast(Settings::WindowMode::Fullscreen) || mode == static_cast(Settings::WindowMode::WindowedFullscreen)) { standardRadioButton->toggle(); customRadioButton->setEnabled(false); customWidthSpinBox->setEnabled(false); diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a99bd72831..fa84bcf14c 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -554,7 +554,7 @@ void OMW::Engine::createWindow(Settings::Manager& settings) int screen = settings.getInt("screen", "Video"); int width = settings.getInt("resolution x", "Video"); int height = settings.getInt("resolution y", "Video"); - bool fullscreen = settings.getBool("fullscreen", "Video"); + Settings::WindowMode windowMode = static_cast(Settings::Manager::getInt("window mode", "Video")); bool windowBorder = settings.getBool("window border", "Video"); bool vsync = settings.getBool("vsync", "Video"); unsigned int antialiasing = std::max(0, settings.getInt("antialiasing", "Video")); @@ -562,15 +562,17 @@ void OMW::Engine::createWindow(Settings::Manager& settings) int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(screen), pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(screen); - if(fullscreen) + if(windowMode == Settings::WindowMode::Fullscreen || windowMode == Settings::WindowMode::WindowedFullscreen) { pos_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); } Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE; - if(fullscreen) + if(windowMode == Settings::WindowMode::Fullscreen) flags |= SDL_WINDOW_FULLSCREEN; + else if (windowMode == Settings::WindowMode::WindowedFullscreen) + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; // Allows for Windows snapping features to properly work in borderless window SDL_SetHint("SDL_BORDERLESS_WINDOWED_STYLE", "1"); diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index e79132f0ab..785cec9ef6 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -224,7 +224,7 @@ namespace MWGui getWidget(mSettingsTab, "SettingsTab"); getWidget(mOkButton, "OkButton"); getWidget(mResolutionList, "ResolutionList"); - getWidget(mFullscreenButton, "FullscreenButton"); + getWidget(mWindowModeList, "WindowModeList"); getWidget(mWindowBorderButton, "WindowBorderButton"); getWidget(mTextureFilteringButton, "TextureFilteringButton"); getWidget(mAnisotropyBox, "AnisotropyBox"); @@ -274,6 +274,8 @@ namespace MWGui mLightsResetButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onLightsResetButtonClicked); mMaxLights->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onMaxLightsChanged); + mWindowModeList->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWindowModeChanged); + mKeyboardSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onKeyboardSwitchClicked); mControllerSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onControllerSwitchClicked); @@ -325,7 +327,8 @@ namespace MWGui updateMaxLightsComboBox(mMaxLights); - mWindowBorderButton->setEnabled(!Settings::Manager::getBool("fullscreen", "Video")); + Settings::WindowMode windowMode = static_cast(Settings::Manager::getInt("window mode", "Video")); + mWindowBorderButton->setEnabled(windowMode != Settings::WindowMode::Fullscreen && windowMode != Settings::WindowMode::WindowedFullscreen); mKeyboardSwitch->setStateSelected(true); mControllerSwitch->setStateSelected(false); @@ -433,6 +436,15 @@ namespace MWGui apply(); } + void SettingsWindow::onWindowModeChanged(MyGUI::ComboBox* _sender, size_t pos) + { + if (pos == MyGUI::ITEM_NONE) + return; + + Settings::Manager::setInt("window mode", "Video", static_cast(_sender->getIndexSelected())); + apply(); + } + void SettingsWindow::onMaxLightsChanged(MyGUI::ComboBox* _sender, size_t pos) { int count = 8 * (pos + 1); @@ -485,49 +497,6 @@ namespace MWGui newState = true; } - if (_sender == mFullscreenButton) - { - // check if this resolution is supported in fullscreen - if (mResolutionList->getIndexSelected() != MyGUI::ITEM_NONE) - { - std::string resStr = mResolutionList->getItemNameAt(mResolutionList->getIndexSelected()); - int resX, resY; - parseResolution (resX, resY, resStr); - Settings::Manager::setInt("resolution x", "Video", resX); - Settings::Manager::setInt("resolution y", "Video", resY); - } - - bool supported = false; - int fallbackX = 0, fallbackY = 0; - for (unsigned int i=0; igetItemCount(); ++i) - { - std::string resStr = mResolutionList->getItemNameAt(i); - int resX, resY; - parseResolution (resX, resY, resStr); - - if (i == 0) - { - fallbackX = resX; - fallbackY = resY; - } - - if (resX == Settings::Manager::getInt("resolution x", "Video") - && resY == Settings::Manager::getInt("resolution y", "Video")) - supported = true; - } - - if (!supported && mResolutionList->getItemCount()) - { - if (fallbackX != 0 && fallbackY != 0) - { - Settings::Manager::setInt("resolution x", "Video", fallbackX); - Settings::Manager::setInt("resolution y", "Video", fallbackY); - } - } - - mWindowBorderButton->setEnabled(!newState); - } - if (getSettingType(_sender) == checkButtonType) { Settings::Manager::setBool(getSettingName(_sender), getSettingCategory(_sender), newState); @@ -691,6 +660,59 @@ namespace MWGui mLightingMethodButton->setIndexSelected(mLightingMethodButton->findItemIndexWith(lightingMethodStr)); } + void SettingsWindow::updateWindowModeSettings() + { + size_t index = static_cast(Settings::Manager::getInt("window mode", "Video")); + + if (index > static_cast(Settings::WindowMode::Windowed)) + index = MyGUI::ITEM_NONE; + + mWindowModeList->setIndexSelected(index); + + if (index != static_cast(Settings::WindowMode::Windowed) && index != MyGUI::ITEM_NONE) + { + // check if this resolution is supported in fullscreen + if (mResolutionList->getIndexSelected() != MyGUI::ITEM_NONE) + { + std::string resStr = mResolutionList->getItemNameAt(mResolutionList->getIndexSelected()); + int resX, resY; + parseResolution (resX, resY, resStr); + Settings::Manager::setInt("resolution x", "Video", resX); + Settings::Manager::setInt("resolution y", "Video", resY); + } + + bool supported = false; + int fallbackX = 0, fallbackY = 0; + for (unsigned int i=0; igetItemCount(); ++i) + { + std::string resStr = mResolutionList->getItemNameAt(i); + int resX, resY; + parseResolution (resX, resY, resStr); + + if (i == 0) + { + fallbackX = resX; + fallbackY = resY; + } + + if (resX == Settings::Manager::getInt("resolution x", "Video") + && resY == Settings::Manager::getInt("resolution y", "Video")) + supported = true; + } + + if (!supported && mResolutionList->getItemCount()) + { + if (fallbackX != 0 && fallbackY != 0) + { + Settings::Manager::setInt("resolution x", "Video", fallbackX); + Settings::Manager::setInt("resolution y", "Video", fallbackY); + } + } + + mWindowBorderButton->setEnabled(false); + } + } + void SettingsWindow::layoutControlsBox() { const int h = 18; @@ -866,6 +888,7 @@ namespace MWGui highlightCurrentResolution(); updateControlsBox(); updateLightSettings(); + updateWindowModeSettings(); resetScrollbars(); renderScriptSettings(); resizeScriptSettings(); diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 1a888257a8..bfce6c30dd 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -18,6 +18,8 @@ namespace MWGui void updateLightSettings(); + void updateWindowModeSettings(); + void onResChange(int, int) override { center(); } protected: @@ -26,7 +28,7 @@ namespace MWGui // graphics MyGUI::ListBox* mResolutionList; - MyGUI::Button* mFullscreenButton; + MyGUI::ComboBox* mWindowModeList; MyGUI::Button* mWindowBorderButton; MyGUI::ComboBox* mTextureFilteringButton; MyGUI::Widget* mAnisotropyBox; @@ -72,6 +74,8 @@ namespace MWGui void onLightsResetButtonClicked(MyGUI::Widget* _sender); void onMaxLightsChanged(MyGUI::ComboBox* _sender, size_t pos); + void onWindowModeChanged(MyGUI::ComboBox* _sender, size_t pos); + void onRebindAction(MyGUI::Widget* _sender); void onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel); void onResetDefaultBindings(MyGUI::Widget* _sender); @@ -94,7 +98,7 @@ namespace MWGui void renderScriptSettings(); void computeMinimumWindowSize(); - + private: void resetScrollbars(); }; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index e3d61e7c08..80fb1e546b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1086,7 +1086,7 @@ namespace MWGui else if (setting.first == "Video" && ( setting.second == "resolution x" || setting.second == "resolution y" - || setting.second == "fullscreen" + || setting.second == "window mode" || setting.second == "window border")) changeRes = true; @@ -1101,7 +1101,7 @@ namespace MWGui { mVideoWrapper->setVideoMode(Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video"), - Settings::Manager::getBool("fullscreen", "Video"), + static_cast(Settings::Manager::getInt("window mode", "Video")), Settings::Manager::getBool("window border", "Video")); } } diff --git a/components/sdlutil/sdlvideowrapper.cpp b/components/sdlutil/sdlvideowrapper.cpp index b3ba98ee3c..7d62979e7f 100644 --- a/components/sdlutil/sdlvideowrapper.cpp +++ b/components/sdlutil/sdlvideowrapper.cpp @@ -1,6 +1,7 @@ #include "sdlvideowrapper.hpp" #include +#include #include @@ -68,21 +69,21 @@ namespace SDLUtil Log(Debug::Warning) << "Couldn't set gamma: " << SDL_GetError(); } - void VideoWrapper::setVideoMode(int width, int height, bool fullscreen, bool windowBorder) + void VideoWrapper::setVideoMode(int width, int height, Settings::WindowMode windowMode, bool windowBorder) { SDL_SetWindowFullscreen(mWindow, 0); if (SDL_GetWindowFlags(mWindow) & SDL_WINDOW_MAXIMIZED) SDL_RestoreWindow(mWindow); - if (fullscreen) + if (windowMode == Settings::WindowMode::Fullscreen || windowMode == Settings::WindowMode::WindowedFullscreen) { SDL_DisplayMode mode; SDL_GetWindowDisplayMode(mWindow, &mode); mode.w = width; mode.h = height; SDL_SetWindowDisplayMode(mWindow, &mode); - SDL_SetWindowFullscreen(mWindow, fullscreen); + SDL_SetWindowFullscreen(mWindow, windowMode == Settings::WindowMode::Fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP); } else { diff --git a/components/sdlutil/sdlvideowrapper.hpp b/components/sdlutil/sdlvideowrapper.hpp index 3866c3ec31..b9bcd66b5c 100644 --- a/components/sdlutil/sdlvideowrapper.hpp +++ b/components/sdlutil/sdlvideowrapper.hpp @@ -12,6 +12,11 @@ namespace osgViewer class Viewer; } +namespace Settings +{ + enum class WindowMode; +} + namespace SDLUtil { @@ -25,7 +30,7 @@ namespace SDLUtil void setGammaContrast(float gamma, float contrast); - void setVideoMode(int width, int height, bool fullscreen, bool windowBorder); + void setVideoMode(int width, int height, Settings::WindowMode windowMode, bool windowBorder); void centerWindow(); diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp index d5d9c2d9f6..693941df10 100644 --- a/components/settings/settings.hpp +++ b/components/settings/settings.hpp @@ -16,6 +16,13 @@ namespace Files namespace Settings { + enum class WindowMode + { + Fullscreen = 0, + WindowedFullscreen, + Windowed + }; + /// /// \brief Settings management (can change during runtime) /// diff --git a/docs/source/reference/modding/settings/video.rst b/docs/source/reference/modding/settings/video.rst index 040b9948f7..b05fbf0380 100644 --- a/docs/source/reference/modding/settings/video.rst +++ b/docs/source/reference/modding/settings/video.rst @@ -31,17 +31,24 @@ The window resolution can be selected from a menu of common screen sizes in the Video tab of the Video Panel of the Options menu, or in the Graphics tab of the OpenMW Launcher. The vertical resolution can also be set to a custom value in the Graphics tab of the OpenMW Launcher. -fullscreen ----------- +window mode +----------- -:Type: boolean -:Range: True/False -:Default: False +:Type: integer +:Range: 0, 1, 2 +:Default: 2 (Windowed) -This setting determines whether the entire screen is used for the specified resolution. +This setting determines the window mode. -This setting can be toggled in game using the Fullscreen button in the Video tab of the Video panel in the Options menu. -It can also be toggled with the Full Screen check box in the Graphics tab of the OpenMW Launcher. +0: Exclusive fullscreen + +1: Windowed fullscreen, borderless window that matches screen resolution + +2: Windowed + + +This setting can be toggled in game using the dropdown list in the Video tab of the Video panel in the Options menu. +It can also be toggled with the window mode dropdown in the Graphics tab of the OpenMW Launcher. screen ------ diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index d0e2edfbf6..a134d8ecb8 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -270,17 +270,17 @@ - - - - - - - - + + + + + + + + - + @@ -290,7 +290,7 @@ - + @@ -301,7 +301,7 @@ - + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index e320652f36..3a41f72d9b 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -611,8 +611,9 @@ hrtf = resolution x = 800 resolution y = 600 -# OpenMW takes complete control of the screen. -fullscreen = false +# Specify the window mode. +# 0 = Fullscreen, 1 = Windowed Fullscreen, 2 = Windowed +window mode = 0 # Determines which screen OpenMW is on. (>=0). screen = 0 diff --git a/files/ui/graphicspage.ui b/files/ui/graphicspage.ui index 508a955d7b..8cf26aa1e2 100644 --- a/files/ui/graphicspage.ui +++ b/files/ui/graphicspage.ui @@ -112,17 +112,39 @@ - + Window Border - - + + + + 0 + + + + Fullscreen + + + + + Windowed Fullscreen + + + + + Windowed + + + + + + - Full Screen + Window Mode: