mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-22 21:35:58 +01:00
Fullscreen animated, Added no_gaps_when_only
This commit is contained in:
parent
36fdcc89b3
commit
5d69be9a98
5 changed files with 68 additions and 101 deletions
|
@ -8,7 +8,6 @@ border_size=1
|
||||||
gaps_out=20
|
gaps_out=20
|
||||||
rounding=0
|
rounding=0
|
||||||
max_fps=60 # max fps for updates of config & animations
|
max_fps=60 # max fps for updates of config & animations
|
||||||
layout=0 # 0 - dwindle (default), 1 - master
|
|
||||||
focus_when_hover=1 # 0 - do not switch the focus when hover (only for tiling)
|
focus_when_hover=1 # 0 - do not switch the focus when hover (only for tiling)
|
||||||
main_mod=SUPER # For moving, resizing
|
main_mod=SUPER # For moving, resizing
|
||||||
intelligent_transients=1 # keeps transients always on top.
|
intelligent_transients=1 # keeps transients always on top.
|
||||||
|
@ -18,6 +17,12 @@ no_unmap_saving=1 # disables saving unmapped windows (seems to break sometimes)
|
||||||
# exec-once=/home/me/MyEpicShellScript # will exec the script only when the WM launches
|
# exec-once=/home/me/MyEpicShellScript # will exec the script only when the WM launches
|
||||||
# exec=/home/me/MyEpicShellScript # will exec the script every time the config is reloaded
|
# exec=/home/me/MyEpicShellScript # will exec the script every time the config is reloaded
|
||||||
|
|
||||||
|
# Layout
|
||||||
|
layout=0 # 0 - dwindle (default), 1 - master
|
||||||
|
layout {
|
||||||
|
no_gaps_when_only=0 # disables gaps and borders when only window on screen
|
||||||
|
}
|
||||||
|
|
||||||
# Bar config
|
# Bar config
|
||||||
Bar {
|
Bar {
|
||||||
height=20
|
height=20
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void ConfigManager::init() {
|
void ConfigManager::init() {
|
||||||
|
@ -21,6 +23,7 @@ void ConfigManager::init() {
|
||||||
configValues["focus_when_hover"].intValue = 1;
|
configValues["focus_when_hover"].intValue = 1;
|
||||||
|
|
||||||
configValues["layout"].intValue = LAYOUT_DWINDLE;
|
configValues["layout"].intValue = LAYOUT_DWINDLE;
|
||||||
|
configValues["layout:no_gaps_when_only"].intValue = 0;
|
||||||
|
|
||||||
configValues["max_fps"].intValue = 60;
|
configValues["max_fps"].intValue = 60;
|
||||||
|
|
||||||
|
@ -41,11 +44,11 @@ void ConfigManager::init() {
|
||||||
configValues["col.inactive_border"].intValue = 0x77222222;
|
configValues["col.inactive_border"].intValue = 0x77222222;
|
||||||
|
|
||||||
// animations
|
// animations
|
||||||
configValues["anim:speed"].floatValue = 1;
|
configValues["animations:speed"].floatValue = 1;
|
||||||
configValues["anim:enabled"].intValue = 0;
|
configValues["animations:enabled"].intValue = 0;
|
||||||
configValues["anim:cheap"].intValue = 1;
|
configValues["animations:cheap"].intValue = 1;
|
||||||
configValues["anim:borders"].intValue = 1;
|
configValues["animations:borders"].intValue = 1;
|
||||||
configValues["anim:workspaces"].intValue = 0;
|
configValues["animations:workspaces"].intValue = 0;
|
||||||
|
|
||||||
if (!g_pWindowManager->statusBar) {
|
if (!g_pWindowManager->statusBar) {
|
||||||
isFirstLaunch = true;
|
isFirstLaunch = true;
|
||||||
|
@ -221,44 +224,6 @@ void parseModule(const std::string& COMMANDC, const std::string& VALUE) {
|
||||||
module->value = COMMAND;
|
module->value = COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseBarLine(const std::string& line) {
|
|
||||||
|
|
||||||
// And parse
|
|
||||||
// check if command
|
|
||||||
|
|
||||||
const auto EQUALSPLACE = line.find_first_of('=');
|
|
||||||
|
|
||||||
if (EQUALSPLACE == std::string::npos)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
const auto COMMAND = line.substr(0, EQUALSPLACE);
|
|
||||||
const auto VALUE = line.substr(EQUALSPLACE + 1);
|
|
||||||
|
|
||||||
// Now check commands
|
|
||||||
if (COMMAND == "module") {
|
|
||||||
if (g_pWindowManager->statusBar)
|
|
||||||
parseModule(COMMAND, VALUE);
|
|
||||||
} else {
|
|
||||||
// We need to parse those to let the main thread know e.g. the bar height
|
|
||||||
configSetValueSafe("bar:" + COMMAND, VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseAnimLine(const std::string& line) {
|
|
||||||
// And parse
|
|
||||||
// check if command
|
|
||||||
const auto EQUALSPLACE = line.find_first_of('=');
|
|
||||||
|
|
||||||
if (EQUALSPLACE == std::string::npos)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto COMMAND = line.substr(0, EQUALSPLACE);
|
|
||||||
const auto VALUE = line.substr(EQUALSPLACE + 1);
|
|
||||||
|
|
||||||
configSetValueSafe("anim:" + COMMAND, VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleWindowRule(const std::string& command, const std::string& value) {
|
void handleWindowRule(const std::string& command, const std::string& value) {
|
||||||
const auto RULE = value.substr(0, value.find_first_of(","));
|
const auto RULE = value.substr(0, value.find_first_of(","));
|
||||||
const auto VALUE = value.substr(value.find_first_of(",") + 1);
|
const auto VALUE = value.substr(value.find_first_of(",") + 1);
|
||||||
|
@ -298,13 +263,10 @@ void parseLine(std::string& line) {
|
||||||
line = line.substr(1);
|
line = line.substr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.find("Bar {") != std::string::npos) {
|
if (line.find(" {") != std::string::npos) {
|
||||||
ConfigManager::currentCategory = "bar";
|
auto cat = line.substr(0, line.find(" {"));
|
||||||
return;
|
transform(cat.begin(), cat.end(), cat.begin(), ::tolower);
|
||||||
}
|
ConfigManager::currentCategory = cat;
|
||||||
|
|
||||||
if (line.find("Animations {") != std::string::npos) {
|
|
||||||
ConfigManager::currentCategory = "anim";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,16 +275,6 @@ void parseLine(std::string& line) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigManager::currentCategory == "bar") {
|
|
||||||
parseBarLine(line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConfigManager::currentCategory == "anim") {
|
|
||||||
parseAnimLine(line);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// And parse
|
// And parse
|
||||||
// check if command
|
// check if command
|
||||||
const auto EQUALSPLACE = line.find_first_of('=');
|
const auto EQUALSPLACE = line.find_first_of('=');
|
||||||
|
@ -351,7 +303,14 @@ void parseLine(std::string& line) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
configSetValueSafe(COMMAND, VALUE);
|
if (COMMAND == "module" && ConfigManager::currentCategory == "bar") {
|
||||||
|
if (g_pWindowManager->statusBar)
|
||||||
|
parseModule(COMMAND, VALUE);gi
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
configSetValueSafe(ConfigManager::currentCategory + (ConfigManager::currentCategory == "" ? "" : ":") + COMMAND, VALUE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigManager::loadConfigLoadVars() {
|
void ConfigManager::loadConfigLoadVars() {
|
||||||
|
|
|
@ -7,7 +7,7 @@ void AnimationUtil::move() {
|
||||||
const double DELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - lastFrame).count();
|
const double DELTA = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - lastFrame).count();
|
||||||
lastFrame = std::chrono::high_resolution_clock::now();
|
lastFrame = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
const double ANIMATIONSPEED = std::max(1.f / ((double)ConfigManager::getFloat("anim:speed") * DELTA) * 462.f, (double)1.f);
|
const double ANIMATIONSPEED = std::max(1.f / ((double)ConfigManager::getFloat("animations:speed") * DELTA) * 462.f, (double)1.f);
|
||||||
|
|
||||||
bool updateRequired = false;
|
bool updateRequired = false;
|
||||||
// Now we are (or should be, lul) thread-safe.
|
// Now we are (or should be, lul) thread-safe.
|
||||||
|
@ -24,7 +24,7 @@ void AnimationUtil::move() {
|
||||||
// interp border color if enabled
|
// interp border color if enabled
|
||||||
const auto PREVCOLOR = window.getRealBorderColor().getAsUint32();
|
const auto PREVCOLOR = window.getRealBorderColor().getAsUint32();
|
||||||
|
|
||||||
if (ConfigManager::getInt("anim:borders") == 1) {
|
if (ConfigManager::getInt("animations:borders") == 1) {
|
||||||
window.setRealBorderColor(parabolicColor(window.getRealBorderColor(), window.getEffectiveBorderColor(), ANIMATIONSPEED));
|
window.setRealBorderColor(parabolicColor(window.getRealBorderColor(), window.getEffectiveBorderColor(), ANIMATIONSPEED));
|
||||||
} else {
|
} else {
|
||||||
window.setRealBorderColor(window.getEffectiveBorderColor());
|
window.setRealBorderColor(window.getEffectiveBorderColor());
|
||||||
|
@ -37,7 +37,7 @@ void AnimationUtil::move() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigManager::getInt("anim:enabled") == 0 || window.getIsFloating() || window.getFullscreen()) {
|
if (ConfigManager::getInt("animations:enabled") == 0 || window.getIsFloating()) {
|
||||||
// Disabled animations. instant warps.
|
// Disabled animations. instant warps.
|
||||||
|
|
||||||
if (VECTORDELTANONZERO(window.getRealPosition(), window.getEffectivePosition())
|
if (VECTORDELTANONZERO(window.getRealPosition(), window.getEffectivePosition())
|
||||||
|
@ -96,7 +96,7 @@ void AnimationUtil::move() {
|
||||||
updateRequired = true;
|
updateRequired = true;
|
||||||
g_pWindowManager->setAllWorkspaceWindowsDirtyByID(work.getID());
|
g_pWindowManager->setAllWorkspaceWindowsDirtyByID(work.getID());
|
||||||
|
|
||||||
if (ConfigManager::getInt("anim:workspaces") == 0)
|
if (ConfigManager::getInt("animations:workspaces") == 0)
|
||||||
work.setAnimationInProgress(false);
|
work.setAnimationInProgress(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -427,32 +427,30 @@ void CWindowManager::refreshDirtyWindows() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fullscreen window. No border, all screen.
|
// Fullscreen window. No border, all screen.
|
||||||
if (window.getFullscreen()) {
|
// also do this when "layout:no_gaps_when_only" is set, but with a twist to enable the bar
|
||||||
|
if (window.getFullscreen() || (ConfigManager::getInt("layout:no_gaps_when_only") && getWindowsOnWorkspace(window.getWorkspaceID()) == 1)) {
|
||||||
Values[0] = 0;
|
Values[0] = 0;
|
||||||
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values);
|
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values);
|
||||||
|
|
||||||
const auto MONITOR = getMonitorFromWindow(&window);
|
const auto MONITOR = getMonitorFromWindow(&window);
|
||||||
|
|
||||||
Values[0] = (int)MONITOR->vecSize.x;
|
Values[0] = (int)MONITOR->vecSize.x;
|
||||||
Values[1] = (int)MONITOR->vecSize.y;
|
Values[1] = window.getFullscreen() ? (int) MONITOR->vecSize.y : MONITOR->vecSize.y - getBarHeightForMonitor(window.getMonitor());
|
||||||
if (VECTORDELTANONZERO(window.getLastUpdateSize(), Vector2D(Values[0], Values[1]))) {
|
window.setEffectiveSize(Vector2D(Values[0], Values[1]));
|
||||||
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values);
|
|
||||||
window.setLastUpdateSize(Vector2D(Values[0], Values[1]));
|
|
||||||
}
|
|
||||||
|
|
||||||
Values[0] = (int)MONITOR->vecPosition.x;
|
Values[0] = (int)MONITOR->vecPosition.x;
|
||||||
Values[1] = (int)MONITOR->vecPosition.y;
|
Values[1] = window.getFullscreen() ? (int)MONITOR->vecPosition.y : MONITOR->vecPosition.y + getBarHeightForMonitor(window.getMonitor());
|
||||||
|
window.setEffectivePosition(Vector2D(Values[0], Values[1]));
|
||||||
|
|
||||||
|
Values[0] = (int)window.getRealPosition().x;
|
||||||
|
Values[1] = (int)window.getRealPosition().y;
|
||||||
if (VECTORDELTANONZERO(window.getLastUpdatePosition(), Vector2D(Values[0], Values[1]))) {
|
if (VECTORDELTANONZERO(window.getLastUpdatePosition(), Vector2D(Values[0], Values[1]))) {
|
||||||
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values);
|
const auto COOKIE = xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values);
|
||||||
window.setLastUpdatePosition(Vector2D(Values[0], Values[1]));
|
window.setLastUpdatePosition(Vector2D(Values[0], Values[1]));
|
||||||
|
|
||||||
|
Events::ignoredEvents.push_back(COOKIE.sequence);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Apply rounded corners, does all the checks inside
|
|
||||||
applyShapeToWindow(&window);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the position because the border makes the window jump
|
// Update the position because the border makes the window jump
|
||||||
// I have added the bordersize vec2d before in the setEffectiveSizePosUsingConfig function.
|
// I have added the bordersize vec2d before in the setEffectiveSizePosUsingConfig function.
|
||||||
Values[0] = (int)window.getRealPosition().x - ConfigManager::getInt("border_size");
|
Values[0] = (int)window.getRealPosition().x - ConfigManager::getInt("border_size");
|
||||||
|
@ -467,12 +465,12 @@ void CWindowManager::refreshDirtyWindows() {
|
||||||
Values[0] = (int)ConfigManager::getInt("border_size");
|
Values[0] = (int)ConfigManager::getInt("border_size");
|
||||||
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values);
|
xcb_configure_window(DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_BORDER_WIDTH, Values);
|
||||||
|
|
||||||
// do border
|
|
||||||
Values[0] = window.getRealBorderColor().getAsUint32();
|
Values[0] = window.getRealBorderColor().getAsUint32();
|
||||||
xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values);
|
xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values);
|
||||||
|
}
|
||||||
|
|
||||||
// If it isn't animated or we have non-cheap animations, update the real size
|
// If it isn't animated or we have non-cheap animations, update the real size
|
||||||
if (!window.getIsAnimated() || ConfigManager::getInt("anim:cheap") == 0) {
|
if (!window.getIsAnimated() || ConfigManager::getInt("animations:cheap") == 0) {
|
||||||
Values[0] = (int)window.getRealSize().x;
|
Values[0] = (int)window.getRealSize().x;
|
||||||
Values[1] = (int)window.getRealSize().y;
|
Values[1] = (int)window.getRealSize().y;
|
||||||
if (VECTORDELTANONZERO(window.getLastUpdateSize(), Vector2D(Values[0], Values[1]))) {
|
if (VECTORDELTANONZERO(window.getLastUpdateSize(), Vector2D(Values[0], Values[1]))) {
|
||||||
|
@ -484,7 +482,7 @@ void CWindowManager::refreshDirtyWindows() {
|
||||||
window.setFirstAnimFrame(true);
|
window.setFirstAnimFrame(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfigManager::getInt("anim:cheap") == 1 && window.getFirstAnimFrame() && window.getIsAnimated()) {
|
if (ConfigManager::getInt("animations:cheap") == 1 && window.getFirstAnimFrame() && window.getIsAnimated()) {
|
||||||
// first frame, fix the size if smaller
|
// first frame, fix the size if smaller
|
||||||
window.setFirstAnimFrame(false);
|
window.setFirstAnimFrame(false);
|
||||||
if (window.getRealSize().x < window.getEffectiveSize().x || window.getRealSize().y < window.getEffectiveSize().y) {
|
if (window.getRealSize().x < window.getEffectiveSize().x || window.getRealSize().y < window.getEffectiveSize().y) {
|
||||||
|
@ -753,7 +751,7 @@ void CWindowManager::applyShapeToWindow(CWindow* pWindow) {
|
||||||
|
|
||||||
const uint16_t W = pWindow->getFullscreen() ? MONITOR->vecSize.x : pWindow->getRealSize().x;
|
const uint16_t W = pWindow->getFullscreen() ? MONITOR->vecSize.x : pWindow->getRealSize().x;
|
||||||
const uint16_t H = pWindow->getFullscreen() ? MONITOR->vecSize.y : pWindow->getRealSize().y;
|
const uint16_t H = pWindow->getFullscreen() ? MONITOR->vecSize.y : pWindow->getRealSize().y;
|
||||||
const uint16_t BORDER = pWindow->getFullscreen() ? 0 : ConfigManager::getInt("border_size");
|
const uint16_t BORDER = pWindow->getFullscreen() || (ConfigManager::getInt("layout:no_gaps_when_only") && getWindowsOnWorkspace(pWindow->getWorkspaceID()) == 1) ? 0 : ConfigManager::getInt("border_size");
|
||||||
const uint16_t TOTALW = W + 2 * BORDER;
|
const uint16_t TOTALW = W + 2 * BORDER;
|
||||||
const uint16_t TOTALH = H + 2 * BORDER;
|
const uint16_t TOTALH = H + 2 * BORDER;
|
||||||
|
|
||||||
|
@ -862,7 +860,7 @@ void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto MONITOR = getMonitorFromWindow(pWindow);
|
const auto MONITOR = getMonitorFromWindow(pWindow);
|
||||||
const auto BARHEIGHT = (MONITOR->ID == ConfigManager::getInt("bar:monitor") ? (ConfigManager::getInt("bar:enabled") == 1 ? ConfigManager::getInt("bar:height") : ConfigManager::parseError == "" ? 0 : ConfigManager::getInt("bar:height")) : 0);
|
const auto BARHEIGHT = getBarHeightForMonitor(pWindow->getMonitor());
|
||||||
|
|
||||||
// set some flags.
|
// set some flags.
|
||||||
const bool DISPLAYLEFT = STICKS(pWindow->getPosition().x, MONITOR->vecPosition.x);
|
const bool DISPLAYLEFT = STICKS(pWindow->getPosition().x, MONITOR->vecPosition.x);
|
||||||
|
@ -2315,14 +2313,14 @@ void CWindowManager::startWipeAnimOnWorkspace(const int& oldwork, const int& new
|
||||||
|
|
||||||
for (auto& work : workspaces) {
|
for (auto& work : workspaces) {
|
||||||
if (work.getID() == oldwork) {
|
if (work.getID() == oldwork) {
|
||||||
if (ConfigManager::getInt("anim:workspaces") == 1)
|
if (ConfigManager::getInt("animations:workspaces") == 1)
|
||||||
work.setCurrentOffset(Vector2D(0,0));
|
work.setCurrentOffset(Vector2D(0,0));
|
||||||
else
|
else
|
||||||
work.setCurrentOffset(Vector2D(150000, 150000));
|
work.setCurrentOffset(Vector2D(150000, 150000));
|
||||||
work.setGoalOffset(Vector2D(PMONITOR->vecSize.x, 0));
|
work.setGoalOffset(Vector2D(PMONITOR->vecSize.x, 0));
|
||||||
work.setAnimationInProgress(true);
|
work.setAnimationInProgress(true);
|
||||||
} else if (work.getID() == newwork) {
|
} else if (work.getID() == newwork) {
|
||||||
if (ConfigManager::getInt("anim:workspaces") == 1)
|
if (ConfigManager::getInt("animations:workspaces") == 1)
|
||||||
work.setCurrentOffset(Vector2D(-PMONITOR->vecSize.x, 0));
|
work.setCurrentOffset(Vector2D(-PMONITOR->vecSize.x, 0));
|
||||||
else
|
else
|
||||||
work.setCurrentOffset(Vector2D(0, 0));
|
work.setCurrentOffset(Vector2D(0, 0));
|
||||||
|
@ -2363,3 +2361,7 @@ bool CWindowManager::shouldBeManaged(const int& window) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CWindowManager::getBarHeightForMonitor(const int& mon) {
|
||||||
|
return (mon == ConfigManager::getInt("bar:monitor") ? (ConfigManager::getInt("bar:enabled") == 1 ? ConfigManager::getInt("bar:height") : ConfigManager::parseError == "" ? 0 : ConfigManager::getInt("bar:height")) : 0);
|
||||||
|
}
|
|
@ -166,6 +166,7 @@ private:
|
||||||
void focusOnWorkspace(const int&);
|
void focusOnWorkspace(const int&);
|
||||||
void dispatchQueuedWarp();
|
void dispatchQueuedWarp();
|
||||||
CWindow* getMasterForWorkspace(const int&);
|
CWindow* getMasterForWorkspace(const int&);
|
||||||
|
int getBarHeightForMonitor(const int&);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CWindowManager> g_pWindowManager = std::make_unique<CWindowManager>();
|
inline std::unique_ptr<CWindowManager> g_pWindowManager = std::make_unique<CWindowManager>();
|
||||||
|
|
Loading…
Reference in a new issue