mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-08-24 12:24:01 +02:00
Merge origin/main
This commit is contained in:
@@ -102,13 +102,19 @@ jobs:
|
|||||||
if: matrix.os == 'ubuntu'
|
if: matrix.os == 'ubuntu'
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y cmake ninja-build libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libnss3 patchelf xdg-utils clang-15 llvm-15
|
sudo apt-get install -y cmake ninja-build libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libnss3 patchelf xdg-utils
|
||||||
# crates/yaak-web compiles SQLite to wasm via sqlite-wasm-rs, whose C shim
|
# crates/yaak-web compiles SQLite to wasm via sqlite-wasm-rs, whose C shim
|
||||||
# uses C23 [[noreturn]]. Ubuntu 22.04's default clang-14 rejects it; clang-15
|
# uses C23 [[noreturn]] and expects a freestanding wasm32 target. Ubuntu
|
||||||
# from the same repos accepts it. Only the wasm build uses this compiler, so
|
# 22.04 ships only clang <=15: 14 rejects the attribute, and 15 falls
|
||||||
# the shipped binary keeps 22.04's glibc floor.
|
# through to host glibc headers ("bits/libc-header-start.h" not found).
|
||||||
echo "CC_wasm32_unknown_unknown=/usr/bin/clang-15" >> "$GITHUB_ENV"
|
# clang-18 handles it (it is what ubuntu-24.04 uses). Install it from
|
||||||
echo "AR_wasm32_unknown_unknown=/usr/bin/llvm-ar-15" >> "$GITHUB_ENV"
|
# apt.llvm.org since 22.04's repos stop at 15. Only the wasm build uses
|
||||||
|
# this compiler, so the shipped binary keeps 22.04's glibc floor.
|
||||||
|
wget -qO /tmp/llvm.sh https://apt.llvm.org/llvm.sh
|
||||||
|
chmod +x /tmp/llvm.sh
|
||||||
|
sudo /tmp/llvm.sh 18
|
||||||
|
echo "CC_wasm32_unknown_unknown=/usr/bin/clang-18" >> "$GITHUB_ENV"
|
||||||
|
echo "AR_wasm32_unknown_unknown=/usr/bin/llvm-ar-18" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
- name: Install Protoc for plugin-runtime
|
- name: Install Protoc for plugin-runtime
|
||||||
uses: arduino/setup-protoc@v3
|
uses: arduino/setup-protoc@v3
|
||||||
|
|||||||
@@ -333,7 +333,9 @@ export function formatHotkeyString(trigger: string): string[] {
|
|||||||
} else if (p === "Alt") {
|
} else if (p === "Alt") {
|
||||||
labelParts.push("⌥");
|
labelParts.push("⌥");
|
||||||
} else if (p === "Enter") {
|
} else if (p === "Enter") {
|
||||||
labelParts.push("↩");
|
// U+21A9 has an emoji presentation, which Chromium's font fallback picks
|
||||||
|
// (a blue glyph among monochrome ones). U+FE0E forces the text form.
|
||||||
|
labelParts.push("↩︎");
|
||||||
} else if (p === "Tab") {
|
} else if (p === "Tab") {
|
||||||
labelParts.push("⇥");
|
labelParts.push("⇥");
|
||||||
} else if (p === "Backspace") {
|
} else if (p === "Backspace") {
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ const ALL_CAPABILITIES: PlatformCapabilities = {
|
|||||||
localFiles: true,
|
localFiles: true,
|
||||||
timeline: true,
|
timeline: true,
|
||||||
multiWindow: true,
|
multiWindow: true,
|
||||||
|
windowChrome: true,
|
||||||
plugins: true,
|
plugins: true,
|
||||||
encryption: true,
|
encryption: true,
|
||||||
updater: true,
|
updater: true,
|
||||||
|
|||||||
@@ -257,6 +257,13 @@ export interface PlatformCapabilities {
|
|||||||
timeline: boolean;
|
timeline: boolean;
|
||||||
/** More than one window or tab on the same data. */
|
/** More than one window or tab on the same data. */
|
||||||
multiWindow: boolean;
|
multiWindow: boolean;
|
||||||
|
/**
|
||||||
|
* The page is the window's titlebar: it draws the drag region and window
|
||||||
|
* controls, and leaves room for macOS traffic lights. False when something
|
||||||
|
* else owns the frame around the page (a browser tab), so none of that
|
||||||
|
* chrome should be reserved or drawn.
|
||||||
|
*/
|
||||||
|
windowChrome: boolean;
|
||||||
/** The plugin runtime. */
|
/** The plugin runtime. */
|
||||||
plugins: boolean;
|
plugins: boolean;
|
||||||
/** Workspace encryption backed by a key the host keeps. */
|
/** Workspace encryption backed by a key the host keeps. */
|
||||||
|
|||||||
@@ -138,13 +138,16 @@ Reported honestly, so callers gate on the question rather than on the host:
|
|||||||
|
|
||||||
| True | False |
|
| True | False |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `httpSending`, `timeline`, `cookieJar` | `grpc`, `websocket`, `git`, `sync`, `tlsOptions`, `localFiles`, `multiWindow`, `plugins`, `encryption`, `updater`, `clipboardRead`, `systemFonts`, `license` |
|
| `httpSending`, `timeline`, `cookieJar` | `grpc`, `websocket`, `git`, `sync`, `tlsOptions`, `localFiles`, `multiWindow`, `windowChrome`, `plugins`, `encryption`, `updater`, `clipboardRead`, `systemFonts`, `license` |
|
||||||
|
|
||||||
`multiWindow: false` means the host cannot open a *second window* on demand —
|
`multiWindow: false` means the host cannot open a *second window* on demand —
|
||||||
what `cmd_new_child_window` does for Settings and workspace switching. It is not
|
what `cmd_new_child_window` does for Settings and workspace switching. It is not
|
||||||
a claim that nothing else is looking: other tabs may well be open on the same
|
a claim that nothing else is looking: other tabs may well be open on the same
|
||||||
worker, and it pushes every write to all of them regardless.
|
worker, and it pushes every write to all of them regardless.
|
||||||
|
|
||||||
|
`windowChrome: false` means the browser owns the frame around the page, so the
|
||||||
|
header draws no window controls and reserves no room for macOS traffic lights.
|
||||||
|
|
||||||
## Multiple tabs
|
## Multiple tabs
|
||||||
|
|
||||||
Each tab mints a label at load (`tab_xxxxxxxx`) and sends it with every command;
|
Each tab mints a label at load (`tab_xxxxxxxx`) and sends it with every command;
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ function capabilitiesFor(): PlatformCapabilities {
|
|||||||
// else is looking: other tabs may well be open on the same worker, and it
|
// else is looking: other tabs may well be open on the same worker, and it
|
||||||
// pushes every write to all of them regardless of this flag.
|
// pushes every write to all of them regardless of this flag.
|
||||||
multiWindow: false,
|
multiWindow: false,
|
||||||
|
// The browser draws the frame around the page. There are no traffic lights
|
||||||
|
// to leave room for and no window controls to draw.
|
||||||
|
windowChrome: false,
|
||||||
plugins: false,
|
plugins: false,
|
||||||
encryption: false,
|
encryption: false,
|
||||||
updater: false,
|
updater: false,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useCapability } from "@yaakapp-internal/platform";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
|
import type { CSSProperties, HTMLAttributes, ReactNode } from "react";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
@@ -31,6 +32,10 @@ export function HeaderSize({
|
|||||||
interfaceScale,
|
interfaceScale,
|
||||||
}: HeaderSizeProps) {
|
}: HeaderSizeProps) {
|
||||||
const isFullscreen = useIsFullscreen();
|
const isFullscreen = useIsFullscreen();
|
||||||
|
// The header only doubles as the titlebar when the host hands the page the
|
||||||
|
// window frame (Tauri) and the user hasn't opted for the native one. In a
|
||||||
|
// browser tab the frame is the browser's: no controls, no traffic lights.
|
||||||
|
const drawsWindowChrome = useCapability("windowChrome") && !useNativeTitlebar;
|
||||||
const finalStyle = useMemo<CSSProperties>(() => {
|
const finalStyle = useMemo<CSSProperties>(() => {
|
||||||
const s = { ...style };
|
const s = { ...style };
|
||||||
|
|
||||||
@@ -38,8 +43,8 @@ export function HeaderSize({
|
|||||||
if (size === "md") s.minHeight = HEADER_SIZE_MD;
|
if (size === "md") s.minHeight = HEADER_SIZE_MD;
|
||||||
if (size === "lg") s.minHeight = HEADER_SIZE_LG;
|
if (size === "lg") s.minHeight = HEADER_SIZE_LG;
|
||||||
|
|
||||||
if (useNativeTitlebar) {
|
if (!drawsWindowChrome) {
|
||||||
// No style updates when using native titlebar
|
// No style updates when something else draws the titlebar
|
||||||
} else if (osType === "macos") {
|
} else if (osType === "macos") {
|
||||||
if (!isFullscreen) {
|
if (!isFullscreen) {
|
||||||
// Add large padding for window controls
|
// Add large padding for window controls
|
||||||
@@ -57,7 +62,7 @@ export function HeaderSize({
|
|||||||
interfaceScale,
|
interfaceScale,
|
||||||
size,
|
size,
|
||||||
style,
|
style,
|
||||||
useNativeTitlebar,
|
drawsWindowChrome,
|
||||||
osType,
|
osType,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -82,7 +87,7 @@ export function HeaderSize({
|
|||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
{!hideControls && !useNativeTitlebar && (
|
{!hideControls && drawsWindowChrome && (
|
||||||
<WindowControls
|
<WindowControls
|
||||||
onlyX={onlyXWindowControl}
|
onlyX={onlyXWindowControl}
|
||||||
osType={osType}
|
osType={osType}
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ import { fileURLToPath } from "url";
|
|||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
const isBranchCheckout = process.argv[4] === "1";
|
// Git supplies three arguments when invoking this as a post-checkout hook. When run directly,
|
||||||
|
// assume the caller wants to configure the current worktree instead of requiring placeholder refs.
|
||||||
|
const isManualRun = process.argv.length === 2;
|
||||||
|
const isBranchCheckout = isManualRun || process.argv[4] === "1";
|
||||||
|
|
||||||
if (!isBranchCheckout) {
|
if (!isBranchCheckout) {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
|||||||
Reference in New Issue
Block a user