-
-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathmod.rs
More file actions
119 lines (100 loc) · 3.52 KB
/
mod.rs
File metadata and controls
119 lines (100 loc) · 3.52 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
//! Macos specific logic, such as window settings, etc.
pub mod accessibility;
pub mod discovery;
pub mod haptics;
pub mod launching;
pub mod urlscheme;
use iced::wgpu::rwh::WindowHandle;
pub(super) use self::discovery::get_installed_apps;
pub(super) use self::haptics::perform_haptic;
use objc2_service_management::SMAppService;
pub fn start_at_login() {
unsafe {
SMAppService::mainAppService().registerAndReturnError().ok();
}
}
pub fn stop_at_login() {
unsafe {
SMAppService::mainAppService()
.unregisterAndReturnError()
.ok();
}
}
pub fn get_autostart_status() -> bool {
unsafe {
SMAppService::mainAppService()
.registerAndReturnError()
.ok()
.is_some()
}
}
/// This sets the activation policy of the app to Accessory, allowing rustcast to be visible ontop
/// of fullscreen apps
pub(super) fn set_activation_policy_accessory() {
use objc2::MainThreadMarker;
use objc2_app_kit::{NSApp, NSApplicationActivationPolicy};
let mtm = MainThreadMarker::new().expect("must be on main thread");
let app = NSApp(mtm);
app.setActivationPolicy(NSApplicationActivationPolicy::Accessory);
}
/// This carries out the window configuration for the macos window (only things that are macos specific)
pub(super) fn macos_window_config(handle: &WindowHandle) {
use iced::wgpu::rwh::RawWindowHandle;
use objc2::rc::Retained;
use objc2_app_kit::NSView;
match handle.as_raw() {
RawWindowHandle::AppKit(handle) => {
let ns_view = handle.ns_view.as_ptr();
let ns_view: Retained<NSView> = unsafe { Retained::retain(ns_view.cast()) }.unwrap();
let ns_window = ns_view
.window()
.expect("view was not installed in a window");
use objc2_app_kit::{NSFloatingWindowLevel, NSWindowCollectionBehavior};
ns_window.setLevel(NSFloatingWindowLevel);
ns_window.setCollectionBehavior(NSWindowCollectionBehavior::CanJoinAllSpaces);
}
_ => {
panic!(
"Why are you running this as a non-appkit window? this is a macos only app as of now"
);
}
}
}
/// This is the function that forces focus onto rustcast
#[allow(deprecated)]
pub(super) fn focus_this_app() {
use objc2::MainThreadMarker;
use objc2_app_kit::NSApp;
let mtm = MainThreadMarker::new().expect("must be on main thread");
let app = NSApp(mtm);
app.activateIgnoringOtherApps(true);
}
/// This is the struct that represents the process serial number, allowing us to transform the process to a UI element
#[repr(C)]
struct ProcessSerialNumber {
low: u32,
hi: u32,
}
/// This is the function that transforms the process to a UI element, and hides the dock icon
///
/// see mostly <https://github.com/electron/electron/blob/e181fd040f72becd135db1fa977622b81da21643/shell/browser/browser_mac.mm#L512C1-L532C2>
///
/// returns ApplicationServices OSStatus (u32)
///
/// doesn't seem to do anything if you haven't opened a window yet, so wait to call it until after that.
pub(super) fn transform_process_to_ui_element() -> u32 {
use objc2_application_services::{
TransformProcessType, kCurrentProcess, kProcessTransformToUIElementApplication,
};
use std::ptr;
let psn = ProcessSerialNumber {
low: 0,
hi: kCurrentProcess,
};
unsafe {
TransformProcessType(
ptr::from_ref(&psn).cast(),
kProcessTransformToUIElementApplication,
)
}
}