Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Window Controls Overlay #8707

Merged
merged 12 commits into from
Jul 16, 2023
Merged

Implement Window Controls Overlay #8707

merged 12 commits into from
Jul 16, 2023

Conversation

ferothefox
Copy link
Contributor

@ferothefox ferothefox commented Jul 14, 2023

Fixes: #7199 #8650 #6278 #4292 (on Windows)

Hey @Eugeny, I've daily-driven Tabby for a little while and I love its customizability. It reminds me of Vivaldi in a lot of ways! This is my first PR here and I'd love to try to fix a long-standing issue with the tab bar location and the window controls.

This PR aims to mitigate this issue by replacing the custom window controls with the Window Controls Overlay API that Electron provides.

Specifically, my code:

  • Updates Electron to the latest stable (from version 22 to version 25) to fix an issue where overlay buttons with transparennt backgrounds have issues with hover styles (see fix: WCO transparent background electron/electron#38693). This does not seem to affect any other functionality in Tabby - all packages appear to work fine and no obvious breaking changes were observed. I've been able to build and run the app perfectly fine.
  • Adds new styles to compensate for the space taken up by the controls. Extra padding and adjustments are needed to prevent clipping.

Known issues

I've tested this throroughly on Windows 11, but there's some other issues with this implementation that need to be addressed in order for this to be considered production-ready.

Issue 1

  • Currently, this is only feasibly usable dark themes. The background color of the overlayed buttons are transparent to not clash with any themes, but the icon colors are hardcoded to white.

here's a visual example:
image

Dark themes work flawlessly, however in lighter themes...

image
It is impossible to know the window buttons exist, even when hovering directly over them.

We'd need to implement a way to pass the currently applied theme's colors to Electron (probably via IPC) and update the colors of the window controls accordingly so that they don't cause issues like this.

Issue 2

  • the settings button is obscured when the window frame is set to thin and tabs location is on top.
    image

Issue 3

  • I did not consider Linux heavily when I made this PR. Linux users will still see a broken window controls experience when not using the native titlebar. This should probably be set by default if a user is on Linux.

Other than that, I'm proud of how this turned out!
electron_un4bK8oc2L

@Eugeny
Copy link
Owner

Eugeny commented Jul 14, 2023

Thank you! Might be a stupid question, but what are the advantages of WCO besides it being native?

PS issue 1: you'd need to watch for config changes and respond to them in window.ts same way it's done for window vibrancy settings right now. Issue 2 is just a missing margin somewhere now that the window controls are not in the DOM tree.

@ferothefox
Copy link
Contributor Author

Not a stupid question at all! That's exactly its advantage. It unifies window control implementations across macOS and Windows. IIRC setting frame to false on macOS defaults to WCO. On Windows 11, it lets people use snap layouts

@ferothefox
Copy link
Contributor Author

ferothefox commented Jul 14, 2023

@Eugeny Pinging for the latest update - the WCO colors now respect the theme that you're using :)

electron_pxyW3eUJHX.mp4

Also, apologies for the messy commits below. Trying to rapidly iterate and it's evidently not the wisest thing to do right now. This is practically finished IMO, just waiting for your review.

@ferothefox
Copy link
Contributor Author

ferothefox commented Jul 16, 2023

After a day of using a built version of the last commit here, I can say it's working quite smoothly now. Not sure how to resolve the CI errors, but I'm sure it's nothing a re-run can't fix. No rush to merge or anything :)

Edit: it looks like we're going to be all green following this merge!

Copy link
Owner

@Eugeny Eugeny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few comments, otherwise LGTM ✌️

@@ -94,12 +94,19 @@ export class Window {
} else {
if (process.platform === 'darwin') {
bwOptions.titleBarStyle = 'hidden'
// If not macOS and native appearance is not toggled, use WCO.
} else {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does WCO work on Linux? This code path implies it does, the comment in titleBar.component.scss implies it doesn't.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't, but good catch, will fix

@@ -94,12 +94,19 @@ export class Window {
} else {
if (process.platform === 'darwin') {
bwOptions.titleBarStyle = 'hidden'
// If not macOS and native appearance is not toggled, use WCO.
} else {
bwOptions.titleBarStyle = 'hidden'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be moved out of the if

}
}

if (process.platform === 'darwin') {
this.window = new BrowserWindow(bwOptions) as GlasstronWindow
} else {
// this.window = new BrowserWindow(bwOptions) as GlasstronWindow
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please clean up commented code across the PR

@@ -1,16 +1,20 @@
title-bar(
*ngIf='ready && !hostWindow.isFullscreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
(dblclick)='hostWindow.toggleMaximize()',
[class.hide-controls]='hostApp.platform !== Platform.Linux && !hostWindow.isFullscreen',
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be controlled via an @input on TitleBarComponent, not a class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the latest commit, window controls in the titlebar component is an ngIf now ✨

@ferothefox
Copy link
Contributor Author

I believe that resolves your comments :)

@Eugeny Eugeny merged commit ddab79d into Eugeny:master Jul 16, 2023
@Eugeny
Copy link
Owner

Eugeny commented Jul 16, 2023

Tested on all 3 platforms and it works nicely - well done!

@all-contributors add @ferothefox for code

@allcontributors
Copy link
Contributor

@Eugeny

I've put up a pull request to add @ferothefox! 🎉

@Clem-Fern
Copy link
Contributor

Hi @Eugeny, @ferothefox :)
I hope you two doing well.

I encountered an error while working on tabby with the master branch and I think it has something to do with this PR (I'm on Linux):

index.ts:173 Unhandled exception: TypeError: this.window.setTitleBarOverlay is not a function
    at IpcMainImpl.<anonymous> (/home/clem/git/tabby/app/dist/webpack:/tabby/lib/window.ts:397:25)
    at IpcMainImpl.emit (node:events:513:28)
    at IpcMainImpl.emit (node:domain:489:12)
    at WebContents.<anonymous> (node:electron/js2c/browser_init:2:88498)
    at WebContents.emit (node:events:513:28)
    at WebContents.emit (node:domain:489:12)

tabby/app/lib/window.ts

Lines 390 to 403 in 0101ffd

ipcMain.on('window-set-window-controls-color', (event, theme) => {
if (!this.window || event.sender !== this.window.webContents) {
return
}
const symbolColor: string = theme.foreground
this.window.setTitleBarOverlay(
{
symbolColor: symbolColor,
height: 32,
},
)
})

After a quick look in the electron doc, it seems that the function setTitleBarOverlay is available on Windows platform only.

@Eugeny
Copy link
Owner

Eugeny commented Jul 19, 2023

Hey, normally when Electron docs refer to functions as only available on platform X, that means it's a noop on other platforms (also supported by the electron TS typings). I've seen it too, but the error by itself is harmless as the setTitleBarOverlay call is at the very end of the event handler.

I'm waiting to see if it's going to be fixed in the electron updates and if it's not, I'll just replace it with this.window['setTitleBarOverlay']?.(...

@Clem-Fern
Copy link
Contributor

Oh I see, I was not sure what was the impact exactly so, in doubt, i preferred report this.
Thank's for your insight anyway ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

the windows controlls moves to left bottom when tabs are aranged to left.
3 participants