Skip to content

Commit 04a2452

Browse files
Desktop: Support cursor icon change (#3223)
* browser console message forwarding * replace target to make it easy to identify browser console messages * use warn as per review comment * cursor icon change * fix win build
1 parent b4be616 commit 04a2452

File tree

5 files changed

+94
-12
lines changed

5 files changed

+94
-12
lines changed

desktop/src/app.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,11 @@ impl App {
305305
self.cef_schedule = Some(instant);
306306
}
307307
}
308+
AppEvent::CursorChange(cursor) => {
309+
if let Some(window) = &self.window {
310+
window.set_cursor(cursor);
311+
}
312+
}
308313
AppEvent::CloseWindow => {
309314
// TODO: Implement graceful shutdown
310315

desktop/src/cef.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub(crate) trait CefEventHandler: Clone + Send + Sync + 'static {
4444
#[cfg(feature = "accelerated_paint")]
4545
fn draw_gpu(&self, shared_texture: SharedTextureHandle);
4646
fn load_resource(&self, path: PathBuf) -> Option<Resource>;
47+
fn cursor_change(&self, cursor: winit::cursor::Cursor);
4748
/// Schedule the main event loop to run the CEF event loop after the timeout.
4849
/// See [`_cef_browser_process_handler_t::on_schedule_message_pump_work`] for more documentation.
4950
fn schedule_cef_message_loop_work(&self, scheduled_time: Instant);
@@ -224,6 +225,10 @@ impl CefEventHandler for CefHandler {
224225
None
225226
}
226227

228+
fn cursor_change(&self, cursor: winit::cursor::Cursor) {
229+
self.app_event_scheduler.schedule(AppEvent::CursorChange(cursor));
230+
}
231+
227232
fn schedule_cef_message_loop_work(&self, scheduled_time: std::time::Instant) {
228233
self.app_event_scheduler.schedule(AppEvent::ScheduleBrowserWork(scheduled_time));
229234
}

desktop/src/cef/internal/browser_process_client.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ impl<H: CefEventHandler> BrowserProcessClientImpl<H> {
1919
Self {
2020
object: std::ptr::null_mut(),
2121
render_handler,
22-
event_handler,
23-
display_handler: DisplayHandler::new(DisplayHandlerImpl::new()),
22+
event_handler: event_handler.clone(),
23+
display_handler: DisplayHandler::new(DisplayHandlerImpl::new(event_handler)),
2424
}
2525
}
2626
}

desktop/src/cef/internal/display_handler.rs

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,86 @@
11
use cef::rc::{Rc, RcImpl};
2-
use cef::sys::{_cef_display_handler_t, cef_base_ref_counted_t, cef_log_severity_t::*};
2+
use cef::sys::{_cef_display_handler_t, cef_base_ref_counted_t, cef_cursor_type_t::*, cef_log_severity_t::*};
33
use cef::{CefString, ImplDisplayHandler, WrapDisplayHandler};
4+
use winit::cursor::CursorIcon;
45

5-
pub(crate) struct DisplayHandlerImpl {
6+
use crate::cef::CefEventHandler;
7+
8+
pub(crate) struct DisplayHandlerImpl<H: CefEventHandler> {
69
object: *mut RcImpl<_cef_display_handler_t, Self>,
10+
event_handler: H,
711
}
812

9-
impl DisplayHandlerImpl {
10-
pub fn new() -> Self {
11-
Self { object: std::ptr::null_mut() }
13+
impl<H: CefEventHandler> DisplayHandlerImpl<H> {
14+
pub fn new(event_handler: H) -> Self {
15+
Self {
16+
object: std::ptr::null_mut(),
17+
event_handler,
18+
}
1219
}
1320
}
1421

15-
impl ImplDisplayHandler for DisplayHandlerImpl {
22+
impl<H: CefEventHandler> ImplDisplayHandler for DisplayHandlerImpl<H> {
23+
fn on_cursor_change(&self, _browser: Option<&mut cef::Browser>, _cursor: cef::CursorHandle, cursor_type: cef::CursorType, _custom_cursor_info: Option<&cef::CursorInfo>) -> ::std::os::raw::c_int {
24+
let cursor = match cursor_type.into() {
25+
CT_POINTER => CursorIcon::Default,
26+
CT_CROSS => CursorIcon::Crosshair,
27+
CT_HAND => CursorIcon::Pointer,
28+
CT_IBEAM => CursorIcon::Text,
29+
CT_WAIT => CursorIcon::Wait,
30+
CT_HELP => CursorIcon::Help,
31+
CT_EASTRESIZE => CursorIcon::EResize,
32+
CT_NORTHRESIZE => CursorIcon::NResize,
33+
CT_NORTHEASTRESIZE => CursorIcon::NeResize,
34+
CT_NORTHWESTRESIZE => CursorIcon::NwResize,
35+
CT_SOUTHRESIZE => CursorIcon::SResize,
36+
CT_SOUTHEASTRESIZE => CursorIcon::SeResize,
37+
CT_SOUTHWESTRESIZE => CursorIcon::SwResize,
38+
CT_WESTRESIZE => CursorIcon::WResize,
39+
CT_NORTHSOUTHRESIZE => CursorIcon::NsResize,
40+
CT_EASTWESTRESIZE => CursorIcon::EwResize,
41+
CT_NORTHEASTSOUTHWESTRESIZE => CursorIcon::NeswResize,
42+
CT_NORTHWESTSOUTHEASTRESIZE => CursorIcon::NwseResize,
43+
CT_COLUMNRESIZE => CursorIcon::ColResize,
44+
CT_ROWRESIZE => CursorIcon::RowResize,
45+
CT_MIDDLEPANNING => CursorIcon::AllScroll,
46+
CT_EASTPANNING => CursorIcon::AllScroll,
47+
CT_NORTHPANNING => CursorIcon::AllScroll,
48+
CT_NORTHEASTPANNING => CursorIcon::AllScroll,
49+
CT_NORTHWESTPANNING => CursorIcon::AllScroll,
50+
CT_SOUTHPANNING => CursorIcon::AllScroll,
51+
CT_SOUTHEASTPANNING => CursorIcon::AllScroll,
52+
CT_SOUTHWESTPANNING => CursorIcon::AllScroll,
53+
CT_WESTPANNING => CursorIcon::AllScroll,
54+
CT_MOVE => CursorIcon::Move,
55+
CT_VERTICALTEXT => CursorIcon::VerticalText,
56+
CT_CELL => CursorIcon::Cell,
57+
CT_CONTEXTMENU => CursorIcon::ContextMenu,
58+
CT_ALIAS => CursorIcon::Alias,
59+
CT_PROGRESS => CursorIcon::Progress,
60+
CT_NODROP => CursorIcon::NoDrop,
61+
CT_COPY => CursorIcon::Copy,
62+
CT_NONE => CursorIcon::Default,
63+
CT_NOTALLOWED => CursorIcon::NotAllowed,
64+
CT_ZOOMIN => CursorIcon::ZoomIn,
65+
CT_ZOOMOUT => CursorIcon::ZoomOut,
66+
CT_GRAB => CursorIcon::Grab,
67+
CT_GRABBING => CursorIcon::Grabbing,
68+
CT_MIDDLE_PANNING_VERTICAL => CursorIcon::AllScroll,
69+
CT_MIDDLE_PANNING_HORIZONTAL => CursorIcon::AllScroll,
70+
CT_CUSTOM => CursorIcon::Default,
71+
CT_DND_NONE => CursorIcon::Default,
72+
CT_DND_MOVE => CursorIcon::Move,
73+
CT_DND_COPY => CursorIcon::Copy,
74+
CT_DND_LINK => CursorIcon::Alias,
75+
CT_NUM_VALUES => CursorIcon::Default,
76+
_ => CursorIcon::Default,
77+
};
78+
79+
self.event_handler.cursor_change(cursor.into());
80+
81+
1 // We handled the cursor change.
82+
}
83+
1684
fn on_console_message(
1785
&self,
1886
_browser: Option<&mut cef::Browser>,
@@ -41,24 +109,27 @@ impl ImplDisplayHandler for DisplayHandlerImpl {
41109
}
42110
}
43111

44-
impl Clone for DisplayHandlerImpl {
112+
impl<H: CefEventHandler> Clone for DisplayHandlerImpl<H> {
45113
fn clone(&self) -> Self {
46114
unsafe {
47115
let rc_impl = &mut *self.object;
48116
rc_impl.interface.add_ref();
49117
}
50-
Self { object: self.object }
118+
Self {
119+
object: self.object,
120+
event_handler: self.event_handler.clone(),
121+
}
51122
}
52123
}
53-
impl Rc for DisplayHandlerImpl {
124+
impl<H: CefEventHandler> Rc for DisplayHandlerImpl<H> {
54125
fn as_base(&self) -> &cef_base_ref_counted_t {
55126
unsafe {
56127
let base = &*self.object;
57128
std::mem::transmute(&base.cef_object)
58129
}
59130
}
60131
}
61-
impl WrapDisplayHandler for DisplayHandlerImpl {
132+
impl<H: CefEventHandler> WrapDisplayHandler for DisplayHandlerImpl<H> {
62133
fn wrap_rc(&mut self, object: *mut RcImpl<_cef_display_handler_t, Self>) {
63134
self.object = object;
64135
}

desktop/src/event.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use graphite_desktop_wrapper::messages::DesktopWrapperMessage;
33

44
pub(crate) enum AppEvent {
55
UiUpdate(wgpu::Texture),
6+
CursorChange(winit::cursor::Cursor),
67
ScheduleBrowserWork(std::time::Instant),
78
WebCommunicationInitialized,
89
DesktopWrapperMessage(DesktopWrapperMessage),

0 commit comments

Comments
 (0)