Counteract zoom-level changes in custom titlebar

This commit is contained in:
Fedor Indutny 2022-06-20 11:26:31 -07:00 committed by GitHub
parent dacbee711f
commit 9407654262
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 123 additions and 34 deletions

View File

@ -624,8 +624,10 @@ async function getTitleBarOverlay(): Promise<TitleBarOverlayOptions | false> {
color = '#e8e8e8'; color = '#e8e8e8';
symbolColor = '#1b1b1b'; symbolColor = '#1b1b1b';
} else if (theme === 'dark') { } else if (theme === 'dark') {
color = '#24292e'; // $color-gray-80
symbolColor = '#fff'; color = '#2e2e2e';
// $color-gray-05
symbolColor = '#e9e9e9';
} else { } else {
throw missingCaseError(theme); throw missingCaseError(theme);
} }

View File

@ -124,7 +124,7 @@
</head> </head>
<body class="overflow-hidden"> <body class="overflow-hidden">
<div id="app-container"> <div id="app-container">
<div class="app-loading-screen"> <div class="app-loading-screen app-loading-screen--without-titlebar">
<div class="module-title-bar-drag-area"></div> <div class="module-title-bar-drag-area"></div>
<div class="content"> <div class="content">

View File

@ -77,7 +77,7 @@
"fs-xattr": "0.3.0" "fs-xattr": "0.3.0"
}, },
"dependencies": { "dependencies": {
"@indutny/frameless-titlebar": "2.2.0", "@indutny/frameless-titlebar": "2.3.0-rc.4",
"@popperjs/core": "2.9.2", "@popperjs/core": "2.9.2",
"@react-spring/web": "9.4.5", "@react-spring/web": "9.4.5",
"@signalapp/libsignal-client": "0.17.0", "@signalapp/libsignal-client": "0.17.0",

View File

@ -225,8 +225,10 @@ $loading-height: 16px;
top: 0; top: 0;
bottom: 0; bottom: 0;
/* There is no titlebar during loading screen on Windows */ &--without-titlebar {
-webkit-app-region: drag; /* There is no titlebar during loading screen on Windows */
-webkit-app-region: drag;
}
/* Note: background-color is intentionally transparent until body has the /* Note: background-color is intentionally transparent until body has the
* theme class. * theme class.

View File

@ -2,6 +2,9 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
body { body {
// Overriden by ts/background.ts
--zoom-factor: 1;
// These should match the logic in `ts/types/Settings.ts`'s `getTitleBarVisibility`. // These should match the logic in `ts/types/Settings.ts`'s `getTitleBarVisibility`.
// //
// It'd be great if we could use the `:fullscreen` selector here, but that does not seem // It'd be great if we could use the `:fullscreen` selector here, but that does not seem
@ -9,7 +12,7 @@ body {
--title-bar-drag-area-height: 0px; // Needs to have a unit to work with `calc()`. --title-bar-drag-area-height: 0px; // Needs to have a unit to work with `calc()`.
--draggable-app-region: initial; --draggable-app-region: initial;
&.os-macos:not(.full-screen) { &.os-macos:not(.full-screen) {
--title-bar-drag-area-height: 28px; --title-bar-drag-area-height: calc(28px / var(--zoom-factor));
--draggable-app-region: drag; --draggable-app-region: drag;
} }
@ -17,12 +20,12 @@ body {
--titlebar-height: 0px; --titlebar-height: 0px;
&.os-windows:not(.full-screen) { &.os-windows:not(.full-screen) {
--titlebar-height: 28px; --titlebar-height: calc(28px / var(--zoom-factor));
// Account for border eating one pixel out of the titlebar and making it // Account for border eating one pixel out of the titlebar and making it
// look unbalanced // look unbalanced
&.os-windows-11 { &.os-windows-11 {
--titlebar-height: calc(28px + 1px); --titlebar-height: calc((28px + 1px) / var(--zoom-factor));
} }
--window-height: calc(100vh - var(--titlebar-height)); --window-height: calc(100vh - var(--titlebar-height));

View File

@ -10,8 +10,10 @@
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: calc(100vw * var(--zoom-factor));
z-index: $z-index-window-controls; z-index: $z-index-window-controls;
transform: scale(calc(1 / var(--zoom-factor)));
transform-origin: 0 0;
// This matches the inline styles of frameless-titlebar // This matches the inline styles of frameless-titlebar
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,

View File

@ -700,7 +700,16 @@ export async function startApp(): Promise<void> {
}, },
}); });
webFrame.setZoomFactor(window.Events.getZoomFactor()); const zoomFactor = window.Events.getZoomFactor();
webFrame.setZoomFactor(zoomFactor);
document.body.style.setProperty('--zoom-factor', zoomFactor.toString());
window.addEventListener('resize', () => {
document.body.style.setProperty(
'--zoom-factor',
webFrame.getZoomFactor().toString()
);
});
// How long since we were last running? // How long since we were last running?
const lastHeartbeat = toDayMillis(window.storage.get('lastHeartbeat', 0)); const lastHeartbeat = toDayMillis(window.storage.get('lastHeartbeat', 0));

View File

@ -38,6 +38,7 @@ type PropsType = {
menuOptions: MenuOptionsType; menuOptions: MenuOptionsType;
platform: string; platform: string;
isWindows11: boolean; isWindows11: boolean;
hideMenuBar: boolean;
executeMenuRole: ExecuteMenuRoleType; executeMenuRole: ExecuteMenuRoleType;
executeMenuAction: (action: MenuActionType) => void; executeMenuAction: (action: MenuActionType) => void;
@ -52,6 +53,7 @@ export const App = ({
executeMenuRole, executeMenuRole,
getPreferredBadge, getPreferredBadge,
hasInitialLoadCompleted, hasInitialLoadCompleted,
hideMenuBar,
i18n, i18n,
isCustomizingPreferredReactions, isCustomizingPreferredReactions,
isFullScreen, isFullScreen,
@ -152,12 +154,13 @@ export const App = ({
isFullScreen={isFullScreen} isFullScreen={isFullScreen}
platform={platform} platform={platform}
isWindows11={isWindows11} isWindows11={isWindows11}
executeMenuRole={executeMenuRole}
titleBarDoubleClick={titleBarDoubleClick}
hasMenu hasMenu
hideMenuBar={hideMenuBar}
localeMessages={localeMessages} localeMessages={localeMessages}
menuOptions={menuOptions} menuOptions={menuOptions}
executeMenuRole={executeMenuRole}
executeMenuAction={executeMenuAction} executeMenuAction={executeMenuAction}
titleBarDoubleClick={titleBarDoubleClick}
> >
<div <div
className={classNames({ className={classNames({

View File

@ -1,7 +1,7 @@
// Copyright 2021 Signal Messenger, LLC // Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import React from 'react'; import React, { useMemo } from 'react';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import TitleBar from '@indutny/frameless-titlebar'; import TitleBar from '@indutny/frameless-titlebar';
import type { MenuItem } from '@indutny/frameless-titlebar'; import type { MenuItem } from '@indutny/frameless-titlebar';
@ -28,6 +28,7 @@ export type PropsType = Readonly<{
isMaximized?: boolean; isMaximized?: boolean;
isFullScreen?: boolean; isFullScreen?: boolean;
isWindows11: boolean; isWindows11: boolean;
hideMenuBar?: boolean;
platform: string; platform: string;
executeMenuRole: ExecuteMenuRoleType; executeMenuRole: ExecuteMenuRoleType;
titleBarDoubleClick?: () => void; titleBarDoubleClick?: () => void;
@ -115,6 +116,7 @@ export const TitleBarContainer = (props: PropsType): JSX.Element => {
isMaximized, isMaximized,
isFullScreen, isFullScreen,
isWindows11, isWindows11,
hideMenuBar,
executeMenuRole, executeMenuRole,
titleBarDoubleClick, titleBarDoubleClick,
children, children,
@ -123,6 +125,81 @@ export const TitleBarContainer = (props: PropsType): JSX.Element => {
iconSrc = 'images/icon_32.png', iconSrc = 'images/icon_32.png',
} = props; } = props;
const titleBarTheme = useMemo(
() => ({
bar: {
// See stylesheets/_global.scss
height: isWindows11 ? TITLEBAR_HEIGHT + 1 : TITLEBAR_HEIGHT,
palette:
theme === ThemeType.light ? ('light' as const) : ('dark' as const),
...(theme === ThemeType.dark
? {
// $color-gray-05
color: '#e9e9e9',
// $color-gray-80
background: '#2e2e2e',
// $color-gray-95
borderBottom: '1px solid #121212',
//
button: {
active: {
// $color-gray-05
color: '#e9e9e9',
// $color-gray-75
background: '#3b3b3b',
},
hover: {
// $color-gray-05
color: '#e9e9e9',
// $color-gray-75
background: '#3b3b3b',
},
},
}
: {}),
},
// Hide overlay
menu: {
overlay: {
opacity: 0,
},
autoHide: hideMenuBar,
...(theme === ThemeType.dark
? {
separator: {
// $color-gray-95
color: '#5e5e5e',
},
accelerator: {
// $color-gray-25
color: '#b9b9b9',
},
list: {
// $color-gray-75
background: '#3b3b3b',
boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.12)',
borderRadius: '0px 0px 6px 6px',
},
}
: {
list: {
boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.12)',
borderRadius: '0px 0px 6px 6px',
},
}),
},
// Zoom support
enableOverflow: false,
scalingFunction(value: string) {
return `calc(${value} * var(--zoom-factor))`;
},
}),
[theme, isWindows11, hideMenuBar]
);
if (platform !== 'win32' || isFullScreen) { if (platform !== 'win32' || isFullScreen) {
return <>{children}</>; return <>{children}</>;
} }
@ -157,22 +234,6 @@ export const TitleBarContainer = (props: PropsType): JSX.Element => {
maybeMenu = convertMenu(menuTemplate, executeMenuRole); maybeMenu = convertMenu(menuTemplate, executeMenuRole);
} }
const titleBarTheme = {
bar: {
// See stylesheets/_global.scss
height: isWindows11 ? TITLEBAR_HEIGHT + 1 : TITLEBAR_HEIGHT,
palette:
theme === ThemeType.light ? ('light' as const) : ('dark' as const),
},
// Hide overlay
menu: {
overlay: {
opacity: 0,
},
},
};
return ( return (
<div className="TitleBarContainer"> <div className="TitleBarContainer">
<TitleBar <TitleBar

View File

@ -118,3 +118,8 @@ export const getPreferredReactionEmoji = createSelector(
skinTone skinTone
) )
); );
export const getHideMenuBar = createSelector(
getItems,
(state: ItemsStateType): boolean => Boolean(state['hide-menu-bar'])
);

View File

@ -25,6 +25,7 @@ import {
getPlatform, getPlatform,
} from '../selectors/user'; } from '../selectors/user';
import { shouldShowStoriesView } from '../selectors/stories'; import { shouldShowStoriesView } from '../selectors/stories';
import { getHideMenuBar } from '../selectors/items';
import { getConversationsStoppingSend } from '../selectors/conversations'; import { getConversationsStoppingSend } from '../selectors/conversations';
import { getIsCustomizingPreferredReactions } from '../selectors/preferredReactions'; import { getIsCustomizingPreferredReactions } from '../selectors/preferredReactions';
import { mapDispatchToProps } from '../actions'; import { mapDispatchToProps } from '../actions';
@ -43,6 +44,7 @@ const mapStateToProps = (state: StateType) => {
menuOptions: getMenuOptions(state), menuOptions: getMenuOptions(state),
platform: getPlatform(state), platform: getPlatform(state),
isWindows11: window.SignalContext.OS.isWindows11(), isWindows11: window.SignalContext.OS.isWindows11(),
hideMenuBar: getHideMenuBar(state),
renderCallManager: () => <SmartCallManager />, renderCallManager: () => <SmartCallManager />,
renderCustomizingPreferredReactionsModal: () => ( renderCustomizingPreferredReactionsModal: () => (
<SmartCustomizingPreferredReactionsModal /> <SmartCustomizingPreferredReactionsModal />

View File

@ -1378,10 +1378,10 @@
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
"@indutny/frameless-titlebar@2.2.0": "@indutny/frameless-titlebar@2.3.0-rc.4":
version "2.2.0" version "2.3.0-rc.4"
resolved "https://registry.yarnpkg.com/@indutny/frameless-titlebar/-/frameless-titlebar-2.2.0.tgz#600ad754dda50105d2c4fe0de8bb25837eca1a8c" resolved "https://registry.yarnpkg.com/@indutny/frameless-titlebar/-/frameless-titlebar-2.3.0-rc.4.tgz#1d70427e12047e655231e0c1eabf962ce1fda54d"
integrity sha512-TJQ3ZJyUdtOAVIdGSV8GxXPPpt6WdlFtqwDAvgV2SbOXng5/uioSBd7iySyDA48suR7XCaa41V4/xp/E/5uVpg== integrity sha512-c4UOLJE/3Poimqtfk0MsSw8/2lqGl7ssfzH0Ufz2nEeTfedTujBQGr2YkkbxxvAYRDGz5vrHQPbFpYXB93Zv5g==
dependencies: dependencies:
classnames "^2.2.6" classnames "^2.2.6"
deepmerge "^4.2.2" deepmerge "^4.2.2"