Skip to content

Commit

Permalink
Fix context menu and implement CEF app protocol. Use autoreleasepool.
Browse files Browse the repository at this point in the history
  • Loading branch information
cztomczak committed Nov 10, 2024
1 parent 292cba9 commit 3366127
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 59 deletions.
46 changes: 45 additions & 1 deletion app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,54 @@
// Project website: https://github.com/cztomczak/phpdesktop

#include "app.h"
#include "client.h"
#include "mongoose_server.h"
#include "settings.h"

#include "include/wrapper/cef_helpers.h"

void CreateMainBrowser()
{
LOG(INFO) << "Create main browser";

json_value* app_settings = Settings();
CefBrowserSettings browser_settings;

CefWindowInfo window_info;
std::string runtime_style((*app_settings)["chrome"]["runtime_style"]);
if (runtime_style == "alloy") {
window_info.runtime_style = CEF_RUNTIME_STYLE_ALLOY;
LOG(INFO) << "Runtime style: alloy";
} else if (runtime_style == "chrome") {
window_info.runtime_style = CEF_RUNTIME_STYLE_CHROME;
LOG(INFO) << "Runtime style: chrome";
} else {
LOG(WARNING) << "Invalid runtime style in settings.json: " << runtime_style;
window_info.runtime_style = CEF_RUNTIME_STYLE_ALLOY;
}

// Create window explicitilly TODO
// std::string app_icon_path((*app_settings)["main_window"]["icon"]);
// app_icon_path = GetFullPath(app_icon_path);
// bool center_on_screen = (*app_settings)["main_window"]["center_on_screen"];
// const char* title = (*Settings())["main_window"]["title"];

int default_width = static_cast<int>(
(*app_settings)["main_window"]["default_size"][0]);
int default_height = static_cast<int>(
(*app_settings)["main_window"]["default_size"][1]);
CefRect browser_rect(0, 0, default_width, default_height);
window_info.SetAsChild(nullptr, browser_rect);

CefBrowserHost::CreateBrowser(
window_info,
Client::GetInstance(),
mongoose_get_url(),
browser_settings,
nullptr,
nullptr);
}

App::App()
{
}
Expand Down Expand Up @@ -62,5 +106,5 @@ void App::OnBeforeCommandLineProcessing(const CefString& process_type,
void App::OnContextInitialized()
{
CEF_REQUIRE_UI_THREAD();
const char* title = (*Settings())["main_window"]["title"];
CreateMainBrowser();
}
23 changes: 21 additions & 2 deletions client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,26 @@ Client* Client::GetInstance() {
}
}

bool Client::IsClosing()
{
return is_closing;
}

void Client::CloseAllBrowsers(bool force_close)
{
CEF_REQUIRE_UI_THREAD();
LOG(INFO) << "Close all browsers";

if (browser_list_.empty()) {
return;
}

BrowserList::const_iterator it = browser_list_.begin();
for (; it != browser_list_.end(); ++it) {
(*it)->GetHost()->CloseBrowser(force_close);
}
}

// CefContextMenuHandler.

#define _MENU_ID_DEVTOOLS MENU_ID_USER_FIRST + 1
Expand Down Expand Up @@ -143,8 +163,7 @@ void Client::OnBeforeClose(CefRefPtr<CefBrowser> browser)

// Cookies are not flushed to disk when closing app immediately.
// Need to call FlushStore manually when browser is closing.
browser->GetHost()->GetRequestContext()->GetCookieManager(nullptr)
->FlushStore(nullptr);
browser->GetHost()->GetRequestContext()->GetCookieManager(nullptr)->FlushStore(nullptr);

// Remove from the list of existing browsers.
BrowserList::iterator bit = browser_list_.begin();
Expand Down
4 changes: 4 additions & 0 deletions client.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Client : public CefClient,

// Provide access to the single global instance of this object.
static Client* GetInstance();
bool IsClosing();
void CloseAllBrowsers(bool force_close);

// CefClient.
CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override {
Expand Down Expand Up @@ -84,6 +86,8 @@ class Client : public CefClient,
typedef std::list<CefRefPtr<CefBrowser>> BrowserList;
BrowserList browser_list_;

bool is_closing = false;

// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(Client);
};
123 changes: 68 additions & 55 deletions main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "mongoose_server.h"
#include "settings.h"

#include "include/cef_application_mac.h"
#include "include/base/cef_logging.h"
#include "include/wrapper/cef_helpers.h"
#import "include/wrapper/cef_library_loader.h"
Expand All @@ -24,47 +25,58 @@
// Globals
std::string g_cgi_env_from_argv = "";

void create_browser()
{
// The call to CreateBrowserSync cannot be in the same block scope
// as the call to CefShutdown otherwise it results in segmentation
// fault with the stack trace as seen below. Making a call to
// browser->Release() did not help.
// ----
// #0 MaybeSendDestroyedNotification () at
// ./../../chrome/browser/profiles/profile.cc:294
// #1 0x00007ffff34c74b5 in Shutdown () at
// ../../cef/libcef/browser/browser_context.cc:81
// ----
json_value* app_settings = Settings();
CefBrowserSettings browser_settings;
CefWindowInfo window_info;
std::string runtime_style((*app_settings)["chrome"]["runtime_style"]);
if (runtime_style == "alloy") {
window_info.runtime_style = CEF_RUNTIME_STYLE_ALLOY;
LOG(INFO) << "Runtime style: Alloy";
} else if (runtime_style == "chrome") {
window_info.runtime_style = CEF_RUNTIME_STYLE_CHROME;
LOG(INFO) << "Runtime style: Chrome";
} else {
LOG(WARNING) << "Invalid runtime style in settings.json: " << runtime_style;
window_info.runtime_style = CEF_RUNTIME_STYLE_ALLOY;
}
int default_width = static_cast<int>(
(*app_settings)["main_window"]["default_size"][0]);
int default_height = static_cast<int>(
(*app_settings)["main_window"]["default_size"][1]);
CefRect browser_rect(0, 0, default_width, default_height);
window_info.SetAsChild(nullptr, browser_rect);
CefRefPtr<CefBrowser> browser = CefBrowserHost::CreateBrowserSync(
window_info,
Client::GetInstance(),
mongoose_get_url(),
browser_settings,
nullptr,
nullptr);
LOG(INFO) << "Browser window handle=" << browser->GetHost()->GetWindowHandle();
@interface SharedAppDelegate : NSObject <NSApplicationDelegate>
- (void)createApplication:(id)object;
- (void)tryToTerminateApplication:(NSApplication*)app;
@end

@interface SharedApplication : NSApplication <CefAppProtocol> {
@private
BOOL handlingSendEvent_;
}
@end

@implementation SharedApplication
- (BOOL)isHandlingSendEvent {
return handlingSendEvent_;
}

- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
handlingSendEvent_ = handlingSendEvent;
}

- (void)sendEvent:(NSEvent*)event {
CefScopedSendingEvent sendingEventScoper;
[super sendEvent:event];
}

- (void)terminate:(id)sender {
SharedAppDelegate* delegate = static_cast<SharedAppDelegate*>([NSApp delegate]);
[delegate tryToTerminateApplication:self];
}
@end

@implementation SharedAppDelegate
- (void)createApplication:(id)object {
[NSApplication sharedApplication];
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:nil];
[[NSApplication sharedApplication] setDelegate:self];
}

- (void)tryToTerminateApplication:(NSApplication*)app {
Client* client = Client::GetInstance();
if (client && !client->IsClosing()) {
client->CloseAllBrowsers(false);
}
}

- (NSApplicationTerminateReply)applicationShouldTerminate:
(NSApplication*)sender {
return NSTerminateNow;
}
@end

int main(int argc, char **argv) {
// Load the CEF framework library at runtime instead of linking directly
Expand All @@ -74,6 +86,8 @@ int main(int argc, char **argv) {
return 1;
}

@autoreleasepool {

// Passing ENV variables to PHP using the --cgi-environment
// command line arg passed to app.
if (argv) {
Expand Down Expand Up @@ -221,28 +235,25 @@ int remote_debugging_port(
cef_settings.remote_debugging_port = remote_debugging_port;
}

// App implements application-level callbacks for the browser
// process.
// App implements application-level callbacks for the browser process.
CefRefPtr<App> app(new App);

[SharedApplication sharedApplication];

// Log messages created by LOG() macro will be written to debug.log
// file only after CEF was initialized. Before CEF is initialized
// all logs are only printed to console.
LOG(INFO) << "Initialize CEF";
CefInitialize(main_args, cef_settings, app.get(), nullptr);

// Create window TODO
std::string app_icon_path((*app_settings)["main_window"]["icon"]);
app_icon_path = GetFullPath(app_icon_path);
bool center_on_screen = (*app_settings)["main_window"]["center_on_screen"];
int default_width = static_cast<int>(
(*app_settings)["main_window"]["default_size"][0]);
int default_height = static_cast<int>(
(*app_settings)["main_window"]["default_size"][1]);
if (!CefInitialize(main_args, cef_settings, app.get(), nullptr)) {
LOG(ERROR) << "Failed to initialize CEF";
return 1;
}

// Create browser
LOG(INFO) << "Create browser";
create_browser();
// Create the application delegate.
NSObject* delegate = [[SharedAppDelegate alloc] init];
[delegate performSelectorOnMainThread:@selector(createApplication:)
withObject:nil
waitUntilDone:NO];

LOG(INFO) << "Run CEF message loop";
CefRunMessageLoop();
Expand All @@ -253,5 +264,7 @@ int remote_debugging_port(
LOG(INFO) << "Shutdown CEF";
CefShutdown();

} // end @autoreleasepool

return 0;
}
2 changes: 1 addition & 1 deletion settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"enable_menu": true,
"navigation": true,
"print": true,
"view_source": true,
"view_source": false,
"devtools": true
}
}
Expand Down

0 comments on commit 3366127

Please sign in to comment.