How do I create a CEF browser inside an NSWindow?

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

How do I create a CEF browser inside an NSWindow?

Postby pupeno » Wed Mar 04, 2015 9:34 am

Hello,

I'm reading through cefsimple and I came to this line:

Code: Select all
    CefBrowserHost::CreateBrowser(window_info, handler.get(), url,
                                  browser_settings, NULL);


in simple_app.cc that triggers the creation of a window with a browser inside it. But my app already has a window, inheriting from NSWindow and instantiated by loading a nib (xib) file. How do I create the browser inside that NSWindow?
pupeno
Techie
 
Posts: 24
Joined: Wed Feb 25, 2015 7:48 am

Re: How do I create a CEF browser inside an NSWindow?

Postby magreenblatt » Wed Mar 04, 2015 10:46 am

Pass the parent NSView to CreateBrowser via the CefWindowInfo argument.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: How do I create a CEF browser inside an NSWindow?

Postby pupeno » Sat Mar 14, 2015 1:45 am

Hello,

Thanks for the reply. I got this to work, but I want to be sure I'm not doing anything wrong. In cefsimple there's a class, SimpleApp, that inherits CefApp, CefBrowserProcessHandler and calls CreateBrowser in its method OnContextInitialized: https://code.google.com/p/chromiumembed ... _app.cc#46

Now, I created a class that inherits NSView and I moved all the code of that method to it, in the method -(void)startCef. Am I doing something inadvertedly wrong? It seems to work, but I'm not sure whether I'm causing some threading issue or whether it's working by chance in my machine and it'll explode in another. It seems that by the time my nib is loaded and startCef gets called, OnContextInitialized would have been called anyway.

This is my class:

Code: Select all
#import <Cocoa/Cocoa.h>
#include "include/cef_app.h"

@interface CACefBrowser : NSView
@end

@implementation CACefBrowser

- (void)startCef {
    CEF_REQUIRE_UI_THREAD();

    // Information used when creating the browser inside this NSView.
    CefWindowInfo window_info;
    window_info.SetAsChild(self, 20, 20, self.frame.size.width - 40, self.frame.size.height - 40);

    // CACefHandler implements browser-level callbacks.
    CACefHandler *caCefHandler = new CACefHandler();
    CefRefPtr<CACefHandler> handler(caCefHandler);

    // Specify CEF browser settings here.
    CefBrowserSettings browser_settings;

    std::string url = "https://google.com";

    // Create the first browser window.
    CefBrowserHost::CreateBrowser(window_info, handler.get(), url, browser_settings, NULL);
}

- (instancetype)initWithFrame: (NSRect)frameRect {
    self = [super initWithFrame: frameRect];
    [self startCef];
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    [self startCef];
}
@end
pupeno
Techie
 
Posts: 24
Joined: Wed Feb 25, 2015 7:48 am

Re: How do I create a CEF browser inside an NSWindow?

Postby magreenblatt » Sun Mar 15, 2015 5:46 pm

pupeno wrote:Am I doing something inadvertedly wrong?

It looks fine to me. What is your concern?
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: How do I create a CEF browser inside an NSWindow?

Postby pupeno » Mon Mar 16, 2015 11:23 am

Hello,

My concern is that that code used to run once and only once in the original cefsimple and now in my app it would run several times. And indeed, new CACefHandler() would crash on the second run because its constructor was:

Code: Select all
CACefHandler::CACefHandler()
: is_closing_(false) {
    DCHECK(!g_instance);
    g_instance = this;
}


CACefHandler is, for now, just a renamed SimpleHandler:

https://bitbucket.org/chromiumembedded/ ... ster#cl-21

I change new CACefHandler() to CACefHandler::GetInstance() and GetInstance() to

Code: Select all
CACefHandler* CACefHandler::GetInstance() {
    if(g_instance == NULL) {
        new CACefHandler();
    }
    return g_instance;
}


so it has proper singleton behaviour. But I'm just assuming here, should it be a singleton or not? The sample code I'm reading is inconsistent in this regard and my concern is that since I don't completely understand CEF yet I might be doing something wrong.

For example, in my own code, OnBeforeClose (https://bitbucket.org/chromiumembedded/ ... ster#cl-59) doesn't get called. I don't know why as it's hard to debug why a piece of code doesn't get a callback. As a possible side effect of that, my application never quits.
pupeno
Techie
 
Posts: 24
Joined: Wed Feb 25, 2015 7:48 am

Re: How do I create a CEF browser inside an NSWindow?

Postby magreenblatt » Mon Mar 16, 2015 4:35 pm

The desired life span for your CefClient handlers will depend on your application. For example, if you use the same CefClient for all browsers then it makes sense to scope its lifespan to main and use a singleton pattern. If, on the other hand, you use multiple CefClient instances then you will need to manage those multiple instances in a different way. The cefsimple application demonstrates the singleton pattern while the cefclient application (at current master) demonstrates the CefClient-per-browser pattern.
magreenblatt
Site Admin
 
Posts: 12409
Joined: Fri May 29, 2009 6:57 pm

Re: How do I create a CEF browser inside an NSWindow?

Postby pupeno » Mon Mar 16, 2015 6:24 pm

Last time I checked cefclient, it also seemed to have a singleton handle. I look at the master branch in bitbucket and it looks quite different to what I seen before. I'm trying to build a couple of applications using CEF from a modern Cocoa/Swift application. I been hammering at it quite hard for many weeks now (starting from no experience in Cocoa or Swift it was quite a step learning curve). I read everything that was written the CEF documentation. Do you have any recommendations on how to approach this problem?
pupeno
Techie
 
Posts: 24
Joined: Wed Feb 25, 2015 7:48 am

Re: How do I create a CEF browser inside an NSWindow?

Postby dee1000 » Tue Mar 17, 2015 9:48 am

Hi,

I am also trying do some modifications using CEF3. You seem to be having some success. What was your approach to adopting CEF?

Did you a) modify a cefclient example , or b) did you create a separate project and and imported the CEF classes into it, or c) did you create a separate app much like cefclient and cefsimple, or d) other approach?

D
dee1000
Newbie
 
Posts: 6
Joined: Sun Mar 15, 2015 4:20 pm

Re: How do I create a CEF browser inside an NSWindow?

Postby pupeno » Tue Mar 17, 2015 4:28 pm

My approach so far was to create a brand new Swift project and start copying code from cefsimple making sure it compiles and runs. Then I started refactoring and converting into Swift was much as possible. It was not easy and I think I have huge flaws in my codebase because, for example, the app won't quit. I really wish Apple's WebView didn't have such an stupid way of handling cookies.
pupeno
Techie
 
Posts: 24
Joined: Wed Feb 25, 2015 7:48 am


Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 97 guests