Skip to content

Commit 40d2fe4

Browse files
committed
Use a helper to do the NSRunAlertPanelReleativeToWindow() function
1 parent 3efb7cb commit 40d2fe4

File tree

1 file changed

+64
-13
lines changed

1 file changed

+64
-13
lines changed

Source/NSAlert.m

Lines changed: 64 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)