Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"Bash(\"build/tests/Release/display-lock-unittests.exe\")",
"Bash(\"display-lock-unittests.exe\")",
"Bash(\"./display-lock-unittests.exe\")",
"Bash(xxd:*)"
"Bash(xxd:*)",
"Bash(\"C:\\\\Users\\\\japos\\\\git\\\\Display-Lock\\\\build\\\\tests\\\\Debug\\\\display-lock-unittests.exe\")"
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line adds a developer-specific absolute path containing a username. The .local.json suffix suggests this file should contain local developer settings that shouldn't be committed to version control. Consider adding this file to .gitignore or removing this developer-specific path from the committed version.

Suggested change
"Bash(xxd:*)",
"Bash(\"C:\\\\Users\\\\japos\\\\git\\\\Display-Lock\\\\build\\\\tests\\\\Debug\\\\display-lock-unittests.exe\")"
"Bash(xxd:*)"

Copilot uses AI. Check for mistakes.
]
}
}
47 changes: 26 additions & 21 deletions src/components/win.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct PREVIOUSRECT
int x;
int y;
LONG_PTR previousStyle;
LONG_PTR previousExStyle;
LONG_PTR currentStyle;
};

Expand Down Expand Up @@ -103,13 +104,23 @@ inline BOOL checkResizeStyle(HWND activeWindow)
return (GetWindowLongPtr(activeWindow, GWL_STYLE) & WS_SIZEBOX);
}

// toggles borderlessWindow
inline void toggleBorderlessWindow(HWND activeWindow)
// removes border styles to make window borderless
inline void removeBorderStyles(HWND activeWindow)
{
// XOR WS_OVERLAPPED, WS_THICKFRAME, WS_SYSMENU, WS_CAPTION
SetWindowLongPtr(activeWindow, GWL_STYLE, GetWindowLongPtr(activeWindow, GWL_STYLE) ^ WS_OVERLAPPED ^ WS_THICKFRAME ^ WS_SYSMENU ^ WS_CAPTION);
// XOR WS_EX_WINDOWEDGE
SetWindowLongPtr(activeWindow, GWL_EXSTYLE, GetWindowLongPtr(activeWindow, GWL_EXSTYLE) ^ WS_EX_WINDOWEDGE);
const LONG_PTR mask = WS_OVERLAPPED | WS_THICKFRAME | WS_SYSMENU | WS_CAPTION;
const LONG_PTR exMask = WS_EX_WINDOWEDGE;

SetWindowLongPtr(activeWindow, GWL_STYLE, GetWindowLongPtr(activeWindow, GWL_STYLE) & ~mask);
SetWindowLongPtr(activeWindow, GWL_EXSTYLE, GetWindowLongPtr(activeWindow, GWL_EXSTYLE) & ~exMask);
SetWindowPos(activeWindow, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}

// restores original border styles
inline void restoreBorderStyles(HWND activeWindow, LONG_PTR originalStyle, LONG_PTR originalExStyle)
{
SetWindowLongPtr(activeWindow, GWL_STYLE, originalStyle);
SetWindowLongPtr(activeWindow, GWL_EXSTYLE, originalExStyle);
SetWindowPos(activeWindow, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}

// resizes borderless window
Expand All @@ -125,7 +136,7 @@ void resizeBorderless(WINDOW activeWindow, PREVIOUSRECT *prev)
prev->x = activeWindow.size.left;
prev->y = activeWindow.size.top;

SetWindowPos(activeWindow.hWnd, NULL, prev->x, prev->y, prev->width, prev->height, 0);
SetWindowPos(activeWindow.hWnd, NULL, prev->x, prev->y, prev->width, prev->height, SWP_FRAMECHANGED);
}

// enable fullscreen
Expand All @@ -140,13 +151,13 @@ void enableFullScreen(WINDOW activeWindow, PREVIOUSRECT *prev)
prev->x = activeWindow.size.left;
prev->y = activeWindow.size.top;

SetWindowPos(activeWindow.hWnd, NULL, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0);
SetWindowPos(activeWindow.hWnd, NULL, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), SWP_FRAMECHANGED);
}

// disable full screen
inline void disableFullScreen(WINDOW activeWindow, PREVIOUSRECT *prev)
{
SetWindowPos(activeWindow.hWnd, NULL, prev->x, prev->y, prev->width, prev->height, 0);
SetWindowPos(activeWindow.hWnd, NULL, prev->x, prev->y, prev->width, prev->height, SWP_FRAMECHANGED);
}

// check if process is still running
Expand All @@ -168,10 +179,11 @@ int CALLBACK cursorLock(void *arguments)
PREVIOUSRECT previousRect;

previousRect.previousStyle = GetWindowLongPtr(selectedWindow.hWnd, GWL_STYLE);
previousRect.previousExStyle = GetWindowLongPtr(selectedWindow.hWnd, GWL_EXSTYLE);

if (settings->borderless)
{
toggleBorderlessWindow(selectedWindow.hWnd);
removeBorderStyles(selectedWindow.hWnd);
if (!settings->fullScreen)
resizeBorderless(selectedWindow, &previousRect);
}
Expand Down Expand Up @@ -218,10 +230,11 @@ int CALLBACK cursorLock(void *arguments)
break;
}

// check fi the window style has changed
// check if the window style has changed
if (previousRect.currentStyle != GetWindowLongPtr(selectedWindow.hWnd, GWL_STYLE))
{
SetWindowLongPtr(selectedWindow.hWnd, GWL_STYLE, previousRect.currentStyle);
SetWindowPos(selectedWindow.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

if (settings->borderless && !settings->fullScreen)
resizeBorderless(selectedWindow, &previousRect);
Expand All @@ -243,16 +256,8 @@ int CALLBACK cursorLock(void *arguments)
Sleep(1);
}

// if window style was changed, change it back
if (styleChanged)
SetWindowLongPtr(selectedWindow.hWnd, GWL_STYLE, previousRect.previousStyle);

if (settings->borderless)
{
toggleBorderlessWindow(selectedWindow.hWnd);
if (!settings->fullScreen)
resizeBorderless(selectedWindow, &previousRect);
}
// Restore original styles (handles borderless, styleChanged, etc. all at once)
restoreBorderStyles(selectedWindow.hWnd, previousRect.previousStyle, previousRect.previousExStyle);

if (settings->fullScreen)
disableFullScreen(selectedWindow, &previousRect);
Expand Down