Skip to content

Commit f84d310

Browse files
better solution
1 parent 241642c commit f84d310

File tree

6 files changed

+80
-68
lines changed

6 files changed

+80
-68
lines changed

desktop/src/app.rs

Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,22 @@ use crate::cef;
1818
use crate::consts::CEF_MESSAGE_LOOP_MAX_ITERATIONS;
1919
use crate::event::{AppEvent, AppEventScheduler};
2020
use crate::persist::PersistentData;
21-
use crate::render::GraphicsState;
21+
use crate::render::{RenderError, RenderState};
2222
use crate::window::Window;
2323
use crate::wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Platform};
2424
use crate::wrapper::{DesktopWrapper, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages};
2525

2626
pub(crate) struct App {
27-
cef_context: Box<dyn cef::CefContext>,
27+
render_state: Option<RenderState>,
28+
wgpu_context: WgpuContext,
2829
window: Option<Window>,
2930
window_scale: f64,
30-
cef_schedule: Option<Instant>,
31-
cef_view_info_sender: Sender<cef::ViewInfoUpdate>,
32-
graphics_state: Option<GraphicsState>,
33-
wgpu_context: WgpuContext,
3431
app_event_receiver: Receiver<AppEvent>,
3532
app_event_scheduler: AppEventScheduler,
3633
desktop_wrapper: DesktopWrapper,
34+
cef_context: Box<dyn cef::CefContext>,
35+
cef_schedule: Option<Instant>,
36+
cef_view_info_sender: Sender<cef::ViewInfoUpdate>,
3737
last_ui_update: Instant,
3838
avg_frame_time: f32,
3939
start_render_sender: SyncSender<()>,
@@ -77,17 +77,17 @@ impl App {
7777
persistent_data.load_from_disk();
7878

7979
Self {
80-
cef_context,
81-
window: None,
82-
window_scale: 1.0,
83-
cef_schedule: Some(Instant::now()),
84-
graphics_state: None,
85-
cef_view_info_sender,
80+
render_state: None,
8681
wgpu_context,
82+
window: None,
83+
window_scale: 1.,
8784
app_event_receiver,
8885
app_event_scheduler,
8986
desktop_wrapper: DesktopWrapper::new(),
9087
last_ui_update: Instant::now(),
88+
cef_context,
89+
cef_schedule: Some(Instant::now()),
90+
cef_view_info_sender,
9191
avg_frame_time: 0.,
9292
start_render_sender,
9393
web_communication_initialized: false,
@@ -97,6 +97,17 @@ impl App {
9797
}
9898
}
9999

100+
fn resize_window(&mut self, width: u32, height: u32) {
101+
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Size { width, height });
102+
self.cef_context.notify_view_info_changed();
103+
if let Some(render_state) = &mut self.render_state {
104+
render_state.resize(width, height);
105+
}
106+
if let Some(window) = &self.window {
107+
window.request_redraw();
108+
}
109+
}
110+
100111
fn handle_desktop_frontend_message(&mut self, message: DesktopFrontendMessage, responses: &mut Vec<DesktopWrapperMessage>) {
101112
match message {
102113
DesktopFrontendMessage::ToWeb(messages) => {
@@ -162,23 +173,23 @@ impl App {
162173
});
163174
}
164175
DesktopFrontendMessage::UpdateViewportPhysicalBounds { x, y, width, height } => {
165-
if let Some(graphics_state) = &mut self.graphics_state
176+
if let Some(render_state) = &mut self.render_state
166177
&& let Some(window) = &self.window
167178
{
168179
let window_size = window.surface_size();
169180

170181
let viewport_offset_x = x / window_size.width as f64;
171182
let viewport_offset_y = y / window_size.height as f64;
172-
graphics_state.set_viewport_offset([viewport_offset_x as f32, viewport_offset_y as f32]);
183+
render_state.set_viewport_offset([viewport_offset_x as f32, viewport_offset_y as f32]);
173184

174185
let viewport_scale_x = if width != 0.0 { window_size.width as f64 / width } else { 1.0 };
175186
let viewport_scale_y = if height != 0.0 { window_size.height as f64 / height } else { 1.0 };
176-
graphics_state.set_viewport_scale([viewport_scale_x as f32, viewport_scale_y as f32]);
187+
render_state.set_viewport_scale([viewport_scale_x as f32, viewport_scale_y as f32]);
177188
}
178189
}
179190
DesktopFrontendMessage::UpdateOverlays(scene) => {
180-
if let Some(graphics_state) = &mut self.graphics_state {
181-
graphics_state.set_overlays_scene(scene);
191+
if let Some(render_state) = &mut self.render_state {
192+
render_state.set_overlays_scene(scene);
182193
}
183194
}
184195
DesktopFrontendMessage::PersistenceWriteDocument { id, document } => {
@@ -331,42 +342,25 @@ impl App {
331342
NodeGraphExecutionResult::HasRun(texture) => {
332343
self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::PollNodeGraphEvaluation);
333344
if let Some(texture) = texture
334-
&& let Some(graphics_state) = self.graphics_state.as_mut()
345+
&& let Some(render_state) = self.render_state.as_mut()
335346
&& let Some(window) = self.window.as_ref()
336347
{
337-
graphics_state.bind_viewport_texture(texture);
348+
render_state.bind_viewport_texture(texture);
338349
window.request_redraw();
339350
}
340351
}
341352
NodeGraphExecutionResult::NotRun => {}
342353
},
343354
AppEvent::UiUpdate(texture) => {
344-
let width = texture.width();
345-
let height = texture.height();
346-
if let Some(graphics_state) = self.graphics_state.as_mut() {
347-
graphics_state.resize(width, height);
348-
graphics_state.bind_ui_texture(texture);
355+
if let Some(render_state) = self.render_state.as_mut() {
356+
render_state.bind_ui_texture(texture);
349357
let elapsed = self.last_ui_update.elapsed().as_secs_f32();
350358
self.last_ui_update = Instant::now();
351359
if elapsed < 0.5 {
352360
self.avg_frame_time = (self.avg_frame_time * 3. + elapsed) / 4.;
353361
}
354362
}
355363
if let Some(window) = &self.window {
356-
// Workaround for missing resize events on mac
357-
// TODO: Find a cleaner solution
358-
#[cfg(target_os = "macos")]
359-
{
360-
let surface_size = window.surface_size();
361-
if width != surface_size.width || height != surface_size.height {
362-
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Size {
363-
width: surface_size.width as usize,
364-
height: surface_size.height as usize,
365-
});
366-
self.cef_context.notify_view_info_changed();
367-
}
368-
}
369-
370364
window.request_redraw();
371365
}
372366
}
@@ -405,9 +399,8 @@ impl ApplicationHandler for App {
405399

406400
self.window = Some(window);
407401

408-
let graphics_state = GraphicsState::new(self.window.as_ref().unwrap(), self.wgpu_context.clone());
409-
410-
self.graphics_state = Some(graphics_state);
402+
let render_state = RenderState::new(self.window.as_ref().unwrap(), self.wgpu_context.clone());
403+
self.render_state = Some(render_state);
411404

412405
self.desktop_wrapper.init(self.wgpu_context.clone());
413406

@@ -434,11 +427,8 @@ impl ApplicationHandler for App {
434427
self.app_event_scheduler.schedule(AppEvent::CloseWindow);
435428
}
436429
WindowEvent::SurfaceResized(PhysicalSize { width, height }) => {
437-
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Size {
438-
width: width as usize,
439-
height: height as usize,
440-
});
441-
self.cef_context.notify_view_info_changed();
430+
self.resize_window(width, height);
431+
442432
if let Some(window) = &self.window {
443433
let maximized = window.is_maximized();
444434
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(DesktopWrapperMessage::UpdateMaximized { maximized }));
@@ -450,18 +440,21 @@ impl ApplicationHandler for App {
450440
self.cef_context.notify_view_info_changed();
451441
}
452442
WindowEvent::RedrawRequested => {
453-
let Some(ref mut graphics_state) = self.graphics_state else { return };
454-
// Only rerender once we have a new UI texture to display
443+
let Some(render_state) = &mut self.render_state else { return };
455444
if let Some(window) = &self.window {
456-
match graphics_state.render(window) {
445+
match render_state.render(window) {
457446
Ok(_) => {}
458-
Err(wgpu::SurfaceError::Lost) => {
447+
Err(RenderError::OutdatedUITextureError) => {
448+
self.cef_context.notify_view_info_changed();
449+
}
450+
Err(RenderError::SurfaceError(wgpu::SurfaceError::Lost)) => {
459451
tracing::warn!("lost surface");
460452
}
461-
Err(wgpu::SurfaceError::OutOfMemory) => {
453+
Err(RenderError::SurfaceError(wgpu::SurfaceError::OutOfMemory)) => {
454+
tracing::error!("GPU out of memory");
462455
event_loop.exit();
463456
}
464-
Err(e) => tracing::error!("{:?}", e),
457+
Err(RenderError::SurfaceError(e)) => tracing::error!("Render error: {:?}", e),
465458
}
466459
let _ = self.start_render_sender.try_send(());
467460
}

desktop/src/cef.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ pub(crate) trait CefEventHandler: Send + Sync + 'static {
5555

5656
#[derive(Clone, Copy)]
5757
pub(crate) struct ViewInfo {
58-
width: usize,
59-
height: usize,
58+
width: u32,
59+
height: u32,
6060
scale: f64,
6161
}
6262
impl ViewInfo {
@@ -78,10 +78,10 @@ impl ViewInfo {
7878
pub(crate) fn zoom(&self) -> f64 {
7979
self.scale.ln() / 1.2_f64.ln()
8080
}
81-
pub(crate) fn width(&self) -> usize {
81+
pub(crate) fn width(&self) -> u32 {
8282
self.width
8383
}
84-
pub(crate) fn height(&self) -> usize {
84+
pub(crate) fn height(&self) -> u32 {
8585
self.height
8686
}
8787
}
@@ -92,7 +92,7 @@ impl Default for ViewInfo {
9292
}
9393

9494
pub(crate) enum ViewInfoUpdate {
95-
Size { width: usize, height: usize },
95+
Size { width: u32, height: u32 },
9696
Scale(f64),
9797
}
9898

desktop/src/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub(crate) const APP_NAME: &str = "Graphite";
2+
#[cfg(target_os = "linux")]
23
pub(crate) const APP_ID: &str = "rs.graphite.Graphite";
34

45
pub(crate) const APP_DIRECTORY_NAME: &str = "graphite";

desktop/src/render.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
mod frame_buffer_ref;
22
pub(crate) use frame_buffer_ref::FrameBufferRef;
33

4-
mod graphics_state;
5-
pub(crate) use graphics_state::GraphicsState;
4+
mod state;
5+
pub(crate) use state::{RenderError, RenderState};

desktop/src/render/graphics_state.rs renamed to desktop/src/render/state.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::wrapper::{Color, WgpuContext, WgpuExecutor};
44

55
#[derive(derivative::Derivative)]
66
#[derivative(Debug)]
7-
pub(crate) struct GraphicsState {
7+
pub(crate) struct RenderState {
88
surface: wgpu::Surface<'static>,
99
context: WgpuContext,
1010
executor: WgpuExecutor,
@@ -22,7 +22,7 @@ pub(crate) struct GraphicsState {
2222
overlays_scene: Option<vello::Scene>,
2323
}
2424

25-
impl GraphicsState {
25+
impl RenderState {
2626
pub(crate) fn new(window: &Window, context: WgpuContext) -> Self {
2727
let size = window.surface_size();
2828
let surface = window.create_surface(context.instance.clone());
@@ -230,12 +230,15 @@ impl GraphicsState {
230230
self.bind_overlays_texture(texture);
231231
}
232232

233-
pub(crate) fn render(&mut self, window: &Window) -> Result<(), wgpu::SurfaceError> {
233+
pub(crate) fn render(&mut self, window: &Window) -> Result<(), RenderError> {
234234
if let Some(scene) = self.overlays_scene.take() {
235235
self.render_overlays(scene);
236236
}
237237

238-
let output = self.surface.get_current_texture()?;
238+
let output = self.surface.get_current_texture().map_err(|e| RenderError::SurfaceError(e))?;
239+
let output_width = output.texture.width();
240+
let output_height = output.texture.height();
241+
239242
let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default());
240243

241244
let mut encoder = self.context.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Render Encoder") });
@@ -277,6 +280,12 @@ impl GraphicsState {
277280
window.pre_present_notify();
278281
output.present();
279282

283+
if let Some(ui_texture) = &self.ui_texture
284+
&& (output_width != ui_texture.width() || output_height != ui_texture.height())
285+
{
286+
return Err(RenderError::OutdatedUITextureError);
287+
}
288+
280289
Ok(())
281290
}
282291

@@ -312,6 +321,11 @@ impl GraphicsState {
312321
}
313322
}
314323

324+
pub(crate) enum RenderError {
325+
OutdatedUITextureError,
326+
SurfaceError(wgpu::SurfaceError),
327+
}
328+
315329
#[repr(C)]
316330
#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
317331
struct Constants {

desktop/wrapper/src/utils.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub(crate) mod menu {
33
use base64::engine::Engine;
44
use base64::engine::general_purpose::STANDARD as BASE64;
55

6-
use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, LabeledKey, LabeledShortcut};
6+
use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, LabeledKeyOrMouseMotion, LabeledShortcut};
77
use graphite_editor::messages::input_mapper::utility_types::misc::ActionShortcut;
88
use graphite_editor::messages::layout::LayoutMessage;
99
use graphite_editor::messages::tool::tool_messages::tool_prelude::{LayoutGroup, LayoutTarget, MenuListEntry, SubLayout, Widget, WidgetId};
@@ -68,9 +68,9 @@ pub(crate) mod menu {
6868
value,
6969
label,
7070
icon,
71-
shortcut_keys,
72-
children,
7371
disabled,
72+
tooltip_shortcut,
73+
children,
7474
..
7575
}: &MenuListEntry = entry;
7676
path.push(value.clone());
@@ -83,7 +83,7 @@ pub(crate) mod menu {
8383
return MenuItem::SubMenu { id, text, enabled, items };
8484
}
8585

86-
let shortcut = match shortcut_keys {
86+
let shortcut = match tooltip_shortcut {
8787
Some(ActionShortcut::Shortcut(LabeledShortcut(shortcut))) => convert_labeled_keys_to_shortcut(shortcut),
8888
_ => None,
8989
};
@@ -126,10 +126,14 @@ pub(crate) mod menu {
126126
items
127127
}
128128

129-
fn convert_labeled_keys_to_shortcut(labeled_keys: &Vec<LabeledKey>) -> Option<Shortcut> {
129+
fn convert_labeled_keys_to_shortcut(labeled_keys: &Vec<LabeledKeyOrMouseMotion>) -> Option<Shortcut> {
130130
let mut key: Option<KeyCode> = None;
131131
let mut modifiers = Modifiers::default();
132132
for labeled_key in labeled_keys {
133+
let LabeledKeyOrMouseMotion::Key(labeled_key) = labeled_key else {
134+
// Return None for shortcuts that include mouse motion because we can't show them in native menu
135+
return None;
136+
};
133137
match labeled_key.key() {
134138
Key::Shift => modifiers |= Modifiers::SHIFT,
135139
Key::Control => modifiers |= Modifiers::CONTROL,

0 commit comments

Comments
 (0)