开发者

Using WebView in a modal NSWindow not working?

开发者 https://www.devze.com 2023-01-24 13:40 出处:网络
How should you use WebKit\'s WebView with a modal dialog? [_webView setMainFrameURL:[NSString fromStdString:url]];

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. Witho开发者_如何转开发ut the runModalForWindow, everything is working.


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.


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
0

精彩评论

暂无评论...
验证码 换一张
取 消