@@ -1770,6 +1770,50 @@ void NSBeginInformationalAlertSheet(NSString *title,
17701770 NSReleaseAlertPanel (panel);
17711771}
17721772
1773+ // Helper to run a sheet on the main thread and capture the result.
1774+ @interface _GSRunSheetHelper : NSObject
1775+ {
1776+ GSAlertPanel *_panel;
1777+ NSWindow *_docWindow;
1778+ NSInteger _result;
1779+ }
1780+ - (id )initWithPanel : (GSAlertPanel *)panel docWindow : (NSWindow *)docWindow ;
1781+ - (void )runSheetOnMainThread ;
1782+ - (NSInteger )result ;
1783+ @end
1784+
1785+ @implementation _GSRunSheetHelper
1786+ - (id )initWithPanel : (GSAlertPanel *)panel docWindow : (NSWindow *)docWindow
1787+ {
1788+ if ((self = [super init ]) != nil )
1789+ {
1790+ _panel = RETAIN (panel);
1791+ _docWindow = docWindow; // not retaining window to avoid cycles
1792+ _result = NSAlertErrorReturn ;
1793+ }
1794+ return self;
1795+ }
1796+
1797+ - (void )dealloc
1798+ {
1799+ RELEASE (_panel);
1800+ [super dealloc ];
1801+ }
1802+
1803+ - (void )runSheetOnMainThread
1804+ {
1805+ [NSApp beginSheet: _panel
1806+ modalForWindow: _docWindow
1807+ modalDelegate: nil
1808+ didEndSelector: NULL
1809+ contextInfo: NULL ];
1810+ _result = [_panel result ];
1811+ }
1812+
1813+ - (NSInteger )result { return _result; }
1814+
1815+ @end
1816+
17731817// Synchronous sheet-aware alert. If docWindow is nil, fall back to
17741818// NSRunAlertPanel which shows a modal alert. Otherwise display a sheet
17751819// attached to docWindow and run a modal loop until it completes.
@@ -1806,20 +1850,27 @@ void NSBeginInformationalAlertSheet(NSString *title,
18061850
18071851 panel = getSomeSheet (&standardAlertPanel, defaultTitle, title, message,
18081852 defaultButton, alternateButton, otherButton);
1853+ /* Run the sheet on the main thread to ensure it is presented. */
1854+ if (GSCurrentThread () != GSAppKitThread)
1855+ {
1856+ _GSRunSheetHelper *h = [[_GSRunSheetHelper alloc ] initWithPanel: panel
1857+ docWindow: docWindow];
1858+ [h performSelectorOnMainThread: @selector (runSheetOnMainThread )
1859+ withObject: nil
1860+ waitUntilDone: YES ];
1861+ result = [h result ];
1862+ RELEASE (h);
1863+ }
1864+ else
1865+ {
1866+ [NSApp beginSheet: panel
1867+ modalForWindow: docWindow
1868+ modalDelegate: nil
1869+ didEndSelector: NULL
1870+ contextInfo: NULL ];
1871+ result = [panel result ];
1872+ }
18091873
1810- /* Begin sheet synchronously; under GNUstep beginSheet calls runModalForWindow
1811- which will invoke the modalDelegate didEndSelector; we call beginSheet
1812- and then return the panel result. */
1813- [NSApp beginSheet: panel
1814- modalForWindow: docWindow
1815- modalDelegate: nil
1816- didEndSelector: NULL
1817- contextInfo: NULL ];
1818-
1819- /* The sheet will run its modal session in -beginSheet; by the time
1820- beginSheet returns, the sheet has already completed. Retrieve
1821- the result and cleanup. */
1822- result = [panel result ];
18231874 NSReleaseAlertPanel (panel);
18241875 return result;
18251876}
0 commit comments