@@ -757,6 +757,43 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
757757
758758 private registerListeners ( ) : void {
759759
760+ // macOS: Use 'ready-to-show' event to show window when ready (prevents blank screen)
761+ // This is the Electron best practice for macOS to avoid flicker and blank screens
762+ // The 'ready-to-show' event fires when the window is ready to be displayed without flicker
763+ if ( isMacintosh ) {
764+ let readyToShowFired = false ;
765+ this . _register ( Event . fromNodeEventEmitter ( this . _win , 'ready-to-show' ) ( ( ) => {
766+ if ( ! readyToShowFired && this . _win && ! this . _win . isDestroyed ( ) ) {
767+ readyToShowFired = true ;
768+ this . logService . trace ( 'window#ready-to-show: window ready, ensuring visibility on macOS' ) ;
769+
770+ // Ensure window is visible with valid bounds
771+ if ( ! this . _win . isVisible ( ) ) {
772+ this . _win . showInactive ( ) ;
773+ }
774+ if ( this . _win . isMinimized ( ) ) {
775+ this . _win . restore ( ) ;
776+ }
777+
778+ // Validate bounds
779+ const bounds = this . _win . getBounds ( ) ;
780+ if ( bounds && ( bounds . width === 0 || bounds . height === 0 ) ) {
781+ this . logService . warn ( 'window#ready-to-show: invalid bounds, resetting' ) ;
782+ this . _win . setSize ( 1024 , 768 ) ;
783+ this . _win . center ( ) ;
784+ }
785+
786+ // Focus the window to ensure it's active and rendered
787+ // Use setTimeout to ensure this happens after the window is fully ready
788+ setTimeout ( ( ) => {
789+ if ( this . _win && ! this . _win . isDestroyed ( ) ) {
790+ this . _win . focus ( ) ;
791+ }
792+ } , 0 ) ;
793+ }
794+ } ) ) ;
795+ }
796+
760797 // Window error conditions to handle
761798 this . _register ( Event . fromNodeEventEmitter ( this . _win , 'unresponsive' ) ( ( ) => this . onWindowError ( WindowError . UNRESPONSIVE ) ) ) ;
762799 this . _register ( Event . fromNodeEventEmitter ( this . _win , 'responsive' ) ( ( ) => this . onWindowError ( WindowError . RESPONSIVE ) ) ) ;
@@ -1134,56 +1171,59 @@ export class CodeWindow extends BaseWindow implements ICodeWindow {
11341171 // Load URL
11351172 this . _win . loadURL ( FileAccess . asBrowserUri ( `vs/code/electron-browser/workbench/workbench${ this . environmentMainService . isBuilt ? '' : '-dev' } .html` ) . toString ( true ) ) ;
11361173
1137- // Fix for macOS blank screen: Ensure window is visible and has valid bounds
1138- // This fix runs immediately and also after the page loads to handle timing issues
1174+ // macOS: Comprehensive fix for blank screen issue
1175+ // The window is created with show: false to reduce flicker, but on macOS this can cause blank screens
1176+ // We use multiple strategies to ensure the window is visible:
1177+ // 1. 'ready-to-show' event (handled in registerListeners) - primary method
1178+ // 2. Immediate check after loadURL - fallback if ready-to-show doesn't fire
1179+ // 3. Page load events - ensure visibility after content loads
1180+ // 4. Timeout fallback - last resort
11391181 if ( isMacintosh && this . _win ) {
1140- // Immediate fix: Force window to be shown if it's not visible
1141- if ( ! this . _win . isVisible ( ) ) {
1142- this . _win . showInactive ( ) ;
1143- }
1144- // Ensure window is not minimized
1145- if ( this . _win . isMinimized ( ) ) {
1146- this . _win . restore ( ) ;
1147- }
1148- // Validate and fix window bounds if invalid (0x0 or off-screen)
1149- const bounds = this . _win . getBounds ( ) ;
1150- if ( bounds && ( bounds . width === 0 || bounds . height === 0 ) ) {
1151- // Reset to default size if invalid
1152- this . _win . setSize ( 1024 , 768 ) ;
1153- this . _win . center ( ) ;
1154- }
1155-
1156- // Additional fix: Ensure window is visible after page loads (handles async loadURL timing)
1157- // Use both 'did-finish-load' and 'dom-ready' events to catch all cases
1182+ // Immediate check: Show window if it's not visible (fallback if ready-to-show hasn't fired)
11581183 const ensureWindowVisible = ( ) => {
11591184 if ( this . _win && ! this . _win . isDestroyed ( ) ) {
11601185 if ( ! this . _win . isVisible ( ) ) {
1186+ this . logService . trace ( 'window#load: forcing window to show on macOS' ) ;
11611187 this . _win . showInactive ( ) ;
11621188 }
11631189 if ( this . _win . isMinimized ( ) ) {
11641190 this . _win . restore ( ) ;
11651191 }
1166- // Re-check bounds after page load
1167- const currentBounds = this . _win . getBounds ( ) ;
1168- if ( currentBounds && ( currentBounds . width === 0 || currentBounds . height === 0 ) ) {
1192+
1193+ // Validate and fix window bounds
1194+ const bounds = this . _win . getBounds ( ) ;
1195+ if ( bounds && ( bounds . width === 0 || bounds . height === 0 ) ) {
1196+ this . logService . warn ( 'window#load: invalid window bounds detected, resetting to default size' ) ;
11691197 this . _win . setSize ( 1024 , 768 ) ;
11701198 this . _win . center ( ) ;
11711199 }
1172- // Ensure window is focused to prevent blank screen
1200+
1201+ // Focus the window to ensure it's active and rendered
11731202 this . _win . focus ( ) ;
11741203 }
11751204 } ;
11761205
1177- // Listen for page load events to ensure window is visible
1178- this . _win . webContents . once ( 'did-finish-load' , ensureWindowVisible ) ;
1179- this . _win . webContents . once ( 'dom-ready' , ensureWindowVisible ) ;
1206+ // Immediate check (in case ready-to-show already fired or won't fire)
1207+ ensureWindowVisible ( ) ;
1208+
1209+ // Listen for page load events as additional safety net
1210+ this . _win . webContents . once ( 'did-finish-load' , ( ) => {
1211+ this . logService . trace ( 'window#load: did-finish-load event, ensuring window visibility' ) ;
1212+ ensureWindowVisible ( ) ;
1213+ } ) ;
1214+
1215+ this . _win . webContents . once ( 'dom-ready' , ( ) => {
1216+ this . logService . trace ( 'window#load: dom-ready event, ensuring window visibility' ) ;
1217+ ensureWindowVisible ( ) ;
1218+ } ) ;
11801219
1181- // Also ensure visibility after a short delay as a fallback
1220+ // Fallback: Ensure visibility after a delay (handles edge cases)
11821221 setTimeout ( ( ) => {
1183- if ( this . _win && ! this . _win . isDestroyed ( ) ) {
1222+ if ( this . _win && ! this . _win . isDestroyed ( ) && ! this . _win . isVisible ( ) ) {
1223+ this . logService . warn ( 'window#load: window still not visible after delay, forcing show' ) ;
11841224 ensureWindowVisible ( ) ;
11851225 }
1186- } , 100 ) ;
1226+ } , 500 ) ;
11871227 }
11881228
11891229 // Remember that we did load
0 commit comments