Skip to content

feat(input): Enhance window management capabilities - #2608

Draft
githubawn wants to merge 7 commits into
TheSuperHackers:mainfrom
githubawn:feat/fullscreen-toggle
Draft

feat(input): Enhance window management capabilities#2608
githubawn wants to merge 7 commits into
TheSuperHackers:mainfrom
githubawn:feat/fullscreen-toggle

Conversation

@githubawn

@githubawn githubawn commented Apr 16, 2026

Copy link
Copy Markdown

Alt+Enter Borderless Fullscreen & Live Resize Reflow Integration

Integrates Alt+Enter fullscreen / windowed toggling with live resizing during games.

Summary of Changes

  • Alt+Enter Toggle: Toggles borderless fullscreen matching native monitor bounds, persisting the setting to options.ini.
  • Startup Priority: Command-line parameters (-win/-nowin) override persistent preferences.
  • **Deferred Preferences Saving: Relocated preference-writing logic from the OS-level hook into performLiveResize(). Saving only occurs upon a successful D3D reset, ensuring options.ini is updated with both the window state and the new resolution.
  • ** Unblocked In-Game Options Menu: Removed the block in OptionsMenu.cpp that disabled the resolution dropdown during a match, allowing in-game resolution adjustments.

This change was generated with AI assistance. All generated code has been reviewed, tested, and verified for correctness.

todo, replicate to generals

@greptile-apps

greptile-apps Bot commented Apr 16, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds persistent borderless-fullscreen toggling and live resize handling for Zero Hour.

  • Adds Alt+Enter/F11 window-mode toggles, command-line precedence, and deferred Direct3D resizing.
  • Reflows scripted UI layouts and recreates the in-game control bar after resolution changes.
  • Enables in-game resolution selection and updates the shared Direct3D resolution-reset path.

Confidence Score: 4/5

The PR is not yet safe to merge because a persisted windowed preference is decoded as fullscreen on the next launch.

The resize path writes windowed=true through setBool as "1", while getWindowed recognizes only "yes", so successfully selecting windowed mode does not survive restart.

Files Needing Attention: Core/GameEngine/Source/Common/OptionPreferences.cpp

Important Files Changed

Filename Overview
Core/GameEngine/Source/Common/OptionPreferences.cpp Adds window-mode persistence, but the setter writes a boolean representation that the new getter cannot read as true.
GeneralsMD/Code/Main/WinMain.cpp Adds guarded fullscreen hotkeys, window-style transitions, and retryable deferred display resizing.
GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp Adds guarded GUI-tree reflow and removes destroyed windows from the layout registry.
GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp Records original scripted window geometry for resolution-dependent reflow.
Core/Libraries/Source/WWVegas/WW3D2/dx8wrapper.cpp Routes resolution changes through the full render-device reset path so window mode and bit depth can change.

Sequence Diagram

sequenceDiagram
  participant Input as Win32 input/resize
  participant Main as WinMain
  participant Display as W3D Display
  participant UI as GameWindow UI
  participant Prefs as Options.ini
  Input->>Main: Alt+Enter, F11, or WM_SIZE
  Main->>Main: Queue deferred resize
  Main->>Display: Apply display mode
  alt Reset succeeds
    Display-->>Main: Success
    Main->>UI: Reflow layouts and recreate control bar
    Main->>Prefs: Persist window mode and resolution
  else Reset fails
    Display-->>Main: Failure
    Main->>Main: Keep resize pending
  end
Loading
Prompt To Fix All With AI
### Issue 1
Core/GameEngine/Source/Common/OptionPreferences.cpp:779
**Windowed preference format mismatch**

When a successful resize persists windowed mode, `setBool` stores true as `"1"`, but `getWindowed` recognizes only `"yes"`. On the next launch without a command-line override, the game interprets the saved windowed setting as fullscreen.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (7): Last reviewed commit: "fix(winmain): clear deferred resize flag..." | Re-trigger Greptile

Comment thread Core/GameEngine/Source/Common/OptionPreferences.cpp Outdated
Comment thread GeneralsMD/Code/Main/WinMain.cpp Outdated
@stephanmeesters

Copy link
Copy Markdown

Haven't read too closely but when the resolution is set to native display resolution, will alt+enter here switch between borderless and fullscreen? How is this typically implemented in games?

@githubawn

Copy link
Copy Markdown
Author

Currently it switches between exclusive and windowed that covers the entire screen. Have a small regression there as the titel bars uncenters the borderless window.

In modern games they don't let you set the fullscreen resolution anymore, the resolution setting only applies to windowed. The fullscreen resolution is always the desktop resolution.

Comment thread GeneralsMD/Code/Main/WinMain.cpp Outdated
@githubawn
githubawn marked this pull request as draft April 16, 2026 17:52
@xezon xezon changed the title feat(input)/Add Alt+Enter support for fullscreen toggling feat(input): Add Alt+Enter support for fullscreen toggling Apr 18, 2026
@githubawn githubawn changed the title feat(input): Add Alt+Enter support for fullscreen toggling feat(input): Enhance window management capabilities Jun 27, 2026
@githubawn
githubawn force-pushed the feat/fullscreen-toggle branch 2 times, most recently from f4fca7f to 4d29ea6 Compare June 27, 2026 18:58
@githubawn
githubawn marked this pull request as ready for review June 27, 2026 18:58
@githubawn
githubawn marked this pull request as draft June 27, 2026 18:59
@githubawn
githubawn force-pushed the feat/fullscreen-toggle branch from 4d29ea6 to 76bd972 Compare June 27, 2026 19:05
Comment thread GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManager.cpp Outdated
@githubawn

Copy link
Copy Markdown
Author

@greptile review

Comment on lines +411 to +418
void checkAndApplyDeferredResize()
{
if (g_resizePending && isResizeSafe())
{
g_resizePending = false;
performLiveResize(ApplicationHWnd);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Deferred resize flag cleared before the attempt leaves resize unretried on D3D failure

g_resizePending is set to false before performLiveResize is called. If TheDisplay->setDisplayMode(...) inside performLiveResize returns false (e.g., the D3D device is lost or a reset fails), the window has already been resized by SetWindowPos but the D3D surface stays at the previous dimensions. Because g_resizePending is now false, nothing re-triggers the resize — the mismatch persists until the user manually initiates another resize or toggle.

Consider clearing the flag only on a successful apply: have performLiveResize return a bool and conditionally reset g_resizePending.

Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/Main/WinMain.cpp
Line: 411-418

Comment:
**Deferred resize flag cleared before the attempt leaves resize unretried on D3D failure**

`g_resizePending` is set to `false` before `performLiveResize` is called. If `TheDisplay->setDisplayMode(...)` inside `performLiveResize` returns `false` (e.g., the D3D device is lost or a reset fails), the window has already been resized by `SetWindowPos` but the D3D surface stays at the previous dimensions. Because `g_resizePending` is now `false`, nothing re-triggers the resize — the mismatch persists until the user manually initiates another resize or toggle.

Consider clearing the flag only on a successful apply: have `performLiveResize` return a `bool` and conditionally reset `g_resizePending`.

How can I resolve this? If you propose a fix, please make it concise.

@githubawn
githubawn force-pushed the feat/fullscreen-toggle branch from 11331e1 to f140157 Compare July 30, 2026 21:59
@githubawn
githubawn marked this pull request as ready for review July 30, 2026 22:00

void OptionPreferences::setWindowed(Bool windowed)
{
setBool("Windowed", windowed);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Windowed preference format mismatch

When a successful resize persists windowed mode, setBool stores true as "1", but getWindowed recognizes only "yes". On the next launch without a command-line override, the game interprets the saved windowed setting as fullscreen.

Prompt To Fix With AI
This is a comment left during a code review.
Path: Core/GameEngine/Source/Common/OptionPreferences.cpp
Line: 779

Comment:
**Windowed preference format mismatch**

When a successful resize persists windowed mode, `setBool` stores true as `"1"`, but `getWindowed` recognizes only `"yes"`. On the next launch without a command-line override, the game interprets the saved windowed setting as fullscreen.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@githubawn
githubawn marked this pull request as draft July 30, 2026 22:04
@githubawn

Copy link
Copy Markdown
Author

Deferred until #2639 is merged to keep feature parity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants