Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add monitor override #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
};