browser/browser_view_delegate: initial commit

This commit is contained in:
Adam
2023-03-13 19:28:15 +00:00
parent fe5664211c
commit 3f1f3bcbf5
2 changed files with 193 additions and 0 deletions

View File

@@ -0,0 +1,167 @@
#include "browser_view_delegate.hxx"
#include "include/capi/views/cef_browser_view_capi.h"
#include "include/capi/views/cef_view_capi.h"
cef_size_t CEF_CALLBACK get_preferred_size(cef_view_delegate_t*, cef_view_t*);
cef_size_t CEF_CALLBACK get_minimum_size(cef_view_delegate_t*, cef_view_t*);
cef_size_t CEF_CALLBACK get_maximum_size(cef_view_delegate_t*, cef_view_t*);
int CEF_CALLBACK get_height_for_width(cef_view_delegate_t*, cef_view_t*, int);
void CEF_CALLBACK on_parent_view_changed(cef_view_delegate_t*, cef_view_t*, int, cef_view_t*);
void CEF_CALLBACK on_child_view_changed(cef_view_delegate_t*, cef_view_t*, int, cef_view_t*);
void CEF_CALLBACK on_window_changed(cef_view_delegate_t*, cef_view_t*, int);
void CEF_CALLBACK on_layout_changed(cef_view_delegate_t*, cef_view_t*, const cef_rect_t*);
void CEF_CALLBACK on_focus(cef_view_delegate_t*, cef_view_t*);
void CEF_CALLBACK on_blur(cef_view_delegate_t*, cef_view_t*);
void CEF_CALLBACK on_browser_created(cef_browser_view_delegate_t*, cef_browser_view_t*, cef_browser_t*);
void CEF_CALLBACK on_browser_destroyed(cef_browser_view_delegate_t*, cef_browser_view_t*, cef_browser_t*);
cef_browser_view_delegate_t* CEF_CALLBACK get_delegate_for_popup_browser_view(cef_browser_view_delegate_t*, cef_browser_view_t*, const cef_browser_settings_t*, cef_client_t*, int);
int CEF_CALLBACK on_popup_browser_view_created(cef_browser_view_delegate_t*, cef_browser_view_t*, cef_browser_view_t*, int);
cef_chrome_toolbar_type_t CEF_CALLBACK get_chrome_toolbar_type(cef_browser_view_delegate_t*);
namespace BrowserViewDelegate {
Browser::BrowserViewDelegate* resolve(cef_browser_view_delegate_t* delegate) {
return reinterpret_cast<Browser::BrowserViewDelegate*>(reinterpret_cast<uintptr_t>(delegate) - offsetof(Browser::BrowserViewDelegate, cef_delegate));
}
Browser::BrowserViewDelegate* resolve_view(cef_view_delegate_t* view_delegate) {
auto offset = offsetof(Browser::BrowserViewDelegate, cef_delegate) + offsetof(cef_browser_view_delegate_t, base);
return reinterpret_cast<Browser::BrowserViewDelegate*>(reinterpret_cast<uintptr_t>(view_delegate) - offset);
}
Browser::BrowserViewDelegate* resolve_base(cef_base_ref_counted_t* base) {
auto offset = offsetof(Browser::BrowserViewDelegate, cef_delegate) + offsetof(cef_browser_view_delegate_t, base) + offsetof(cef_view_delegate_t, base);
return reinterpret_cast<Browser::BrowserViewDelegate*>(reinterpret_cast<uintptr_t>(base) - offset);
}
void CEF_CALLBACK add_ref(cef_base_ref_counted_t* delegate) {
resolve_base(delegate)->add_ref();
}
int CEF_CALLBACK release(cef_base_ref_counted_t* delegate) {
return resolve_base(delegate)->release();
}
int CEF_CALLBACK has_one_ref(cef_base_ref_counted_t* delegate) {
return (resolve_base(delegate)->refcount == 1) ? 1 : 0;
}
int CEF_CALLBACK has_any_refs(cef_base_ref_counted_t* app) {
return (resolve_base(app)->refcount >= 1) ? 1 : 0;
}
}
Browser::BrowserViewDelegate::BrowserViewDelegate(Browser::Details details): details(details) {
this->cef_delegate.base.base.size = sizeof(cef_browser_view_delegate_t);
this->cef_delegate.base.base.add_ref = ::BrowserViewDelegate::add_ref;
this->cef_delegate.base.base.release = ::BrowserViewDelegate::release;
this->cef_delegate.base.base.has_one_ref = ::BrowserViewDelegate::has_one_ref;
this->cef_delegate.base.base.has_at_least_one_ref = ::BrowserViewDelegate::has_any_refs;
this->cef_delegate.base.get_preferred_size = ::get_preferred_size;
this->cef_delegate.base.get_minimum_size = ::get_minimum_size;
this->cef_delegate.base.get_maximum_size = ::get_maximum_size;
this->cef_delegate.base.get_height_for_width = ::get_height_for_width;
this->cef_delegate.base.on_parent_view_changed = ::on_parent_view_changed;
this->cef_delegate.base.on_child_view_changed = ::on_child_view_changed;
this->cef_delegate.base.on_window_changed = ::on_window_changed;
this->cef_delegate.base.on_layout_changed = ::on_layout_changed;
this->cef_delegate.base.on_focus = ::on_focus;
this->cef_delegate.base.on_blur = ::on_blur;
this->cef_delegate.on_browser_created = ::on_browser_created;
this->cef_delegate.on_browser_destroyed = ::on_browser_destroyed;
this->cef_delegate.get_delegate_for_popup_browser_view = ::get_delegate_for_popup_browser_view;
this->cef_delegate.on_popup_browser_view_created = ::on_popup_browser_view_created;
this->cef_delegate.get_chrome_toolbar_type = ::get_chrome_toolbar_type;
this->refcount = 1;
}
void Browser::BrowserViewDelegate::add_ref() {
this->refcount += 1;
}
int Browser::BrowserViewDelegate::release() {
// Since this->refcount is atomic, the operation of decrementing it and checking if the result
// is 0 must only access the value once. Accessing it twice would cause a race condition.
if (--this->refcount == 0) {
this->destroy();
return 1;
}
return 0;
}
void Browser::BrowserViewDelegate::destroy() {
// Any self-cleanup should be done here
}
cef_browser_view_delegate_t* Browser::BrowserViewDelegate::delegate() {
this->add_ref();
return &this->cef_delegate;
}
cef_size_t CEF_CALLBACK get_preferred_size(cef_view_delegate_t* delegate, cef_view_t*) {
Browser::BrowserViewDelegate* self = BrowserViewDelegate::resolve_view(delegate);
return cef_size_t { .width = self->details.preferred_width, .height = self->details.preferred_height };
}
cef_size_t CEF_CALLBACK get_minimum_size(cef_view_delegate_t* delegate, cef_view_t*) {
Browser::BrowserViewDelegate* self = BrowserViewDelegate::resolve_view(delegate);
return cef_size_t { .width = self->details.min_width, .height = self->details.min_height };
}
cef_size_t CEF_CALLBACK get_maximum_size(cef_view_delegate_t* delegate, cef_view_t*) {
Browser::BrowserViewDelegate* self = BrowserViewDelegate::resolve_view(delegate);
return cef_size_t { .width = self->details.max_width, .height = self->details.max_height };
}
int CEF_CALLBACK get_height_for_width(cef_view_delegate_t* delegate, cef_view_t*, int) {
return BrowserViewDelegate::resolve_view(delegate)->details.preferred_height;
}
void CEF_CALLBACK on_parent_view_changed(cef_view_delegate_t*, cef_view_t*, int, cef_view_t*) {
}
void CEF_CALLBACK on_child_view_changed(cef_view_delegate_t*, cef_view_t*, int, cef_view_t*) {
}
void CEF_CALLBACK on_window_changed(cef_view_delegate_t*, cef_view_t*, int) {
}
void CEF_CALLBACK on_layout_changed(cef_view_delegate_t*, cef_view_t*, const cef_rect_t*) {
}
void CEF_CALLBACK on_focus(cef_view_delegate_t*, cef_view_t*) {
}
void CEF_CALLBACK on_blur(cef_view_delegate_t*, cef_view_t*) {
}
void CEF_CALLBACK on_browser_created(cef_browser_view_delegate_t*, cef_browser_view_t*, cef_browser_t*) {
}
void CEF_CALLBACK on_browser_destroyed(cef_browser_view_delegate_t*, cef_browser_view_t*, cef_browser_t*) {
}
cef_browser_view_delegate_t* CEF_CALLBACK get_delegate_for_popup_browser_view(
cef_browser_view_delegate_t* self,
cef_browser_view_t*,
const cef_browser_settings_t*,
cef_client_t*,
int
) {
return self;
}
int CEF_CALLBACK on_popup_browser_view_created(cef_browser_view_delegate_t*, cef_browser_view_t*, cef_browser_view_t*, int) {
return false;
}
cef_chrome_toolbar_type_t CEF_CALLBACK get_chrome_toolbar_type(cef_browser_view_delegate_t*) {
return CEF_CTT_NONE;
}

View File

@@ -0,0 +1,26 @@
#ifndef _BOLT_BROWSER_VIEW_DELEGATE_HXX_
#define _BOLT_BROWSER_VIEW_DELEGATE_HXX_
#include <atomic>
#include "include/capi/views/cef_browser_view_delegate_capi.h"
#include "details.hxx"
namespace Browser {
struct BrowserViewDelegate {
cef_browser_view_delegate_t cef_delegate;
std::atomic_ulong refcount;
const Details details;
BrowserViewDelegate(Details);
void add_ref();
int release();
void destroy();
cef_browser_view_delegate_t* delegate();
BrowserViewDelegate(const BrowserViewDelegate&) = delete;
BrowserViewDelegate& operator=(const BrowserViewDelegate&) = delete;
};
}
#endif