Desktop: Hide menu bar in fullscreen mode on Mac (#3464)
hide menu bar in fullscreen mode on mac
This commit is contained in:
parent
6d852f11af
commit
7532bd7260
|
|
@ -28,6 +28,9 @@ pub(crate) struct App {
|
||||||
wgpu_context: WgpuContext,
|
wgpu_context: WgpuContext,
|
||||||
window: Option<Window>,
|
window: Option<Window>,
|
||||||
window_scale: f64,
|
window_scale: f64,
|
||||||
|
window_size: PhysicalSize<u32>,
|
||||||
|
window_maximized: bool,
|
||||||
|
window_fullscreen: bool,
|
||||||
app_event_receiver: Receiver<AppEvent>,
|
app_event_receiver: Receiver<AppEvent>,
|
||||||
app_event_scheduler: AppEventScheduler,
|
app_event_scheduler: AppEventScheduler,
|
||||||
desktop_wrapper: DesktopWrapper,
|
desktop_wrapper: DesktopWrapper,
|
||||||
|
|
@ -81,6 +84,9 @@ impl App {
|
||||||
wgpu_context,
|
wgpu_context,
|
||||||
window: None,
|
window: None,
|
||||||
window_scale: 1.,
|
window_scale: 1.,
|
||||||
|
window_size: PhysicalSize { width: 0, height: 0 },
|
||||||
|
window_maximized: false,
|
||||||
|
window_fullscreen: false,
|
||||||
app_event_receiver,
|
app_event_receiver,
|
||||||
app_event_scheduler,
|
app_event_scheduler,
|
||||||
desktop_wrapper: DesktopWrapper::new(),
|
desktop_wrapper: DesktopWrapper::new(),
|
||||||
|
|
@ -97,6 +103,56 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resize(&mut self) {
|
||||||
|
let Some(window) = &self.window else {
|
||||||
|
tracing::error!("Resize failed due to missing window");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let maximized = window.is_maximized();
|
||||||
|
if maximized != self.window_maximized {
|
||||||
|
self.window_maximized = maximized;
|
||||||
|
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(DesktopWrapperMessage::UpdateMaximized { maximized }));
|
||||||
|
}
|
||||||
|
|
||||||
|
let fullscreen = window.is_fullscreen();
|
||||||
|
if fullscreen != self.window_fullscreen {
|
||||||
|
self.window_fullscreen = fullscreen;
|
||||||
|
self.app_event_scheduler
|
||||||
|
.schedule(AppEvent::DesktopWrapperMessage(DesktopWrapperMessage::UpdateFullscreen { fullscreen }));
|
||||||
|
}
|
||||||
|
|
||||||
|
let size = window.surface_size();
|
||||||
|
let scale = window.scale_factor();
|
||||||
|
let is_new_size = size != self.window_size;
|
||||||
|
let is_new_scale = scale != self.window_scale;
|
||||||
|
|
||||||
|
if !is_new_size && !is_new_scale {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_new_size {
|
||||||
|
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Size {
|
||||||
|
width: size.width,
|
||||||
|
height: size.height,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if is_new_scale {
|
||||||
|
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Scale(scale));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.cef_context.notify_view_info_changed();
|
||||||
|
|
||||||
|
if let Some(render_state) = &mut self.render_state {
|
||||||
|
render_state.resize(size.width, size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.request_redraw();
|
||||||
|
|
||||||
|
self.window_size = size;
|
||||||
|
self.window_scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_desktop_frontend_message(&mut self, message: DesktopFrontendMessage, responses: &mut Vec<DesktopWrapperMessage>) {
|
fn handle_desktop_frontend_message(&mut self, message: DesktopFrontendMessage, responses: &mut Vec<DesktopWrapperMessage>) {
|
||||||
match message {
|
match message {
|
||||||
DesktopFrontendMessage::ToWeb(messages) => {
|
DesktopFrontendMessage::ToWeb(messages) => {
|
||||||
|
|
@ -393,22 +449,13 @@ impl App {
|
||||||
impl ApplicationHandler for App {
|
impl ApplicationHandler for App {
|
||||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||||
let window = Window::new(event_loop, self.app_event_scheduler.clone());
|
let window = Window::new(event_loop, self.app_event_scheduler.clone());
|
||||||
|
|
||||||
self.window_scale = window.scale_factor();
|
|
||||||
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Scale(self.window_scale));
|
|
||||||
|
|
||||||
// Ensures the CEF texture does not remain at 1x1 pixels until the window is resized by the user
|
|
||||||
// Affects only some Mac devices (issue found on 2023 M2 Mac Mini).
|
|
||||||
let PhysicalSize { width, height } = window.surface_size();
|
|
||||||
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Size { width, height });
|
|
||||||
|
|
||||||
self.cef_context.notify_view_info_changed();
|
|
||||||
|
|
||||||
self.window = Some(window);
|
self.window = Some(window);
|
||||||
|
|
||||||
let render_state = RenderState::new(self.window.as_ref().unwrap(), self.wgpu_context.clone());
|
let render_state = RenderState::new(self.window.as_ref().unwrap(), self.wgpu_context.clone());
|
||||||
self.render_state = Some(render_state);
|
self.render_state = Some(render_state);
|
||||||
|
|
||||||
|
self.resize();
|
||||||
|
|
||||||
self.desktop_wrapper.init(self.wgpu_context.clone());
|
self.desktop_wrapper.init(self.wgpu_context.clone());
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
|
|
@ -433,32 +480,15 @@ impl ApplicationHandler for App {
|
||||||
WindowEvent::CloseRequested => {
|
WindowEvent::CloseRequested => {
|
||||||
self.app_event_scheduler.schedule(AppEvent::CloseWindow);
|
self.app_event_scheduler.schedule(AppEvent::CloseWindow);
|
||||||
}
|
}
|
||||||
WindowEvent::SurfaceResized(PhysicalSize { width, height }) => {
|
WindowEvent::SurfaceResized(_) | WindowEvent::ScaleFactorChanged { .. } => {
|
||||||
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Size { width, height });
|
self.resize();
|
||||||
self.cef_context.notify_view_info_changed();
|
|
||||||
|
|
||||||
if let Some(render_state) = &mut self.render_state {
|
|
||||||
render_state.resize(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(window) = &self.window {
|
|
||||||
let maximized = window.is_maximized();
|
|
||||||
self.app_event_scheduler.schedule(AppEvent::DesktopWrapperMessage(DesktopWrapperMessage::UpdateMaximized { maximized }));
|
|
||||||
|
|
||||||
window.request_redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowEvent::ScaleFactorChanged { scale_factor, .. } => {
|
|
||||||
self.window_scale = scale_factor;
|
|
||||||
let _ = self.cef_view_info_sender.send(cef::ViewInfoUpdate::Scale(self.window_scale));
|
|
||||||
self.cef_context.notify_view_info_changed();
|
|
||||||
}
|
}
|
||||||
WindowEvent::RedrawRequested => {
|
WindowEvent::RedrawRequested => {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
self.resize();
|
||||||
|
|
||||||
let Some(render_state) = &mut self.render_state else { return };
|
let Some(render_state) = &mut self.render_state else { return };
|
||||||
if let Some(window) = &self.window {
|
if let Some(window) = &self.window {
|
||||||
let size = window.surface_size();
|
|
||||||
render_state.resize(size.width, size.height);
|
|
||||||
|
|
||||||
match render_state.render(window) {
|
match render_state.render(window) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(RenderError::OutdatedUITextureError) => {
|
Err(RenderError::OutdatedUITextureError) => {
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,10 @@ impl Window {
|
||||||
self.winit_window.is_maximized()
|
self.winit_window.is_maximized()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_fullscreen(&self) -> bool {
|
||||||
|
self.winit_window.fullscreen().is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn start_drag(&self) {
|
pub(crate) fn start_drag(&self) {
|
||||||
let _ = self.winit_window.drag_window();
|
let _ = self.winit_window.drag_window();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,10 @@ pub(super) fn handle_desktop_wrapper_message(dispatcher: &mut DesktopWrapperMess
|
||||||
let message = FrontendMessage::UpdateMaximized { maximized };
|
let message = FrontendMessage::UpdateMaximized { maximized };
|
||||||
dispatcher.queue_editor_message(message);
|
dispatcher.queue_editor_message(message);
|
||||||
}
|
}
|
||||||
|
DesktopWrapperMessage::UpdateFullscreen { fullscreen } => {
|
||||||
|
let message = FrontendMessage::UpdateFullscreen { fullscreen };
|
||||||
|
dispatcher.queue_editor_message(message);
|
||||||
|
}
|
||||||
DesktopWrapperMessage::LoadDocument {
|
DesktopWrapperMessage::LoadDocument {
|
||||||
id,
|
id,
|
||||||
document,
|
document,
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,9 @@ pub enum DesktopWrapperMessage {
|
||||||
UpdateMaximized {
|
UpdateMaximized {
|
||||||
maximized: bool,
|
maximized: bool,
|
||||||
},
|
},
|
||||||
|
UpdateFullscreen {
|
||||||
|
fullscreen: bool,
|
||||||
|
},
|
||||||
LoadDocument {
|
LoadDocument {
|
||||||
id: DocumentId,
|
id: DocumentId,
|
||||||
document: Document,
|
document: Document,
|
||||||
|
|
|
||||||
|
|
@ -326,6 +326,9 @@ pub enum FrontendMessage {
|
||||||
UpdateMaximized {
|
UpdateMaximized {
|
||||||
maximized: bool,
|
maximized: bool,
|
||||||
},
|
},
|
||||||
|
UpdateFullscreen {
|
||||||
|
fullscreen: bool,
|
||||||
|
},
|
||||||
UpdateViewportHolePunch {
|
UpdateViewportHolePunch {
|
||||||
active: bool,
|
active: bool,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<LayoutCol class="main-window" classes={{ "viewport-hole-punch": $appWindow.viewportHolePunch }}>
|
<LayoutCol class="main-window" classes={{ "viewport-hole-punch": $appWindow.viewportHolePunch }}>
|
||||||
<TitleBar />
|
{#if !($appWindow.platform == "Mac" && $appWindow.fullscreen)}
|
||||||
|
<TitleBar />
|
||||||
|
{/if}
|
||||||
<Workspace />
|
<Workspace />
|
||||||
<StatusBar />
|
<StatusBar />
|
||||||
{#if $dialog.visible}
|
{#if $dialog.visible}
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,10 @@ export class UpdateMaximized extends JsMessage {
|
||||||
readonly maximized!: boolean;
|
readonly maximized!: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class UpdateFullscreen extends JsMessage {
|
||||||
|
readonly fullscreen!: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class CloseWindow extends JsMessage {}
|
export class CloseWindow extends JsMessage {}
|
||||||
|
|
||||||
export class UpdateViewportHolePunch extends JsMessage {
|
export class UpdateViewportHolePunch extends JsMessage {
|
||||||
|
|
@ -1742,7 +1746,6 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||||
UpdateLayersPanelControlBarRightLayout,
|
UpdateLayersPanelControlBarRightLayout,
|
||||||
UpdateLayersPanelState,
|
UpdateLayersPanelState,
|
||||||
UpdateLayerWidths,
|
UpdateLayerWidths,
|
||||||
UpdateMaximized,
|
|
||||||
UpdateMenuBarLayout,
|
UpdateMenuBarLayout,
|
||||||
UpdateMouseCursor,
|
UpdateMouseCursor,
|
||||||
UpdateNodeGraphControlBarLayout,
|
UpdateNodeGraphControlBarLayout,
|
||||||
|
|
@ -1754,6 +1757,8 @@ export const messageMakers: Record<string, MessageMaker> = {
|
||||||
UpdateNodeThumbnail,
|
UpdateNodeThumbnail,
|
||||||
UpdateOpenDocumentsList,
|
UpdateOpenDocumentsList,
|
||||||
UpdatePlatform,
|
UpdatePlatform,
|
||||||
|
UpdateMaximized,
|
||||||
|
UpdateFullscreen,
|
||||||
UpdatePropertiesPanelLayout,
|
UpdatePropertiesPanelLayout,
|
||||||
UpdatePropertiesPanelState,
|
UpdatePropertiesPanelState,
|
||||||
UpdateStatusBarHintsLayout,
|
UpdateStatusBarHintsLayout,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
import { type Editor } from "@graphite/editor";
|
import { type Editor } from "@graphite/editor";
|
||||||
import { type AppWindowPlatform, UpdatePlatform, UpdateViewportHolePunch, UpdateMaximized as UpdateMaximized } from "@graphite/messages";
|
import { type AppWindowPlatform, UpdatePlatform, UpdateViewportHolePunch, UpdateMaximized, UpdateFullscreen } from "@graphite/messages";
|
||||||
|
|
||||||
export function createAppWindowState(editor: Editor) {
|
export function createAppWindowState(editor: Editor) {
|
||||||
const { subscribe, update } = writable({
|
const { subscribe, update } = writable({
|
||||||
platform: "Web" as AppWindowPlatform,
|
platform: "Web" as AppWindowPlatform,
|
||||||
maximized: false,
|
maximized: false,
|
||||||
|
fullscreen: false,
|
||||||
viewportHolePunch: false,
|
viewportHolePunch: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -23,6 +24,12 @@ export function createAppWindowState(editor: Editor) {
|
||||||
return state;
|
return state;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
editor.subscriptions.subscribeJsMessage(UpdateFullscreen, (updateFullscreen) => {
|
||||||
|
update((state) => {
|
||||||
|
state.fullscreen = updateFullscreen.fullscreen;
|
||||||
|
return state;
|
||||||
|
});
|
||||||
|
});
|
||||||
editor.subscriptions.subscribeJsMessage(UpdateViewportHolePunch, (viewportHolePunch) => {
|
editor.subscriptions.subscribeJsMessage(UpdateViewportHolePunch, (viewportHolePunch) => {
|
||||||
update((state) => {
|
update((state) => {
|
||||||
state.viewportHolePunch = viewportHolePunch.active;
|
state.viewportHolePunch = viewportHolePunch.active;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue