Skip to content

Commit

Permalink
feat: pretty borders on win10/win11 (#41)
Browse files Browse the repository at this point in the history
* feat: add pretty borders to win10/11/macos

* limit feature to win only

* nicer icons, better cross-system behavior

* small css fix

* use iife for backward compat

* better app init state
  • Loading branch information
golota60 authored Dec 25, 2023
1 parent 1337c08 commit a230553
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 49 deletions.
21 changes: 19 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,25 @@
<title>Tauri + React + TS</title>
</head>

<body>
<div id="root">Loading...</div>
<body style="background: #030711; width: 100vw; height: 100vh; overflow:hidden;">
<div data-tauri-drag-region class="titlebar">
<div class="titlebar-button" id="titlebar-minimize">
<img
src="/minus-line.svg"
alt="minimize"
/>
</div>
<div class="titlebar-button" id="titlebar-maximize">
<img
src="/window-max.svg"
alt="maximize"
/>
</div>
<div class="titlebar-button" id="titlebar-close">
<img src="/close-line.svg" alt="close" />
</div>
</div>
<div id="root"><p style="font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; color: white; position:fixed; left: calc(50% - 100px); top: calc(50% - 32px);">Loading, the app is initializing...</p></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
1 change: 1 addition & 0 deletions public/close-line.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/minus-line.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/window-max.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ tokio = { version = "1.35.0", features = ["full"] }
thiserror = "1.0.50"
uuid = "1.6.1"
tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
window-shadows = "0.2.2"

[features]
# by default Tauri runs in production mode
Expand Down
50 changes: 46 additions & 4 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use loose_idasen::BtError;
use tauri_plugin_autostart::MacosLauncher;

use btleplug::platform::Peripheral as PlatformPeripheral;
use tauri::GlobalShortcutManager;
use tauri::{GlobalShortcutManager, Window, WindowBuilder};
use tauri::{async_runtime::block_on, Manager, SystemTray, SystemTrayEvent};
use window_shadows::set_shadow;

mod desk_mutex;
mod config_utils;
Expand All @@ -18,6 +19,41 @@ mod tray_utils;

pub struct TauriSharedDesk(Mutex<Result<PlatformPeripheral, BtError>>);

// Whether a system should have custom decorations or not
#[tauri::command]
fn has_custom_decorations() -> bool {
if cfg!(windows) {
return true;
}
false
}

pub trait WindowInitUtils {
fn init_trayasen(self, title: &str, err_msg: &str, init_script: Option<&str>) -> Window;
}

impl WindowInitUtils for WindowBuilder<'_> {
fn init_trayasen(self, title: &str, err_msg: &str, init_script: Option<&str>) -> Window {
// We want to replace borders only on windows, as on macOS they are pretty enough, and on Linux it's not supported by `window_shadows`
let mut window_builder = if has_custom_decorations() {
self.inner_size(1280.0, 720.0).title(title).always_on_top(true).decorations(false)
} else {
self.inner_size(1280.0, 720.0).title(title).always_on_top(true)
};

if let Some(init_script) = init_script {
window_builder = window_builder.initialization_script(init_script);
}

let window_instance= window_builder.build().expect(err_msg);
if has_custom_decorations() {
set_shadow(&window_instance, true).unwrap();
}
window_instance
}
}


#[tauri::command]
fn create_new_elem(
app_handle: tauri::AppHandle,
Expand Down Expand Up @@ -170,7 +206,8 @@ fn main() {
}
}
Err(e) => {
let err_window = tauri::WindowBuilder::new(app, "init_window", tauri::WindowUrl::App("index.html".into())).inner_size(1280.0, 720.0).title("Trayasen - Woops!").always_on_top(true).build().expect("Error while creating window");
let err_window = tauri::WindowBuilder::new(app, "init_window", tauri::WindowUrl::App("index.html".into())).init_trayasen("Trayasen - Woops!","Error while creating window", None);

// Open error window with the error
println!("opening error window! error: {}", e);

Expand All @@ -191,12 +228,16 @@ fn main() {
}
}
None => {
let init_window = tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into())).inner_size(1280.0, 720.0).title("Trayasen - Setup").always_on_top(true).build().expect("Error while creating window");

let init_window = tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into())).init_trayasen("Trayasen - Setup", "Error while creating window", None);
// If loc_name doesn't exist, that means there's no saved desk - meaning we need to show the initial setup window
init_window
.show()
.expect("Error while trying to show the window");


#[cfg(any(windows, target_os = "macos"))]
set_shadow(&init_window, true).unwrap();
}
}

Expand All @@ -211,6 +252,7 @@ fn main() {
config_utils::reset_desk,
loose_idasen::get_available_desks_to_connect,
connect_to_desk_by_name,
has_custom_decorations
])
.enable_macos_default_menu(false)
// Register all the tray events, eg. clicks and stuff
Expand Down
65 changes: 26 additions & 39 deletions src-tauri/src/tray_utils.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,46 @@
use tauri::AppHandle;

use crate::WindowInitUtils;

pub fn handle_exit_menu_click() {
std::process::exit(0);
}

pub fn handle_about_menu_click(app: &AppHandle) {
match tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into()))
.always_on_top(true)
.initialization_script(
r#"
tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into()))
.init_trayasen(
"Trayasen - About/Options",
"Error while trying to open about window",
Some(
r#"
history.replaceState({}, '','/about');
"#,
)
.title("Trayasen - About/Options")
.build()
{
Ok(_) => {}
Err(_) => {
println!("Error while trying to open about window");
}
}
),
);
}

pub fn handle_new_position_menu_click(app: &AppHandle) {
match tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into()))
.always_on_top(true)
.initialization_script(
r#"
tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into()))
.init_trayasen(
"Trayasen - Add position",
"Error while trying to open new postition window",
Some(
r#"
history.replaceState({}, '','/new-position');
"#,
)
.title("Trayasen - Add position")
.build()
{
Ok(_) => {}
Err(_) => {
println!("Error while trying to open new postition window");
}
}
),
);
}

pub fn handle_manage_positions_menu_click(app: &AppHandle) {
match tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into()))
.always_on_top(true)
.initialization_script(
r#"
tauri::WindowBuilder::new(app, "main", tauri::WindowUrl::App("index.html".into()))
.init_trayasen(
"Trayasen - Manage positions",
"Error while trying to open manage positions window",
Some(
r#"
history.replaceState({}, '','/manage-positions');
"#,
)
.title("Trayasen - Manage positions")
.build()
{
Ok(_) => {}
Err(_) => {
println!("Error while trying to open manage positions window");
}
}
),
);
}
21 changes: 21 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
import React from "react";
import ReactDOM from "react-dom/client";
import { appWindow } from "@tauri-apps/api/window";
import App from "./App";
import "./style.css";
import { hasCustomDecorations } from "./rustUtils";

(async () => {
const customDecorations = await hasCustomDecorations();

if (customDecorations) {
document
?.getElementById("titlebar-minimize")
?.addEventListener("click", () => appWindow.minimize());
document
?.getElementById("titlebar-maximize")
?.addEventListener("click", () => appWindow.toggleMaximize());
document
?.getElementById("titlebar-close")
?.addEventListener("click", () => appWindow.close());
} else {
// if window doesn't have custom decorations, remove the titlebar altogether
document?.querySelector(".titlebar")?.remove();
}
})();

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
Expand Down
4 changes: 4 additions & 0 deletions src/rustUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ export const removeConfig = async () => {
export const resetDesk = async () => {
return await invoke("reset_desk");
};

export const hasCustomDecorations = async () => {
return await invoke("has_custom_decorations");
};
35 changes: 31 additions & 4 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@
border: 3px solid var(--primary-scroll);
}

#root {
width: 100vw;
height: 100vh;
}

@tailwind base;
@tailwind components;
Expand Down Expand Up @@ -81,3 +77,34 @@
font-feature-settings: "rlig" 1, "calt" 1;
}
}

#root {
width: 100vw;
height: 100vh;
}

.titlebar {
height: 30px;
background: #190781;
user-select: none;
display: flex;
justify-content: flex-end;
position: fixed;
border-radius: 6px 6px 0px 0px;
top: 0;
left: 0;
right: 0;
}
#titlebar-close:hover {
background: #be1a54;
}
.titlebar-button {
display: inline-flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
}
.titlebar-button:hover {
background: #5b6bc3;
}

0 comments on commit a230553

Please sign in to comment.