From 85d61c76c28ae196c5fa933326513f4fc70f0d52 Mon Sep 17 00:00:00 2001 From: mon-jai <91261297+mon-jai@users.noreply.github.com> Date: Sun, 8 Oct 2023 23:26:22 +0800 Subject: [PATCH] Add an option to use the Windows title bar (#912) Co-authored-by: Brendan Forster --- app/src/lib/app-state.ts | 4 ++ app/src/lib/get-title-bar-config.ts | 48 +++++++++++++++ app/src/lib/ipc-shared.ts | 4 ++ app/src/lib/stores/app-store.ts | 15 +++++ app/src/main-process/app-window.ts | 4 ++ app/src/main-process/main.ts | 19 ++++++ app/src/models/popup.ts | 2 + app/src/ui/app.tsx | 19 +++--- app/src/ui/dispatcher/dispatcher.ts | 15 +++++ app/src/ui/lib/title-bar-style.ts | 17 ++++++ app/src/ui/main-process-proxy.ts | 7 +++ app/src/ui/preferences/appearance.tsx | 69 ++++++++++++++++++---- app/src/ui/preferences/confirm-restart.tsx | 58 ++++++++++++++++++ app/src/ui/preferences/preferences.tsx | 12 +++- app/src/ui/window/title-bar.tsx | 12 ++-- app/src/ui/window/window-controls.tsx | 5 -- app/styles/ui/window/_title-bar.scss | 10 +++- 17 files changed, 291 insertions(+), 29 deletions(-) create mode 100644 app/src/lib/get-title-bar-config.ts create mode 100644 app/src/ui/lib/title-bar-style.ts create mode 100644 app/src/ui/preferences/confirm-restart.tsx diff --git a/app/src/lib/app-state.ts b/app/src/lib/app-state.ts index cd99ca63d65..9c32f13863d 100644 --- a/app/src/lib/app-state.ts +++ b/app/src/lib/app-state.ts @@ -32,6 +32,7 @@ import { WindowState } from './window-state' import { Shell } from './shells' import { ApplicableTheme, ApplicationTheme } from '../ui/lib/application-theme' +import { TitleBarStyle } from '../ui/lib/title-bar-style' import { IAccountRepositories } from './stores/api-repositories-store' import { ManualConflictResolution } from '../models/manual-conflict-resolution' import { Banner } from '../models/banner' @@ -278,6 +279,9 @@ export interface IAppState { /** The currently applied appearance (aka theme) */ readonly currentTheme: ApplicableTheme + /** The selected title bar style for the application */ + readonly titleBarStyle: TitleBarStyle + /** * A map keyed on a user account (GitHub.com or GitHub Enterprise) * containing an object with repositories that the authenticated diff --git a/app/src/lib/get-title-bar-config.ts b/app/src/lib/get-title-bar-config.ts new file mode 100644 index 00000000000..ced0aeddb2f --- /dev/null +++ b/app/src/lib/get-title-bar-config.ts @@ -0,0 +1,48 @@ +import { writeFile } from 'fs/promises' +import { existsSync, readFileSync } from 'fs' +import { join } from 'path' +import { app } from 'electron' +import { TitleBarStyle } from '../ui/lib/title-bar-style' + +export type TitleBarConfig = { + titleBarStyle: TitleBarStyle +} + +let cachedTitleBarConfig: TitleBarConfig | null = null + +// The function has to be synchronous, +// since we need its return value to create electron BrowserWindow +export function readTitleBarConfigFileSync(): TitleBarConfig { + if (cachedTitleBarConfig) { + return cachedTitleBarConfig + } + + const titleBarConfigPath = getTitleBarConfigPath() + + if (existsSync(titleBarConfigPath)) { + const storedTitleBarConfig = JSON.parse( + readFileSync(titleBarConfigPath, 'utf8') + ) + + if ( + storedTitleBarConfig.titleBarStyle === 'native' || + storedTitleBarConfig.titleBarStyle === 'custom' + ) { + cachedTitleBarConfig = storedTitleBarConfig + } + } + + // Cache the default value if the config file is not found, or if it contains an invalid value. + if (cachedTitleBarConfig == null) { + cachedTitleBarConfig = { titleBarStyle: 'native' } + } + + return cachedTitleBarConfig +} + +export function saveTitleBarConfigFile(config: TitleBarConfig) { + return writeFile(getTitleBarConfigPath(), JSON.stringify(config), 'utf8') +} + +const getTitleBarConfigPath = () => + join(app.getPath('userData'), '.title-bar-config') diff --git a/app/src/lib/ipc-shared.ts b/app/src/lib/ipc-shared.ts index e47dc6f4f03..6d1f5b4f69a 100644 --- a/app/src/lib/ipc-shared.ts +++ b/app/src/lib/ipc-shared.ts @@ -13,6 +13,7 @@ import { Architecture } from './get-architecture' import { EndpointToken } from './endpoint-token' import { PathType } from '../ui/lib/app-proxy' import { ThemeSource } from '../ui/lib/theme-source' +import { TitleBarStyle } from '../ui/lib/title-bar-style' import { DesktopNotificationPermission } from 'desktop-notifications/dist/notification-permission' import { NotificationCallback } from 'desktop-notifications/dist/notification-callback' import { DesktopAliveEvent } from './stores/alive-store' @@ -65,6 +66,7 @@ export type RequestChannels = { blur: () => void 'update-accounts': (accounts: ReadonlyArray) => void 'quit-and-install-updates': () => void + 'restart-app': () => void 'quit-app': () => void 'minimize-window': () => void 'maximize-window': () => void @@ -123,6 +125,8 @@ export type RequestResponseChannels = { 'should-use-dark-colors': () => Promise 'save-guid': (guid: string) => Promise 'get-guid': () => Promise + 'save-title-bar-style': (titleBarStyle: TitleBarStyle) => Promise + 'get-title-bar-style': () => Promise 'show-notification': ( title: string, body: string, diff --git a/app/src/lib/stores/app-store.ts b/app/src/lib/stores/app-store.ts index 1dab7acd59a..23b0edb61d8 100644 --- a/app/src/lib/stores/app-store.ts +++ b/app/src/lib/stores/app-store.ts @@ -80,6 +80,7 @@ import { getPersistedThemeName, setPersistedTheme, } from '../../ui/lib/application-theme' +import { TitleBarStyle } from '../../ui/lib/title-bar-style' import { getAppMenu, getCurrentWindowState, @@ -91,6 +92,8 @@ import { sendWillQuitEvenIfUpdatingSync, quitApp, sendCancelQuittingSync, + saveTitleBarStyle, + getTitleBarStyle, } from '../../ui/main-process-proxy' import { API, @@ -528,6 +531,7 @@ export class AppStore extends TypedBaseStore { private selectedBranchesTab = BranchesTab.Branches private selectedTheme = ApplicationTheme.System private currentTheme: ApplicableTheme = ApplicationTheme.Light + private titleBarStyle: TitleBarStyle = 'native' private useWindowsOpenSSH: boolean = false @@ -1027,6 +1031,7 @@ export class AppStore extends TypedBaseStore { selectedBranchesTab: this.selectedBranchesTab, selectedTheme: this.selectedTheme, currentTheme: this.currentTheme, + titleBarStyle: this.titleBarStyle, apiRepositories: this.apiRepositoriesStore.getState(), useWindowsOpenSSH: this.useWindowsOpenSSH, showCommitLengthWarning: this.showCommitLengthWarning, @@ -2218,6 +2223,8 @@ export class AppStore extends TypedBaseStore { this.emitUpdate() }) + this.titleBarStyle = await getTitleBarStyle() + this.lastThankYou = getObject(lastThankYouKey) this.pullRequestSuggestedNextAction = @@ -6564,6 +6571,14 @@ export class AppStore extends TypedBaseStore { return Promise.resolve() } + /** + * Set the title bar style for the application + */ + public _setTitleBarStyle(titleBarStyle: TitleBarStyle) { + this.titleBarStyle = titleBarStyle + return saveTitleBarStyle(titleBarStyle) + } + public async _resolveCurrentEditor() { const match = await findEditorOrDefault(this.selectedExternalEditor) const resolvedExternalEditor = match != null ? match.editor : null diff --git a/app/src/main-process/app-window.ts b/app/src/main-process/app-window.ts index 0fabf6c23b1..233f0248c14 100644 --- a/app/src/main-process/app-window.ts +++ b/app/src/main-process/app-window.ts @@ -13,6 +13,7 @@ import { getWindowState, registerWindowStateChangedEvents, } from '../lib/window-state' +import { readTitleBarConfigFileSync } from '../lib/get-title-bar-config' import { MenuEvent } from './menu' import { URLActionType } from '../lib/parse-app-url' import { ILaunchStats } from '../lib/stats' @@ -75,6 +76,9 @@ export class AppWindow { } else if (__WIN32__) { windowOptions.frame = false } else if (__LINUX__) { + if (readTitleBarConfigFileSync().titleBarStyle === 'custom') { + windowOptions.frame = false + } windowOptions.icon = join(__dirname, 'static', 'logos', '512x512.png') // relax restriction here for users trying to run app at a small diff --git a/app/src/main-process/main.ts b/app/src/main-process/main.ts index d9e4b3f2946..1a1607b8a65 100644 --- a/app/src/main-process/main.ts +++ b/app/src/main-process/main.ts @@ -44,6 +44,10 @@ import { } from '../lib/get-architecture' import { buildSpellCheckMenu } from './menu/build-spell-check-menu' import { getMainGUID, saveGUIDFile } from '../lib/get-main-guid' +import { + readTitleBarConfigFileSync, + saveTitleBarConfigFile, +} from '../lib/get-title-bar-config' import { getNotificationsPermission, requestNotificationsPermission, @@ -509,6 +513,11 @@ app.on('ready', () => { mainWindow?.quitAndInstallUpdate() ) + ipcMain.on('restart-app', () => { + app.relaunch() + app.exit() + }) + ipcMain.on('quit-app', () => app.quit()) ipcMain.on('minimize-window', () => mainWindow?.minimizeWindow()) @@ -694,6 +703,16 @@ app.on('ready', () => { ipcMain.handle('save-guid', (_, guid) => saveGUIDFile(guid)) + ipcMain.handle( + 'get-title-bar-style', + async () => readTitleBarConfigFileSync().titleBarStyle + ) + + ipcMain.handle( + 'save-title-bar-style', + async (_, titleBarStyle) => await saveTitleBarConfigFile({ titleBarStyle }) + ) + ipcMain.handle('show-notification', async (_, title, body, userInfo) => showNotification(title, body, userInfo) ) diff --git a/app/src/models/popup.ts b/app/src/models/popup.ts index b5691513128..5ee3f50dd54 100644 --- a/app/src/models/popup.ts +++ b/app/src/models/popup.ts @@ -96,6 +96,7 @@ export enum PopupType { UnknownAuthors = 'UnknownAuthors', ConfirmRepoRulesBypass = 'ConfirmRepoRulesBypass', TestIcons = 'TestIcons', + ConfirmRestart = 'ConfirmRestart', } interface IBasePopup { @@ -425,5 +426,6 @@ export type PopupDetail = | { type: PopupType.TestIcons } + | { type: PopupType.ConfirmRestart } export type Popup = IBasePopup & PopupDetail diff --git a/app/src/ui/app.tsx b/app/src/ui/app.tsx index 5b9393bf6f5..6679ef7924e 100644 --- a/app/src/ui/app.tsx +++ b/app/src/ui/app.tsx @@ -71,6 +71,7 @@ import { Welcome } from './welcome' import { AppMenuBar } from './app-menu' import { UpdateAvailable, renderBanner } from './banners' import { Preferences } from './preferences' +import { ConfirmRestart } from './preferences/confirm-restart' import { RepositorySettings } from './repository-settings' import { AppError } from './app-error' import { MissingRepository } from './missing-repository' @@ -1463,8 +1464,8 @@ export class App extends React.Component { * on Windows. */ private renderAppMenuBar() { - // We only render the app menu bar on Windows - if (!__WIN32__) { + // We do not render the app menu bar on macOS + if (__DARWIN__) { return null } @@ -1515,9 +1516,9 @@ export class App extends React.Component { this.state.currentFoldout && this.state.currentFoldout.type === FoldoutType.AppMenu - // As Linux still uses the classic Electron menu, we are opting out of the - // custom menu that is shown as part of the title bar below - if (__LINUX__) { + // We do not render the app menu bar on Linux when the user has selected + // the "native" menu option + if (__LINUX__ && this.state.titleBarStyle === 'native') { return null } @@ -1525,12 +1526,12 @@ export class App extends React.Component { // the title bar when the menu bar is active. On other platforms we // never render the title bar while in full-screen mode. if (inFullScreen) { - if (!__WIN32__ || !menuBarActive) { + if (__DARWIN__ || !menuBarActive) { return null } } - const showAppIcon = __WIN32__ && !this.state.showWelcomeFlow + const showAppIcon = !__DARWIN__ && !this.state.showWelcomeFlow const inWelcomeFlow = this.state.showWelcomeFlow const inNoRepositoriesView = this.inNoRepositoriesViewState() @@ -1723,6 +1724,7 @@ export class App extends React.Component { onDismissed={onPopupDismissedFn} selectedShell={this.state.selectedShell} selectedTheme={this.state.selectedTheme} + titleBarStyle={this.state.titleBarStyle} repositoryIndicatorsEnabled={this.state.repositoryIndicatorsEnabled} onOpenFileInExternalEditor={this.openFileInExternalEditor} underlineLinks={this.state.underlineLinks} @@ -2640,6 +2642,9 @@ export class App extends React.Component { /> ) } + case PopupType.ConfirmRestart: { + return + } default: return assertNever(popup, `Unknown popup type: ${popup}`) } diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index 18a2ab7fb4f..f9dd0b29987 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -91,6 +91,7 @@ import { TipState, IValidBranch } from '../../models/tip' import { Banner, BannerType } from '../../models/banner' import { ApplicationTheme } from '../lib/application-theme' +import { TitleBarStyle } from '../lib/title-bar-style' import { installCLI } from '../lib/install-cli' import { executeMenuItem, @@ -2441,6 +2442,20 @@ export class Dispatcher { return this.appStore._setSelectedTheme(theme) } + /** + * Set the title bar style for the application + */ + public async setTitleBarStyle(titleBarStyle: TitleBarStyle) { + const existingState = this.appStore.getState() + const { titleBarStyle: existingTitleBarStyle } = existingState + + await this.appStore._setTitleBarStyle(titleBarStyle) + + if (titleBarStyle !== existingTitleBarStyle) { + this.showPopup({ type: PopupType.ConfirmRestart }) + } + } + /** * Increments either the `repoWithIndicatorClicked` or * the `repoWithoutIndicatorClicked` metric diff --git a/app/src/ui/lib/title-bar-style.ts b/app/src/ui/lib/title-bar-style.ts new file mode 100644 index 00000000000..452842d7794 --- /dev/null +++ b/app/src/ui/lib/title-bar-style.ts @@ -0,0 +1,17 @@ +/** + * This string enum represents the supported modes for rendering the title bar + * in the app. + * + * - 'native' - Use the default window style and chrome supported by the window + * manager + * + * - 'custom' - Hide the default window style and chrome and display the menu + * provided by GitHub Desktop + * + * This is only available on the Linux build. For other operating systems this + * is not configurable: + * + * - macOS uses the native title bar + * - Windows uses the custom title bar + */ +export type TitleBarStyle = 'native' | 'custom' diff --git a/app/src/ui/main-process-proxy.ts b/app/src/ui/main-process-proxy.ts index 5fb8d758dc9..22f092159ad 100644 --- a/app/src/ui/main-process-proxy.ts +++ b/app/src/ui/main-process-proxy.ts @@ -164,6 +164,9 @@ export const checkForUpdates = invokeProxy('check-for-updates', 1) /** Tell the main process to quit the app and install updates */ export const quitAndInstallUpdate = sendProxy('quit-and-install-updates', 0) +/** Tell the main process to restart the app */ +export const restartApp = sendProxy('restart-app', 0) + /** Tell the main process to quit the app */ export const quitApp = sendProxy('quit-app', 0) @@ -379,6 +382,10 @@ export const showOpenDialog = invokeProxy('show-open-dialog', 1) export const saveGUID = invokeProxy('save-guid', 1) export const getGUID = invokeProxy('get-guid', 0) +/** Tell the main process read/save the the title bar style */ +export const saveTitleBarStyle = invokeProxy('save-title-bar-style', 1) +export const getTitleBarStyle = invokeProxy('get-title-bar-style', 0) + /** Tell the main process to show a notification */ export const showNotification = invokeProxy('show-notification', 3) diff --git a/app/src/ui/preferences/appearance.tsx b/app/src/ui/preferences/appearance.tsx index 26c0a33ca5b..46fb07c1140 100644 --- a/app/src/ui/preferences/appearance.tsx +++ b/app/src/ui/preferences/appearance.tsx @@ -4,18 +4,32 @@ import { supportsSystemThemeChanges, getCurrentlyAppliedTheme, } from '../lib/application-theme' +import { TitleBarStyle } from '../lib/title-bar-style' import { Row } from '../lib/row' import { DialogContent } from '../dialog' import { RadioGroup } from '../lib/radio-group' +import { Select } from '../lib/select' import { encodePathAsUrl } from '../../lib/path' interface IAppearanceProps { readonly selectedTheme: ApplicationTheme readonly onSelectedThemeChanged: (theme: ApplicationTheme) => void + readonly titleBarStyle: TitleBarStyle + readonly onTitleBarStyleChanged: (titleBarStyle: TitleBarStyle) => void } interface IAppearanceState { readonly selectedTheme: ApplicationTheme | null + readonly titleBarStyle: TitleBarStyle +} + +function getTitleBarStyleDescription(titleBarStyle: TitleBarStyle): string { + switch (titleBarStyle) { + case 'custom': + return 'Uses the menu system provided by GitHub Desktop, hiding the default chrome provided by your window manager.' + case 'native': + return 'Uses the menu system and chrome provided by your window manager.' + } } export class Appearance extends React.Component< @@ -29,7 +43,10 @@ export class Appearance extends React.Component< props.selectedTheme !== ApplicationTheme.System || supportsSystemThemeChanges() - this.state = { selectedTheme: usePropTheme ? props.selectedTheme : null } + this.state = { + selectedTheme: usePropTheme ? props.selectedTheme : null, + titleBarStyle: props.titleBarStyle, + } if (!usePropTheme) { this.initializeSelectedTheme() @@ -61,6 +78,12 @@ export class Appearance extends React.Component< this.props.onSelectedThemeChanged(theme) } + private onSelectChanged = (event: React.FormEvent) => { + const titleBarStyle = event.currentTarget.value as TitleBarStyle + this.setState({ titleBarStyle }) + this.props.onTitleBarStyleChanged(titleBarStyle) + } + public renderThemeSwatch = (theme: ApplicationTheme) => { const darkThemeImage = encodePathAsUrl(__dirname, 'static/ghd_dark.svg') const lightThemeImage = encodePathAsUrl(__dirname, 'static/ghd_light.svg') @@ -98,6 +121,29 @@ export class Appearance extends React.Component< } } + private renderTitleBarStyleDropdown() { + const { titleBarStyle } = this.state + const titleBarStyleDescription = getTitleBarStyleDescription(titleBarStyle) + + return ( +
+

Title bar style

+ + + +
+ {titleBarStyleDescription} +
+
+ ) + } + public render() { const { selectedTheme } = this.state @@ -118,15 +164,18 @@ export class Appearance extends React.Component< return (

Theme

- - - ariaLabelledBy="theme-heading" - className="theme-selector" - selectedKey={selectedTheme} - radioButtonKeys={themes} - onSelectionChanged={this.onSelectedThemeChanged} - renderRadioButtonLabelContents={this.renderThemeSwatch} - /> + + + ariaLabelledBy="theme-heading" + className="theme-selector" + selectedKey={selectedTheme} + radioButtonKeys={themes} + onSelectionChanged={this.onSelectedThemeChanged} + renderRadioButtonLabelContents={this.renderThemeSwatch} + /> + + + {this.renderTitleBarStyleDropdown()}
) } diff --git a/app/src/ui/preferences/confirm-restart.tsx b/app/src/ui/preferences/confirm-restart.tsx new file mode 100644 index 00000000000..537ee0a320b --- /dev/null +++ b/app/src/ui/preferences/confirm-restart.tsx @@ -0,0 +1,58 @@ +import * as React from 'react' +import { + Dialog, + DialogContent, + DialogFooter, + OkCancelButtonGroup, +} from '../dialog' +import { restartApp } from '../main-process-proxy' + +interface IConfirmRestartProps { + /** + * Callback to use when the dialog gets closed. + */ + readonly onDismissed: () => void +} + +export class ConfirmRestart extends React.Component { + public constructor(props: IConfirmRestartProps) { + super(props) + } + + public render() { + return ( + + +

Restart GitHub Desktop to apply the title bar settings change?

+
+ {this.renderFooter()} +
+ ) + } + + private renderFooter() { + return ( + + + + ) + } + + private onNotNow = () => { + this.props.onDismissed() + } + + private onSubmit = async () => { + this.props.onDismissed() + restartApp() + } +} diff --git a/app/src/ui/preferences/preferences.tsx b/app/src/ui/preferences/preferences.tsx index 342def67d8e..f9a81565026 100644 --- a/app/src/ui/preferences/preferences.tsx +++ b/app/src/ui/preferences/preferences.tsx @@ -22,6 +22,7 @@ import { } from '../lib/identifier-rules' import { Appearance } from './appearance' import { ApplicationTheme } from '../lib/application-theme' +import { TitleBarStyle } from '../lib/title-bar-style' import { OkCancelButtonGroup } from '../dialog/ok-cancel-button-group' import { Integrations } from './integrations' import { @@ -67,6 +68,7 @@ interface IPreferencesProps { readonly selectedExternalEditor: string | null readonly selectedShell: Shell readonly selectedTheme: ApplicationTheme + readonly titleBarStyle: TitleBarStyle readonly repositoryIndicatorsEnabled: boolean readonly onOpenFileInExternalEditor: (path: string) => void readonly underlineLinks: boolean @@ -98,7 +100,7 @@ interface IPreferencesState { readonly selectedExternalEditor: string | null readonly availableShells: ReadonlyArray readonly selectedShell: Shell - + readonly titleBarStyle: TitleBarStyle /** * If unable to save Git configuration values (name, email) * due to an existing configuration lock file this property @@ -152,6 +154,7 @@ export class Preferences extends React.Component< selectedExternalEditor: this.props.selectedExternalEditor, availableShells: [], selectedShell: this.props.selectedShell, + titleBarStyle: this.props.titleBarStyle, repositoryIndicatorsEnabled: this.props.repositoryIndicatorsEnabled, initiallySelectedTheme: this.props.selectedTheme, isLoadingGitConfig: true, @@ -413,6 +416,8 @@ export class Preferences extends React.Component< ) break @@ -602,6 +607,10 @@ export class Preferences extends React.Component< this.setState({ showDiffCheckMarks }) } + private onTitleBarStyleChanged = (titleBarStyle: TitleBarStyle) => { + this.setState({ titleBarStyle }) + } + private renderFooter() { const hasDisabledError = this.state.disallowedCharactersMessage != null @@ -711,6 +720,7 @@ export class Preferences extends React.Component< ) } await this.props.dispatcher.setShell(this.state.selectedShell) + await this.props.dispatcher.setTitleBarStyle(this.state.titleBarStyle) await this.props.dispatcher.setConfirmDiscardChangesSetting( this.state.confirmDiscardChanges ) diff --git a/app/src/ui/window/title-bar.tsx b/app/src/ui/window/title-bar.tsx index b6fe9b7c041..4de3108240f 100644 --- a/app/src/ui/window/title-bar.tsx +++ b/app/src/ui/window/title-bar.tsx @@ -84,7 +84,7 @@ export class TitleBar extends React.Component { const isMaximized = this.props.windowState === 'maximized' // No Windows controls when we're in full-screen mode. - const winControls = __WIN32__ && !inFullScreen ? : null + const winControls = !inFullScreen ? : null // On Windows it's not possible to resize a frameless window if the // element that sits flush along the window edge has -webkit-app-region: drag. @@ -92,12 +92,14 @@ export class TitleBar extends React.Component { // window controls need to disable dragging so we add a 3px tall element which // disables drag while still letting users drag the app by the titlebar below // those 3px. - const topResizeHandle = - __WIN32__ && !isMaximized ?
: null + const topResizeHandle = !isMaximized ? ( +
+ ) : null // And a 3px wide element on the left hand side. - const leftResizeHandle = - __WIN32__ && !isMaximized ?
: null + const leftResizeHandle = !isMaximized ? ( +
+ ) : null const titleBarClass = this.props.titleBarStyle === 'light' ? 'light-title-bar' : '' diff --git a/app/src/ui/window/window-controls.tsx b/app/src/ui/window/window-controls.tsx index a98aef33062..558d33f47dc 100644 --- a/app/src/ui/window/window-controls.tsx +++ b/app/src/ui/window/window-controls.tsx @@ -114,11 +114,6 @@ export class WindowControls extends React.Component<{}, IWindowControlState> { } public render() { - // We only know how to render fake Windows-y controls - if (!__WIN32__) { - return - } - const min = this.renderButton('minimize', this.onMinimize, minimizePath) const maximizeOrRestore = this.state.windowState === 'maximized' diff --git a/app/styles/ui/window/_title-bar.scss b/app/styles/ui/window/_title-bar.scss index 2662b3bb513..6dae12eab55 100644 --- a/app/styles/ui/window/_title-bar.scss +++ b/app/styles/ui/window/_title-bar.scss @@ -15,7 +15,7 @@ border-bottom: 1px solid #000; } - @include win32 { + @mixin custom-title-bar { height: var(--win32-title-bar-height); background: var(--win32-title-bar-background-color); border-bottom: 1px solid #000; @@ -27,6 +27,14 @@ } } + @include win32 { + @include custom-title-bar; + } + + @include linux { + @include custom-title-bar; + } + .resize-handle { position: absolute; top: 0px;