diff --git a/desktop/src/app.rs b/desktop/src/app.rs index a5573a5c..ccae307d 100644 --- a/desktop/src/app.rs +++ b/desktop/src/app.rs @@ -2,7 +2,7 @@ use crate::CustomEvent; use crate::cef::WindowSize; use crate::consts::{APP_NAME, CEF_MESSAGE_LOOP_MAX_ITERATIONS}; use crate::render::GraphicsState; -use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage}; +use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Platform}; use graphite_desktop_wrapper::{DesktopWrapper, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages}; use rfd::AsyncFileDialog; @@ -152,6 +152,15 @@ impl WinitApp { graphics_state.set_overlays_scene(scene); } } + DesktopFrontendMessage::UpdateWindowState { maximized, minimized } => { + if let Some(window) = &self.window { + window.set_maximized(maximized); + window.set_minimized(minimized); + } + } + DesktopFrontendMessage::CloseWindow => { + let _ = self.event_loop_proxy.send_event(CustomEvent::CloseWindow); + } } } @@ -223,9 +232,17 @@ impl ApplicationHandler for WinitApp { tracing::info!("Winit window created and ready"); self.desktop_wrapper.init(self.wgpu_context.clone()); + + #[cfg(target_os = "windows")] + let platform = Platform::Windows; + #[cfg(target_os = "macos")] + let platform = Platform::Mac; + #[cfg(target_os = "linux")] + let platform = Platform::Linux; + self.dispatch_desktop_wrapper_message(DesktopWrapperMessage::UpdatePlatform(platform)); } - fn user_event(&mut self, _: &ActiveEventLoop, event: CustomEvent) { + fn user_event(&mut self, event_loop: &ActiveEventLoop, event: CustomEvent) { match event { CustomEvent::WebCommunicationInitialized => { self.web_communication_initialized = true; @@ -268,6 +285,12 @@ impl ApplicationHandler for WinitApp { self.cef_schedule = Some(instant); } } + CustomEvent::CloseWindow => { + // TODO: Implement graceful shutdown + + tracing::info!("Exiting main event loop"); + event_loop.exit(); + } } } @@ -276,14 +299,12 @@ impl ApplicationHandler for WinitApp { match event { WindowEvent::CloseRequested => { - tracing::info!("The close button was pressed; stopping"); - event_loop.exit(); + let _ = self.event_loop_proxy.send_event(CustomEvent::CloseWindow); } WindowEvent::Resized(PhysicalSize { width, height }) => { let _ = self.window_size_sender.send(WindowSize::new(width as usize, height as usize)); self.cef_context.notify_of_resize(); } - WindowEvent::RedrawRequested => { let Some(ref mut graphics_state) = self.graphics_state else { return }; // Only rerender once we have a new ui texture to display diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 40234a09..944899cf 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -24,6 +24,7 @@ pub(crate) enum CustomEvent { WebCommunicationInitialized, DesktopWrapperMessage(DesktopWrapperMessage), NodeGraphExecutionResult(NodeGraphExecutionResult), + CloseWindow, } fn main() { diff --git a/desktop/wrapper/src/handle_desktop_wrapper_message.rs b/desktop/wrapper/src/handle_desktop_wrapper_message.rs index 2cc11464..250c9201 100644 --- a/desktop/wrapper/src/handle_desktop_wrapper_message.rs +++ b/desktop/wrapper/src/handle_desktop_wrapper_message.rs @@ -1,6 +1,9 @@ use graphene_std::Color; use graphene_std::raster::Image; -use graphite_editor::messages::prelude::{DocumentMessage, PortfolioMessage}; +use graphite_editor::messages::app_window::app_window_message_handler::AppWindowPlatform; +use graphite_editor::messages::prelude::{AppWindowMessage, DocumentMessage, PortfolioMessage}; + +use crate::messages::Platform; use super::DesktopWrapperMessageDispatcher; use super::messages::{DesktopFrontendMessage, DesktopWrapperMessage, EditorMessage, OpenFileDialogContext, SaveFileDialogContext}; @@ -106,5 +109,14 @@ pub(super) fn handle_desktop_wrapper_message(dispatcher: &mut DesktopWrapperMess dispatcher.queue_editor_message(message.into()); } DesktopWrapperMessage::PollNodeGraphEvaluation => dispatcher.poll_node_graph_evaluation(), + DesktopWrapperMessage::UpdatePlatform(platform) => { + let platform = match platform { + Platform::Windows => AppWindowPlatform::Windows, + Platform::Mac => AppWindowPlatform::Mac, + Platform::Linux => AppWindowPlatform::Linux, + }; + let message = AppWindowMessage::AppWindowUpdatePlatform { platform }; + dispatcher.queue_editor_message(message.into()); + } } } diff --git a/desktop/wrapper/src/intercept_frontend_message.rs b/desktop/wrapper/src/intercept_frontend_message.rs index a8f1ef0b..ed52205f 100644 --- a/desktop/wrapper/src/intercept_frontend_message.rs +++ b/desktop/wrapper/src/intercept_frontend_message.rs @@ -64,6 +64,15 @@ pub(super) fn intercept_frontend_message(dispatcher: &mut DesktopWrapperMessageD FrontendMessage::TriggerVisitLink { url } => { dispatcher.respond(DesktopFrontendMessage::OpenUrl(url)); } + FrontendMessage::UpdateWindowState { maximized, minimized } => { + dispatcher.respond(DesktopFrontendMessage::UpdateWindowState { maximized, minimized }); + + // Forward this to update the ui + return Some(message); + } + FrontendMessage::CloseWindow => { + dispatcher.respond(DesktopFrontendMessage::CloseWindow); + } m => return Some(m), } None diff --git a/desktop/wrapper/src/messages.rs b/desktop/wrapper/src/messages.rs index 0b5258ca..dae7aaaa 100644 --- a/desktop/wrapper/src/messages.rs +++ b/desktop/wrapper/src/messages.rs @@ -30,6 +30,11 @@ pub enum DesktopFrontendMessage { height: f32, }, UpdateOverlays(vello::Scene), + UpdateWindowState { + maximized: bool, + minimized: bool, + }, + CloseWindow, } pub struct FileFilter { @@ -47,6 +52,7 @@ pub enum DesktopWrapperMessage { ImportSvg { path: PathBuf, content: Vec }, ImportImage { path: PathBuf, content: Vec }, PollNodeGraphEvaluation, + UpdatePlatform(Platform), } pub enum OpenFileDialogContext { @@ -58,3 +64,9 @@ pub enum SaveFileDialogContext { Document { document_id: DocumentId, content: Vec }, File { content: Vec }, } + +pub enum Platform { + Windows, + Mac, + Linux, +} diff --git a/editor/src/messages/app_window/app_window_message.rs b/editor/src/messages/app_window/app_window_message.rs index f21c831b..d0631606 100644 --- a/editor/src/messages/app_window/app_window_message.rs +++ b/editor/src/messages/app_window/app_window_message.rs @@ -1,9 +1,12 @@ use crate::messages::prelude::*; +use super::app_window_message_handler::AppWindowPlatform; + #[impl_message(Message, AppWindow)] #[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)] pub enum AppWindowMessage { AppWindowMinimize, AppWindowMaximize, + AppWindowUpdatePlatform { platform: AppWindowPlatform }, AppWindowClose, } diff --git a/editor/src/messages/app_window/app_window_message_handler.rs b/editor/src/messages/app_window/app_window_message_handler.rs index 1b57cec6..db4036b5 100644 --- a/editor/src/messages/app_window/app_window_message_handler.rs +++ b/editor/src/messages/app_window/app_window_message_handler.rs @@ -6,34 +6,34 @@ use graphite_proc_macros::{ExtractField, message_handler_data}; pub struct AppWindowMessageHandler { platform: AppWindowPlatform, maximized: bool, - viewport_hole_punch_active: bool, + minimized: bool, } #[message_handler_data] impl MessageHandler for AppWindowMessageHandler { fn process_message(&mut self, message: AppWindowMessage, responses: &mut std::collections::VecDeque, _: ()) { match message { - AppWindowMessage::AppWindowMinimize => { - self.platform = if self.platform == AppWindowPlatform::Mac { - AppWindowPlatform::Windows - } else { - AppWindowPlatform::Mac - }; - responses.add(FrontendMessage::UpdatePlatform { platform: self.platform }); - } AppWindowMessage::AppWindowMaximize => { self.maximized = !self.maximized; - responses.add(FrontendMessage::UpdateMaximized { maximized: self.maximized }); - - self.viewport_hole_punch_active = !self.viewport_hole_punch_active; - responses.add(FrontendMessage::UpdateViewportHolePunch { - active: self.viewport_hole_punch_active, + responses.add(FrontendMessage::UpdateWindowState { + maximized: self.maximized, + minimized: self.minimized, }); } - AppWindowMessage::AppWindowClose => { - self.platform = AppWindowPlatform::Web; + AppWindowMessage::AppWindowMinimize => { + self.minimized = !self.minimized; + responses.add(FrontendMessage::UpdateWindowState { + maximized: self.maximized, + minimized: self.minimized, + }); + } + AppWindowMessage::AppWindowUpdatePlatform { platform } => { + self.platform = platform; responses.add(FrontendMessage::UpdatePlatform { platform: self.platform }); } + AppWindowMessage::AppWindowClose => { + responses.add(FrontendMessage::CloseWindow); + } } } diff --git a/editor/src/messages/frontend/frontend_message.rs b/editor/src/messages/frontend/frontend_message.rs index 50b75536..ae472d19 100644 --- a/editor/src/messages/frontend/frontend_message.rs +++ b/editor/src/messages/frontend/frontend_message.rs @@ -329,9 +329,11 @@ pub enum FrontendMessage { UpdatePlatform { platform: AppWindowPlatform, }, - UpdateMaximized { + UpdateWindowState { maximized: bool, + minimized: bool, }, + CloseWindow, UpdateViewportHolePunch { active: bool, }, diff --git a/frontend/src/messages.ts b/frontend/src/messages.ts index df4196ce..059a5e9e 100644 --- a/frontend/src/messages.ts +++ b/frontend/src/messages.ts @@ -356,10 +356,13 @@ export class UpdatePlatform extends JsMessage { readonly platform!: AppWindowPlatform; } -export class UpdateMaximized extends JsMessage { +export class UpdateWindowState extends JsMessage { readonly maximized!: boolean; + readonly minimized!: boolean; } +export class CloseWindow extends JsMessage {} + export class UpdateViewportHolePunch extends JsMessage { readonly active!: boolean; } @@ -1741,7 +1744,7 @@ export const messageMakers: Record = { UpdateLayersPanelControlBarLeftLayout, UpdateLayersPanelControlBarRightLayout, UpdateLayerWidths, - UpdateMaximized, + UpdateWindowState, UpdateMenuBarLayout, UpdateMouseCursor, UpdateNodeGraphControlBarLayout, diff --git a/frontend/src/state-providers/app-window.ts b/frontend/src/state-providers/app-window.ts index 4a022ca1..5bef32b1 100644 --- a/frontend/src/state-providers/app-window.ts +++ b/frontend/src/state-providers/app-window.ts @@ -3,7 +3,7 @@ import { writable } from "svelte/store"; import { type Editor } from "@graphite/editor"; -import { type AppWindowPlatform, UpdatePlatform, UpdateMaximized, UpdateViewportHolePunch } from "@graphite/messages"; +import { type AppWindowPlatform, UpdatePlatform, UpdateViewportHolePunch, UpdateWindowState } from "@graphite/messages"; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export function createAppWindowState(editor: Editor) { @@ -20,9 +20,9 @@ export function createAppWindowState(editor: Editor) { return state; }); }); - editor.subscriptions.subscribeJsMessage(UpdateMaximized, (maximized) => { + editor.subscriptions.subscribeJsMessage(UpdateWindowState, (updateWindowState) => { update((state) => { - state.maximized = maximized.maximized; + state.maximized = updateWindowState.maximized; return state; }); });