Skip to content

Commit

Permalink
Use native dark theme titlebar on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny-signal committed Jan 16, 2024
1 parent b574ba5 commit 23e3883
Show file tree
Hide file tree
Showing 43 changed files with 150 additions and 963 deletions.
2 changes: 0 additions & 2 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import React from 'react';

import 'sanitize.css';
import '../stylesheets/manifest.scss';
import '../node_modules/@indutny/frameless-titlebar/dist/styles.css';

import * as styles from './styles.scss';
import messages from '../_locales/en/messages.json';
Expand Down Expand Up @@ -97,7 +96,6 @@ window.SignalContext = {
waitForChange: () => new Promise(noop),
},
OS: {
hasCustomTitleBar: () => false,
getClassName: () => '',
platform: '',
release: '',
Expand Down
24 changes: 0 additions & 24 deletions ACKNOWLEDGMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,6 @@ Signal Desktop makes use of the following open source projects.

License: MIT

## @indutny/frameless-titlebar

MIT License

Copyright (c) 2019 Cristian Ponce

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

## @indutny/sneequals

Copyright Fedor Indutny, 2022.
Expand Down
5 changes: 0 additions & 5 deletions about.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
rel="stylesheet"
type="text/css"
/>
<link
href="node_modules/@indutny/frameless-titlebar/dist/styles.css"
rel="stylesheet"
type="text/css"
/>
<link href="stylesheets/manifest.css" rel="stylesheet" type="text/css" />
</head>
<body>
Expand Down
1 change: 0 additions & 1 deletion app/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ if (getEnvironment() === Environment.Production) {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '';
process.env.SIGNAL_ENABLE_HTTP = '';
process.env.SIGNAL_CI_CONFIG = '';
process.env.CUSTOM_TITLEBAR = '';
}

// We load config after we've made our modifications to NODE_ENV
Expand Down
128 changes: 7 additions & 121 deletions app/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
} from 'electron';
import type {
MenuItemConstructorOptions,
TitleBarOverlayOptions,
LoginItemSettingsOptions,
} from 'electron';
import { z } from 'zod';
Expand Down Expand Up @@ -95,7 +94,6 @@ import { MainSQL } from '../ts/sql/main';
import * as sqlChannels from './sql_channel';
import * as windowState from './window_state';
import type { CreateTemplateOptionsType } from './menu';
import type { MenuActionType } from '../ts/types/menu';
import { createTemplate } from './menu';
import { installFileHandler, installWebHandler } from './protocol_filter';
import OS from '../ts/util/os/osMain';
Expand Down Expand Up @@ -541,10 +539,7 @@ async function handleUrl(rawTarget: string) {
}
}

async function handleCommonWindowEvents(
window: BrowserWindow,
titleBarOverlay: TitleBarOverlayOptions | false = false
) {
async function handleCommonWindowEvents(window: BrowserWindow) {
window.webContents.on('will-navigate', (event, rawTarget) => {
event.preventDefault();

Expand Down Expand Up @@ -578,23 +573,6 @@ async function handleCommonWindowEvents(
await zoomFactorService.syncWindow(window);

nativeThemeNotifier.addWindow(window);

if (titleBarOverlay) {
const onThemeChange = async () => {
try {
const newOverlay = await getTitleBarOverlay();
if (!newOverlay) {
return;
}
window.setTitleBarOverlay(newOverlay);
} catch (error) {
console.error('onThemeChange error', error);
}
};

nativeTheme.on('updated', onThemeChange);
settingsChannel?.on('change:themeSetting', onThemeChange);
}
}

const DEFAULT_WIDTH = ciMode ? 1024 : 800;
Expand Down Expand Up @@ -654,45 +632,11 @@ if (OS.isWindows()) {
// - Windows < 10 (7, 8)
// - macOS (but no custom titlebar is displayed, see
// `--title-bar-drag-area-height` in `stylesheets/_titlebar.scss`
const mainTitleBarStyle =
(OS.isMacOS() || OS.hasCustomTitleBar()) &&
!isTestEnvironment(getEnvironment())
? ('hidden' as const)
: ('default' as const);

const nonMainTitleBarStyle = OS.hasCustomTitleBar()
const mainTitleBarStyle = OS.isMacOS()
? ('hidden' as const)
: ('default' as const);

async function getTitleBarOverlay(): Promise<TitleBarOverlayOptions | false> {
if (!OS.hasCustomTitleBar()) {
return false;
}

const theme = await getResolvedThemeSetting();

let color: string;
let symbolColor: string;
if (theme === 'light') {
color = '#e8e8e8';
symbolColor = '#1b1b1b';
} else if (theme === 'dark') {
// $color-gray-80
color = '#2e2e2e';
// $color-gray-05
symbolColor = '#e9e9e9';
} else {
throw missingCaseError(theme);
}

return {
color,
symbolColor,

// Should match `--titlebar-height` in stylesheets/_titlebar.scss
height: 28 - 1,
};
}
const nonMainTitleBarStyle = 'default' as const;

async function safeLoadURL(window: BrowserWindow, url: string): Promise<void> {
let wasDestroyed = false;
Expand Down Expand Up @@ -731,8 +675,6 @@ async function createWindow() {
const usePreloadBundle =
!isTestEnvironment(getEnvironment()) || forcePreloadBundle;

const titleBarOverlay = await getTitleBarOverlay();

const windowOptions: Electron.BrowserWindowConstructorOptions = {
show: false,
width: DEFAULT_WIDTH,
Expand All @@ -741,7 +683,6 @@ async function createWindow() {
minHeight: MIN_HEIGHT,
autoHideMenuBar: false,
titleBarStyle: mainTitleBarStyle,
titleBarOverlay,
backgroundColor: isTestEnvironment(getEnvironment())
? '#ffffff' // Tests should always be rendered on a white background
: await getBackgroundColor(),
Expand Down Expand Up @@ -887,7 +828,7 @@ async function createWindow() {
mainWindow.webContents.openDevTools();
}

await handleCommonWindowEvents(mainWindow, titleBarOverlay);
await handleCommonWindowEvents(mainWindow);

// App dock icon bounce
bounce.init(mainWindow);
Expand Down Expand Up @@ -1288,15 +1229,12 @@ async function showAbout() {
return;
}

const titleBarOverlay = await getTitleBarOverlay();

const options = {
width: 500,
height: 500,
resizable: false,
title: getResolvedMessagesLocale().i18n('icu:aboutSignalDesktop'),
titleBarStyle: nonMainTitleBarStyle,
titleBarOverlay,
autoHideMenuBar: true,
backgroundColor: await getBackgroundColor(),
show: false,
Expand All @@ -1313,7 +1251,7 @@ async function showAbout() {

aboutWindow = new BrowserWindow(options);

await handleCommonWindowEvents(aboutWindow, titleBarOverlay);
await handleCommonWindowEvents(aboutWindow);

aboutWindow.on('closed', () => {
aboutWindow = undefined;
Expand All @@ -1338,16 +1276,13 @@ async function showSettingsWindow() {
return;
}

const titleBarOverlay = await getTitleBarOverlay();

const options = {
width: 700,
height: 700,
frame: true,
resizable: false,
title: getResolvedMessagesLocale().i18n('icu:signalDesktopPreferences'),
titleBarStyle: mainTitleBarStyle,
titleBarOverlay,
autoHideMenuBar: true,
backgroundColor: await getBackgroundColor(),
show: false,
Expand All @@ -1364,7 +1299,7 @@ async function showSettingsWindow() {

settingsWindow = new BrowserWindow(options);

await handleCommonWindowEvents(settingsWindow, titleBarOverlay);
await handleCommonWindowEvents(settingsWindow);

settingsWindow.on('closed', () => {
settingsWindow = undefined;
Expand Down Expand Up @@ -1434,15 +1369,12 @@ async function showDebugLogWindow() {
}
}

const titleBarOverlay = await getTitleBarOverlay();

const options: Electron.BrowserWindowConstructorOptions = {
width: 700,
height: 500,
resizable: false,
title: getResolvedMessagesLocale().i18n('icu:debugLog'),
titleBarStyle: nonMainTitleBarStyle,
titleBarOverlay,
autoHideMenuBar: true,
backgroundColor: await getBackgroundColor(),
show: false,
Expand All @@ -1459,7 +1391,7 @@ async function showDebugLogWindow() {

debugLogWindow = new BrowserWindow(options);

await handleCommonWindowEvents(debugLogWindow, titleBarOverlay);
await handleCommonWindowEvents(debugLogWindow);

debugLogWindow.on('closed', () => {
debugLogWindow = undefined;
Expand Down Expand Up @@ -2504,12 +2436,6 @@ ipc.on('locale-display-names', event => {
event.returnValue = getResolvedMessagesLocale().localeDisplayNames;
});

// TODO DESKTOP-5241
ipc.on('OS.getHasCustomTitleBar', event => {
// eslint-disable-next-line no-param-reassign
event.returnValue = OS.hasCustomTitleBar();
});

// TODO DESKTOP-5241
ipc.on('OS.getClassName', event => {
// eslint-disable-next-line no-param-reassign
Expand Down Expand Up @@ -2836,46 +2762,6 @@ async function zoomReset() {
await zoomFactorService.zoomReset();
}

ipc.handle('executeMenuAction', async (_event, action: MenuActionType) => {
if (action === 'forceUpdate') {
drop(forceUpdate());
} else if (action === 'openArtCreator') {
drop(openArtCreator());
} else if (action === 'openContactUs') {
openContactUs();
} else if (action === 'openForums') {
openForums();
} else if (action === 'openJoinTheBeta') {
openJoinTheBeta();
} else if (action === 'openReleaseNotes') {
openReleaseNotes();
} else if (action === 'openSupportPage') {
openSupportPage();
} else if (action === 'setupAsNewDevice') {
setupAsNewDevice();
} else if (action === 'setupAsStandalone') {
setupAsStandalone();
} else if (action === 'showAbout') {
drop(showAbout());
} else if (action === 'showDebugLog') {
drop(showDebugLogWindow());
} else if (action === 'showKeyboardShortcuts') {
showKeyboardShortcuts();
} else if (action === 'showSettings') {
drop(showSettingsWindow());
} else if (action === 'showWindow') {
showWindow();
} else if (action === 'zoomIn') {
drop(zoomIn());
} else if (action === 'zoomOut') {
drop(zoomOut());
} else if (action === 'zoomReset') {
drop(zoomReset());
} else {
throw missingCaseError(action);
}
});

ipc.handle(
'net.resolveHost',
(_event, hostname: string, queryType?: 'A' | 'AAAA') => {
Expand Down
5 changes: 0 additions & 5 deletions background.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,6 @@
rel="stylesheet"
type="text/css"
/>
<link
href="node_modules/@indutny/frameless-titlebar/dist/styles.css"
rel="stylesheet"
type="text/css"
/>
<link href="stylesheets/manifest.css" rel="stylesheet" type="text/css" />
</head>
<body class="overflow-hidden">
Expand Down
5 changes: 0 additions & 5 deletions debug_log.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
rel="stylesheet"
type="text/css"
/>
<link
href="node_modules/@indutny/frameless-titlebar/dist/styles.css"
rel="stylesheet"
type="text/css"
/>
<link href="stylesheets/manifest.css" rel="stylesheet" type="text/css" />
</head>
<body>
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
"dependencies": {
"@formatjs/fast-memoize": "1.2.6",
"@formatjs/intl-localematcher": "0.2.32",
"@indutny/frameless-titlebar": "2.3.5",
"@indutny/sneequals": "4.0.0",
"@nodert-win10-rs4/windows.data.xml.dom": "0.4.4",
"@nodert-win10-rs4/windows.ui.notifications": "0.4.4",
Expand Down
5 changes: 0 additions & 5 deletions settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@
rel="stylesheet"
type="text/css"
/>
<link
href="node_modules/@indutny/frameless-titlebar/dist/styles.css"
rel="stylesheet"
type="text/css"
/>
<link href="stylesheets/manifest.css" rel="stylesheet" type="text/css" />
</head>
<body>
Expand Down
4 changes: 2 additions & 2 deletions stylesheets/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -784,8 +784,8 @@ $rtl-icon-map: (
@mixin install-screen {
align-items: center;
display: flex;
width: var(--window-width);
height: var(--window-height);
width: 100vw;
height: 100vh;
justify-content: center;
line-height: 30px;
user-select: none;
Expand Down

0 comments on commit 23e3883

Please sign in to comment.