Skip to content

Commit

Permalink
Add monitor override
Browse files Browse the repository at this point in the history
  • Loading branch information
triglav committed Jul 2, 2018
1 parent 2a500d2 commit 76d12a3
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 34 deletions.
6 changes: 6 additions & 0 deletions DATA/DSfix.ini
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ hudBottomRightOpacity 0.5f
# 1 = enable
borderlessFullscreen 0

# Monitor override
# -1 = no override (the main/nearest screen)
# N = use monitor N (starts with 0, -1 is used if it is not found)
# This setting is for multiple monitors, everyone else should leave it at -1.
monitorOverride -1

# disable cursor at startup
# 0 = no change
# 1 = off at start
Expand Down
2 changes: 2 additions & 0 deletions Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ void Settings::report() {

void Settings::init() {
if(!inited) {
auto const monitor_id = getMonitorOverride();
WindowManager::get().overrideMonitor(monitor_id);
if(getDisableCursor()) WindowManager::get().toggleCursorVisibility();
if(getCaptureCursor()) WindowManager::get().toggleCursorCapture();
if(getBorderlessFullscreen()) WindowManager::get().toggleBorderlessFullscreen();
Expand Down
1 change: 1 addition & 0 deletions Settings.def
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ SETTING(float, HudBottomRightOpacity, "hudBottomRightOpacity", 1.0f)

// Screen Options
SETTING(bool, BorderlessFullscreen, "borderlessFullscreen", false);
SETTING(int, MonitorOverride, "monitorOverride", -1);
SETTING(bool, ForceFullscreen, "forceFullscreen", false);
SETTING(bool, ForceWindowed, "forceWindowed", false);
SETTING(unsigned, PresentWidth, "presentWidth", 0);
Expand Down
99 changes: 65 additions & 34 deletions WindowManager.cpp
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
#include "WindowManager.h"
#include <utility>

WindowManager WindowManager::instance;

void WindowManager::applyCursorCapture() {
if(captureCursor) {
RECT clientrect;
HWND hwnd = ::GetActiveWindow();
::GetClientRect(hwnd, &clientrect);
void WindowManager::applyCursorCapture() {
if(captureCursor) {
RECT clientrect;
HWND hwnd = ::GetActiveWindow();
::GetClientRect(hwnd, &clientrect);
::ClientToScreen(hwnd, (LPPOINT)&clientrect.left);
::ClientToScreen(hwnd, (LPPOINT)&clientrect.right);
::ClipCursor(&clientrect);
} else {
::ClipCursor(NULL);
::ClientToScreen(hwnd, (LPPOINT)&clientrect.right);
::ClipCursor(&clientrect);
} else {
::ClipCursor(NULL);
}
}

void WindowManager::toggleCursorCapture() {
captureCursor = !captureCursor;
}

void WindowManager::toggleCursorVisibility() {
cursorVisible = !cursorVisible;
void WindowManager::toggleCursorVisibility() {
cursorVisible = !cursorVisible;
::ShowCursor(cursorVisible);
}

void WindowManager::toggleBorderlessFullscreen() {
borderlessFullscreen = !borderlessFullscreen;
HWND hwnd = ::GetActiveWindow();
if(borderlessFullscreen) {
// store previous rect
::GetClientRect(hwnd, &prevWindowRect);
// set styles
void WindowManager::toggleBorderlessFullscreen() {
borderlessFullscreen = !borderlessFullscreen;
HWND hwnd = ::GetActiveWindow();
if(borderlessFullscreen) {
// store previous rect
::GetClientRect(hwnd, &prevWindowRect);
// set styles
LONG lStyle = ::GetWindowLong(hwnd, GWL_STYLE);
prevStyle = lStyle;
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
Expand All @@ -40,13 +41,9 @@ void WindowManager::toggleBorderlessFullscreen() {
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
::SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);
// adjust size & position
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
int monitorWidth = info.rcMonitor.right - info.rcMonitor.left;
int monitorHeight = info.rcMonitor.bottom - info.rcMonitor.top;
::SetWindowPos(hwnd, NULL, info.rcMonitor.left, info.rcMonitor.top, monitorWidth, monitorHeight, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER);
int monitorWidth = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
int monitorHeight = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;
::SetWindowPos(hwnd, NULL, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorWidth, monitorHeight, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOOWNERZORDER);
} else {
// restore previous window
::SetWindowLong(hwnd, GWL_STYLE, prevStyle);
Expand All @@ -63,23 +60,57 @@ void WindowManager::resize(unsigned clientW, unsigned clientH) {
// Store current window rect
::GetClientRect(hwnd, &prevWindowRect);
// Get monitor size
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
int monitorWidth = info.rcMonitor.right - info.rcMonitor.left;
int monitorHeight = info.rcMonitor.bottom - info.rcMonitor.top;
int monitorWidth = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
int monitorHeight = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;

// How much do we overlap or are smaller than the actual screen size
int widthDiff = monitorWidth - (clientW ? clientW : prevWindowRect.right);
int heightDiff = monitorHeight - (clientH ? clientH : prevWindowRect.bottom);

RECT desiredRect;
desiredRect.left = widthDiff / 2;
desiredRect.top = heightDiff / 2;
desiredRect.left = monitorInfo.rcMonitor.left + widthDiff / 2;
desiredRect.top = monitorInfo.rcMonitor.top + heightDiff / 2;
desiredRect.right = monitorWidth - (widthDiff / 2);
desiredRect.bottom = monitorHeight - (heightDiff / 2);
desiredRect.bottom = monitorHeight - (heightDiff / 2);
LONG lStyle = ::GetWindowLong(hwnd, GWL_STYLE);
::AdjustWindowRect(&desiredRect, lStyle, false);
::SetWindowPos(hwnd, NULL, desiredRect.left, desiredRect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
}

BOOL CALLBACK monitorEnumProc(
HMONITOR hMonitor,
HDC hdcMonitor,
LPRECT lprcMonitor,
LPARAM dwData
) {
static int i = 0;

const auto data = reinterpret_cast<std::pair<MONITORINFO*, int>*>(dwData);
if (i++ == data->second)
{
data->first->cbSize = sizeof(MONITORINFO);
GetMonitorInfo(hMonitor, data->first);
return FALSE;
}
return TRUE;
}

void WindowManager::overrideMonitor(int monitor_id) {
// If there is a monitor given, tries to find it
if (monitor_id != -1)
{
monitorInfo.cbSize = 0;
std::pair<MONITORINFO*, int> data{ &monitorInfo, monitor_id };
EnumDisplayMonitors(nullptr, nullptr, monitorEnumProc, reinterpret_cast<LPARAM>(&data));
if (monitorInfo.cbSize != 0)
{
return;
}
}

// If there is no override, uses the 'nearest' monitor to the current window
HWND hwnd = ::GetActiveWindow();
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
monitorInfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &monitorInfo);
}
2 changes: 2 additions & 0 deletions WindowManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class WindowManager {
bool borderlessFullscreen;
RECT prevWindowRect;
long prevStyle, prevExStyle;
MONITORINFO monitorInfo;

public:
static WindowManager& get() {
Expand All @@ -22,4 +23,5 @@ class WindowManager {
void toggleCursorVisibility();
void toggleBorderlessFullscreen();
void resize(unsigned clientW, unsigned clientH);
void overrideMonitor(int monitor_id);
};

0 comments on commit 76d12a3

Please sign in to comment.