Skip to content

Commit

Permalink
added 'remove from dock' (accessory mode) tray option which fixes ful…
Browse files Browse the repository at this point in the history
…lscreen on macos #168
  • Loading branch information
5rahim committed Dec 9, 2024
1 parent cd980ad commit 2fd67a5
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 30 deletions.
1 change: 1 addition & 0 deletions seanime-desktop/src-tauri/capabilities/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"core:tray:default",
"shell:allow-open",
"shell:default",
"core:window:allow-set-title-bar-style",
"core:window:allow-center",
"core:window:allow-request-user-attention",
"core:window:allow-set-resizable",
Expand Down
23 changes: 23 additions & 0 deletions seanime-desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,27 @@ pub fn run() {
server_process_for_setup,
is_shutdown_for_setup,
);

let app_handle_1 = app.handle().clone();
main_window.listen("macos-activation-policy-accessory", move |_| {
println!("EVENT macos-activation-policy-accessory");
#[cfg(target_os = "macos")]
app_handle_1
.set_activation_policy(tauri::ActivationPolicy::Accessory)
.unwrap();
});

// main_window.on_window_event()

let app_handle_2 = app.handle().clone();
main_window.listen("macos-activation-policy-regular", move |_| {
println!("EVENT macos-activation-policy-regular");
#[cfg(target_os = "macos")]
app_handle_2
.set_activation_policy(tauri::ActivationPolicy::Regular)
.unwrap();
});

Ok(())
})
.build(tauri::generate_context!())
Expand Down Expand Up @@ -87,6 +108,7 @@ pub fn run() {
} => {
let is_shutdown_guard = is_shutdown_for_exit.lock().unwrap();
if label.as_str() == MAIN_WINDOW_LABEL && !*is_shutdown_guard {
println!("Main window close request");
// Hide the window when user clicks 'X'
let win = app.get_webview_window(label.as_str()).unwrap();
win.hide().unwrap();
Expand All @@ -110,6 +132,7 @@ pub fn run() {

// The app is about to exit
tauri::RunEvent::ExitRequested { .. } => {
println!("Main window exit request");
let mut child_guard = server_process_for_exit.lock().unwrap();
if let Some(child) = child_guard.take() {
// Kill server process
Expand Down
20 changes: 19 additions & 1 deletion seanime-desktop/src-tauri/src/tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,21 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
true,
None::<&str>,
)?;
let accessory_mode_i = MenuItem::with_id(
app,
"accessory_mode",
"Remove from dock",
true,
None::<&str>,
)?;
let mut items: Vec<&dyn tauri::menu::IsMenuItem<R>> = vec![&toggle_visibility_i, &quit_i];

#[cfg(target_os = "macos")]
{
items = vec![&toggle_visibility_i, &accessory_mode_i, &quit_i];
}

let menu = Menu::with_items(app, &[&toggle_visibility_i, &quit_i])?;
let menu = Menu::with_items(app, &items)?;

let _ = TrayIconBuilder::with_id("tray")
.icon(app.default_window_icon().unwrap().clone())
Expand All @@ -44,6 +57,11 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
}
}
}
"accessory_mode" => {
#[cfg(target_os = "macos")]
app.set_activation_policy(tauri::ActivationPolicy::Accessory)
.unwrap();
}
// "hide" => {
// if let Some(window) = app.get_webview_window(MAIN_WINDOW_LABEL) {
// if window.is_minimized().unwrap() {
Expand Down
127 changes: 98 additions & 29 deletions seanime-web/src/app/(main)/_tauri/tauri-window-title-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export function TauriWindowTitleBar(props: TauriWindowTitleBarProps) {

const [showTrafficLights, setShowTrafficLights] = React.useState(false)
const [displayDragRegion, setDisplayDragRegion] = React.useState(true)
const dragRegionRef = React.useRef<HTMLDivElement>(null)


function handleMinimize() {
Expand All @@ -34,6 +35,30 @@ export function TauriWindowTitleBar(props: TauriWindowTitleBarProps) {
getCurrentWebviewWindow().close().then()
}

// Check if the window is in fullscreen mode, and hide the traffic lights & drag region if it is
function onFullscreenChange(ev?: Event) {
if (getCurrentWebviewWindow().label !== "main") return


if (platform() === "macos") {
ev?.preventDefault()
if (!document.fullscreenElement) {
getCurrentWebviewWindow().setTitleBarStyle("overlay").then()
setDisplayDragRegion(true)
setShowTrafficLights(true)
} else {
setDisplayDragRegion(false)
setShowTrafficLights(false)
}
} else {
getCurrentWebviewWindow().isFullscreen().then((fullscreen) => {
console.log("setting displayDragRegion to", !fullscreen)
setShowTrafficLights(!fullscreen)
setDisplayDragRegion(!fullscreen)
})
}
}

React.useEffect(() => {

const listener = getCurrentWebviewWindow().onResized(() => {
Expand All @@ -44,16 +69,6 @@ export function TauriWindowTitleBar(props: TauriWindowTitleBarProps) {
})
})

// Check if the window is in fullscreen mode, and hide the traffic lights & drag region if it is
function onFullscreenChange() {
if (getCurrentWebviewWindow().label !== "main") return

getCurrentWebviewWindow().isFullscreen().then((fullscreen) => {
setShowTrafficLights(!fullscreen)
setDisplayDragRegion(!fullscreen)
})
}

document.addEventListener("fullscreenchange", onFullscreenChange)

return () => {
Expand All @@ -62,6 +77,60 @@ export function TauriWindowTitleBar(props: TauriWindowTitleBarProps) {
}
}, [])

/**
*
* const policyRef = React.useRef("regular")
*
* // Check if the window is in fullscreen mode, and hide the traffic lights & drag region if it is
* function onFullscreenChange(ev?: Event) {
* if (getCurrentWebviewWindow().label !== "main") return
*
* if (platform() === "macos") {
* // Bug fix for macOS where fullscreen doesn't work if the activation policy is set to Regular
* if (document.fullscreenElement && policyRef.current !== "accessory") { // entering fullscreen
* getCurrentWebviewWindow().setFullscreen(true).then(() => {
* setShowTrafficLights(false)
* setDisplayDragRegion(false)
* })
* getCurrentWebviewWindow().emit("macos-activation-policy-accessory").then(() => {
* policyRef.current = "accessory"
* })
* } else if (policyRef.current !== "regular") { // exiting fullscreen
* getCurrentWebviewWindow().setFullscreen(false).then(() => {
* setShowTrafficLights(true)
* setDisplayDragRegion(true)
* })
* getCurrentWebviewWindow().emit("macos-activation-policy-regular").then(() => {
* getCurrentWebviewWindow().setTitleBarStyle("overlay").then()
* })
* policyRef.current = "regular"
* }
* } else {
* getCurrentWebviewWindow().isFullscreen().then((fullscreen) => {
* setShowTrafficLights(!fullscreen)
* setDisplayDragRegion(!fullscreen)
* })
* }
* }
*
* React.useEffect(() => {
* const listener = getCurrentWebviewWindow().onResized(() => {
* onFullscreenChange()
* // Get the current window maximized state
* getCurrentWebviewWindow().isMaximized().then((maximized) => {
* setMaximized(maximized)
* })
* })
*
* document.addEventListener("fullscreenchange", onFullscreenChange)
*
* return () => {
* listener.then((f) => f()) // remove the listener
* document.removeEventListener("fullscreenchange", onFullscreenChange)
* }
* }, [])
*/

const [currentPlatform, setCurrentPlatform] = React.useState("")

React.useEffect(() => {
Expand Down Expand Up @@ -100,25 +169,25 @@ export function TauriWindowTitleBar(props: TauriWindowTitleBarProps) {
{displayDragRegion && <div className="flex flex-1 cursor-grab active:cursor-grabbing" data-tauri-drag-region></div>}
{(currentPlatform === "windows" && showTrafficLights) &&
<div className="flex h-10 items-center justify-center gap-1 mr-2 !cursor-default">
<IconButton
className="outline-none w-11 size-8 rounded-lg duration-0 shadow-none text-white hover:text-white bg-transparent hover:bg-[rgba(255,255,255,0.05)] active:text-white active:bg-[rgba(255,255,255,0.1)]"
icon={<VscChromeMinimize className="text-[0.95rem]" />}
onClick={handleMinimize}
tabIndex={-1}
/>
<IconButton
className="outline-none w-11 size-8 rounded-lg duration-0 shadow-none text-white hover:text-white bg-transparent hover:bg-[rgba(255,255,255,0.05)] active:text-white active:bg-[rgba(255,255,255,0.1)]"
icon={maximized ? <VscChromeRestore className="text-[0.95rem]" /> : <VscChromeMaximize className="text-[0.95rem]" />}
onClick={toggleMaximized}
tabIndex={-1}
/>
<IconButton
className="outline-none w-11 size-8 rounded-lg duration-0 shadow-none text-white hover:text-white bg-transparent hover:bg-red-500 active:bg-red-600 active:text-white"
icon={<VscChromeClose className="text-[0.95rem]" />}
onClick={handleClose}
tabIndex={-1}
/>
</div>}
<IconButton
className="outline-none w-11 size-8 rounded-lg duration-0 shadow-none text-white hover:text-white bg-transparent hover:bg-[rgba(255,255,255,0.05)] active:text-white active:bg-[rgba(255,255,255,0.1)]"
icon={<VscChromeMinimize className="text-[0.95rem]" />}
onClick={handleMinimize}
tabIndex={-1}
/>
<IconButton
className="outline-none w-11 size-8 rounded-lg duration-0 shadow-none text-white hover:text-white bg-transparent hover:bg-[rgba(255,255,255,0.05)] active:text-white active:bg-[rgba(255,255,255,0.1)]"
icon={maximized ? <VscChromeRestore className="text-[0.95rem]" /> : <VscChromeMaximize className="text-[0.95rem]" />}
onClick={toggleMaximized}
tabIndex={-1}
/>
<IconButton
className="outline-none w-11 size-8 rounded-lg duration-0 shadow-none text-white hover:text-white bg-transparent hover:bg-red-500 active:bg-red-600 active:text-white"
icon={<VscChromeClose className="text-[0.95rem]" />}
onClick={handleClose}
tabIndex={-1}
/>
</div>}
</div>
</>
)
Expand Down

0 comments on commit 2fd67a5

Please sign in to comment.