CefView / CocoaCefView

A Cocoa View object encapsulated CEF view based on NSView
MIT License
19 stars 6 forks source link

[问题] 询问关于原版CEF调整大小的问题。 #6

Closed FlashTang closed 3 years ago

FlashTang commented 3 years ago

你好 tishion ,我想询问一个关于原版CEF调整大小的问题(非CocoaCefView) 以下是原版CEF的 cefclient 例子root_window_mac.mm 文件中 创建浏览器窗口方法

if (!is_popup_) {
    // Create the browser window.
    browser_window_->CreateBrowser(
        CAST_NSVIEW_TO_CEF_WINDOW_HANDLE(viewForCEF),
        CefRect(0, 0, width, height), settings, nullptr,
        root_window_.delegate_->GetRequestContext(&root_window_));
  }

其中 CAST_NSVIEW_TO_CEF_WINDOW_HANDLE(viewForCEF) ,这里的view本来是contentView , 我把它改成自己创建的一个NSView ,我想让网页随viewForCEF大小变化

viewForCEF = [[NSView alloc]initWithFrame:NSMakeRect(0, 0, width, height)];
[contentView addSubview:viewForCEF];

然后我实验创建了一个NSButton ,按这个按钮,运行:

-(void)buttonPressed {
    NSLog(@"Button pressed!");
    CGFloat w = window_.contentView.frame.size.width - 100;
    CGFloat h = window_.contentView.frame.size.height;
    [viewForCEF setFrame:NSMakeRect(0, 0,w,h)];
}

我发现这个方法是可行的,是我想要的效果,网页大小刚好比窗口大小100,完美 但是如果把调整viewForCEF大小的代码放进 NSWindowDelegate windowDidResize 里,就出问题了,网页大小不对,而且被clip掉了:

 - (void)windowDidResize:(NSNotification *)notification{

    CGFloat w = window_.contentView.frame.size.width - 100;
    CGFloat h = window_.contentView.frame.size.height;
    [viewForCEF setFrame:NSMakeRect(0, 0,w,h)];

}

我发现,如果上面的代码放在NSTimer里或用dispatch_after 或 performSelector 方法延迟0.5秒左右也可以完美调整网页大小(即网页大小为viewForCEF的大小),另外使用手动按钮运行调整大小代码也是一样的道理

- (void)windowDidResize:(NSNotification *)notification{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(buttonPressed) object:nil];
    [self performSelector:@selector(buttonPressed) withObject:nil afterDelay:0.5];
}

所以我想请问,有什么方法可以立即调整viewForCEF的大小,且能够使网页大小和viewForCEF大小一致呢? 这是一个线程的问题,还是什么问题? 这问题我搜索了整个网络都没有答案,资料太少,我又菜 谢谢🙏

FlashTang commented 3 years ago

终于找到原因了,是因为browser没有创建完成的原因(windowDidResize第一次自动调用),另外加之 width - 100 会有负数出现, 解决办法是确保browser创建完成后,再调整view的大小。

-(void)buttonPressed {
    CGFloat w = window_.contentView.frame.size.width - 100;
    CGFloat h = window_.contentView.frame.size.height;
    [viewForCEF setFrame:NSMakeRect(0, 0,fmax(w,0),fmax(h,0))];
}

- (void)windowDidResize:(NSNotification *)notification{

    client::BrowserWindow* browser_window = root_window_->browser_window();
    if (browser_window && !browser_window->IsClosing()) {
        CefRefPtr<CefBrowser> browser = browser_window->GetBrowser();
        if (browser.get()) {

             [self buttonPressed];

        }
    }

}