-
-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathmacos.rs
More file actions
169 lines (142 loc) · 6.19 KB
/
macos.rs
File metadata and controls
169 lines (142 loc) · 6.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#![allow(deprecated)]
use tauri::{AppHandle, LogicalPosition, Manager, Monitor, PhysicalSize, Position, WebviewWindow};
#[cfg(target_os = "macos")]
use tauri::Runtime;
use crate::appstate::AppState;
use crate::window_manager::{WindowManager, NEW_UI_WINDOW_ID, OLD_UI_WINDOW_ID};
#[cfg(target_os = "macos")]
use cocoa::{
appkit::{NSView, NSWindow, NSWindowButton, NSWindowStyleMask, NSWindowTitleVisibility},
base::id,
};
#[cfg(target_os = "macos")]
use objc::{msg_send, sel, sel_impl};
#[cfg(target_os = "macos")]
pub fn enable_rounded_corners<R: Runtime>(window: WebviewWindow<R>) -> Result<(), String> {
window
.with_webview(move |webview| {
unsafe {
let ns_window = webview.ns_window() as id;
let mut style_mask = ns_window.styleMask();
// Add necessary styles for rounded corners
style_mask |= NSWindowStyleMask::NSFullSizeContentViewWindowMask;
style_mask |= NSWindowStyleMask::NSTitledWindowMask;
style_mask |= NSWindowStyleMask::NSClosableWindowMask;
style_mask |= NSWindowStyleMask::NSMiniaturizableWindowMask;
style_mask |= NSWindowStyleMask::NSResizableWindowMask;
ns_window.setStyleMask_(style_mask);
ns_window.setTitlebarAppearsTransparent_(cocoa::base::YES);
// Hide the window title
ns_window.setTitleVisibility_(NSWindowTitleVisibility::NSWindowTitleHidden);
// Hide the standard window buttons (close, minimize, zoom)
let close_button =
ns_window.standardWindowButton_(NSWindowButton::NSWindowCloseButton);
if !close_button.is_null() {
let _: () = msg_send![close_button, setHidden: cocoa::base::YES];
}
let miniaturize_button =
ns_window.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton);
if !miniaturize_button.is_null() {
let _: () = msg_send![miniaturize_button, setHidden: cocoa::base::YES];
}
let zoom_button =
ns_window.standardWindowButton_(NSWindowButton::NSWindowZoomButton);
if !zoom_button.is_null() {
let _: () = msg_send![zoom_button, setHidden: cocoa::base::YES];
}
let content_view = ns_window.contentView();
content_view.setWantsLayer(cocoa::base::YES);
}
})
.map_err(|e| e.to_string())
}
/// Try to get monitor at the given position, with a fall back to primary monitor, and then to the
/// first one on the list of available monitors.
fn get_monitor_for_position(app: &AppHandle, x: f64, y: f64) -> Option<Monitor> {
if let Ok(Some(monitor)) = app.monitor_from_point(x, y) {
return Some(monitor);
}
if let Ok(Some(monitor)) = app.primary_monitor() {
return Some(monitor);
}
// On macOS, it seems this is the only working method (as of Tauri 2.11), but fortunately it
// returns the current monitor as the first one.
if let Ok(mut monitors) = app.available_monitors() {
monitors.pop()
} else {
None
}
}
fn get_tray_window_position(
app: &AppHandle,
size: PhysicalSize<u32>,
) -> Option<LogicalPosition<f64>> {
let app_state = app.state::<AppState>();
let tray_click_position = app_state.tray_click_position.lock().unwrap().to_owned();
if let Some(tray_position) = tray_click_position {
let monitor = get_monitor_for_position(app, tray_position.x, tray_position.y)?;
let scale_factor = monitor.scale_factor();
let monitor_position = monitor.position().to_logical::<f64>(scale_factor);
let monitor_size = monitor.size().to_logical::<f64>(scale_factor);
let tray_position = tray_position.to_logical::<f64>(scale_factor);
let window_size = size.to_logical::<f64>(scale_factor);
let mut x = tray_position.x;
let mut y = tray_position.y;
x = x.clamp(
monitor_position.x,
monitor_position.x + monitor_size.width - window_size.width,
);
y = y.clamp(
monitor_position.y,
monitor_position.y + monitor_size.height - window_size.height,
);
Some(LogicalPosition::new(x, y))
} else {
let monitor = app.primary_monitor().ok().flatten()?;
let scale_factor = monitor.scale_factor();
let monitor_position = monitor.position().to_logical::<f64>(scale_factor);
let monitor_size = monitor.size().to_logical::<f64>(scale_factor);
let window_size = size.to_logical::<f64>(scale_factor);
let gap = crate::window_manager::WINDOW_GAP;
let x = monitor_position.x + monitor_size.width - window_size.width - gap;
let y = monitor_position.y + gap;
Some(LogicalPosition::new(x, y))
}
}
fn position_window_near_tray(app: &AppHandle, window: &WebviewWindow) {
let size = window.outer_size().unwrap_or_default();
if let Some(position) = get_tray_window_position(app, size) {
if let Err(err) = window.set_position(Position::Logical(position)) {
warn!("Failed to position window near tray icon: {err}");
}
}
}
impl WindowManager {
pub fn open_tray(app: &AppHandle) -> tauri::Result<WebviewWindow> {
let window = if let Some(window) = app.get_webview_window(NEW_UI_WINDOW_ID) {
let _ = window.unminimize();
window
} else {
Self::build_tray_window(app)?
};
position_window_near_tray(app, &window);
#[cfg(target_os = "macos")]
let _ = app.show();
let _ = window.show();
let _ = window.set_focus();
Ok(window)
}
pub fn open_full_view(app: &AppHandle) -> tauri::Result<WebviewWindow> {
let window = if let Some(window) = app.get_webview_window(OLD_UI_WINDOW_ID) {
let _ = window.unminimize();
window
} else {
Self::build_full_window(app)?
};
#[cfg(target_os = "macos")]
let _ = app.show();
let _ = window.show();
let _ = window.set_focus();
Ok(window)
}
}