mirror of
https://github.com/priyanshujain/margin-calendar.git
synced 2026-10-02 11:07:04 +00:00
fix few bugs
This commit is contained in:
1 parent
c1c6db1406
commit
1c709967f8
7 files changed
+61
-22
No files matched your search
@@ -127,8 +127,13 @@ assume away.
|
|||||||
## Platforms
|
## Platforms
|
||||||
|
|
||||||
macOS uses the overlay title bar with the header row padded for the traffic lights, as margin
|
macOS uses the overlay title bar with the header row padded for the traffic lights, as margin
|
||||||
does. Linux has no traffic lights, so that padding is conditional. Linux builds need
|
does. The lights are moved down to the header's centre line (`trafficLightPosition` in
|
||||||
`libwebkit2gtk-4.1-dev` and ship as AppImage and deb.
|
`tauri.conf.json`), because AppKit places them for a 32pt title bar and the header is 46px.
|
||||||
|
Closing the window on macOS hides it rather than quitting, the way WhatsApp and Slack do: the
|
||||||
|
process stays in the Dock with sync running, a Dock click brings the window back, and Cmd+Q
|
||||||
|
quits. Both halves live in `lib.rs`. Linux has no traffic lights, so that padding is
|
||||||
|
conditional, and closing the window there quits. Linux builds need `libwebkit2gtk-4.1-dev` and
|
||||||
|
ship as AppImage and deb.
|
||||||
|
|
||||||
## Order of work
|
## Order of work
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
"core:window:allow-destroy",
|
"core:window:allow-destroy",
|
||||||
"core:window:allow-start-dragging",
|
"core:window:allow-start-dragging",
|
||||||
"core:window:allow-toggle-maximize",
|
|
||||||
"updater:default",
|
"updater:default",
|
||||||
"process:allow-restart"
|
"process:allow-restart"
|
||||||
]
|
]
|
||||||
|
|||||||
+40
-3
@@ -219,6 +219,20 @@ fn watch_for_the_consent_tab_closing(window: &tauri::WebviewWindow) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The other half of closing on macOS. The red button and Cmd+W hide the window rather than
|
||||||
|
/// destroy it (`on_window_event` in `run`), the way WhatsApp and Slack do: the app stays in the
|
||||||
|
/// Dock with sync still running, and Cmd+Q is what quits. AppKit does nothing of its own for a
|
||||||
|
/// Dock click when it can see no window, so bringing it back is on us. `unminimize` covers the
|
||||||
|
/// yellow button, which lands here for the same reason.
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
fn show_main_window(app: &tauri::AppHandle) {
|
||||||
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
|
let _ = window.unminimize();
|
||||||
|
let _ = window.show();
|
||||||
|
let _ = window.set_focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
// generate_context! first, so the updater plugin registers only when the merged config
|
// generate_context! first, so the updater plugin registers only when the merged config
|
||||||
@@ -286,7 +300,17 @@ pub fn run() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
builder
|
#[cfg(target_os = "macos")]
|
||||||
|
{
|
||||||
|
builder = builder.on_window_event(|window, event| {
|
||||||
|
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
|
||||||
|
api.prevent_close();
|
||||||
|
let _ = window.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let app = builder
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
google::accounts_list,
|
google::accounts_list,
|
||||||
google::account_connect,
|
google::account_connect,
|
||||||
@@ -301,6 +325,19 @@ pub fn run() {
|
|||||||
sync::sync_status,
|
sync::sync_status,
|
||||||
sync::sync_flush
|
sync::sync_flush
|
||||||
])
|
])
|
||||||
.run(context)
|
.build(context)
|
||||||
.expect("error while running Margin Calendar");
|
.expect("error while building Margin Calendar");
|
||||||
|
|
||||||
|
app.run(|app, event| {
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
if let tauri::RunEvent::Reopen {
|
||||||
|
has_visible_windows: false,
|
||||||
|
..
|
||||||
|
} = event
|
||||||
|
{
|
||||||
|
show_main_window(app);
|
||||||
|
}
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
let _ = (app, event);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,8 @@
|
|||||||
"height": 900,
|
"height": 900,
|
||||||
"minWidth": 880,
|
"minWidth": 880,
|
||||||
"minHeight": 560,
|
"minHeight": 560,
|
||||||
"titleBarStyle": "Overlay"
|
"titleBarStyle": "Overlay",
|
||||||
|
"trafficLightPosition": { "x": 9, "y": 25 }
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|||||||
+5
-2
@@ -27,7 +27,7 @@ import { useSync } from "./store/useSync";
|
|||||||
import { notify } from "./store/useToast";
|
import { notify } from "./store/useToast";
|
||||||
import { useCompact, usePhone, useTouch } from "./useMedia";
|
import { useCompact, usePhone, useTouch } from "./useMedia";
|
||||||
import { syncFlush } from "./api/sync";
|
import { syncFlush } from "./api/sync";
|
||||||
import { isDesktop, isTauri, live, type AuthEvent, type SyncStatus } from "./ipc";
|
import { isDesktop, isMacDesktop, isTauri, live, type AuthEvent, type SyncStatus } from "./ipc";
|
||||||
|
|
||||||
/** Long enough for sync_flush's own 1s lock wait plus its 4s drain budget. */
|
/** Long enough for sync_flush's own 1s lock wait plus its 4s drain budget. */
|
||||||
const FLUSH_TIMEOUT_MS = 5500;
|
const FLUSH_TIMEOUT_MS = 5500;
|
||||||
@@ -91,8 +91,11 @@ function App() {
|
|||||||
// `isDesktop` genuinely means desktop here: there is no close to intercept on a phone, and the
|
// `isDesktop` genuinely means desktop here: there is no close to intercept on a phone, and the
|
||||||
// window commands live in a capability that platform does not get, so this would be a rejected
|
// window commands live in a capability that platform does not get, so this would be a rejected
|
||||||
// IPC call rather than a no-op. The outbox still drains on the next launch either way.
|
// IPC call rather than a no-op. The outbox still drains on the next launch either way.
|
||||||
|
//
|
||||||
|
// Not on macOS, where closing the window hides it (lib.rs) and the process, sync loop included,
|
||||||
|
// carries on behind it. A listener here would be the thing that destroyed the window instead.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isDesktop) return;
|
if (!isDesktop || isMacDesktop) return;
|
||||||
const win = getCurrentWindow();
|
const win = getCurrentWindow();
|
||||||
const unlisten = win.onCloseRequested(async (event) => {
|
const unlisten = win.onCloseRequested(async (event) => {
|
||||||
if (useSync.getState().pendingWrites === 0) return;
|
if (useSync.getState().pendingWrites === 0) return;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// The only persistent chrome. It carries the date range, the view switcher and the current time
|
// The only persistent chrome. It carries the date range, the view switcher and the current time
|
||||||
// range, and on macOS the traffic lights float over it, so it costs no extra height.
|
// range, and on macOS the traffic lights float over it, so it costs no extra height.
|
||||||
|
|
||||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
|
||||||
import type { MouseEvent as ReactMouseEvent } from "react";
|
|
||||||
import { Icon } from "./Icon";
|
import { Icon } from "./Icon";
|
||||||
import { useCalendarView, spanFor, type View } from "../store/useCalendarView";
|
import { useCalendarView, spanFor, type View } from "../store/useCalendarView";
|
||||||
import { useOverlays } from "../store/useOverlays";
|
import { useOverlays } from "../store/useOverlays";
|
||||||
@@ -10,7 +8,6 @@ import { useSync } from "../store/useSync";
|
|||||||
import { useTheme } from "../store/useTheme";
|
import { useTheme } from "../store/useTheme";
|
||||||
import { addDays, formatRange } from "../time";
|
import { addDays, formatRange } from "../time";
|
||||||
import { keyLabel, keysFor } from "../keys/bindings";
|
import { keyLabel, keysFor } from "../keys/bindings";
|
||||||
import { isDesktop } from "../ipc";
|
|
||||||
import type { CommandId } from "../keys/commands";
|
import type { CommandId } from "../keys/commands";
|
||||||
|
|
||||||
// Exported where the phone bar shows the same thing: two rows of chrome that disagreed about which
|
// Exported where the phone bar shows the same thing: two rows of chrome that disagreed about which
|
||||||
@@ -55,17 +52,10 @@ export function Header() {
|
|||||||
const { from, to } = spanFor(view, anchor);
|
const { from, to } = spanFor(view, anchor);
|
||||||
const step = moveDay;
|
const step = moveDay;
|
||||||
|
|
||||||
// Double click to zoom, the way a native title bar does. Tauri's drag region only handles this
|
// Dragging and double click to zoom both come from Tauri's drag region script, which skips
|
||||||
// when the header itself is the event target, and the layout children cover it end to end, so
|
// buttons on its own. A second toggle from here would undo the first.
|
||||||
// it is wired explicitly. A double click on a control is not a title bar gesture.
|
|
||||||
const onDoubleClick = (e: ReactMouseEvent<HTMLElement>) => {
|
|
||||||
if (!isDesktop) return;
|
|
||||||
if ((e.target as HTMLElement).closest("button, input, select, a")) return;
|
|
||||||
void getCurrentWindow().toggleMaximize();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="titlebar" data-tauri-drag-region onDoubleClick={onDoubleClick}>
|
<header className="titlebar" data-tauri-drag-region>
|
||||||
<div className="lead" data-tauri-drag-region>
|
<div className="lead" data-tauri-drag-region>
|
||||||
<button
|
<button
|
||||||
className="icon-button"
|
className="icon-button"
|
||||||
|
|||||||
@@ -112,6 +112,10 @@ select {
|
|||||||
padding: var(--safe-top) 14px 0;
|
padding: var(--safe-top) 14px 0;
|
||||||
background: var(--shell);
|
background: var(--shell);
|
||||||
border-bottom: 1px solid var(--line);
|
border-bottom: 1px solid var(--line);
|
||||||
|
/* Tauri's drag region lets the second click of a double click through to the webview so it can
|
||||||
|
zoom on mouseup, and WebKit would otherwise read that click as "select the nearest word". */
|
||||||
|
-webkit-user-select: none;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The macOS traffic lights float over this row, so it opens a lane for them and costs no extra
|
/* The macOS traffic lights float over this row, so it opens a lane for them and costs no extra
|
||||||
|
|||||||
Reference in new issue
Block a user