Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ include_dir = "0.7.4"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
tracing = "0.1.41"
rfd = "0.15.4"
open = "5.3.2"

[profile.dev]
opt-level = 1
Expand Down
1 change: 1 addition & 0 deletions desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ glam = { workspace = true }
vello = { workspace = true }
derivative = { workspace = true }
rfd = { workspace = true }
open = { workspace = true }
9 changes: 9 additions & 0 deletions desktop/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ impl WinitApp {
}
}

for message in responses.extract_if(.., |m| matches!(m, FrontendMessage::TriggerVisitLink { .. })) {
let _ = thread::spawn(move || {
let FrontendMessage::TriggerVisitLink { url } = message else { unreachable!() };
if let Err(e) = open::that(&url) {
tracing::error!("Failed to open URL: {}: {}", url, e);
}
});
}

if responses.is_empty() {
return;
}
Expand Down
9 changes: 5 additions & 4 deletions desktop/src/cef/internal.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
mod browser_process_app;
mod browser_process_client;
mod browser_process_handler;
mod browser_process_life_span_handler;
mod render_handler;
mod render_process_app;
mod render_process_handler;
mod render_process_v8_handler;

pub(crate) use browser_process_app::BrowserProcessAppImpl;
pub(crate) use browser_process_client::BrowserProcessClientImpl;
pub(crate) use render_handler::RenderHandlerImpl;
pub(crate) use render_process_app::RenderProcessAppImpl;
pub(super) use browser_process_app::BrowserProcessAppImpl;
pub(super) use browser_process_client::BrowserProcessClientImpl;
pub(super) use render_handler::RenderHandlerImpl;
pub(super) use render_process_app::RenderProcessAppImpl;
8 changes: 7 additions & 1 deletion desktop/src/cef/internal/browser_process_client.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use cef::rc::{Rc, RcImpl};
use cef::sys::{_cef_client_t, cef_base_ref_counted_t};
use cef::{ImplClient, RenderHandler, WrapClient};
use cef::{ImplClient, LifeSpanHandler, RenderHandler, WrapClient};

use crate::cef::CefEventHandler;
use crate::cef::ipc::{MessageType, UnpackMessage, UnpackedMessage};

use super::browser_process_life_span_handler::BrowserProcessLifeSpanHandlerImpl;

pub(crate) struct BrowserProcessClientImpl<H: CefEventHandler> {
object: *mut RcImpl<_cef_client_t, Self>,
render_handler: RenderHandler,
Expand Down Expand Up @@ -47,6 +49,10 @@ impl<H: CefEventHandler> ImplClient for BrowserProcessClientImpl<H> {
Some(self.render_handler.clone())
}

fn life_span_handler(&self) -> Option<cef::LifeSpanHandler> {
Some(LifeSpanHandler::new(BrowserProcessLifeSpanHandlerImpl::new()))
}

fn get_raw(&self) -> *mut _cef_client_t {
self.object.cast()
}
Expand Down
64 changes: 64 additions & 0 deletions desktop/src/cef/internal/browser_process_life_span_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use cef::rc::{Rc, RcImpl};
use cef::sys::{_cef_life_span_handler_t, cef_base_ref_counted_t};
use cef::{ImplLifeSpanHandler, WrapLifeSpanHandler};

pub(crate) struct BrowserProcessLifeSpanHandlerImpl {
object: *mut RcImpl<_cef_life_span_handler_t, Self>,
}
impl BrowserProcessLifeSpanHandlerImpl {
pub(crate) fn new() -> Self {
Self { object: std::ptr::null_mut() }
}
}

impl ImplLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
fn on_before_popup(
&self,
_browser: Option<&mut cef::Browser>,
_frame: Option<&mut cef::Frame>,
_popup_id: ::std::os::raw::c_int,
target_url: Option<&cef::CefString>,
_target_frame_name: Option<&cef::CefString>,
_target_disposition: cef::WindowOpenDisposition,
_user_gesture: ::std::os::raw::c_int,
_popup_features: Option<&cef::PopupFeatures>,
_window_info: Option<&mut cef::WindowInfo>,
_client: Option<&mut Option<impl cef::ImplClient>>,
_settings: Option<&mut cef::BrowserSettings>,
_extra_info: Option<&mut Option<cef::DictionaryValue>>,
_no_javascript_access: Option<&mut ::std::os::raw::c_int>,
) -> ::std::os::raw::c_int {
let target = target_url.map(|url| url.to_string()).unwrap_or("unknown".to_string());
tracing::error!("Browser tried to open a popup at URL: {}", target);

// Deny any popup by returning 1
1
}

fn get_raw(&self) -> *mut _cef_life_span_handler_t {
self.object.cast()
}
}

impl Clone for BrowserProcessLifeSpanHandlerImpl {
fn clone(&self) -> Self {
unsafe {
let rc_impl = &mut *self.object;
rc_impl.interface.add_ref();
}
Self { object: self.object }
}
}
impl Rc for BrowserProcessLifeSpanHandlerImpl {
fn as_base(&self) -> &cef_base_ref_counted_t {
unsafe {
let base = &*self.object;
std::mem::transmute(&base.cef_object)
}
}
}
impl WrapLifeSpanHandler for BrowserProcessLifeSpanHandlerImpl {
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_life_span_handler_t, Self>) {
self.object = object;
}
}
Loading