дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
fix(window): show the window buttons in full screen on macOS (#2015)
Native full screen moves a window's buttons into the bar revealed with the menu bar, and a project tab shown in its group's full-screen Space has none, so the title bar's slot for them stayed empty. The title bar now draws them there while the window fills the screen: close closes that project's tab, the green button leaves full screen, and minimize is disabled.
Цей коміт міститься в:
1 джерело
257fb0f50f
коміт
429b8f0efe
16 files changed
+205
-7
No files matched your search
@@ -431,6 +431,7 @@ pub fn builder() -> tauri_specta::Builder<tauri::Wry> {
|
||||
window::window_toggle_fullscreen,
|
||||
window::window_flash_taskbar,
|
||||
window::window_set_titlebar_height,
|
||||
window::window_is_fullscreen,
|
||||
window_drag::window_start_drag,
|
||||
window::window_take_launch,
|
||||
window::window_close_context,
|
||||
|
||||
@@ -193,6 +193,20 @@ pub fn window_open_projects(
|
||||
.collect())
|
||||
}
|
||||
|
||||
/// Whether this window fills the screen: in native full screen, or (macOS) shown in its window
|
||||
/// group's full-screen Space.
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub fn window_is_fullscreen(window: WebviewWindow) -> bool {
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
use tauri::Manager;
|
||||
crate::window_groups::in_fullscreen(window.app_handle(), &window)
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
window.is_fullscreen().unwrap_or(false)
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Type)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CloseContext {
|
||||
|
||||
@@ -135,6 +135,7 @@ pub fn set_fullscreen_auxiliary(window: &WebviewWindow, host: Option<&WebviewWin
|
||||
if let Some(frame) = frame {
|
||||
native.setFrame_display(frame, true);
|
||||
}
|
||||
target.state::<crate::state::AppState>().sink.emit(ide_core::IdeEvent::WindowFullscreenChanged);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -12,11 +12,12 @@ use objc2::{
|
||||
runtime::ProtocolObject,
|
||||
};
|
||||
use objc2_app_kit::{
|
||||
NSToolbar, NSWindow, NSWindowDidExitFullScreenNotification, NSWindowStyleMask, NSWindowToolbarStyle,
|
||||
NSWindowWillEnterFullScreenNotification,
|
||||
NSToolbar, NSWindow, NSWindowDidEnterFullScreenNotification, NSWindowDidExitFullScreenNotification,
|
||||
NSWindowStyleMask, NSWindowToolbarStyle, NSWindowWillEnterFullScreenNotification,
|
||||
};
|
||||
use objc2_foundation::{NSNotificationCenter, NSObjectProtocol};
|
||||
use std::{cell::Cell, cell::RefCell, collections::HashMap, rc::Rc};
|
||||
use tauri::Manager;
|
||||
|
||||
/// Unified compact (38pt) and unified (52pt) toolbars; pick the one closer to the web bar.
|
||||
const COMPACT_MAX_HEIGHT: f64 = 45.0;
|
||||
@@ -55,7 +56,7 @@ impl Drop for Observer {
|
||||
|
||||
struct Tracked {
|
||||
state: Rc<Fullscreen>,
|
||||
_observers: [Observer; 2],
|
||||
_observers: [Observer; 3],
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
@@ -71,7 +72,7 @@ fn apply(window: &NSWindow, state: &Fullscreen) {
|
||||
}
|
||||
}
|
||||
|
||||
fn track(window: &NSWindow) -> Tracked {
|
||||
fn track(window: &NSWindow, app: &tauri::AppHandle) -> Tracked {
|
||||
let state = Rc::new(Fullscreen::default());
|
||||
if window.styleMask().contains(NSWindowStyleMask::FullScreen) {
|
||||
state.will_enter();
|
||||
@@ -79,11 +80,14 @@ fn track(window: &NSWindow) -> Tracked {
|
||||
let observe = |name, change: fn(&Fullscreen)| {
|
||||
let weak = Weak::new(window);
|
||||
let state = state.clone();
|
||||
let app = app.clone();
|
||||
let block = block2::RcBlock::new(move |_| {
|
||||
change(&state);
|
||||
if let Some(window) = weak.load() {
|
||||
apply(&window, &state);
|
||||
}
|
||||
// The web title bar shows the window buttons itself in full screen.
|
||||
app.state::<crate::state::AppState>().sink.emit(ide_core::IdeEvent::WindowFullscreenChanged);
|
||||
});
|
||||
let observer = unsafe {
|
||||
NSNotificationCenter::defaultCenter().addObserverForName_object_queue_usingBlock(
|
||||
@@ -98,6 +102,7 @@ fn track(window: &NSWindow) -> Tracked {
|
||||
let observers = unsafe {
|
||||
[
|
||||
observe(NSWindowWillEnterFullScreenNotification, Fullscreen::will_enter),
|
||||
observe(NSWindowDidEnterFullScreenNotification, Fullscreen::will_enter),
|
||||
observe(NSWindowDidExitFullScreenNotification, Fullscreen::did_exit),
|
||||
]
|
||||
};
|
||||
@@ -106,12 +111,13 @@ fn track(window: &NSWindow) -> Tracked {
|
||||
|
||||
pub fn set_height(window: &tauri::WebviewWindow, height: f64) -> tauri::Result<()> {
|
||||
let label = window.label().to_owned();
|
||||
let app = window.app_handle().clone();
|
||||
// with_webview runs on the AppKit thread.
|
||||
window.with_webview(move |webview| unsafe {
|
||||
let Some(mtm) = MainThreadMarker::new() else { return };
|
||||
let native = &*webview.ns_window().cast::<NSWindow>();
|
||||
let state =
|
||||
WINDOWS.with_borrow_mut(|windows| windows.entry(label).or_insert_with(|| track(native)).state.clone());
|
||||
let state = WINDOWS
|
||||
.with_borrow_mut(|windows| windows.entry(label).or_insert_with(|| track(native, &app)).state.clone());
|
||||
if native.toolbar().is_none() {
|
||||
let toolbar = NSToolbar::new(mtm);
|
||||
native.setToolbar(Some(&toolbar));
|
||||
|
||||
Reference in new issue
Заблокувати користувача