From 94076542628383d8b1e20b71a2a4a799a16faf2d Mon Sep 17 00:00:00 2001 From: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> Date: Mon, 20 Jun 2022 11:26:31 -0700 Subject: [PATCH] Counteract zoom-level changes in custom titlebar --- app/main.ts | 6 +- background.html | 2 +- package.json | 2 +- stylesheets/_global.scss | 6 +- stylesheets/_titlebar.scss | 9 +- stylesheets/components/TitleBarContainer.scss | 4 +- ts/background.ts | 11 ++- ts/components/App.tsx | 7 +- ts/components/TitleBarContainer.tsx | 95 +++++++++++++++---- ts/state/selectors/items.ts | 5 + ts/state/smart/App.tsx | 2 + yarn.lock | 8 +- 12 files changed, 123 insertions(+), 34 deletions(-) diff --git a/app/main.ts b/app/main.ts index f6b50fccc..5b74bca8f 100644 --- a/app/main.ts +++ b/app/main.ts @@ -624,8 +624,10 @@ async function getTitleBarOverlay(): Promise { color = '#e8e8e8'; symbolColor = '#1b1b1b'; } else if (theme === 'dark') { - color = '#24292e'; - symbolColor = '#fff'; + // $color-gray-80 + color = '#2e2e2e'; + // $color-gray-05 + symbolColor = '#e9e9e9'; } else { throw missingCaseError(theme); } diff --git a/background.html b/background.html index 57f1bb46a..60b92c433 100644 --- a/background.html +++ b/background.html @@ -124,7 +124,7 @@
-
+
diff --git a/package.json b/package.json index be3e9cd6f..4f8a3df3e 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "fs-xattr": "0.3.0" }, "dependencies": { - "@indutny/frameless-titlebar": "2.2.0", + "@indutny/frameless-titlebar": "2.3.0-rc.4", "@popperjs/core": "2.9.2", "@react-spring/web": "9.4.5", "@signalapp/libsignal-client": "0.17.0", diff --git a/stylesheets/_global.scss b/stylesheets/_global.scss index 5306bb3ff..c02bb9f70 100644 --- a/stylesheets/_global.scss +++ b/stylesheets/_global.scss @@ -225,8 +225,10 @@ $loading-height: 16px; top: 0; bottom: 0; - /* There is no titlebar during loading screen on Windows */ - -webkit-app-region: drag; + &--without-titlebar { + /* There is no titlebar during loading screen on Windows */ + -webkit-app-region: drag; + } /* Note: background-color is intentionally transparent until body has the * theme class. diff --git a/stylesheets/_titlebar.scss b/stylesheets/_titlebar.scss index 3cda13aa6..bd1346491 100644 --- a/stylesheets/_titlebar.scss +++ b/stylesheets/_titlebar.scss @@ -2,6 +2,9 @@ // SPDX-License-Identifier: AGPL-3.0-only body { + // Overriden by ts/background.ts + --zoom-factor: 1; + // 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 @@ -9,7 +12,7 @@ body { --title-bar-drag-area-height: 0px; // Needs to have a unit to work with `calc()`. --draggable-app-region: initial; &.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; } @@ -17,12 +20,12 @@ body { --titlebar-height: 0px; &.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 // look unbalanced &.os-windows-11 { - --titlebar-height: calc(28px + 1px); + --titlebar-height: calc((28px + 1px) / var(--zoom-factor)); } --window-height: calc(100vh - var(--titlebar-height)); diff --git a/stylesheets/components/TitleBarContainer.scss b/stylesheets/components/TitleBarContainer.scss index fbdfcd402..2ad010720 100644 --- a/stylesheets/components/TitleBarContainer.scss +++ b/stylesheets/components/TitleBarContainer.scss @@ -10,8 +10,10 @@ position: fixed; top: 0; left: 0; - width: 100%; + width: calc(100vw * var(--zoom-factor)); 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 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, diff --git a/ts/background.ts b/ts/background.ts index 6ac47cdb3..231b11a94 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -700,7 +700,16 @@ export async function startApp(): Promise { }, }); - 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? const lastHeartbeat = toDayMillis(window.storage.get('lastHeartbeat', 0)); diff --git a/ts/components/App.tsx b/ts/components/App.tsx index 68540021c..0aaf185a8 100644 --- a/ts/components/App.tsx +++ b/ts/components/App.tsx @@ -38,6 +38,7 @@ type PropsType = { menuOptions: MenuOptionsType; platform: string; isWindows11: boolean; + hideMenuBar: boolean; executeMenuRole: ExecuteMenuRoleType; executeMenuAction: (action: MenuActionType) => void; @@ -52,6 +53,7 @@ export const App = ({ executeMenuRole, getPreferredBadge, hasInitialLoadCompleted, + hideMenuBar, i18n, isCustomizingPreferredReactions, isFullScreen, @@ -152,12 +154,13 @@ export const App = ({ isFullScreen={isFullScreen} platform={platform} isWindows11={isWindows11} + executeMenuRole={executeMenuRole} + titleBarDoubleClick={titleBarDoubleClick} hasMenu + hideMenuBar={hideMenuBar} localeMessages={localeMessages} menuOptions={menuOptions} - executeMenuRole={executeMenuRole} executeMenuAction={executeMenuAction} - titleBarDoubleClick={titleBarDoubleClick} >
void; @@ -115,6 +116,7 @@ export const TitleBarContainer = (props: PropsType): JSX.Element => { isMaximized, isFullScreen, isWindows11, + hideMenuBar, executeMenuRole, titleBarDoubleClick, children, @@ -123,6 +125,81 @@ export const TitleBarContainer = (props: PropsType): JSX.Element => { iconSrc = 'images/icon_32.png', } = 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) { return <>{children}; } @@ -157,22 +234,6 @@ export const TitleBarContainer = (props: PropsType): JSX.Element => { 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 (
Boolean(state['hide-menu-bar']) +); diff --git a/ts/state/smart/App.tsx b/ts/state/smart/App.tsx index bdde0fa85..49e36078d 100644 --- a/ts/state/smart/App.tsx +++ b/ts/state/smart/App.tsx @@ -25,6 +25,7 @@ import { getPlatform, } from '../selectors/user'; import { shouldShowStoriesView } from '../selectors/stories'; +import { getHideMenuBar } from '../selectors/items'; import { getConversationsStoppingSend } from '../selectors/conversations'; import { getIsCustomizingPreferredReactions } from '../selectors/preferredReactions'; import { mapDispatchToProps } from '../actions'; @@ -43,6 +44,7 @@ const mapStateToProps = (state: StateType) => { menuOptions: getMenuOptions(state), platform: getPlatform(state), isWindows11: window.SignalContext.OS.isWindows11(), + hideMenuBar: getHideMenuBar(state), renderCallManager: () => , renderCustomizingPreferredReactionsModal: () => ( diff --git a/yarn.lock b/yarn.lock index 4b433c554..d104c47d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1378,10 +1378,10 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@indutny/frameless-titlebar@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@indutny/frameless-titlebar/-/frameless-titlebar-2.2.0.tgz#600ad754dda50105d2c4fe0de8bb25837eca1a8c" - integrity sha512-TJQ3ZJyUdtOAVIdGSV8GxXPPpt6WdlFtqwDAvgV2SbOXng5/uioSBd7iySyDA48suR7XCaa41V4/xp/E/5uVpg== +"@indutny/frameless-titlebar@2.3.0-rc.4": + version "2.3.0-rc.4" + resolved "https://registry.yarnpkg.com/@indutny/frameless-titlebar/-/frameless-titlebar-2.3.0-rc.4.tgz#1d70427e12047e655231e0c1eabf962ce1fda54d" + integrity sha512-c4UOLJE/3Poimqtfk0MsSw8/2lqGl7ssfzH0Ufz2nEeTfedTujBQGr2YkkbxxvAYRDGz5vrHQPbFpYXB93Zv5g== dependencies: classnames "^2.2.6" deepmerge "^4.2.2"