element-desktop/src/macos-titlebar.ts
2023-10-25 10:10:52 +01:00

165 lines
5.7 KiB
TypeScript

/*
Copyright 2023 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { BrowserWindow } from "electron";
export function setupMacosTitleBar(window: BrowserWindow): void {
if (process.platform !== "darwin") return;
let cssKey: string | undefined;
async function applyStyling(): Promise<void> {
cssKey = await window.webContents.insertCSS(`
/* Create margin of space for the traffic light buttons */
.mx_UserMenu {
/* We zero the margin and use padding as we want to use it as a drag handle */
margin-top: 0 !important;
margin-left: 0 !important;
padding-top: 32px !important;
padding-left: 20px !important;
-webkit-app-region: drag;
-webkit-user-select: none;
}
/* Exclude the button from being a drag handle and not working */
.mx_UserMenu > * {
-webkit-app-region: no-drag;
}
/* Maintain alignment of the toggle space panel button */
.mx_SpacePanel_toggleCollapse {
/* 19px original top value, 32px margin-top above, 12px original margin-top value */
top: calc(19px + 32px - 12px) !important;
}
/* Prevent the media lightbox sender info from clipping into the traffic light buttons */
.mx_ImageView_info_wrapper {
margin-top: 32px;
}
/* Mark the splash screen as a drag handle */
.mx_MatrixChat_splash {
-webkit-app-region: drag;
}
/* Exclude the splash buttons from being drag handles */
.mx_MatrixChat_splashButtons {
-webkit-app-region: no-drag;
}
/* Mark the background as a drag handle */
.mx_AuthPage {
-webkit-app-region: drag;
}
/* Exclude the main content elements from being drag handles */
.mx_AuthPage .mx_AuthPage_modalBlur,
.mx_AuthPage .mx_AuthFooter > * {
-webkit-app-region: no-drag;
}
/* Mark the home page background as a drag handle */
.mx_HomePage {
-webkit-app-region: drag;
}
/* Exclude interactive elements from being drag handles */
.mx_HomePage .mx_HomePage_body,
.mx_HomePage .mx_HomePage_default_wrapper > * {
-webkit-app-region: no-drag;
}
/* Mark the header as a drag handle */
.mx_ImageView_panel {
-webkit-app-region: drag;
}
/* Exclude header interactive elements from being drag handles */
.mx_ImageView_panel > .mx_ImageView_info_wrapper,
.mx_ImageView_panel > .mx_ImageView_title,
.mx_ImageView_panel > .mx_ImageView_toolbar > * {
-webkit-app-region: no-drag;
}
/* Mark the background as a drag handle only if no modal is open */
.mx_MatrixChat_wrapper[aria-hidden="false"] .mx_RoomView_wrapper,
.mx_MatrixChat_wrapper[aria-hidden="false"] .mx_HomePage {
-webkit-app-region: drag;
}
/* Exclude content elements from being drag handles */
.mx_SpaceRoomView_landing > *,
.mx_RoomPreviewBar,
.mx_RoomView_body,
.mx_AutoHideScrollbar,
.mx_RightPanel_ResizeWrapper,
.mx_RoomPreviewCard,
.mx_LeftPanel,
.mx_RoomView,
.mx_SpaceRoomView,
.mx_AccessibleButton {
-webkit-app-region: no-drag;
}
/* Exclude context menus and their backgrounds */
.mx_ContextualMenu, .mx_ContextualMenu_background {
-webkit-app-region: no-drag;
}
/* Exclude iframes, such as recaptcha */
iframe {
-webkit-app-region: no-drag;
}
/* Add a bar above room header + left panel */
.mx_LeftPanel {
flex-direction: column;
}
.mx_LeftPanel::before {
content: "";
height: 20px;
-webkit-app-region: drag;
}
.mx_RoomView::before,
.mx_SpaceRoomView::before {
content: "";
-webkit-app-region: drag;
}
.mx_SpaceRoomView::before {
display: block;
height: 24px;
}
.mx_RoomView[data-room-header="new"]::before {
height: 13px;
}
.mx_RoomView[data-room-header="legacy"]::before {
height: 27px;
}
`);
}
window.on("enter-full-screen", () => {
if (cssKey !== undefined) {
window.webContents.removeInsertedCSS(cssKey);
}
});
window.on("leave-full-screen", () => {
applyStyling();
});
window.webContents.on("did-finish-load", () => {
if (!window.isFullScreen()) {
applyStyling();
}
});
}