[MM-59841] Migrate to titleBarOverlay
for Windows (#3111)
This commit is contained in:
parent
b2cd2dc60d
commit
8ff64d285a
|
@ -1,3 +0,0 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.16763 0.00233459L9.98984 0.825763L5.8259 4.99587L9.99767 9.16147L9.17424 9.98368L5.0037 5.8193L0.831506 9.99768L0.0092966 9.17425L4.18027 4.99709L0.00232887 0.82533L0.825757 0.00311899L5.00248 4.17366L9.16763 0.00233459Z" fill="black"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 392 B |
|
@ -1,3 +0,0 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="9" height="9" stroke="black"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 163 B |
|
@ -1,3 +0,0 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="4" width="10" height="1" fill="black"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 152 B |
|
@ -1,3 +0,0 @@
|
|||
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 8V10H0V2H2V0H10V8H8ZM7 3H1V9H7V3ZM3 2H8V7H9V1H3V2Z" fill="black"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 222 B |
|
@ -45,10 +45,7 @@ export const MODAL_RESULT = 'modal-result';
|
|||
export const MODAL_OPEN = 'modal-open';
|
||||
export const MODAL_CLOSE = 'modal-close';
|
||||
export const NOTIFY_MENTION = 'notify_mention';
|
||||
export const WINDOW_CLOSE = 'window_close';
|
||||
export const WINDOW_MINIMIZE = 'window_minimize';
|
||||
export const WINDOW_MAXIMIZE = 'window_maximize';
|
||||
export const WINDOW_RESTORE = 'window_restore';
|
||||
export const EXIT_FULLSCREEN = 'exit-fullscreen';
|
||||
export const GET_FULL_SCREEN_STATUS = 'get-full-screen-status';
|
||||
|
||||
export const UPDATE_TARGET_URL = 'update_target_url';
|
||||
|
|
|
@ -319,7 +319,6 @@ describe('common/config', () => {
|
|||
const config = new Config();
|
||||
config.reload = jest.fn();
|
||||
config.init(configPath, appName, appPath);
|
||||
config.useNativeWindow = false;
|
||||
config.defaultConfigData = {defaultSetting: 'default', otherDefaultSetting: 'default'};
|
||||
config.localConfigData = {otherDefaultSetting: 'local', localSetting: 'local', otherLocalSetting: 'local'};
|
||||
config.buildConfigData = {otherLocalSetting: 'build', buildSetting: 'build', otherBuildSetting: 'build'};
|
||||
|
@ -329,7 +328,6 @@ describe('common/config', () => {
|
|||
config.combinedData.darkMode = false;
|
||||
expect(config.combinedData).toStrictEqual({
|
||||
appName: 'app-name',
|
||||
useNativeWindow: false,
|
||||
darkMode: false,
|
||||
otherBuildSetting: 'registry',
|
||||
registrySetting: 'registry',
|
||||
|
@ -350,7 +348,6 @@ describe('common/config', () => {
|
|||
config.buildConfigData = {enableServerManagement: true};
|
||||
config.registryConfigData = {};
|
||||
config.predefinedServers.push(server, server);
|
||||
config.useNativeWindow = false;
|
||||
config.localConfigData = {teams: [
|
||||
server,
|
||||
{
|
||||
|
@ -370,7 +367,6 @@ describe('common/config', () => {
|
|||
config.combinedData.darkMode = false;
|
||||
expect(config.combinedData).toStrictEqual({
|
||||
appName: 'app-name',
|
||||
useNativeWindow: false,
|
||||
darkMode: false,
|
||||
enableServerManagement: true,
|
||||
});
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
import {EventEmitter} from 'events';
|
||||
|
||||
import {Logger} from 'common/log';
|
||||
import Utils, {copy} from 'common/utils/util';
|
||||
import {copy} from 'common/utils/util';
|
||||
import * as Validator from 'common/Validator';
|
||||
import {getDefaultViewsForConfigServer} from 'common/views/View';
|
||||
|
||||
|
@ -36,7 +35,6 @@ export class Config extends EventEmitter {
|
|||
|
||||
private registryConfig: RegistryConfig;
|
||||
private _predefinedServers: ConfigServer[];
|
||||
private useNativeWindow: boolean;
|
||||
|
||||
private combinedData?: CombinedConfig;
|
||||
private localConfigData?: ConfigType;
|
||||
|
@ -52,11 +50,6 @@ export class Config extends EventEmitter {
|
|||
if (buildConfig.defaultServers) {
|
||||
this._predefinedServers.push(...buildConfig.defaultServers.map((server, index) => getDefaultViewsForConfigServer({...server, order: index})));
|
||||
}
|
||||
try {
|
||||
this.useNativeWindow = os.platform() === 'win32' && !Utils.isVersionGreaterThanOrEqualTo(os.release(), '6.2');
|
||||
} catch {
|
||||
this.useNativeWindow = false;
|
||||
}
|
||||
}
|
||||
|
||||
init = (configFilePath: string, appName: string, appPath: string) => {
|
||||
|
@ -370,7 +363,6 @@ export class Config extends EventEmitter {
|
|||
this.localConfigData,
|
||||
this.buildConfigData,
|
||||
this.registryConfigData,
|
||||
{useNativeWindow: this.useNativeWindow},
|
||||
);
|
||||
|
||||
// We don't want to include the servers in the combined config, they should only be accesible via the ServerManager
|
||||
|
|
|
@ -25,10 +25,6 @@ import {
|
|||
UPDATE_PATHS,
|
||||
SERVERS_URL_MODIFIED,
|
||||
GET_DARK_MODE,
|
||||
WINDOW_CLOSE,
|
||||
WINDOW_MAXIMIZE,
|
||||
WINDOW_MINIMIZE,
|
||||
WINDOW_RESTORE,
|
||||
DOUBLE_CLICK_ON_WINDOW,
|
||||
TOGGLE_SECURE_INPUT,
|
||||
GET_APP_INFO,
|
||||
|
@ -97,12 +93,8 @@ import {
|
|||
flushCookiesStore,
|
||||
} from './utils';
|
||||
import {
|
||||
handleClose,
|
||||
handleDoubleClick,
|
||||
handleGetDarkMode,
|
||||
handleMaximize,
|
||||
handleMinimize,
|
||||
handleRestore,
|
||||
} from './windows';
|
||||
|
||||
import {protocols} from '../../../electron-builder.json';
|
||||
|
@ -283,10 +275,6 @@ function initializeInterCommunicationEventListeners() {
|
|||
ipcMain.on(UPDATE_CONFIGURATION, updateConfiguration);
|
||||
|
||||
ipcMain.handle(GET_DARK_MODE, handleGetDarkMode);
|
||||
ipcMain.on(WINDOW_CLOSE, handleClose);
|
||||
ipcMain.on(WINDOW_MAXIMIZE, handleMaximize);
|
||||
ipcMain.on(WINDOW_MINIMIZE, handleMinimize);
|
||||
ipcMain.on(WINDOW_RESTORE, handleRestore);
|
||||
ipcMain.on(DOUBLE_CLICK_ON_WINDOW, handleDoubleClick);
|
||||
|
||||
ipcMain.on(TOGGLE_SECURE_INPUT, handleToggleSecureInput);
|
||||
|
|
|
@ -13,20 +13,6 @@ export const handleGetDarkMode = () => {
|
|||
return Config.darkMode;
|
||||
};
|
||||
|
||||
export const handleClose = (event: IpcMainEvent) => BrowserWindow.fromWebContents(event.sender)?.close();
|
||||
export const handleMaximize = (event: IpcMainEvent) => BrowserWindow.fromWebContents(event.sender)?.maximize();
|
||||
export const handleMinimize = (event: IpcMainEvent) => BrowserWindow.fromWebContents(event.sender)?.minimize();
|
||||
export const handleRestore = (event: IpcMainEvent) => {
|
||||
const window = BrowserWindow.fromWebContents(event.sender);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
window.restore();
|
||||
if (window.isFullScreen()) {
|
||||
window.setFullScreen(false);
|
||||
}
|
||||
};
|
||||
|
||||
export const handleDoubleClick = (event: IpcMainEvent, windowType?: string) => {
|
||||
log.debug('handleDoubleClick', windowType);
|
||||
|
||||
|
|
|
@ -14,10 +14,7 @@ import {
|
|||
OPEN_SERVERS_DROPDOWN,
|
||||
SWITCH_TAB,
|
||||
CLOSE_VIEW,
|
||||
WINDOW_CLOSE,
|
||||
WINDOW_MINIMIZE,
|
||||
WINDOW_MAXIMIZE,
|
||||
WINDOW_RESTORE,
|
||||
EXIT_FULLSCREEN,
|
||||
DOUBLE_CLICK_ON_WINDOW,
|
||||
FOCUS_BROWSERVIEW,
|
||||
RELOAD_CURRENT_VIEW,
|
||||
|
@ -117,10 +114,7 @@ contextBridge.exposeInMainWorld('desktop', {
|
|||
openServersDropdown: () => ipcRenderer.send(OPEN_SERVERS_DROPDOWN),
|
||||
switchTab: (viewId) => ipcRenderer.send(SWITCH_TAB, viewId),
|
||||
closeView: (viewId) => ipcRenderer.send(CLOSE_VIEW, viewId),
|
||||
closeWindow: () => ipcRenderer.send(WINDOW_CLOSE),
|
||||
minimizeWindow: () => ipcRenderer.send(WINDOW_MINIMIZE),
|
||||
maximizeWindow: () => ipcRenderer.send(WINDOW_MAXIMIZE),
|
||||
restoreWindow: () => ipcRenderer.send(WINDOW_RESTORE),
|
||||
exitFullScreen: () => ipcRenderer.send(EXIT_FULLSCREEN),
|
||||
doubleClickOnWindow: (windowName) => ipcRenderer.send(DOUBLE_CLICK_ON_WINDOW, windowName),
|
||||
focusCurrentView: () => ipcRenderer.send(FOCUS_BROWSERVIEW),
|
||||
reloadCurrentView: () => ipcRenderer.send(RELOAD_CURRENT_VIEW),
|
||||
|
|
|
@ -18,13 +18,13 @@ import {
|
|||
SERVERS_UPDATE,
|
||||
UPDATE_APPSTATE_FOR_VIEW_ID,
|
||||
UPDATE_MENTIONS,
|
||||
MAXIMIZE_CHANGE,
|
||||
MAIN_WINDOW_CREATED,
|
||||
MAIN_WINDOW_RESIZED,
|
||||
MAIN_WINDOW_FOCUSED,
|
||||
VIEW_FINISHED_RESIZING,
|
||||
TOGGLE_SECURE_INPUT,
|
||||
EMIT_CONFIGURATION,
|
||||
EXIT_FULLSCREEN,
|
||||
} from 'common/communication';
|
||||
import Config from 'common/config';
|
||||
import {Logger} from 'common/log';
|
||||
|
@ -50,7 +50,6 @@ export class MainWindow extends EventEmitter {
|
|||
private ready: boolean;
|
||||
private isResizing: boolean;
|
||||
private lastEmittedBounds?: Electron.Rectangle;
|
||||
private isMaximized: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -58,11 +57,11 @@ export class MainWindow extends EventEmitter {
|
|||
// Create the browser window.
|
||||
this.ready = false;
|
||||
this.isResizing = false;
|
||||
this.isMaximized = false;
|
||||
|
||||
ipcMain.handle(GET_FULL_SCREEN_STATUS, () => this.win?.isFullScreen());
|
||||
ipcMain.on(VIEW_FINISHED_RESIZING, this.handleViewFinishedResizing);
|
||||
ipcMain.on(EMIT_CONFIGURATION, this.handleUpdateTitleBarOverlay);
|
||||
ipcMain.on(EXIT_FULLSCREEN, this.handleExitFullScreen);
|
||||
|
||||
ServerManager.on(SERVERS_UPDATE, this.handleUpdateConfig);
|
||||
|
||||
|
@ -83,7 +82,7 @@ export class MainWindow extends EventEmitter {
|
|||
frame: !this.isFramelessWindow(),
|
||||
fullscreen: this.shouldStartFullScreen(),
|
||||
titleBarStyle: 'hidden' as const,
|
||||
titleBarOverlay: process.platform === 'linux' ? this.getTitleBarOverlay() : false,
|
||||
titleBarOverlay: this.getTitleBarOverlay(),
|
||||
trafficLightPosition: {x: 12, y: 12},
|
||||
backgroundColor: '#fff', // prevents blurry text: https://electronjs.org/docs/faq#the-font-looks-blurry-what-is-this-and-what-can-i-do
|
||||
webPreferences: {
|
||||
|
@ -129,9 +128,6 @@ export class MainWindow extends EventEmitter {
|
|||
this.win.on('focus', this.onFocus);
|
||||
this.win.on('blur', this.onBlur);
|
||||
this.win.on('unresponsive', this.onUnresponsive);
|
||||
this.win.on('maximize', this.onMaximize);
|
||||
this.win.on('unmaximize', this.onUnmaximize);
|
||||
this.win.on('restore', this.onRestore);
|
||||
this.win.on('enter-full-screen', this.onEnterFullScreen);
|
||||
this.win.on('leave-full-screen', this.onLeaveFullScreen);
|
||||
this.win.on('will-resize', this.onWillResize);
|
||||
|
@ -252,6 +248,7 @@ export class MainWindow extends EventEmitter {
|
|||
private getTitleBarOverlay = () => {
|
||||
return {
|
||||
color: Config.darkMode ? '#2e2e2e' : '#efefef',
|
||||
symbolColor: Config.darkMode ? '#c1c1c1' : '#474747',
|
||||
height: TAB_BAR_HEIGHT,
|
||||
};
|
||||
};
|
||||
|
@ -465,24 +462,6 @@ export class MainWindow extends EventEmitter {
|
|||
}, 10);
|
||||
};
|
||||
|
||||
private onMaximize = () => {
|
||||
this.isMaximized = true;
|
||||
this.win?.webContents.send(MAXIMIZE_CHANGE, true);
|
||||
this.emitBounds();
|
||||
};
|
||||
|
||||
private onUnmaximize = () => {
|
||||
this.isMaximized = false;
|
||||
this.win?.webContents.send(MAXIMIZE_CHANGE, false);
|
||||
this.emitBounds();
|
||||
};
|
||||
|
||||
private onRestore = () => {
|
||||
if (this.isMaximized && !this.win?.isMaximized()) {
|
||||
this.win?.maximize();
|
||||
}
|
||||
};
|
||||
|
||||
private onEnterFullScreen = () => {
|
||||
this.win?.webContents.send('enter-full-screen');
|
||||
this.emitBounds();
|
||||
|
@ -544,6 +523,12 @@ export class MainWindow extends EventEmitter {
|
|||
this.isResizing = false;
|
||||
};
|
||||
|
||||
private handleExitFullScreen = () => {
|
||||
if (this.win?.isFullScreen()) {
|
||||
this.win.setFullScreen(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Server Manager update handler
|
||||
*/
|
||||
|
|
|
@ -18,10 +18,6 @@ import ExtraBar from './ExtraBar';
|
|||
import ServerDropdownButton from './ServerDropdownButton';
|
||||
import TabBar from './TabBar';
|
||||
|
||||
import closeButton from '../../assets/titlebar/chrome-close.svg';
|
||||
import maximizeButton from '../../assets/titlebar/chrome-maximize.svg';
|
||||
import minimizeButton from '../../assets/titlebar/chrome-minimize.svg';
|
||||
import restoreButton from '../../assets/titlebar/chrome-restore.svg';
|
||||
import {playSound} from '../notificationSounds';
|
||||
|
||||
import '../css/components/UpgradeButton.scss';
|
||||
|
@ -38,7 +34,6 @@ type Props = {
|
|||
openMenu: () => void;
|
||||
darkMode: boolean;
|
||||
appName: string;
|
||||
useNativeWindow: boolean;
|
||||
intl: IntlShape;
|
||||
};
|
||||
|
||||
|
@ -326,23 +321,13 @@ class MainPage extends React.PureComponent<Props, State> {
|
|||
this.handleSelectTab(tab[0].id!);
|
||||
};
|
||||
|
||||
handleClose = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
handleExitFullScreen = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
e.stopPropagation(); // since it is our button, the event goes into MainPage's onclick event, getting focus back.
|
||||
window.desktop.closeWindow();
|
||||
};
|
||||
|
||||
handleMinimize = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
e.stopPropagation();
|
||||
window.desktop.minimizeWindow();
|
||||
};
|
||||
|
||||
handleMaximize = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
e.stopPropagation();
|
||||
window.desktop.maximizeWindow();
|
||||
};
|
||||
|
||||
handleRestore = () => {
|
||||
window.desktop.restoreWindow();
|
||||
if (!this.state.fullScreen) {
|
||||
return;
|
||||
}
|
||||
window.desktop.exitFullScreen();
|
||||
};
|
||||
|
||||
openMenu = () => {
|
||||
|
@ -430,60 +415,6 @@ class MainPage extends React.PureComponent<Props, State> {
|
|||
/>
|
||||
) : null;
|
||||
|
||||
let maxButton;
|
||||
if (this.state.maximized || this.state.fullScreen) {
|
||||
maxButton = (
|
||||
<div
|
||||
className='button restore-button'
|
||||
onClick={this.handleRestore}
|
||||
>
|
||||
<img
|
||||
src={restoreButton}
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
maxButton = (
|
||||
<div
|
||||
className='button max-button'
|
||||
onClick={this.handleMaximize}
|
||||
>
|
||||
<img
|
||||
src={maximizeButton}
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let titleBarButtons;
|
||||
if (window.process.platform === 'win32' && !this.props.useNativeWindow) {
|
||||
titleBarButtons = (
|
||||
<span className='title-bar-btns'>
|
||||
<div
|
||||
className='button min-button'
|
||||
onClick={this.handleMinimize}
|
||||
>
|
||||
<img
|
||||
src={minimizeButton}
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
{maxButton}
|
||||
<div
|
||||
className='button close-button'
|
||||
onClick={this.handleClose}
|
||||
>
|
||||
<img
|
||||
src={closeButton}
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const totalMentionCount = Object.keys(this.state.mentionCounts).reduce((sum, key) => {
|
||||
// Strip out current server from unread and mention counts
|
||||
if (this.state.tabs.get(this.state.activeServerId!)?.map((tab) => tab.id).includes(key)) {
|
||||
|
@ -541,7 +472,16 @@ class MainPage extends React.PureComponent<Props, State> {
|
|||
)}
|
||||
{tabsRow}
|
||||
{downloadsDropdownButton}
|
||||
{titleBarButtons}
|
||||
{window.process.platform !== 'darwin' && this.state.fullScreen &&
|
||||
<span className='title-bar-btns'>
|
||||
<div
|
||||
className='button full-screen-button'
|
||||
onClick={this.handleExitFullScreen}
|
||||
>
|
||||
<i className='icon icon-arrow-collapse'/>
|
||||
</div>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</Row>
|
||||
);
|
||||
|
|
|
@ -176,23 +176,8 @@ body {
|
|||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.topBar .title-bar-btns>.close-button:hover {
|
||||
background: #E81123 !important;
|
||||
}
|
||||
|
||||
.topBar .title-bar-btns>.close-button:hover>img {
|
||||
filter: invert(100%);
|
||||
-webkit-filter: invert(100%);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.topBar .title-bar-btns>.close-button:active {
|
||||
background: #f1707a !important;
|
||||
}
|
||||
|
||||
.topBar .title-bar-btns>.close-button:active>img {
|
||||
filter: invert(100%);
|
||||
-webkit-filter: invert(100%);
|
||||
.topBar .title-bar-btns>.full-screen-button {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.topBar .title-bar-btns img {
|
||||
|
@ -204,14 +189,7 @@ body {
|
|||
-webkit-filter: invert(100%);
|
||||
}
|
||||
|
||||
.topBar .title-bar-btns>.min-button {
|
||||
grid-column: 1;
|
||||
}
|
||||
.topBar .title-bar-btns>.max-button, .topBar .title-bar-btns>.restore-button {
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.topBar .title-bar-btns>.close-button {
|
||||
.topBar .title-bar-btns>.close-button, .topBar .title-bar-btns>.full-screen-button {
|
||||
grid-column: 3;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,6 @@ class Root extends React.PureComponent<Record<string, never>, State> {
|
|||
openMenu={this.openMenu}
|
||||
darkMode={config.darkMode}
|
||||
appName={config.appName}
|
||||
useNativeWindow={config.useNativeWindow}
|
||||
/>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
|
|
@ -119,7 +119,6 @@ export type RegistryConfig = {
|
|||
|
||||
export type CombinedConfig = Omit<Config, 'teams'> & Omit<BuildConfig, 'defaultServers'> & {
|
||||
appName: string;
|
||||
useNativeWindow: boolean;
|
||||
}
|
||||
|
||||
export type LocalConfiguration = Config & {
|
||||
|
|
|
@ -34,10 +34,7 @@ declare global {
|
|||
openServersDropdown: () => void;
|
||||
switchTab: (viewId: string) => void;
|
||||
closeView: (viewId: string) => void;
|
||||
closeWindow: () => void;
|
||||
minimizeWindow: () => void;
|
||||
maximizeWindow: () => void;
|
||||
restoreWindow: () => void;
|
||||
exitFullScreen: () => void;
|
||||
doubleClickOnWindow: (windowName?: string) => void;
|
||||
focusCurrentView: () => void;
|
||||
reloadCurrentView: () => void;
|
||||
|
|
Loading…
Reference in a new issue