Skip to content

Commit 201d374

Browse files
use browser zoom if needed
1 parent 426c994 commit 201d374

15 files changed

+189
-62
lines changed

desktop/src/app.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl App {
182182
}
183183
DesktopFrontendMessage::DragWindow => {
184184
if let Some(window) = &self.window {
185-
let _ = window.start_drag();
185+
window.start_drag();
186186
}
187187
}
188188
DesktopFrontendMessage::CloseWindow => {
@@ -384,7 +384,7 @@ impl ApplicationHandler for App {
384384
}
385385

386386
fn window_event(&mut self, event_loop: &dyn ActiveEventLoop, _window_id: WindowId, event: WindowEvent) {
387-
self.cef_context.handle_window_event(&event, self.window_scale);
387+
self.cef_context.handle_window_event(&event);
388388

389389
match event {
390390
WindowEvent::CloseRequested => {

desktop/src/cef.rs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use texture_import::SharedTextureHandle;
3838

3939
pub(crate) use context::{CefContext, CefContextBuilder, InitError};
4040

41-
pub(crate) trait CefEventHandler: Clone + Send + Sync + 'static {
41+
pub(crate) trait CefEventHandler: Send + Sync + 'static {
4242
fn view_info(&self) -> ViewInfo;
4343
fn draw<'a>(&self, frame_buffer: FrameBufferRef<'a>);
4444
#[cfg(feature = "accelerated_paint")]
@@ -50,17 +50,26 @@ pub(crate) trait CefEventHandler: Clone + Send + Sync + 'static {
5050
fn schedule_cef_message_loop_work(&self, scheduled_time: Instant);
5151
fn initialized_web_communication(&self);
5252
fn receive_web_message(&self, message: &[u8]);
53+
fn duplicate(&self) -> Self
54+
where
55+
Self: Sized;
5356
}
5457

5558
#[derive(Clone, Copy)]
5659
pub(crate) struct ViewInfo {
5760
width: usize,
5861
height: usize,
5962
scale: f64,
63+
use_fractional: bool,
6064
}
6165
impl ViewInfo {
6266
pub(crate) fn new() -> Self {
63-
Self { width: 1, height: 1, scale: 1.0 }
67+
Self {
68+
width: 1,
69+
height: 1,
70+
scale: 1.0,
71+
use_fractional: false,
72+
}
6473
}
6574
pub(crate) fn apply_update(&mut self, update: ViewInfoUpdate) {
6675
match update {
@@ -73,15 +82,42 @@ impl ViewInfo {
7382
}
7483
_ => {}
7584
}
85+
self.use_fractional = self.use_fractional();
86+
}
87+
pub(crate) fn scale(&self) -> Option<f64> {
88+
if self.use_fractional {
89+
return None;
90+
}
91+
Some(self.scale)
7692
}
77-
pub(crate) fn scale(&self) -> f64 {
78-
self.scale
93+
pub(crate) fn zoom(&self) -> Option<f64> {
94+
if !self.use_fractional {
95+
return None;
96+
}
97+
Some(self.scale.ln() / 1.2f64.ln())
98+
}
99+
pub(crate) fn width(&self) -> usize {
100+
if self.use_fractional { self.width } else { (self.width as f64 / self.scale).round() as usize }
79101
}
80-
pub(crate) fn scaled_width(&self) -> usize {
81-
(self.width as f64 / self.scale).round() as usize
102+
pub(crate) fn height(&self) -> usize {
103+
if self.use_fractional { self.height } else { (self.height as f64 / self.scale).round() as usize }
82104
}
83-
pub(crate) fn scaled_height(&self) -> usize {
84-
(self.height as f64 / self.scale).round() as usize
105+
106+
fn use_fractional(&self) -> bool {
107+
#[cfg(not(target_os = "macos"))]
108+
{
109+
let frac_width = (self.width as f64 / self.scale) as usize;
110+
let frac_height = (self.height as f64 / self.scale) as usize;
111+
frac_width != self.width || frac_height != self.height
112+
}
113+
#[cfg(target_os = "macos")]
114+
{
115+
let int_width = (self.width as f64 / self.scale.round()) as usize;
116+
let int_height = (self.height as f64 / self.scale.round()) as usize;
117+
let frac_width = (self.width as f64 / self.scale) as usize;
118+
let frac_height = (self.height as f64 / self.scale) as usize;
119+
int_width != frac_width || int_height != frac_height
120+
}
85121
}
86122
}
87123
impl Default for ViewInfo {
@@ -116,7 +152,6 @@ impl Read for ResourceReader {
116152
}
117153
}
118154

119-
#[derive(Clone)]
120155
pub(crate) struct CefHandler {
121156
wgpu_context: WgpuContext,
122157
app_event_scheduler: AppEventScheduler,
@@ -271,6 +306,17 @@ impl CefEventHandler for CefHandler {
271306
};
272307
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(desktop_wrapper_message));
273308
}
309+
310+
fn duplicate(&self) -> Self
311+
where
312+
Self: Sized,
313+
{
314+
Self {
315+
wgpu_context: self.wgpu_context.clone(),
316+
app_event_scheduler: self.app_event_scheduler.clone(),
317+
view_info_receiver: self.view_info_receiver.clone(),
318+
}
319+
}
274320
}
275321

276322
struct ViewInfoReceiver {

desktop/src/cef/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub(crate) use builder::{CefContextBuilder, InitError};
88
pub(crate) trait CefContext {
99
fn work(&mut self);
1010

11-
fn handle_window_event(&mut self, event: &winit::event::WindowEvent, scale: f64);
11+
fn handle_window_event(&mut self, event: &winit::event::WindowEvent);
1212

1313
fn notify_view_info_changed(&self);
1414

desktop/src/cef/context/builder.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
33
use cef::args::Args;
44
use cef::sys::{CEF_API_VERSION_LAST, cef_resultcode_t};
55
use cef::{
6-
App, BrowserSettings, CefString, Client, DictionaryValue, ImplCommandLine, ImplRequestContext, RenderHandler, RequestContextSettings, SchemeHandlerFactory, Settings, WindowInfo, api_hash,
6+
App, BrowserSettings, CefString, Client, DictionaryValue, ImplCommandLine, ImplRequestContext, RequestContextSettings, SchemeHandlerFactory, Settings, WindowInfo, api_hash,
77
browser_host_create_browser_sync, execute_process,
88
};
99

@@ -13,7 +13,7 @@ use crate::cef::CefEventHandler;
1313
use crate::cef::consts::{RESOURCE_DOMAIN, RESOURCE_SCHEME};
1414
use crate::cef::dirs::create_instance_dir;
1515
use crate::cef::input::InputState;
16-
use crate::cef::internal::{BrowserProcessAppImpl, BrowserProcessClientImpl, RenderHandlerImpl, RenderProcessAppImpl, SchemeHandlerFactoryImpl};
16+
use crate::cef::internal::{BrowserProcessAppImpl, BrowserProcessClientImpl, RenderProcessAppImpl, SchemeHandlerFactoryImpl};
1717

1818
pub(crate) struct CefContextBuilder<H: CefEventHandler> {
1919
pub(crate) args: Args,
@@ -131,7 +131,7 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
131131

132132
fn initialize_inner(self, event_handler: &H, settings: Settings) -> Result<(), InitError> {
133133
// Attention! Wrapping this in an extra App is necessary, otherwise the program still compiles but segfaults
134-
let mut cef_app = App::new(BrowserProcessAppImpl::new(event_handler.clone()));
134+
let mut cef_app = App::new(BrowserProcessAppImpl::new(event_handler.duplicate()));
135135

136136
let result = cef::initialize(Some(self.args.as_main_args()), Some(&settings), Some(&mut cef_app), std::ptr::null_mut());
137137
if result != 1 {
@@ -146,8 +146,7 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
146146
}
147147

148148
fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: PathBuf, disable_gpu_acceleration: bool) -> Result<SingleThreadedCefContext, InitError> {
149-
let render_handler = RenderHandler::new(RenderHandlerImpl::new(event_handler.clone()));
150-
let mut client = Client::new(BrowserProcessClientImpl::new(render_handler, event_handler.clone()));
149+
let mut client = Client::new(BrowserProcessClientImpl::new(&event_handler));
151150

152151
#[cfg(feature = "accelerated_paint")]
153152
let use_accelerated_paint = if disable_gpu_acceleration {
@@ -180,7 +179,7 @@ fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: PathBuf, d
180179
return Err(InitError::RequestContextCreationFailed);
181180
};
182181

183-
let mut scheme_handler_factory = SchemeHandlerFactory::new(SchemeHandlerFactoryImpl::new(event_handler.clone()));
182+
let mut scheme_handler_factory = SchemeHandlerFactory::new(SchemeHandlerFactoryImpl::new(event_handler.duplicate()));
184183
incognito_request_context.clear_scheme_handler_factories();
185184
incognito_request_context.register_scheme_handler_factory(Some(&CefString::from(RESOURCE_SCHEME)), Some(&CefString::from(RESOURCE_DOMAIN)), Some(&mut scheme_handler_factory));
186185

@@ -197,6 +196,7 @@ fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: PathBuf, d
197196

198197
if let Some(browser) = browser {
199198
Ok(SingleThreadedCefContext {
199+
event_handler: Box::new(event_handler),
200200
browser,
201201
input_state: InputState::default(),
202202
instance_dir,

desktop/src/cef/context/multithreaded.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ impl CefContext for MultiThreadedCefContextProxy {
1919
// CEF handles its own message loop in multi-threaded mode
2020
}
2121

22-
fn handle_window_event(&mut self, event: &WindowEvent, scale: f64) {
22+
fn handle_window_event(&mut self, event: &WindowEvent) {
2323
let event_clone = event.clone();
2424
run_on_ui_thread(move || {
2525
CONTEXT.with(|b| {
2626
if let Some(context) = b.borrow_mut().as_mut() {
27-
context.handle_window_event(&event_clone, scale);
27+
context.handle_window_event(&event_clone);
2828
}
2929
});
3030
});

desktop/src/cef/context/singlethreaded.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use cef::{Browser, ImplBrowser};
22
use winit::event::WindowEvent;
33

4-
use crate::cef::input;
54
use crate::cef::input::InputState;
65
use crate::cef::internal::NotifyViewInfoChanged;
76
use crate::cef::ipc::{MessageType, SendMessage};
7+
use crate::cef::{CefEventHandler, input};
88

99
use super::CefContext;
1010

1111
pub(super) struct SingleThreadedCefContext {
12+
pub(super) event_handler: Box<dyn CefEventHandler>,
1213
pub(super) browser: Browser,
1314
pub(super) input_state: InputState,
1415
pub(super) instance_dir: std::path::PathBuf,
@@ -19,12 +20,13 @@ impl CefContext for SingleThreadedCefContext {
1920
cef::do_message_loop_work();
2021
}
2122

22-
fn handle_window_event(&mut self, event: &WindowEvent, scale: f64) {
23-
input::handle_window_event(&self.browser, &mut self.input_state, event, scale)
23+
fn handle_window_event(&mut self, event: &WindowEvent) {
24+
input::handle_window_event(&self.browser, &mut self.input_state, event, self.event_handler.as_ref());
2425
}
2526

2627
fn notify_view_info_changed(&self) {
27-
self.browser.host().unwrap().notify_view_info_changed();
28+
let view_info = self.event_handler.view_info();
29+
self.browser.host().unwrap().notify_view_info_changed(&view_info);
2830
}
2931

3032
fn send_web_message(&self, message: Vec<u8>) {

desktop/src/cef/input.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,22 @@ use winit::event::{ButtonSource, ElementState, MouseButton, MouseScrollDelta, Wi
77
mod keymap;
88
use keymap::{ToNativeKeycode, ToVKBits};
99

10+
use crate::cef::CefEventHandler;
11+
1012
use super::consts::{MULTICLICK_ALLOWED_TRAVEL, MULTICLICK_TIMEOUT, PINCH_ZOOM_SPEED, SCROLL_LINE_HEIGHT, SCROLL_LINE_WIDTH, SCROLL_SPEED_X, SCROLL_SPEED_Y};
1113

12-
pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputState, event: &WindowEvent, scale: f64) {
14+
pub(crate) fn handle_window_event(browser: &Browser, input_state: &mut InputState, event: &WindowEvent, event_handler: &dyn CefEventHandler) {
1315
match event {
1416
WindowEvent::PointerMoved { position, .. } | WindowEvent::PointerEntered { position, .. } => {
17+
let scale = event_handler.view_info().scale().unwrap_or(1.0);
1518
input_state.cursor_move(&position.to_logical(scale));
1619

1720
let Some(host) = browser.host() else { return };
1821
host.send_mouse_move_event(Some(&input_state.into()), 0);
1922
}
2023
WindowEvent::PointerLeft { position, .. } => {
2124
if let Some(position) = position {
25+
let scale = event_handler.view_info().scale().unwrap_or(1.0);
2226
input_state.cursor_move(&position.to_logical(scale));
2327
}
2428

desktop/src/cef/internal.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod browser_process_app;
22
mod browser_process_client;
33
mod browser_process_handler;
44
mod browser_process_life_span_handler;
5+
mod browser_process_load_handler;
56

67
mod render_process_app;
78
mod render_process_handler;
@@ -19,15 +20,19 @@ pub(super) mod task;
1920

2021
pub(super) use browser_process_app::BrowserProcessAppImpl;
2122
pub(super) use browser_process_client::BrowserProcessClientImpl;
22-
pub(super) use render_handler::RenderHandlerImpl;
2323
pub(super) use render_process_app::RenderProcessAppImpl;
2424
pub(super) use scheme_handler_factory::SchemeHandlerFactoryImpl;
2525

26+
use crate::cef::ViewInfo;
27+
2628
pub(super) trait NotifyViewInfoChanged {
27-
fn notify_view_info_changed(&self);
29+
fn notify_view_info_changed(&self, view_info: &ViewInfo);
2830
}
2931
impl<T: cef::ImplBrowserHost> NotifyViewInfoChanged for T {
30-
fn notify_view_info_changed(&self) {
32+
fn notify_view_info_changed(&self, view_info: &ViewInfo) {
33+
if let Some(zoom) = view_info.zoom() {
34+
self.set_zoom_level(zoom);
35+
}
3136
self.notify_screen_info_changed();
3237
self.was_resized();
3338
}

desktop/src/cef/internal/browser_process_app.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub(crate) struct BrowserProcessAppImpl<H: CefEventHandler> {
1313
object: *mut RcImpl<_cef_app_t, Self>,
1414
event_handler: H,
1515
}
16-
impl<H: CefEventHandler + Clone> BrowserProcessAppImpl<H> {
16+
impl<H: CefEventHandler> BrowserProcessAppImpl<H> {
1717
pub(crate) fn new(event_handler: H) -> Self {
1818
Self {
1919
object: std::ptr::null_mut(),
@@ -22,9 +22,9 @@ impl<H: CefEventHandler + Clone> BrowserProcessAppImpl<H> {
2222
}
2323
}
2424

25-
impl<H: CefEventHandler + Clone> ImplApp for BrowserProcessAppImpl<H> {
25+
impl<H: CefEventHandler> ImplApp for BrowserProcessAppImpl<H> {
2626
fn browser_process_handler(&self) -> Option<BrowserProcessHandler> {
27-
Some(BrowserProcessHandler::new(BrowserProcessHandlerImpl::new(self.event_handler.clone())))
27+
Some(BrowserProcessHandler::new(BrowserProcessHandlerImpl::new(self.event_handler.duplicate())))
2828
}
2929

3030
fn on_register_custom_schemes(&self, registrar: Option<&mut SchemeRegistrar>) {
@@ -80,15 +80,15 @@ impl<H: CefEventHandler + Clone> ImplApp for BrowserProcessAppImpl<H> {
8080
}
8181
}
8282

83-
impl<H: CefEventHandler + Clone> Clone for BrowserProcessAppImpl<H> {
83+
impl<H: CefEventHandler> Clone for BrowserProcessAppImpl<H> {
8484
fn clone(&self) -> Self {
8585
unsafe {
8686
let rc_impl = &mut *self.object;
8787
rc_impl.interface.add_ref();
8888
}
8989
Self {
9090
object: self.object,
91-
event_handler: self.event_handler.clone(),
91+
event_handler: self.event_handler.duplicate(),
9292
}
9393
}
9494
}
@@ -100,7 +100,7 @@ impl<H: CefEventHandler> Rc for BrowserProcessAppImpl<H> {
100100
}
101101
}
102102
}
103-
impl<H: CefEventHandler + Clone> WrapApp for BrowserProcessAppImpl<H> {
103+
impl<H: CefEventHandler> WrapApp for BrowserProcessAppImpl<H> {
104104
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_app_t, Self>) {
105105
self.object = object;
106106
}

0 commit comments

Comments
 (0)