diff --git a/res/layouts/pages/settings_display.xml.lua b/res/layouts/pages/settings_display.xml.lua index f8b24d0b..5dd88a88 100644 --- a/res/layouts/pages/settings_display.xml.lua +++ b/res/layouts/pages/settings_display.xml.lua @@ -53,10 +53,18 @@ function create_checkbox(id, name, tooltip) )) end +function create_selectbox(id, name, tooltip) + tooltip = tooltip or '' + document.root:add(string.format( + "%s", + id, core.str_setting(id), gui.str(tooltip, "settings"), gui.str(name, "settings") + )) +end + function on_open() create_setting("camera.fov", "FOV", 1, "°") create_setting("display.framerate", "Framerate", 1, "", "", true) - create_checkbox("display.fullscreen", "Fullscreen") + --create_checkbox("display.fullscreen", "Fullscreen") create_checkbox("camera.shaking", "Camera Shaking") create_checkbox("camera.inertia", "Camera Inertia") create_checkbox("camera.fov-effects", "Camera FOV Effects") diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 212765f3..d2a4eb20 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -135,10 +135,11 @@ void Engine::initializeClient() { if (ENGINE_DEBUG_BUILD) { menus::create_version_label(*gui); } - keepAlive(settings.display.fullscreen.observe( - [this](bool value) { - if (value != this->window->isFullscreen()) { - this->window->toggleFullscreen(); + keepAlive(settings.display.windowMode.observe( + [this](int value) { + WindowMode mode = static_cast(value); + if (mode != this->window->getMode()) { + this->window->setMode(mode); } }, true @@ -237,7 +238,11 @@ void Engine::updateHotkeys() { gui->toggleDebug(); } if (input->jpressed(Keycode::F11)) { - settings.display.fullscreen.toggle(); + if (settings.display.windowMode.get() != static_cast(WindowMode::FULLSCREEN)) { + settings.display.windowMode.set(static_cast(WindowMode::FULLSCREEN)); + } else { + settings.display.windowMode.set(static_cast(WindowMode::WINDOWED)); + } } } diff --git a/src/io/settings_io.cpp b/src/io/settings_io.cpp index ea9a7bf5..5e1c8327 100644 --- a/src/io/settings_io.cpp +++ b/src/io/settings_io.cpp @@ -49,8 +49,8 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) { builder.add("height", &settings.display.height); builder.add("samples", &settings.display.samples); builder.add("framerate", &settings.display.framerate); - builder.add("fullscreen", &settings.display.fullscreen); builder.add("limit-fps-iconified", &settings.display.limitFpsIconified); + builder.add("window-mode", &settings.display.windowMode); builder.section("camera"); builder.add("sensitivity", &settings.camera.sensitivity); diff --git a/src/settings.hpp b/src/settings.hpp index 52827d1c..f97fb513 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -19,8 +19,8 @@ struct AudioSettings { }; struct DisplaySettings { - /// @brief Is window in full screen mode - FlagSetting fullscreen {false}; + /// @brief Window mode (windowed/fullscreen/borderless) + IntegerSetting windowMode {0, 0, 2}; /// @brief Window width (pixels) IntegerSetting width {1280}; /// @brief Window height (pixels) diff --git a/src/window/Window.hpp b/src/window/Window.hpp index 8800be8c..135e4f7d 100644 --- a/src/window/Window.hpp +++ b/src/window/Window.hpp @@ -10,6 +10,12 @@ class ImageData; class Input; struct DisplaySettings; +enum class WindowMode { + WINDOWED, + FULLSCREEN, + BORDERLESS +}; + class Window { public: Window(glm::ivec2 size) : size(std::move(size)) {} @@ -25,8 +31,8 @@ public: virtual void setShouldClose(bool flag) = 0; virtual void setCursor(CursorShape shape) = 0; - virtual void toggleFullscreen() = 0; - virtual bool isFullscreen() const = 0; + virtual void setMode(WindowMode mode) = 0; + virtual WindowMode getMode() const = 0; virtual void setIcon(const ImageData* image) = 0; @@ -51,6 +57,7 @@ public: > initialize(DisplaySettings* settings, std::string title); protected: glm::ivec2 size; + WindowMode mode = WindowMode::WINDOWED; }; namespace display { diff --git a/src/window/detail/GLFWWindow.cpp b/src/window/detail/GLFWWindow.cpp index accd969f..7685be7c 100644 --- a/src/window/detail/GLFWWindow.cpp +++ b/src/window/detail/GLFWWindow.cpp @@ -406,21 +406,28 @@ public: glfwSetCursor(window, standard_cursors[static_cast(shape)]); } - void toggleFullscreen() override { - fullscreen = !fullscreen; - + void setMode(WindowMode mode) override { + Window::mode = mode; GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* mode = glfwGetVideoMode(monitor); + const GLFWvidmode* glfwMode = glfwGetVideoMode(monitor); if (input.isCursorLocked()){ input.toggleCursor(); } - - if (fullscreen) { + + if (mode == WindowMode::FULLSCREEN) { + const int width = glfwMode->width; + const int height = glfwMode->height; + const int refreshRate = glfwMode->refreshRate; glfwGetWindowPos(window, &posX, &posY); - glfwSetWindowMonitor( - window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate - ); + glfwSetWindowMonitor(window, monitor, 0, 0, width, height, refreshRate); + } + else if(mode == WindowMode::BORDERLESS) { + glfwGetWindowPos(window, &posX, &posY); + glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_FALSE); + glfwSetWindowAttrib(window, GLFW_RESIZABLE, GLFW_FALSE); + glfwSetWindowSize(window, glfwMode->width, glfwMode->height); + glfwSetWindowPos(window, 0, 0); } else { glfwSetWindowMonitor( window, @@ -431,6 +438,8 @@ public: settings->height.get(), GLFW_DONT_CARE ); + glfwSetWindowAttrib(window, GLFW_DECORATED, GLFW_TRUE); + glfwSetWindowAttrib(window, GLFW_RESIZABLE, GLFW_TRUE); window_size_callback(window, settings->width.get(), settings->height.get()); } @@ -439,8 +448,8 @@ public: input.setCursorPosition(xPos, yPos); } - bool isFullscreen() const override { - return fullscreen; + WindowMode getMode() const override { + return mode; } void setIcon(const ImageData* image) override { @@ -459,7 +468,7 @@ public: glViewport(0, 0, width, height); size = {width, height}; - if (!isFullscreen() && !isMaximized()) { + if (mode == WindowMode::WINDOWED && !isMaximized()) { settings->width.set(width); settings->height.set(height); } @@ -542,7 +551,6 @@ public: private: GLFWwindow* window; CursorShape cursor = CursorShape::ARROW; - bool fullscreen = false; int framerate = -1; std::stack scissorStack; glm::vec4 scissorArea; @@ -600,7 +608,7 @@ static void cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) { static void iconify_callback(GLFWwindow* window, int iconified) { auto handler = static_cast(glfwGetWindowUserPointer(window)); - if (handler->isFullscreen() && iconified == 0) { + if (handler->getMode() == WindowMode::FULLSCREEN && iconified == 0) { GLFWmonitor* monitor = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(monitor); glfwSetWindowMonitor(