Skip to content

Commit

Permalink
Support acrylic mode on mac (#27)
Browse files Browse the repository at this point in the history
* implement acrylic mode for mac

* working on mac

* polish non-mac ui

* polish

* bump version
  • Loading branch information
atinylittleshell authored Jan 14, 2024
1 parent 4b9fcc2 commit 7d94310
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 53 deletions.
1 change: 1 addition & 0 deletions apps/app/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async function createWindow() {
titleBarStyle: 'hidden',
icon: path.join(__dirname, 'public', 'icon.png'),
backgroundColor: '#000000',
visualEffectState: 'followWindow',
width: 800,
height: 600,
webPreferences: {
Expand Down
13 changes: 11 additions & 2 deletions apps/app/src/nativeBridge/modules/configModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class ConfigModule extends NativeBridgeModule {
return path.join(getAppDirs().userData, 'config.js');
}

public onRegistered(_mainWindow: BrowserWindow): void {
public onRegistered(mainWindow: BrowserWindow): void {
const configDir = getAppDirs().userData;
const configPath = path.join(configDir, 'config.js');
if (!existsSync(configPath)) {
Expand Down Expand Up @@ -65,10 +65,19 @@ export class ConfigModule extends NativeBridgeModule {
`Loaded config from ${configPath}}: ${JSON.stringify(mod.exports)}`,
);

const resolved = resolveConfig(mod.exports);
const resolved = resolveConfig(mod.exports, os.platform());
this.config = resolved;

this.applyConfig(resolved, mainWindow);
} catch (err: unknown) {
Logger.getInstance().log('error', JSON.stringify(err));
}
}

private applyConfig(config: ResolvedConfig, mainWindow: BrowserWindow): void {
if (config.acrylic) {
mainWindow.setVibrancy('under-window');
mainWindow.setBackgroundColor('#00000000');
}
}
}
4 changes: 2 additions & 2 deletions apps/terminal/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export const metadata: Metadata = {

const Layout = ({ children }: { children: ReactNode }) => {
return (
<html lang="en" data-theme="black">
<body className="h-screen w-screen flex flex-col overflow-hidden bg-black">
<html lang="en" data-theme="black" className="bg-transparent">
<body className="h-screen w-screen flex flex-col overflow-hidden bg-transparent">
<ClientSideProviders>{children}</ClientSideProviders>
</body>
</html>
Expand Down
94 changes: 50 additions & 44 deletions apps/terminal/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -189,58 +189,65 @@ const Page = () => {
return (
<>
<TitleBar>
<div className="tabs">
<a
className={`tab tab-lifted ${
tabId === 0 ? 'tab-active' : ''
} flex items-center gap-1`}
onClick={() => {
setTabId(0);
}}
>
<FiMenu />
</a>
{userTabs.map((userTab) => (
<div className="flex w-screen">
<div className="tabs">
<a
key={userTab.tabId}
className={`tab tab-lifted items-center ${
tabId === userTab.tabId ? 'tab-active' : ''
tabId === 0 ? 'tab-active' : ''
}`}
style={{
backgroundColor:
tabId === userTab.tabId
? config.colorScheme.background
: undefined,
paddingRight: tabId === userTab.tabId ? 0 : undefined,
tabId === 0 ? config.colorScheme.background : undefined,
}}
onClick={() => {
if (tabId === userTab.tabId) {
return;
}
setTabId(userTab.tabId);
setTabId(0);
}}
>
{userTab.tabId}
{userTab.tabId === tabId && (
<button
className="btn btn-ghost btn-square btn-xs opacity-50 hover:bg-transparent hover:opacity-100 ml-2"
onClick={() => {
closeTab();
}}
>
<FiX />
</button>
)}
<FiMenu />
</a>
))}
<a
className="tab tab-lifted"
onClick={() => {
createTab();
}}
>
<FiPlus />
</a>
{userTabs.map((userTab) => (
<a
key={userTab.tabId}
className={`tab tab-lifted items-center ${
tabId === userTab.tabId ? 'tab-active' : ''
}`}
style={{
backgroundColor:
tabId === userTab.tabId
? config.colorScheme.background
: undefined,
paddingRight: tabId === userTab.tabId ? 0 : undefined,
}}
onClick={() => {
if (tabId === userTab.tabId) {
return;
}
setTabId(userTab.tabId);
}}
>
{userTab.tabId}
{userTab.tabId === tabId && (
<button
className="btn btn-ghost btn-square btn-xs opacity-50 hover:bg-transparent hover:opacity-100 ml-2"
onClick={() => {
closeTab();
}}
>
<FiX />
</button>
)}
</a>
))}
<a
className="tab tab-lifted"
onClick={() => {
createTab();
}}
>
<FiPlus />
</a>
</div>
<div className="flex-1 tab tab-lifted cursor-default" />
</div>
</TitleBar>
<div
Expand All @@ -250,8 +257,7 @@ const Page = () => {
paddingBottom: config.terminalBorderWidth,
paddingLeft: config.terminalBorderWidth,
paddingRight: config.terminalBorderWidth,
backgroundColor:
tabId === 0 ? undefined : config.colorScheme.background,
backgroundColor: config.colorScheme.background,
}}
>
<div className="flex-1 relative overflow-hidden">
Expand Down
7 changes: 6 additions & 1 deletion apps/terminal/components/SettingsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ const SettingsPage = () => {
}, []);

return (
<div className="flex-1 w-full h-full relative flex flex-col items-center gap-4 p-4">
<div
className="flex-1 w-full h-full relative flex flex-col items-center gap-4 p-4"
style={{
backgroundColor: configContext.config.colorScheme.background,
}}
>
<img src="/logo.png" alt="Terminal One" className="w-48 h-48" />
<div className="text-2xl font-bold mb-4">TerminalOne v{appVersion}</div>
<div className="form-control w-full max-w-lg">
Expand Down
1 change: 1 addition & 0 deletions apps/terminal/components/Terminal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const Terminal = ({
// TODO: refactor this into multiple effects
const xterm = new XTerm({
allowProposedApi: true,
allowTransparency: true,
});
xtermRef.current = xterm;

Expand Down
2 changes: 1 addition & 1 deletion apps/terminal/components/TitleBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function TitleBar(props: PropsWithChildren) {

return (
<div
className={`flex flex-row item-center relative bg-base-300 ${
className={`flex flex-row item-center relative ${
window.TerminalOne?.platform === 'darwin' ? 'h-16 pt-8' : 'h-8'
}`}
>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@terminalone/monorepo",
"productName": "Terminal One",
"version": "1.0.3",
"version": "1.1.0",
"description": "A fast, elegant and intelligent cross-platform terminal.",
"author": "atinylittleshell <[email protected]>",
"license": "MIT",
Expand Down
18 changes: 16 additions & 2 deletions packages/types/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { isLeft } from 'fp-ts/Either';
import * as t from 'io-ts';
import { PathReporter } from 'io-ts/PathReporter';
import _ from 'lodash';

import { DEFAULT_CONFIG } from './defaultConfig';

Expand Down Expand Up @@ -73,6 +74,7 @@ const Keybinds = {
};

const ConfigTypeContent = {
acrylic: t.boolean,
cursorBlink: t.boolean,
cursorStyle: t.keyof({
block: null,
Expand Down Expand Up @@ -203,14 +205,26 @@ export const validateConfig = (config: unknown): Config => {
const ResolvedConfigType = t.type(ConfigTypeContent);
export type ResolvedConfig = t.TypeOf<typeof ResolvedConfigType>;

export const resolveConfig = (config: unknown): ResolvedConfig => {
export const resolveConfig = (
config: unknown,
platform: string | null = null,
): ResolvedConfig => {
const validatedConfig = validateConfig(config);

const resolvedConfig = {
...DEFAULT_CONFIG,
..._.cloneDeep(DEFAULT_CONFIG),
...validatedConfig,
};

// acrylic is only supported on Mac
if (resolvedConfig.acrylic && platform !== 'darwin') {
resolvedConfig.acrylic = false;
}

if (resolvedConfig.acrylic) {
resolvedConfig.colorScheme.background = '#00000000';
}

// resolve referenced color names
if (
resolvedConfig.terminalBorderColorActive &&
Expand Down
3 changes: 3 additions & 0 deletions packages/types/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import type { ResolvedConfig } from './config';
* This is the default configuration values for Terminal One.
*/
export const DEFAULT_CONFIG: ResolvedConfig = {
// Whether to use acrylic effect on the window background. This is only supported on Mac.
acrylic: false,

// Number of lines to keep in the scrollback buffer.
scrollback: 10000,

Expand Down
34 changes: 34 additions & 0 deletions packages/types/tests/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,38 @@ describe('config', () => {
terminalBorderColorInactive: DEFAULT_CONFIG.colorScheme.background,
});
});

it('should disable acrylic when not on mac', () => {
const resolved = resolveConfig(
{
acrylic: true,
},
'win32',
);
expect(resolved).toEqual({
...DEFAULT_CONFIG,
acrylic: false,
terminalBorderColorActive: DEFAULT_CONFIG.colorScheme.foreground,
terminalBorderColorInactive: DEFAULT_CONFIG.colorScheme.background,
});
});

it('should overwrite background when acrylic is enabled', () => {
const resolved = resolveConfig(
{
acrylic: true,
},
'darwin',
);
expect(resolved).toEqual({
...DEFAULT_CONFIG,
acrylic: true,
colorScheme: {
...DEFAULT_CONFIG.colorScheme,
background: '#00000000',
},
terminalBorderColorActive: DEFAULT_CONFIG.colorScheme.foreground,
terminalBorderColorInactive: resolved.colorScheme.background,
});
});
});

0 comments on commit 7d94310

Please sign in to comment.