gpui-component/crates/wef/cpp/client.h
2025-06-18 10:46:55 +08:00

291 lines
12 KiB
C++

#pragma once
#if defined(_WIN32) || defined(_WIN64)
#define NOMINMAX
#endif
#include <iostream>
#include <limits>
#include <memory>
#include <optional>
#include "browser_callbacks.h"
#include "frame.h"
#include "include/cef_browser.h"
#include "include/cef_client.h"
#include "include/wrapper/cef_message_router.h"
#include "utils.h"
struct WefBrowser;
enum class BrowserState {
Creating,
Created,
Closing,
Closed,
};
class BrowserCallbacksTarget {
private:
bool disable_;
BrowserCallbacks callbacks_;
void* userdata_;
DestroyFn destroy_userdata_;
public:
BrowserCallbacksTarget(BrowserCallbacks callbacks, void* userdata,
DestroyFn destroy_userdata)
: disable_(false),
callbacks_(callbacks),
userdata_(userdata),
destroy_userdata_(destroy_userdata) {}
BrowserCallbacksTarget(const BrowserCallbacksTarget& other) = delete;
BrowserCallbacksTarget& operator=(const BrowserCallbacksTarget& other) =
delete;
BrowserCallbacksTarget(BrowserCallbacksTarget&& other)
: disable_(other.disable_),
callbacks_(std::move(other.callbacks_)),
userdata_(other.userdata_),
destroy_userdata_(other.destroy_userdata_) {
other.disable_ = true;
other.userdata_ = nullptr;
other.destroy_userdata_ = nullptr;
}
~BrowserCallbacksTarget() {
if (destroy_userdata_) {
destroy_userdata_(userdata_);
}
}
void disable() { disable_ = true; }
template <typename Callable>
void call(Callable func) const {
if (disable_) {
return;
}
func(callbacks_, userdata_);
}
};
struct BrowserSharedState {
bool focus;
int cursorX, cursorY;
BrowserState browser_state;
std::optional<CefRefPtr<CefBrowser>> browser;
int width, height;
float device_scale_factor;
BrowserCallbacksTarget callbacks_target;
BrowserSharedState(BrowserCallbacksTarget&& other)
: focus(false),
cursorX(0),
cursorY(0),
browser_state(BrowserState::Creating),
width(800),
height(600),
device_scale_factor(1.0f),
callbacks_target(std::move(other)) {}
BrowserSharedState(const BrowserSharedState& other) = delete;
BrowserSharedState& operator=(const BrowserSharedState& other) = delete;
};
class WefClient : public CefClient,
public CefRenderHandler,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefDialogHandler,
public CefFindHandler,
public CefContextMenuHandler,
public CefRequestHandler,
public CefJSDialogHandler,
public CefFocusHandler,
public CefPermissionHandler,
public CefMessageRouterBrowserSide::Handler {
IMPLEMENT_REFCOUNTING(WefClient);
private:
std::shared_ptr<BrowserSharedState> state_;
CefRefPtr<CefMessageRouterBrowserSide> message_router_;
public:
WefClient(std::shared_ptr<BrowserSharedState> state);
virtual ~WefClient();
/////////////////////////////////////////////////////////////////
// CefClient methods
/////////////////////////////////////////////////////////////////
bool GetScreenInfo(CefRefPtr<CefBrowser> browser,
CefScreenInfo& screen_info) override {
screen_info.device_scale_factor = state_->device_scale_factor;
return true;
}
void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) override {
rect.Set(0, 0,
static_cast<int>(static_cast<float>(state_->width) /
state_->device_scale_factor),
static_cast<int>(static_cast<float>(state_->height) /
state_->device_scale_factor));
}
CefRefPtr<CefRenderHandler> GetRenderHandler() override { return this; }
CefRefPtr<CefDisplayHandler> GetDisplayHandler() override { return this; }
CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }
CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; }
CefRefPtr<CefDialogHandler> GetDialogHandler() override { return this; }
CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override {
return this;
}
CefRefPtr<CefFindHandler> GetFindHandler() override { return this; }
CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override { return this; }
CefRefPtr<CefFocusHandler> GetFocusHandler() override { return this; }
CefRefPtr<CefPermissionHandler> GetPermissionHandler() override {
return this;
}
bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) override {
return message_router_->OnProcessMessageReceived(browser, frame,
source_process, message);
}
/////////////////////////////////////////////////////////////////
// CefRenderHandler methods
/////////////////////////////////////////////////////////////////
void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) override;
void OnPopupSize(CefRefPtr<CefBrowser> browser, const CefRect& rect) override;
void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type,
const RectList& dirtyRects, const void* buffer, int width,
int height) override;
void OnImeCompositionRangeChanged(CefRefPtr<CefBrowser> browser,
const CefRange& selected_range,
const RectList& character_bounds) override;
bool OnCursorChange(CefRefPtr<CefBrowser> browser, CefCursorHandle cursor,
cef_cursor_type_t type,
const CefCursorInfo& custom_cursor_info) override;
/////////////////////////////////////////////////////////////////
// CefDisplayHandler methods
/////////////////////////////////////////////////////////////////
void OnAddressChange(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
const CefString& url) override;
void OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) override;
void OnFaviconURLChange(CefRefPtr<CefBrowser> browser,
const std::vector<CefString>& icon_urls) override;
bool OnTooltip(CefRefPtr<CefBrowser> browser, CefString& text) override;
void OnStatusMessage(CefRefPtr<CefBrowser> browser,
const CefString& value) override;
bool OnConsoleMessage(CefRefPtr<CefBrowser> browser, cef_log_severity_t level,
const CefString& message, const CefString& source,
int line) override;
void OnLoadingProgressChange(CefRefPtr<CefBrowser> browser,
double progress) override;
/////////////////////////////////////////////////////////////////
// CefLifeSpanHandler methods
/////////////////////////////////////////////////////////////////
void OnAfterCreated(CefRefPtr<CefBrowser> browser) override;
bool OnBeforePopup(
CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int popup_id,
const CefString& target_url, const CefString& target_frame_name,
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
bool user_gesture, const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo, CefRefPtr<CefClient>& client,
CefBrowserSettings& settings, CefRefPtr<CefDictionaryValue>& extra_info,
bool* no_javascript_access) override;
bool DoClose(CefRefPtr<CefBrowser> browser) override;
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override;
/////////////////////////////////////////////////////////////////
// CefLoadHandler methods
/////////////////////////////////////////////////////////////////
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser, bool isLoading,
bool canGoBack, bool canGoForward) override;
void OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
TransitionType transition_type) override;
void OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
int httpStatusCode) override;
void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
ErrorCode errorCode, const CefString& errorText,
const CefString& failedUrl) override;
/////////////////////////////////////////////////////////////////
// CefDialogHandler methods
/////////////////////////////////////////////////////////////////
bool OnFileDialog(CefRefPtr<CefBrowser> browser, FileDialogMode mode,
const CefString& title, const CefString& default_file_path,
const std::vector<CefString>& accept_filters,
const std::vector<CefString>& accept_extensions,
const std::vector<CefString>& accept_descriptions,
CefRefPtr<CefFileDialogCallback> callback) override;
/////////////////////////////////////////////////////////////////
// CefContextMenuHandler methods
/////////////////////////////////////////////////////////////////
bool RunContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
CefRefPtr<CefMenuModel> model,
CefRefPtr<CefRunContextMenuCallback> callback) override;
/////////////////////////////////////////////////////////////////
// CefFindHandler methods
/////////////////////////////////////////////////////////////////
void OnFindResult(CefRefPtr<CefBrowser> browser, int identifier, int count,
const CefRect& selectionRect, int activeMatchOrdinal,
bool finalUpdate) override;
/////////////////////////////////////////////////////////////////
// CefJSDialogHandler methods
/////////////////////////////////////////////////////////////////
bool OnJSDialog(CefRefPtr<CefBrowser> browser, const CefString& origin_url,
JSDialogType dialog_type, const CefString& message_text,
const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback,
bool& suppress_message) override;
bool OnBeforeUnloadDialog(CefRefPtr<CefBrowser> browser,
const CefString& message_text, bool is_reload,
CefRefPtr<CefJSDialogCallback> callback) override;
/////////////////////////////////////////////////////////////////
// CefRequestHandler methods
/////////////////////////////////////////////////////////////////
void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser,
TerminationStatus status, int error_code,
const CefString& error_string) override;
bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request, bool user_gesture,
bool is_redirect) override;
/////////////////////////////////////////////////////////////////
// CefFocusHandler methods
/////////////////////////////////////////////////////////////////
void OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next) override;
bool OnSetFocus(CefRefPtr<CefBrowser> browser, FocusSource source) override;
/////////////////////////////////////////////////////////////////
// CefPermissionHandler methods
/////////////////////////////////////////////////////////////////
bool OnRequestMediaAccessPermission(
CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
const CefString& requesting_origin, uint32_t requested_permissions,
CefRefPtr<CefMediaAccessCallback> callback) override;
/////////////////////////////////////////////////////////////////
// CefMessageRouterBrowserSide::Handler methods
/////////////////////////////////////////////////////////////////
bool OnQuery(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
int64_t query_id, const CefString& request, bool persistent,
CefRefPtr<CefMessageRouterBrowserSide::Handler::Callback>
callback) override;
};