Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using WebView in a modal NSWindow not working?

How should you use WebKit's WebView with a modal dialog?

[_webView setMainFrameURL:[NSString fromStdString:url]];
[_nsWindow makeKeyAndOrderFront:nil];
return [NSApp runModalForWindow:_nsWindow];

The preceeding code is only working on Mac OS 10.6. Using 10.5 this is not navigating to the specified URL. Without the runModalForWindow, everything is working.

like image 740
Dodo Avatar asked Jan 24 '26 06:01

Dodo


2 Answers

WebView only works on the main loop and thus doesn't cooperate in this case. One solution would be to run the modal session yourself and keep the main loop manually alive (similar to what is proposed here). E.g.:

NSModalSession session = [NSApp beginModalSessionForWindow:yourWindow];
int result = NSRunContinuesResponse;

// Loop until some result other than continues:
while (result == NSRunContinuesResponse)
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // Run the window modally until there are no events to process:
    result = [NSApp runModalSession:session];

    // Give the main loop some time:
    [[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode];

    // Drain pool to avoid memory getting clogged:
    [pool drain];
}

[NSApp endModalSession:session];

Note that you probably want to use something like -runMode:beforeDate: instead to keep the CPU load down.

like image 134
Georg Fritzsche Avatar answered Jan 26 '26 21:01

Georg Fritzsche


I've been searching for solutions and now I can use WebView on modal session using following code. Without using -runMode:beforeDate my WebView cannot process keyboard or mount events:

- (void) OpenURL:(const char *)_url
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [NSApplication sharedApplication];
    [NSApp setDelegate:self];

    NSString *url = [NSString stringWithUTF8String:_url];

    NSLog(@"OpenURL: %@", url);

    NSRect windowRect = NSMakeRect(10.0f, 10.0f, 800.0f, 600.0f);

    NSWindow *window = [[NSWindow alloc] initWithContentRect:windowRect 
        styleMask:(NSResizableWindowMask|NSClosableWindowMask|NSTitledWindowMask) 
        backing:NSBackingStoreBuffered defer:NO];
    [window setDelegate:self];

    WebView *webview = [[WebView alloc] initWithFrame:windowRect 
        frameName:@"mainFrame" 
        groupName:nil];
    [webview setFrameLoadDelegate:self];
    [[webview mainFrame] 
          loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];

    [window setContentView:webview];
    [window makeKeyAndOrderFront:nil];

    // Modal Session

    NSModalSession session = [NSApp beginModalSessionForWindow:window];
    _result = NSModalResponseContinue;

    while (_result == NSModalResponseContinue) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

        _result = [NSApp runModalSession:session];

        // The event loop is a runloop data source, so any ui event will 
        // wake up the source and make this method returns, and so 
        // you can block the run loop and tell him to wait that
        // something append. [2]
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                    beforeDate:[NSDate distantFuture]];

        [self doSomeWork];

        [pool drain];
    }
    [NSApp endModalSession:session];

    [pool release];
}

You need to call [NSApp stopModal], [NSApp abortModal] or [NSApp stopModalWithCode:yourReturnCode] somewhere like this:

- (void)windowWillClose:(NSNotification *)notification
{
    NSLog(@"windowWillClose");
    [NSApp stopModal];
}

Links:

  • [1]:http://www.dejal.com/blog/2007/01/cocoa-topics-case-modal-webview
  • [2]:http://lists.apple.com/archives/cocoa-dev/2008/Apr/msg02260.html
like image 35
Seunghoon Avatar answered Jan 26 '26 20:01

Seunghoon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!