[Mac]extension弹出窗口的实现
来源:互联网 发布:中国最好的云计算公司 编辑:程序博客网 时间:2024/05/24 02:16
记录为了怕自己以后忘记了。
最近在chromium解了几个extension的bug,顺便把这块整理一下.
1. UI方面,弹出的是一个 NSWindow, 对应的代码是 NSExtensionPopupController : BaseBubbleController
scoped_ptr<extension::ExtensionViewHost> host_;
NSExtensionPopupController的作用是:
1) 控制NSWindow的显示以及关闭,即一个正常Bubble应该有的动作。例如 当你点击popup窗口外的地方,会关闭(这部分功能是继承与 BaseBubbleController的)
2) 在合适的时候,把 extension的内容放到合适的位置显示.
一般显示的时候,是直接调用静态函数的
+ (ExtensionPopupController*)showURL:(GURL)url inBrowser:(Browser*)browser anchoredAt:(NSPoint)anchoredAt arrowLocation:(info_bubble::BubbleArrowLocation) arrowLocation devMode:(BOOL)devMode { extensions::ExtensionViewHost* host = //根据url 和 browser 来创建一个 ExtensionViewHost extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser); DCHECK(host); if (!host) return nil; ... [gPopup close]; // 关闭之前的popup,默认是只显示一个extension的popup ... gPopup = [[ExtensionPopupController alloc] // 创建新的popup的controller initWithHost:host parentWindow:browser->window()->GetNativeWindow() anchoredAt:anchoredAt arrowLocation:arrowLocation devMode:devMode]; return gPopup;}
那么当ExtensionPopupController创建的时候,他已经拥有了他需要的 ExtensionViewHost. 以及BaseBubbleController一些需要的参数,例如箭头位置.
现在又2个问题:
1) ExtensionViewHost 是什么,作用是什么?
C++代码层的view,是真正要在Popup中显示内容的view
2)ExtensionPopupController 那么具体他干了什么呢?
ExtensionPopupController 有2个成员变量,一个是 extension::ExtensionViewHost host_,另外一个是 NSView* extensionView_.
看下他初始化
- (id)initWithHost:(extensions::ExtensionViewHost*)host parentWindow:(NSWindow*)parentWindow anchoredAt:(NSPoint)anchoredAt arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation devMode:(BOOL)devMode {
base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] initWithContentRect:ui::kWindowSizeDeterminedLater styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); // 创建一个 InfoBubbleWindow,最终是作为BaseBubble的window if (!window.get()) return nil; anchoredAt = [parentWindow convertBaseToScreen:anchoredAt]; if ((self = [super initWithWindow:window // 看上面的注释 parentWindow:parentWindow anchoredAt:anchoredAt])) { host_.reset(host); beingInspected_ = devMode; ignoreWindowDidResignKey_ = NO; InfoBubbleView* view = self.bubble; // 获取自己的显示内容的view,其实就是NSWindow的 contentView [view setArrowLocation:arrowLocation]; extensionView_ = host->view()->native_view(); // 这里,把c++的view 与cocoa的算是联系上了,看下面也有介绍 container_.reset(new ExtensionPopupContainer(self)); host->view()->set_container(container_.get()); // 把 view 设置了 container NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(extensionViewFrameChanged) name:NSViewFrameDidChangeNotification object:extensionView_]; [view addSubview:extensionView_]; // 把 extensionView 加入到这个window的 contentView里 notificationBridge_.reset(new DevtoolsNotificationBridge(self)); registrar_.reset(new content::NotificationRegistrar); if (beingInspected_) { // Listen for the extension to finish loading so the dev tools can be // opened. registrar_->Add(notificationBridge_.get(), chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, content::Source<BrowserContext>(host->browser_context())); } } return self;}
看完初始化,估计会oc的人明白差不多了,大体就是说,
c++有view的,他是显示内容的提供者,就是 ExtensionViewHost, 要显示在mac上,他打开一个 NSWindow,然后把 ExtensionViewHost里的真正的view设置为NSWindow的contentView的一个子View,然后就可以画出了,同时用户如果操作或者别的 影响了这个window,比如frame变化,或者widow关闭了,这里会有相应的处理,返回通知host_以让c++侧代码得以反应.
2. 其实这里重点想说下 ExtensionHostView 以及如何去建立 renderer process 去运行extension的.
在上面showURL已经看到
extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser);
返回的是 ExtensionViewHostMac.
ExtensionViewHostMac : public ExtensionViewHost
ExtensionViewHostMac 几乎啥都没做吧
// ExtensionViewHost 是在browser ui线程里来backing一个view用的,例如,可以是popup,infobar, dialog
ExtensionViewHost: public ExtensionHost,
public web_modal::WebContentsModalDialogManagerDelegate,
public web_modal::WebContentsModalDialogHost
重要成员变量:
scoped_ptr<PlatformExtensionView> view_; // 这里是 ExtensionViewMac , typdef的,上面代码里 extensionView_ = host->view()->native_view().
// ExtensionViewMac 其实是一个桥梁,是mac 和 c++代码的桥梁
如何建立起rederer process,需要看 ExtensionHost
ExtensionHost::ExtensionHost(const Extension* extension, SiteInstance* site_instance, const GURL& url, ViewType host_type) : delegate_(ExtensionsBrowserClient::Get()->CreateExtensionHostDelegate()), extension_(extension), extension_id_(extension->id()), browser_context_(site_instance->GetBrowserContext()), render_view_host_(NULL), did_stop_loading_(false), document_element_available_(false), initial_url_(url), extension_function_dispatcher_(browser_context_, this), extension_host_type_(host_type) { // Not used for panels, see PanelHost. DCHECK(host_type == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE || host_type == VIEW_TYPE_EXTENSION_DIALOG || host_type == VIEW_TYPE_EXTENSION_INFOBAR || host_type == VIEW_TYPE_EXTENSION_POPUP); host_contents_.reset(WebContents::Create( // 又见到熟悉的 WebContents::Create WebContents::CreateParams(browser_context_, site_instance))), content::WebContentsObserver::Observe(host_contents_.get()); host_contents_->SetDelegate(this); SetViewType(host_contents_.get(), host_type); render_view_host_ = host_contents_->GetRenderViewHost(); // Listen for when an extension is unloaded from the same profile, as it may // be the same extension that this points to. registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, content::Source<BrowserContext>(browser_context_)); // Set up web contents observers and pref observers. delegate_->OnExtensionHostCreated(host_contents());}
我觉的,当我们看到 WebContents::Create的时候就已经明白了(不明白同学得自己去看了,那是一大块内容,一时半会将不明白).
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
inBrowser:(浏览器*)浏览器
anchoredAt:(NSPoint)anchoredAt
arrowLocation:(info_bubble::BubbleArrowLocation)
arrowLocation
DEVMODE:(BOOL){DEVMODE扩展::ExtensionViewHost*主机=
扩展::ExtensionViewHostFactory::CreatePopupHost(URL,浏览器);
D检查(主机);
如果(!主机)
返回nil;[gPopup关闭窗口];gPopup=[[ExtensionPopupController的alloc]
initWithHost:主机
parentWindow:浏览器 ->窗口() ->GetNativeWindow()
anchoredAt:anchoredAt
arrowLocation:arrowLocation
DEVMODE:DEVMODE];
返回gPopup;
}
- [Mac]extension弹出窗口的实现
- 弹出窗口的实现
- 弹出窗口功能的实现
- jQuery弹出窗口的实现
- android弹出窗口的实现
- MAC中窗口的实现
- 网页方式实现MSN的弹出窗口
- 金山词霸弹出窗口的简易实现
- JQuery+JQuery ui实现的弹出窗口
- android弹出窗口的实现(PopupWindow)
- android弹出窗口的实现(PopupWindow)
- android弹出窗口的实现(PopupWindow)
- android弹出窗口的实现(PopupWindow)
- android弹出窗口的实现(PopupWindow)
- android弹出窗口的实现(PopupWindow)!!!!
- Android弹出窗口的实现(PopupWindow)
- android弹出窗口的实现(PopupWindow)
- android弹出窗口的实现(PopupWindow)
- EXECUTE IMMEDIATE
- 手写格式化类DFormat,用到boost.regex boost.regex_replace boost.bind等
- hdu 3926 Hand in Hand (同构图)
- 继承与组合
- C# 多线程 Mutex 类 Semaphore 类 Monitor 类
- [Mac]extension弹出窗口的实现
- OJ-金额转换
- Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化
- Android View绘制流程
- POJ3009Curling 2.0(DFS+回溯)
- 使AFNetworking支持text/htm数据格式
- 第1次实验——NPC问题(回溯算法、聚类分析)
- $(function(){...});
- PMO工作反思