@@ -137,6 +137,11 @@ ImageEngine* g_pImageEngine = nullptr; // [v3.1] Global Accessor for UIRenderer
137137static CompositionEngine* g_compEngine = nullptr ; // [Fix] Raw pointer to avoid unique_ptr include hell
138138static std::unique_ptr<UIRenderer> g_uiRenderer; // 独立 UI 层渲染器
139139static InputController g_inputController; // Quantum Stream: 输入状态机
140+
141+ // [Fix] Fullscreen State Tracking
142+ static bool g_isFullScreen = false ;
143+ static WINDOWPLACEMENT g_savedWindowPlacement = { sizeof (WINDOWPLACEMENT) };
144+
140145// [Step 3] Unified Resource Management
141146struct ImageResource {
142147 ComPtr<ID2D1Bitmap> bitmap;
@@ -1961,6 +1966,7 @@ void AdjustWindowToImage(HWND hwnd) {
19611966 if (!g_imageResource) return ;
19621967 if (g_runtime.LockWindowSize ) return ; // Don't auto-resize when locked
19631968 if (g_settingsOverlay.IsVisible ()) return ; // Don't resize if Settings is open (prevents jitter)
1969+ if (g_isFullScreen) return ; // [Fix] Don't resize if in Fullscreen mode
19641970
19651971 // [Fix] Use Centralized First-Principles Dimension Logic
19661972 D2D1_SIZE_F effSize = GetEffectiveImageSize ();
@@ -2603,6 +2609,9 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
26032609 return 0 ;
26042610 }
26052611 case WM_NCHITTEST: {
2612+ // [Fix] Disable window edge resizing/interaction in Fullscreen
2613+ if (g_isFullScreen) return HTCLIENT;
2614+
26062615 LRESULT hit = DefWindowProc (hwnd, message, wParam, lParam);
26072616 if (hit != HTCLIENT) return hit;
26082617
@@ -2906,8 +2915,12 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
29062915 g_viewState.DragStartPos = g_viewState.LastMousePos ;
29072916 g_viewState.DragStartTime = GetTickCount ();
29082917
2918+ // Check MiddleDragAction config
29092919 // Check MiddleDragAction config
29102920 if (g_config.MiddleDragAction == MouseAction::WindowDrag) {
2921+ // [Fix] Disable Window Drag in Fullscreen
2922+ if (g_isFullScreen) return 0 ;
2923+
29112924 // Start manual window drag with middle button
29122925 RECT rc;
29132926 GetWindowRect (hwnd, &rc);
@@ -3024,8 +3037,16 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
30243037 if (direction != 0 ) Navigate (hwnd, direction);
30253038 return TRUE ;
30263039 }
3040+
3041+
30273042
30283043 case WM_LBUTTONDBLCLK:
3044+ // [Fix] Fullscreen Exit on Double Click
3045+ if (g_isFullScreen) {
3046+ SendMessage (hwnd, WM_COMMAND, IDM_FULLSCREEN, 0 );
3047+ return 0 ;
3048+ }
3049+
30293050 // Fit Window - restore from maximized first if needed
30303051 if (IsZoomed (hwnd)) {
30313052 ShowWindow (hwnd, SW_RESTORE);
@@ -3068,7 +3089,20 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
30683089 if (g_winControls.HoverState != WindowHit::None) {
30693090 switch (g_winControls.HoverState ) {
30703091 case WindowHit::Close: SendMessage (hwnd, WM_CLOSE, 0 , 0 ); return 0 ;
3071- case WindowHit::Max: ShowWindow (hwnd, IsZoomed (hwnd) ? SW_RESTORE : SW_MAXIMIZE); return 0 ;
3092+ case WindowHit::Max: {
3093+ // [Fix] Exit Fullscreen if active, else toggle Maximize
3094+ if (g_isFullScreen) {
3095+ SendMessage (hwnd, WM_COMMAND, IDM_FULLSCREEN, 0 );
3096+ // Optional: Reset size to initial?
3097+ // IDM_FULLSCREEN restores placement.
3098+ // User requested "Initial window size" - AdjustWindowToImage or similar?
3099+ // For now, toggle Fullscreen restores prior state, which is standard behavior.
3100+ // If user wants specific size, standard Restore should handle it via WindowPlacement.
3101+ } else {
3102+ ShowWindow (hwnd, IsZoomed (hwnd) ? SW_RESTORE : SW_MAXIMIZE);
3103+ }
3104+ return 0 ;
3105+ }
30723106 case WindowHit::Min: ShowWindow (hwnd, SW_MINIMIZE); return 0 ;
30733107 case WindowHit::Pin: SendMessage (hwnd, WM_COMMAND, IDM_ALWAYS_ON_TOP, 0 ); return 0 ;
30743108 default : break ;
@@ -3210,6 +3244,9 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
32103244 }
32113245
32123246 if (g_config.LeftDragAction == MouseAction::WindowDrag) {
3247+ // [Fix] Disable Window Drag in Fullscreen
3248+ if (g_isFullScreen) return 0 ;
3249+
32133250 ReleaseCapture ();
32143251 SendMessage (hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0 );
32153252 return 0 ;
@@ -3472,7 +3509,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
34723509 if (newTotalScale < minScale) newTotalScale = minScale;
34733510 if (newTotalScale > maxScale) newTotalScale = maxScale;
34743511
3475- if (g_config.ResizeWindowOnZoom && !IsZoomed (hwnd) && !g_runtime.LockWindowSize ) {
3512+ if (g_config.ResizeWindowOnZoom && !IsZoomed (hwnd) && !g_runtime.LockWindowSize && !g_isFullScreen ) {
34763513 // 1. Calculate Target Dimensions (Uncapped)
34773514 HMONITOR hMon = MonitorFromWindow (hwnd, MONITOR_DEFAULTTONEAREST);
34783515 MONITORINFO mi = { sizeof (mi) }; GetMonitorInfoW (hMon, &mi);
@@ -3921,7 +3958,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
39213958 if (newTotalScale > 20 .0f ) newTotalScale = 20 .0f ;
39223959
39233960 // Apply zoom with window resize if enabled
3924- if (g_config.ResizeWindowOnZoom && !IsZoomed (hwnd) && !g_runtime.LockWindowSize ) {
3961+ // [Fix] Disable Resize logic if Fullscreen
3962+ if (g_config.ResizeWindowOnZoom && !IsZoomed (hwnd) && !g_runtime.LockWindowSize && !g_isFullScreen) {
39253963 // Get Monitor Info
39263964 HMONITOR hMon = MonitorFromWindow (hwnd, MONITOR_DEFAULTTONEAREST);
39273965 MONITORINFO mi = { sizeof (mi) }; GetMonitorInfoW (hMon, &mi);
@@ -4120,8 +4158,33 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
41204158 break ;
41214159 }
41224160 case IDM_FULLSCREEN: {
4123- if (IsZoomed (hwnd)) ShowWindow (hwnd, SW_RESTORE);
4124- else ShowWindow (hwnd, SW_MAXIMIZE);
4161+ // [Fix] True Fullscreen Implementation
4162+ DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
4163+
4164+ if (g_isFullScreen) {
4165+ // Restore to Windowed
4166+ SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW);
4167+ SetWindowPlacement (hwnd, &g_savedWindowPlacement);
4168+ SetWindowPos (hwnd, nullptr , 0 , 0 , 0 , 0 ,
4169+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
4170+ g_isFullScreen = false ;
4171+ } else {
4172+ // Enter Fullscreen
4173+ MONITORINFO mi = { sizeof (mi) };
4174+ if (GetMonitorInfo (MonitorFromWindow (hwnd, MONITOR_DEFAULTTOPRIMARY), &mi)) {
4175+ GetWindowPlacement (hwnd, &g_savedWindowPlacement);
4176+
4177+ SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
4178+ SetWindowPos (hwnd, HWND_TOP,
4179+ mi.rcMonitor .left , mi.rcMonitor .top ,
4180+ mi.rcMonitor .right - mi.rcMonitor .left ,
4181+ mi.rcMonitor .bottom - mi.rcMonitor .top ,
4182+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
4183+ g_isFullScreen = true ;
4184+ }
4185+ }
4186+ // Trigger repaint to center/resize image
4187+ RequestRepaint (PaintLayer::All);
41254188 break ;
41264189 }
41274190 case IDM_DELETE: {
0 commit comments