diff --git a/res/layouts/pages/settings_display.xml.lua b/res/layouts/pages/settings_display.xml.lua
index f8b24d0b..6934cef6 100644
--- a/res/layouts/pages/settings_display.xml.lua
+++ b/res/layouts/pages/settings_display.xml.lua
@@ -53,10 +53,19 @@ function create_checkbox(id, name, tooltip)
))
end
+
function on_open()
create_setting("camera.fov", "FOV", 1, "°")
create_setting("display.framerate", "Framerate", 1, "", "", true)
- create_checkbox("display.fullscreen", "Fullscreen")
+
+ document.root:add(string.format(
+ "", core.get_setting("display.window-mode"))
+ )
+
create_checkbox("camera.shaking", "Camera Shaking")
create_checkbox("camera.inertia", "Camera Inertia")
create_checkbox("camera.fov-effects", "Camera FOV Effects")
diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt
index 1c650560..03ee8322 100644
--- a/res/texts/ru_RU.txt
+++ b/res/texts/ru_RU.txt
@@ -103,6 +103,8 @@ settings.Limit Background FPS=Ограничить фоновую частоту
settings.Advanced render=Продвинутый рендер
settings.Shadows quality=Качество теней
settings.Conflict=Найдены возможные конфликты
+settings.Windowed=Оконный
+settings.Borderless=Безрамочный
# Управление
chunks.reload=Перезагрузить Чанки
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(