Using WebView in a modal NSWindow not working?

前端 未结 2 978
轻奢々
轻奢々 2021-01-20 13:26

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

[_webView setMainFrameURL:[NSString fromStdString:url]];
[_nsWindow makeKeyAndOrderFront:nil];
retu         


        
相关标签:
2条回答
  • 2021-01-20 13:53

    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 讨论(0)
  • 2021-01-20 14:00

    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.

    0 讨论(0)
提交回复
热议问题