Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,17 @@ This project uses **pnpm** (v9.0.0) as its package manager.

### Code Quality

- `pnpm format` - Format code with Prettier
- `pnpm format:check` - Check formatting without modifying files
- `pnpm format` - Format `apps/` and `packages/` with Oxfmt
- `pnpm format:check` - Check Oxfmt formatting without modifying files
- `pnpm format:files <paths...>` - Format only the specified files with Oxfmt
- `pnpm lint` - Lint code with Oxlint (auto-fix)
- `pnpm lint:check` - Lint code without auto-fix
- `pnpm typecheck` - Type check with tsgo
- `cargo fmt` - Format Rust code (run after any Rust changes)
- `cargo clippy` - Lint Rust code (run after any Rust changes)

Use repository scripts when a matching command exists; they encode the intended tool, scope, and version. Run all TypeScript/JavaScript formatting through `pnpm format`, `pnpm format:check`, or `pnpm format:files`; never invoke Oxfmt directly and never use Prettier in this repository.

### Testing

- `pnpm test` - Run all tests once through Turbo
Expand Down
26 changes: 24 additions & 2 deletions apps/desktop/src/main/app/App.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
clipboard,
ipcMain,
MessageChannelMain,
screen,
type Rectangle,
type WebContents,
} from "electron";
import started from "electron-squirrel-startup";
Expand Down Expand Up @@ -124,9 +126,17 @@ export class App {
});
}

#createWindow(): Window {
#createWindow(autoShow = true, bounds?: Rectangle): Window {
const window = new Window({
preloadPath: path.join(__dirname, "preload.js"),
autoShow,
...(bounds
? {
width: bounds.width,
height: bounds.height,
browserWindowOptions: { x: bounds.x, y: bounds.y },
}
: {}),
});
this.#windows.add(window);

Expand Down Expand Up @@ -216,6 +226,14 @@ export class App {
event.sender.postMessage("workspace.port", null, [port2]);
this.#log.info("workspace port sent to renderer");
});
ipc.handle(ipcMain, "workspace.ready", (event) => {
this.#workspaceForSender(event.sender, "workspace.ready");
const window = this.#requireWindowForWebContents(event.sender);
const browserWindow = window.window;
if (browserWindow.isVisible() || browserWindow.isMinimized()) return;

window.focus();
});
}

#commandContext(): CommandContext {
Expand Down Expand Up @@ -284,9 +302,13 @@ export class App {

#openWorkspaceWindow(opener: Window, session: WorkspaceSession): void {
const closeOpener = this.#workspaces.getForBrowserWindow(opener.window) === null;
const workspaceWindow = this.#createWindow();

const bounds = screen.getDisplayMatching(opener.window.getBounds()).workArea;
const workspaceWindow = this.#createWindow(false, bounds);

this.#workspaces.attachWindow(session.workspaceId, workspaceWindow);
this.#loadWorkspace(workspaceWindow);

if (closeOpener) opener.close();
}

Expand Down
14 changes: 9 additions & 5 deletions apps/desktop/src/main/windows/Window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface WindowOptions {
maximised?: boolean;
preloadPath: string;
browserWindowOptions?: BrowserWindowConstructorOptions;
autoShow: boolean;
}

const WINDOW_DEFAULT_OPTIONS: Omit<WindowOptions, "preloadPath"> = {
Expand All @@ -18,6 +19,7 @@ const WINDOW_DEFAULT_OPTIONS: Omit<WindowOptions, "preloadPath"> = {
title: "Shift",
minWidth: 1200,
maximised: false,
autoShow: false,
};

/** Chrome zoom steps, matching the browser-conventional ladder. */
Expand Down Expand Up @@ -59,21 +61,23 @@ export class Window {
height: windowOptions.height,
title: windowOptions.title,
minWidth: windowOptions.minWidth,
show: windowOptions.maximised,
show: false,
webPreferences: {
...BROWSER_WINDOW_DEFAULT_OPTIONS.webPreferences,
...windowOptions.browserWindowOptions?.webPreferences,
preload: windowOptions.preloadPath,
},
});

if (windowOptions.autoShow) {
this.#window.once("ready-to-show", () => {
this.#window.show();
});
}

if (windowOptions.maximised) {
this.#window.maximize();
}

this.#window.once("ready-to-show", () => {
this.#window.show();
});
}

get window(): BrowserWindow {
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/preload/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const shiftHost: ShiftHost = {
},
workspace: {
connect: invoke(ipcRenderer, "workspace.connect"),
ready: invoke(ipcRenderer, "workspace.ready"),
},
ui: {
onZoomChanged: listen(ipcRenderer, "ui.zoomChanged"),
Expand Down
12 changes: 0 additions & 12 deletions apps/desktop/src/renderer/src/app/Screens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Navigate, Outlet, Route, Routes } from "react-router-dom";
import { Landing } from "@/views/Landing";
import { Home } from "@/views/Home";
import { Editor } from "@/views/Editor";
import { getShiftHost } from "@/host/shiftHost";
import { useSignalState } from "@/lib/signals/useSignal";
import { useEditor, useFont, useWorkspace } from "@/workspace/WorkspaceContext";
import { WorkspaceProvider } from "@/workspace/WorkspaceProvider";
Expand Down Expand Up @@ -66,21 +65,10 @@ const WorkspaceScreens = () => {
};
}, [workspace]);

// Side effect of a document loading: give the editor room.
useEffect(() => {
if (!documentLoaded) return;

async function maximiseWorkspaceWindow(): Promise<void> {
try {
await getShiftHost().commands.run("window.maximise");
} catch (error) {
console.error("maximise on document load failed", error);
}
}

editor.setDesignLocation(font.defaultLocation());

void maximiseWorkspaceWindow();
}, [documentLoaded, editor, font]);

if (connectionError) {
Expand Down
30 changes: 0 additions & 30 deletions apps/desktop/src/renderer/src/components/editor/Canvas.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,21 @@
import { FC, useEffect, useRef } from "react";
import { useParams } from "react-router-dom";

import { CanvasContextProvider } from "@/context/CanvasContextProvider";
import { useDebugSafe } from "@/context/DebugContext";
import { useSignalState } from "@/lib/signals";
import { useEditor } from "@/workspace/WorkspaceContext";
import { zoomMultiplierFromWheel } from "@/lib/transform";
import { InteractiveScene } from "./InteractiveScene";
import { StaticScene } from "./StaticScene";
import { DebugPanel } from "../debug/DebugPanel";
import { TextInput } from "../text/HiddenTextInput";
import { Vec2 } from "@shift/geo";
import { asGlyphId, mintNodeId } from "@shift/types";

export const Canvas: FC = () => {
const editor = useEditor();
const debug = useDebugSafe();

const { glyphId: glyphIdParam } = useParams();
const containerRef = useRef<HTMLDivElement>(null);

const activeSourceId = useSignalState(editor.activeSourceIdCell);
Comment thread
kostyafarber marked this conversation as resolved.
const glyphId = glyphIdParam ? asGlyphId(glyphIdParam) : null;

useEffect(() => {
if (!glyphId) {
editor.scene.clear();
return;
}

const id = mintNodeId();
editor.scene.setNodes([
{
id,
type: "node",
kind: "glyph",
parentId: null,
index: "a0",
glyphId,
sourceId: activeSourceId ?? editor.font.defaultSource.id,
position: { x: 0, y: 0 },
},
]);

editor.editing.enter(id);
}, [activeSourceId, editor, glyphId]);

useEffect(() => {
const element = containerRef.current;
if (!element) return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const ScaleSection = () => {
const [node] = glyphNodes;
if (!node) return null;

return editor.font.layer(node.glyphId, sourceId);
return editor.glyphForId(node.glyphId)?.layerForSource(sourceId) ?? null;
}, [editor, scene, sourceId]);
const selectedPointIds = useMemo(() => selection.ids.filter(isPointId), [selection]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const TransformSection = () => {
const [node] = glyphNodes;
if (!node) return null;

return editor.font.layer(node.glyphId, sourceId);
return editor.glyphForId(node.glyphId)?.layerForSource(sourceId) ?? null;
}, [editor, scene, sourceId]);

useEffect(() => {
Expand Down
Loading
Loading